summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-04-01 15:05:38 -0400
committerAlex Deucher <alexdeucher@gmail.com>2009-04-15 11:45:52 -0400
commit7e10b6222e8f44a3ecc6aaea55a7a7680d133bb3 (patch)
tree226438748f0e626ed6648037249de7a84590a897
parent533d01a5933cd491bbc09cd463ea62475abf4bf2 (diff)
Add ForceLowPowerMode Option
Force the chip to a low power mode at the expense of performance.
-rw-r--r--man/radeon.man5
-rw-r--r--src/radeon.h7
-rw-r--r--src/radeon_driver.c10
-rw-r--r--src/radeon_pm.c26
4 files changed, 47 insertions, 1 deletions
diff --git a/man/radeon.man b/man/radeon.man
index 9a7cf807..f6167038 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -419,6 +419,11 @@ life by reducing power usage. Some users report reduced 3D performance
with this enabled. The default is
.B off.
.TP
+.BI "Option \*qForceLowPowerMode\*q \*q" boolean \*q
+Enable a static low power mode. This can help reduce heat and increase battery
+life by reducing power usage at the expense of performance. The default is
+.B off.
+.TP
.BI "Option \*qVGAAccess\*q \*q" boolean \*q
Tell the driver if it can do legacy VGA IOs to the card. This is
necessary for properly resuming consoles when in VGA text mode, but
diff --git a/src/radeon.h b/src/radeon.h
index 60d56db2..88de0e8f 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -207,7 +207,8 @@ typedef enum {
OPTION_INT10,
OPTION_EXA_VSYNC,
OPTION_ATOM_TVOUT,
- OPTION_R4XX_ATOM
+ OPTION_R4XX_ATOM,
+ OPTION_FORCE_LOW_POWER
} RADEONOpts;
@@ -891,6 +892,9 @@ typedef struct {
Bool r4xx_atom;
+ /* pm */
+ Bool low_power_mode;
+
} RADEONInfoRec, *RADEONInfoPtr;
#define RADEONWaitForFifo(pScrn, entries) \
@@ -1070,6 +1074,7 @@ extern void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
/* radeon_pm.c */
extern void RADEONSetClockGating(ScrnInfoPtr pScrn, Bool enable);
+extern void RADEONStaticLowPowerMode(ScrnInfoPtr pScrn, Bool enable);
#ifdef USE_EXA
/* radeon_exa.c */
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index fe00dd79..ac1a151e 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -195,6 +195,7 @@ static const OptionInfoRec RADEONOptions[] = {
{ OPTION_EXA_VSYNC, "EXAVSync", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_ATOM_TVOUT, "ATOMTVOut", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_R4XX_ATOM, "R4xxATOM", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FORCE_LOW_POWER, "ForceLowPowerMode", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -3333,6 +3334,9 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
else
RADEONSetClockGating(pScrn, FALSE);
+ if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_LOW_POWER, FALSE))
+ RADEONStaticLowPowerMode(pScrn, TRUE);
+
if (info->allowColorTiling && (pScrn->virtualX > info->MaxSurfaceWidth)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Color tiling not supported with virtual x resolutions larger than %d, disabling\n",
@@ -5593,6 +5597,9 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
else
RADEONSetClockGating(pScrn, FALSE);
+ if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_LOW_POWER, FALSE))
+ RADEONStaticLowPowerMode(pScrn, TRUE);
+
for (i = 0; i < config->num_crtc; i++)
radeon_crtc_modeset_ioctl(config->crtc[i], TRUE);
@@ -5753,6 +5760,9 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"RADEONCloseScreen\n");
+ if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_LOW_POWER, FALSE))
+ RADEONStaticLowPowerMode(pScrn, FALSE);
+
/* Mark acceleration as stopped or we might try to access the engine at
* wrong times, especially if we had DRI, after DRI has been stopped
*/
diff --git a/src/radeon_pm.c b/src/radeon_pm.c
index 89e1d8ab..86d739b2 100644
--- a/src/radeon_pm.c
+++ b/src/radeon_pm.c
@@ -476,3 +476,29 @@ RADEONSetClockGating(ScrnInfoPtr pScrn, Bool enable)
enable ? "En" : "Dis");
}
+void RADEONStaticLowPowerMode(ScrnInfoPtr pScrn, Bool enable)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int sclk = (int)info->sclk * 100; /* 10 khz */
+
+ RADEONWaitForIdleMMIO(pScrn);
+
+ if (enable) {
+ if (info->IsAtomBios)
+ atombios_set_engine_clock(pScrn, sclk/2);
+ else
+ RADEONSetEngineClock(pScrn, sclk/2);
+
+ info->low_power_mode = TRUE;
+ } else {
+ if (info->IsAtomBios)
+ atombios_set_engine_clock(pScrn, sclk);
+ else
+ RADEONSetEngineClock(pScrn, sclk);
+
+ info->low_power_mode = FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Low Power Mode %sabled\n",
+ enable ? "En" : "Dis");
+}