diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index 31f732ea07..aeabde514c 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -439,6 +439,8 @@ struct intel_shared_info { uint32 frame_buffer_offset; uint32 fdi_link_frequency; // In Mhz + uint32 hraw_clock; + uint32 hw_cdclk; bool got_vbt; bool single_head_locked; @@ -917,6 +919,11 @@ struct intel_brightness_legacy { #define ICL_DSSM_19200 1 #define ICL_DSSM_38400 2 +#define LCPLL_CTL 0x130040 +#define LCPLL_CLK_FREQ_MASK (3 << 26) +#define LCPLL_CLK_FREQ_450 (0 << 26) +#define LCPLL_CD_SOURCE_FCLK (1 << 21) + // display #define INTEL_DISPLAY_OFFSET 0x1000 @@ -1272,6 +1279,9 @@ struct intel_brightness_legacy { #define DREF_SSC4_DISABLE (0 << 0) #define DREF_SSC4_ENABLE (1 << 0) +#define PCH_RAWCLK_FREQ (0x6204 | REGS_SOUTH_SHARED) +#define RAWCLK_FREQ_MASK 0x3ff + // PLL registers // Multiplier Divisor #define INTEL_DISPLAY_A_PLL (0x6014 | REGS_SOUTH_SHARED) @@ -1603,6 +1613,9 @@ struct intel_brightness_legacy { #define FDI_RX_PHASE_SYNC_POINTER_EN (1 << 0) #define FDI_RX_PHASE_SYNC_POINTER_OVR (1 << 1) +#define SFUSE_STRAP (0x2014 | REGS_SOUTH_SHARED) +#define SFUSE_STRAP_RAW_FREQUENCY (1 << 8) + // CPU Panel Fitters - These are for IronLake and up and are the CPU internal // panel fitters. #define PCH_PANEL_FITTER_BASE_REGISTER 0x68000 diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp b/src/add-ons/accelerants/intel_extreme/Ports.cpp index c5bb79dff8..bb3245e1d2 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.cpp +++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp @@ -781,7 +781,12 @@ Port::_DpAuxTransfer(uint8* transmitBuffer, uint8 transmitSize, | (transmitSize << INTEL_DP_AUX_CTL_MSG_SIZE_SHIFT) | INTEL_DP_AUX_CTL_FW_SYNC_PULSE_SKL(32) | INTEL_DP_AUX_CTL_SYNC_PULSE_SKL(32); } else { - uint32 aux_clock_divider = 0xe1; // TODO: value for 450Mhz + uint32 frequency = gInfo->shared_info->hw_cdclk; + if (channel != AUX_CH_A) + frequency = gInfo->shared_info->hraw_clock; + uint32 aux_clock_divider = (frequency + 2000 / 2) / 2000; + if (gInfo->shared_info->pch_info == INTEL_PCH_LPT && channel != AUX_CH_A) + aux_clock_divider = 0x48; // or 0x3f uint32 timeout = INTEL_DP_AUX_CTL_TIMEOUT_400us; if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_BDW)) timeout = INTEL_DP_AUX_CTL_TIMEOUT_600us; diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp index 05f30504e0..5453c5d784 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp @@ -867,10 +867,38 @@ intel_extreme_init(intel_info &info) } else { info.shared_info->fdi_link_frequency = 2700; } + if (info.shared_info->pch_info >= INTEL_PCH_CNP) { + // TODO read/write info.shared_info->hraw_clock + } else { + info.shared_info->hraw_clock = (read32(info, PCH_RAWCLK_FREQ) + & RAWCLK_FREQ_MASK) * 1000; + TRACE("%s: rawclk rate: %" B_PRIu32 " kHz\n", __func__, info.shared_info->hraw_clock); + } } else { + // TODO read info.shared_info->hraw_clock info.shared_info->fdi_link_frequency = 0; } + if (info.device_type.InGroup(INTEL_GROUP_HAS)) { + uint32 lcpll = read32(info, LCPLL_CTL); + if ((lcpll & LCPLL_CD_SOURCE_FCLK) != 0) + info.shared_info->hw_cdclk = 800000; + else if ((lcpll & LCPLL_CLK_FREQ_MASK) == LCPLL_CLK_FREQ_450) + info.shared_info->hw_cdclk = 450000; + /* ULT type is missing + else if (IS_ULT) + info.shared_info->hw_cdclk = 337500; + */ + else + info.shared_info->hw_cdclk = 540000; + } else if (info.device_type.InGroup(INTEL_GROUP_SNB) + || info.device_type.InGroup(INTEL_GROUP_IVB)) { + info.shared_info->hw_cdclk = 400000; + } else if (info.device_type.InGroup(INTEL_GROUP_ILK)) { + info.shared_info->hw_cdclk = 450000; + } + TRACE("%s: hw_cdclk: %" B_PRIu32 " kHz\n", __func__, info.shared_info->hw_cdclk); + TRACE("%s: completed successfully!\n", __func__); return B_OK; }