diff options
author | Alex Deucher <alex@cube.(none)> | 2008-04-04 18:40:16 -0400 |
---|---|---|
committer | Alex Deucher <alex@cube.(none)> | 2008-04-04 18:40:16 -0400 |
commit | bc0407e53237d7968808110bc0243076377acf6e (patch) | |
tree | a7ead954da137b70ecfe2d131073d3c0d621d40c | |
parent | 5f5e21bb50555c56bd371576074c28c929307ff1 (diff) |
ATOMBIOS: Add support for DynamicClocks option
This patch adds support for dynamic clock gating and static
power management using the atom command tables. In some cases
the bios may already set this up during post, so YMMV.
I was only able to test on desktop cards, so I haven't tested
to see how much (if any) power this saves or how it affects the
thermal footprint.
-rw-r--r-- | src/radeon_atombios.c | 57 | ||||
-rw-r--r-- | src/radeon_atombios.h | 6 | ||||
-rw-r--r-- | src/radeon_driver.c | 22 |
3 files changed, 64 insertions, 21 deletions
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c index f0afba3c..224aae3b 100644 --- a/src/radeon_atombios.c +++ b/src/radeon_atombios.c @@ -519,25 +519,52 @@ rhdAtomASICInit(atomBiosHandlePtr handle) return FALSE; } -Bool -rhdAtomSetScaler(atomBiosHandlePtr handle, unsigned char scalerID, int setting) +int +atombios_dyn_clk_setup(ScrnInfoPtr pScrn, int enable) { - ENABLE_SCALER_PARAMETERS scaler; + RADEONInfoPtr info = RADEONPTR(pScrn); + DYNAMIC_CLOCK_GATING_PS_ALLOCATION dynclk_data; AtomBiosArgRec data; + unsigned char *space; - scaler.ucScaler = scalerID; - scaler.ucEnable = setting; - data.exec.dataSpace = NULL; - data.exec.index = 0x21; - data.exec.pspace = &scaler; - xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling EnableScaler\n"); - if (RHDAtomBiosFunc(handle->scrnIndex, handle, - ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { - xf86DrvMsg(handle->scrnIndex, X_INFO, "EnableScaler Successful\n"); - return TRUE; + dynclk_data.ucEnable = enable; + + data.exec.index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating); + data.exec.dataSpace = (void *)&space; + data.exec.pspace = &dynclk_data; + + if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { + ErrorF("Dynamic clock gating %s success\n", enable? "enable" : "disable"); + return ATOM_SUCCESS; } - xf86DrvMsg(handle->scrnIndex, X_INFO, "EableScaler Failed\n"); - return FALSE; + + ErrorF("Dynamic clock gating %s failure\n", enable? "enable" : "disable"); + return ATOM_NOT_IMPLEMENTED; + +} + +int +atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, int enable) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION pwrmgt_data; + AtomBiosArgRec data; + unsigned char *space; + + pwrmgt_data.ucEnable = enable; + + data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableASIC_StaticPwrMgt); + data.exec.dataSpace = (void *)&space; + data.exec.pspace = &pwrmgt_data; + + if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { + ErrorF("Static power management %s success\n", enable? "enable" : "disable"); + return ATOM_SUCCESS; + } + + ErrorF("Static power management %s failure\n", enable? "enable" : "disable"); + return ATOM_NOT_IMPLEMENTED; + } # endif diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h index 9cb279e6..955f2e4e 100644 --- a/src/radeon_atombios.h +++ b/src/radeon_atombios.h @@ -116,6 +116,12 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn); extern Bool RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn); +extern int +atombios_dyn_clk_setup(ScrnInfoPtr pScrn, int enable); + +extern int +atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, int enable); + extern Bool RADEONGetATOMTVInfo(xf86OutputPtr output); diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 9f008d4d..d5595eaa 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -3067,11 +3067,16 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, RADEONBlank(pScrn); if (info->IsMobility && !IS_AVIVO_VARIANT) { - if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) { + if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) { RADEONSetDynamicClock(pScrn, 1); - } else { + } else { RADEONSetDynamicClock(pScrn, 0); - } + } + } else if (IS_AVIVO_VARIANT) { + if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) { + atombios_static_pwrmgt_setup(pScrn, 1); + atombios_dyn_clk_setup(pScrn, 1); + } } if (IS_R300_VARIANT || IS_RV100_VARIANT) @@ -5173,11 +5178,16 @@ Bool RADEONEnterVT(int scrnIndex, int flags) RADEONWaitForIdleMMIO(pScrn); if (info->IsMobility && !IS_AVIVO_VARIANT) { - if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) { + if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) { RADEONSetDynamicClock(pScrn, 1); - } else { + } else { RADEONSetDynamicClock(pScrn, 0); - } + } + } else if (IS_AVIVO_VARIANT) { + if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) { + atombios_static_pwrmgt_setup(pScrn, 1); + atombios_dyn_clk_setup(pScrn, 1); + } } if (IS_R300_VARIANT || IS_RV100_VARIANT) |