hrev50424 adds 1 changeset to branch 'master'
old head: 00a3a794e0484d4c40daf5256568069b56669cab
new head: a933bb4cbca665fa18c5718219a3143a63763f30
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=a933bb4cbca6+%5E00a3a794e048
----------------------------------------------------------------------------
a933bb4cbca6: intel_extreme: IronLake reference clock activation
[ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev50424
Commit: a933bb4cbca665fa18c5718219a3143a63763f30
URL: http://cgit.haiku-os.org/haiku/commit/?id=a933bb4cbca6
Author: Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date: Sun Jul 17 20:25:08 2016 UTC
----------------------------------------------------------------------------
4 files changed, 130 insertions(+), 1 deletion(-)
.../graphics/intel_extreme/intel_extreme.h | 24 ++++++
.../accelerants/intel_extreme/accelerant.cpp | 19 ++++-
src/add-ons/accelerants/intel_extreme/pll.cpp | 86 ++++++++++++++++++++
src/add-ons/accelerants/intel_extreme/pll.h | 2 +
----------------------------------------------------------------------------
diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h
b/headers/private/graphics/intel_extreme/intel_extreme.h
index 0a5e951..839bdb4 100644
--- a/headers/private/graphics/intel_extreme/intel_extreme.h
+++ b/headers/private/graphics/intel_extreme/intel_extreme.h
@@ -711,6 +711,30 @@ struct intel_free_graphics_memory {
#define INTEL_DISPLAY_B_PLL (0x6018 |
REGS_SOUTH_SHARED)
#define CHV_DISPLAY_C_PLL (0x6030 |
REGS_SOUTH_SHARED)
+// Ironlake PCH reference clk control
+#define PCH_DREF_CONTROL (0x6200 |
REGS_SOUTH_SHARED)
+#define DREF_CONTROL_MASK 0x7fc3
+#define DREF_CPU_SOURCE_OUTPUT_DISABLE (0 << 13)
+#define DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD (2 << 13)
+#define DREF_CPU_SOURCE_OUTPUT_NONSPREAD (3 << 13)
+#define DREF_CPU_SOURCE_OUTPUT_MASK (3 << 13)
+#define DREF_SSC_SOURCE_DISABLE (0 << 11)
+#define DREF_SSC_SOURCE_ENABLE (2 << 11)
+#define DREF_SSC_SOURCE_MASK (3 << 11)
+#define DREF_NONSPREAD_SOURCE_DISABLE (0 << 9)
+#define DREF_NONSPREAD_CK505_ENABLE (1 << 9)
+#define DREF_NONSPREAD_SOURCE_ENABLE (2 << 9)
+#define DREF_NONSPREAD_SOURCE_MASK (3 << 9)
+#define DREF_SUPERSPREAD_SOURCE_DISABLE (0 << 7)
+#define DREF_SUPERSPREAD_SOURCE_ENABLE (2 << 7)
+#define DREF_SUPERSPREAD_SOURCE_MASK (3 << 7)
+#define DREF_SSC4_DOWNSPREAD (0 << 6)
+#define DREF_SSC4_CENTERSPREAD (1 << 6)
+#define DREF_SSC1_DISABLE (0 << 1)
+#define DREF_SSC1_ENABLE (1 << 1)
+#define DREF_SSC4_DISABLE (0 << 0)
+#define DREF_SSC4_ENABLE (1 << 0)
+
// Multiplier Divisor
#define INTEL_DISPLAY_A_PLL_MD (0x601C | REGS_SOUTH_SHARED)
#define INTEL_DISPLAY_B_PLL_MD (0x6020 | REGS_SOUTH_SHARED)
diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp
b/src/add-ons/accelerants/intel_extreme/accelerant.cpp
index f2adfe2..d9ca237 100644
--- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp
+++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2016, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -294,6 +294,8 @@ probe_ports()
read32(INTEL_DIGITAL_PORT_B), read32(INTEL_DIGITAL_PORT_C));
TRACE("lvds: %08" B_PRIx32 "\n", read32(INTEL_DIGITAL_LVDS_PORT));
+ bool foundLVDS = false;
+
gInfo->port_count = 0;
for (int i = INTEL_PORT_A; i <= INTEL_PORT_D; i++) {
Port* displayPort = new(std::nothrow)
DisplayPort((port_index)i);
@@ -368,6 +370,7 @@ probe_ports()
if (lvdsPort == NULL)
return B_NO_MEMORY;
if (lvdsPort->IsConnected()) {
+ foundLVDS = true;
gInfo->ports[gInfo->port_count++] = lvdsPort;
gInfo->head_mode |= HEAD_MODE_LVDS_PANEL;
gInfo->head_mode |= HEAD_MODE_B_DIGITAL;
@@ -387,6 +390,20 @@ probe_ports()
if (gInfo->port_count == 0)
return B_ERROR;
+ // Activate reference clocks if needed
+ if (gInfo->shared_info->pch_info == INTEL_PCH_IBX
+ || gInfo->shared_info->pch_info == INTEL_PCH_CPT) {
+ // XXX: Is LVDS the same as Panel?
+ refclk_activate_ilk(foundLVDS);
+ }
+ /*
+ } else if (gInfo->shared_info->pch_info == INTEL_PCH_LPT) {
+ // TODO: Some kind of stepped bend thing?
+ // only needed for vga
+ refclk_activate_lpt(foundLVDS);
+ }
+ */
+
return B_OK;
}
diff --git a/src/add-ons/accelerants/intel_extreme/pll.cpp
b/src/add-ons/accelerants/intel_extreme/pll.cpp
index fa6b9cb..ff80495 100644
--- a/src/add-ons/accelerants/intel_extreme/pll.cpp
+++ b/src/add-ons/accelerants/intel_extreme/pll.cpp
@@ -463,6 +463,92 @@ compute_pll_divisors(display_mode* current, pll_divisors*
divisors, bool isLVDS)
}
+void
+refclk_activate_ilk(bool hasPanel)
+{
+ CALLED();
+
+ // aka, our engineers hate you
+
+ bool wantsSSC;
+ bool hasCK505;
+ if (gInfo->shared_info->pch_info == INTEL_PCH_IBX) {
+ //XXX: This should be == vbt display_clock_mode
+ hasCK505 = true;
+ wantsSSC = hasCK505;
+ } else {
+ hasCK505 = false;
+ wantsSSC = true;
+ }
+
+ uint32 clkRef = read32(PCH_DREF_CONTROL);
+ uint32 newRef = clkRef;
+
+ newRef &= ~DREF_NONSPREAD_SOURCE_MASK;
+
+ if (hasCK505)
+ newRef |= DREF_NONSPREAD_CK505_ENABLE;
+ else
+ newRef |= DREF_NONSPREAD_SOURCE_ENABLE;
+
+ newRef &= ~DREF_SSC_SOURCE_MASK;
+ newRef &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
+ newRef &= ~DREF_SSC1_ENABLE;
+
+ if (newRef == clkRef) {
+ TRACE("%s: No changes to reference clock.\n", __func__);
+ return;
+ }
+
+ if (hasPanel) {
+ newRef &= ~DREF_SSC_SOURCE_MASK;
+ newRef |= DREF_SSC_SOURCE_ENABLE;
+
+ if (wantsSSC)
+ newRef |= DREF_SSC1_ENABLE;
+ else
+ newRef &= ~DREF_SSC1_ENABLE;
+
+ // Power up SSC before enabling outputs
+ write32(PCH_DREF_CONTROL, newRef);
+ read32(PCH_DREF_CONTROL);
+ spin(200);
+
+ newRef &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
+
+ bool hasEDP = true;
+ if (hasEDP) {
+ if (wantsSSC)
+ newRef |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
+ else
+ newRef |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
+ } else
+ newRef |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
+
+ write32(PCH_DREF_CONTROL, newRef);
+ read32(PCH_DREF_CONTROL);
+ spin(200);
+ } else {
+ newRef &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
+ newRef |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
+
+ write32(PCH_DREF_CONTROL, newRef);
+ read32(PCH_DREF_CONTROL);
+ spin(200);
+
+ if (!wantsSSC) {
+ newRef &= ~DREF_SSC_SOURCE_MASK;
+ newRef |= DREF_SSC_SOURCE_DISABLE;
+ newRef &= ~DREF_SSC1_ENABLE;
+
+ write32(PCH_DREF_CONTROL, newRef);
+ read32(PCH_DREF_CONTROL);
+ spin(200);
+ }
+ }
+}
+
+
#ifdef PLL_TEST_MODE
const struct test_device {
diff --git a/src/add-ons/accelerants/intel_extreme/pll.h
b/src/add-ons/accelerants/intel_extreme/pll.h
index 2b607ce..d30edd2 100644
--- a/src/add-ons/accelerants/intel_extreme/pll.h
+++ b/src/add-ons/accelerants/intel_extreme/pll.h
@@ -36,5 +36,7 @@ bool valid_pll_divisors(pll_divisors* divisors, pll_limits*
limits);
void compute_pll_divisors(display_mode* current, pll_divisors* divisors,
bool isLVDS);
+void refclk_activate_ilk(bool hasPanel);
+
#endif /* INTEL_EXTREME_PLL_H */