intel_extreme: IronLake reference clock activation
This commit is contained in:
@@ -711,6 +711,30 @@ struct intel_free_graphics_memory {
|
|||||||
#define INTEL_DISPLAY_B_PLL (0x6018 | REGS_SOUTH_SHARED)
|
#define INTEL_DISPLAY_B_PLL (0x6018 | REGS_SOUTH_SHARED)
|
||||||
#define CHV_DISPLAY_C_PLL (0x6030 | 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
|
// Multiplier Divisor
|
||||||
#define INTEL_DISPLAY_A_PLL_MD (0x601C | REGS_SOUTH_SHARED)
|
#define INTEL_DISPLAY_A_PLL_MD (0x601C | REGS_SOUTH_SHARED)
|
||||||
#define INTEL_DISPLAY_B_PLL_MD (0x6020 | REGS_SOUTH_SHARED)
|
#define INTEL_DISPLAY_B_PLL_MD (0x6020 | REGS_SOUTH_SHARED)
|
||||||
|
|||||||
@@ -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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -294,6 +294,8 @@ probe_ports()
|
|||||||
read32(INTEL_DIGITAL_PORT_B), read32(INTEL_DIGITAL_PORT_C));
|
read32(INTEL_DIGITAL_PORT_B), read32(INTEL_DIGITAL_PORT_C));
|
||||||
TRACE("lvds: %08" B_PRIx32 "\n", read32(INTEL_DIGITAL_LVDS_PORT));
|
TRACE("lvds: %08" B_PRIx32 "\n", read32(INTEL_DIGITAL_LVDS_PORT));
|
||||||
|
|
||||||
|
bool foundLVDS = false;
|
||||||
|
|
||||||
gInfo->port_count = 0;
|
gInfo->port_count = 0;
|
||||||
for (int i = INTEL_PORT_A; i <= INTEL_PORT_D; i++) {
|
for (int i = INTEL_PORT_A; i <= INTEL_PORT_D; i++) {
|
||||||
Port* displayPort = new(std::nothrow) DisplayPort((port_index)i);
|
Port* displayPort = new(std::nothrow) DisplayPort((port_index)i);
|
||||||
@@ -368,6 +370,7 @@ probe_ports()
|
|||||||
if (lvdsPort == NULL)
|
if (lvdsPort == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
if (lvdsPort->IsConnected()) {
|
if (lvdsPort->IsConnected()) {
|
||||||
|
foundLVDS = true;
|
||||||
gInfo->ports[gInfo->port_count++] = lvdsPort;
|
gInfo->ports[gInfo->port_count++] = lvdsPort;
|
||||||
gInfo->head_mode |= HEAD_MODE_LVDS_PANEL;
|
gInfo->head_mode |= HEAD_MODE_LVDS_PANEL;
|
||||||
gInfo->head_mode |= HEAD_MODE_B_DIGITAL;
|
gInfo->head_mode |= HEAD_MODE_B_DIGITAL;
|
||||||
@@ -387,6 +390,20 @@ probe_ports()
|
|||||||
if (gInfo->port_count == 0)
|
if (gInfo->port_count == 0)
|
||||||
return B_ERROR;
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
#ifdef PLL_TEST_MODE
|
||||||
|
|
||||||
const struct test_device {
|
const struct test_device {
|
||||||
|
|||||||
@@ -36,5 +36,7 @@ bool valid_pll_divisors(pll_divisors* divisors, pll_limits* limits);
|
|||||||
void compute_pll_divisors(display_mode* current, pll_divisors* divisors,
|
void compute_pll_divisors(display_mode* current, pll_divisors* divisors,
|
||||||
bool isLVDS);
|
bool isLVDS);
|
||||||
|
|
||||||
|
void refclk_activate_ilk(bool hasPanel);
|
||||||
|
|
||||||
|
|
||||||
#endif /* INTEL_EXTREME_PLL_H */
|
#endif /* INTEL_EXTREME_PLL_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user