summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-10-21 15:58:18 -0400
committerAlex Deucher <alexdeucher@gmail.com>2009-10-21 15:58:18 -0400
commit66b194a78c470cb3978f310828dd96c3f3e96944 (patch)
treefe0e884f4597509db3e14d613d47a2c2fc819829
parentbd89b7501f294ac645390ef144df569953c81dc4 (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.c47
-rw-r--r--src/radeon_atombios.h3
-rw-r--r--src/radeon_bios.c25
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
@@ -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 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;