From 66b194a78c470cb3978f310828dd96c3f3e96944 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 21 Oct 2009 15:58:18 -0400 Subject: ATOM: fix up get clock info Newer revisions of the atom firmware table have changed. This helps select better pll dividers in some cases. Noticed by Mathias Froehlich. --- src/radeon_atombios.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/radeon_atombios.h | 3 +++ src/radeon_bios.c | 25 +------------------------ 3 files changed, 51 insertions(+), 24 deletions(-) diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c index 13ef1ef..6db821f 100644 --- a/src/radeon_atombios.c +++ b/src/radeon_atombios.c @@ -2126,6 +2126,53 @@ RADEONGetATOMTVInfo(xf86OutputPtr output) return TRUE; } +Bool +RADEONGetATOMClockInfo(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR (pScrn); + RADEONPLLPtr pll = &info->pll; + atomDataTablesPtr atomDataPtr; + uint8_t crev, frev; + + atomDataPtr = info->atomBIOS->atomDataPtr; + if (!rhdAtomGetTableRevisionAndSize( + (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->FirmwareInfo.base), + &crev,&frev,NULL)) { + return FALSE; + } + + switch(crev) { + case 1: + info->sclk = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->ulDefaultEngineClock) / 100.0; + info->mclk = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->ulDefaultMemoryClock) / 100.0; + pll->xclk = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->usMaxPixelClock); + pll->pll_in_min = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->usMinPixelClockPLL_Input); + pll->pll_in_max = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->usMaxPixelClockPLL_Input); + pll->pll_out_min = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->usMinPixelClockPLL_Output); + pll->pll_out_max = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->ulMaxPixelClockPLL_Output); + pll->reference_freq = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->usReferenceClock); + break; + case 2: + case 3: + case 4: + default: + info->sclk = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->ulDefaultEngineClock) / 100.0; + info->mclk = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->ulDefaultMemoryClock) / 100.0; + pll->xclk = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->usMaxPixelClock); + pll->pll_in_min = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->usMinPixelClockPLL_Input); + pll->pll_in_max = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->usMaxPixelClockPLL_Input); + pll->pll_out_min = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->ulMinPixelClockPLL_Output); + pll->pll_out_max = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->ulMaxPixelClockPLL_Output); + pll->reference_freq = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->usReferenceClock); + break; + } + pll->reference_div = 0; + if (pll->pll_out_min == 0) + pll->pll_out_min = 64800; + + return TRUE; +} + Bool RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, DisplayModePtr mode) { diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h index d525063..1f21c46 100644 --- a/src/radeon_atombios.h +++ b/src/radeon_atombios.h @@ -275,6 +275,9 @@ RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, DisplayModePtr mode); extern void RADEONATOMGetIGPInfo(ScrnInfoPtr pScrn); +extern Bool +RADEONGetATOMClockInfo(ScrnInfoPtr pScrn); + extern uint32_t radeon_get_device_index(uint32_t device_support); extern radeon_encoder_ptr diff --git a/src/radeon_bios.c b/src/radeon_bios.c index ecf5403..f19d929 100644 --- a/src/radeon_bios.c +++ b/src/radeon_bios.c @@ -995,30 +995,7 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn) return FALSE; } else { if (info->IsAtomBios) { - pll_info_block = RADEON_BIOS16 (info->MasterDataStart + 12); - - pll->reference_freq = RADEON_BIOS16 (pll_info_block + 82); - pll->reference_div = 0; /* Need to derive from existing setting - or use a new algorithm to calculate - from min_input and max_input - */ - pll->pll_out_min = RADEON_BIOS16 (pll_info_block + 78); - pll->pll_out_max = RADEON_BIOS32 (pll_info_block + 32); - - if (pll->pll_out_min == 0) { - if (IS_AVIVO_VARIANT) - pll->pll_out_min = 64800; - else - pll->pll_out_min = 20000; - } - - pll->pll_in_min = RADEON_BIOS16 (pll_info_block + 74); - pll->pll_in_max = RADEON_BIOS16 (pll_info_block + 76); - - pll->xclk = RADEON_BIOS16 (pll_info_block + 72); - - info->sclk = RADEON_BIOS32(pll_info_block + 8) / 100.0; - info->mclk = RADEON_BIOS32(pll_info_block + 12) / 100.0; + return RADEONGetATOMClockInfo(pScrn); } else { int rev; -- cgit v1.2.3