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 /src | |
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.
Diffstat (limited to 'src')
-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; |