diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-10-21 15:58:18 -0400 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2009-10-21 15:58:18 -0400 |
commit | 66b194a78c470cb3978f310828dd96c3f3e96944 (patch) | |
tree | fe0e884f4597509db3e14d613d47a2c2fc819829 | |
parent | bd89b7501f294ac645390ef144df569953c81dc4 (diff) |
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.
-rw-r--r-- | src/radeon_atombios.c | 47 | ||||
-rw-r--r-- | src/radeon_atombios.h | 3 | ||||
-rw-r--r-- | 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 13ef1ef7..6db821f2 100644 --- a/src/radeon_atombios.c +++ b/src/radeon_atombios.c @@ -2127,6 +2127,53 @@ RADEONGetATOMTVInfo(xf86OutputPtr output) } 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) { RADEONInfoPtr info = RADEONPTR(pScrn); diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h index d5250632..1f21c466 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 ecf54030..f19d9297 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; |