summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alex@cube.(none)>2008-04-04 18:40:16 -0400
committerAlex Deucher <alex@cube.(none)>2008-04-04 18:40:16 -0400
commitbc0407e53237d7968808110bc0243076377acf6e (patch)
treea7ead954da137b70ecfe2d131073d3c0d621d40c
parent5f5e21bb50555c56bd371576074c28c929307ff1 (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.c57
-rw-r--r--src/radeon_atombios.h6
-rw-r--r--src/radeon_driver.c22
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)