intel_extreme: IronLake reference clock activation
This commit is contained in:
parent
00a3a794e0
commit
a933bb4cbc
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue