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