Optimizing ForceLowPowerMode
Markus Stockhausen
markus.stockhausen at collogia.de
Fri Aug 28 12:45:04 PDT 2009
Am Freitag, den 28.08.2009, 11:45 +0200 schrieb Jerome Glisse:
> Patch welcome to add such options i guess we are all delaying power
> saving code to KMS as we would like to be able to change this parameter
> while the GPU is running but this is only doable with KMS as you need
> to block GPU access while changing those. But it's safe to do that on
> ddx startup in non kms world as GPU should be idle.
>
> Range of valid values are more tricky for vram & GPU i think for vram
> it mostly depends on the chips used by the manufacturer and GPU
> frequency then need to follow some equation taking into account
> the vram frequency. So far it seems that dividing gpu/vram clock
> by the same integer is a safe choice. Note that atombios should provide
> various valid & tested gpu/vram clock but it mostly up to the
> manufacturer and many of them are lazy and don't even bother
> testing much various values.
>
> Cheers,
> Jerome
>
Hi,
thanks for your encouragement. As a newbie I do not want to mess up
anything in GIT so I attach the diff of my code to this mail. In this
version the driver allows the user to set any MHz value between 1/4
speed and full speed to GPU and memory independently. I also updated the
man documentation to reflect my changes. Hopefully you can apply this to
the development tree.
Best regards.
Markus
-------------- next part --------------
diff -r -u xf86-video-ati/man/radeon.man mst/man/radeon.man
--- xf86-video-ati/man/radeon.man 2009-08-28 21:28:05.000000000 +0200
+++ mst/man/radeon.man 2009-08-28 21:24:52.000000000 +0200
@@ -418,10 +418,33 @@
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.
+.BI "Option \*qForceStaticPowerMode\*q \*q" boolean \*q
+Enable a static power mode. This can help reduce heat and increase battery life
+life by reducing power usage at the expense of performance. The default is
+.B off.
+.TP
+.BI "Option \*qForceCoreClockSpeed\*q \*q" integer \*q
+Set the GPU clock to the given speed (MHz). This value is only available
+if static power mode is enabled. The driver will check this value against lower
+(1/4 of maximum MHz) and upper bounds (maximum GPU MHz). The default value is
+.B 0
+and will set the GPU to maximum speed. Handle this parameter with care as some
+settings may freeze the display.
+.TP
+.BI "Option \*qForceMemoryClockSpeed\*q \*q" integer \*q
+Set the memory clock to the given speed (MHz). This value is only available
+if static power mode is enabled. The driver will check this value against lower
+(1/4 of maximum MHz) and upper bounds (maximum memory MHz). The default value is
+.B 0
+and will set the memory to maximum speed. Only cards with AtomBIOS are supported
+at the moment. Handle this parameter with care as some settings may freeze the
+display.
+.TP
+.BI "Option \*qForcePCIeLanes\*q \*q" integer \*q
+This option sets the active PCIe express lanes. This feature allows to safe power
+at the cost of reduced performancerad. Available values are 1-16. The default value is
+.B 0
+and will activate all available lanes.
.TP
.BI "Option \*qDynamicPM\*q \*q" boolean \*q
Enable dynamic power mode switching. This can help reduce heat and increase battery
diff -r -u xf86-video-ati/src/radeon_driver.c mst/src/radeon_driver.c
--- xf86-video-ati/src/radeon_driver.c 2009-08-28 21:28:05.000000000 +0200
+++ mst/src/radeon_driver.c 2009-08-28 21:25:35.000000000 +0200
@@ -202,7 +202,10 @@
{ 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 },
+ { OPTION_FORCE_STATIC_POWER, "ForceStaticPowerMode", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FORCE_STATIC_GPU, "ForceCoreClockSpeed", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_FORCE_STATIC_MEM, "ForceMemoryClockSpeed", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_FORCE_STATIC_PCIE, "ForcePCIeLanes", OPTV_INTEGER, {0}, FALSE },
{ OPTION_DYNAMIC_PM, "DynamicPM", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
diff -r -u xf86-video-ati/src/radeon.h mst/src/radeon.h
--- xf86-video-ati/src/radeon.h 2009-08-28 21:28:05.000000000 +0200
+++ mst/src/radeon.h 2009-08-28 21:25:58.000000000 +0200
@@ -218,7 +218,10 @@
OPTION_EXA_VSYNC,
OPTION_ATOM_TVOUT,
OPTION_R4XX_ATOM,
- OPTION_FORCE_LOW_POWER,
+ OPTION_FORCE_STATIC_POWER,
+ OPTION_FORCE_STATIC_GPU,
+ OPTION_FORCE_STATIC_MEM,
+ OPTION_FORCE_STATIC_PCIE,
OPTION_DYNAMIC_PM
} RADEONOpts;
@@ -455,7 +458,7 @@
Bool clock_gating_enabled;
Bool dynamic_mode_enabled;
- Bool force_low_power_enabled;
+ Bool force_static_power_enabled;
} RADEONPowerManagement;
typedef struct _atomBiosHandle *atomBiosHandlePtr;
diff -r -u xf86-video-ati/src/radeon_pm.c mst/src/radeon_pm.c
--- xf86-video-ati/src/radeon_pm.c 2009-08-28 21:28:05.000000000 +0200
+++ mst/src/radeon_pm.c 2009-08-28 21:26:36.000000000 +0200
@@ -768,12 +768,15 @@
RADEONWaitForIdleMMIO(pScrn);
- if (info->IsAtomBios)
- atombios_set_engine_clock(pScrn, info->pm.mode[i].sclk);
- else
+ if (info->IsAtomBios) {
+ if (atombios_set_engine_clock(pScrn, info->pm.mode[i].sclk) != ATOM_SUCCESS)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "set GPU clock failed\n");
+ if (atombios_set_memory_clock(pScrn, info->pm.mode[i].mclk) != ATOM_SUCCESS)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "set memory clock failed\n");
+ } else
RADEONSetEngineClock(pScrn, info->pm.mode[i].sclk);
- if (info->cardType == CARD_PCIE)
+ if (info->cardType == CARD_PCIE)
RADEONSetPCIELanes(pScrn, info->pm.mode[i].pcie_lanes);
info->pm.current_mode = i;
@@ -785,6 +788,7 @@
void RADEONPMInit(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
+ int ForceGPU, ForceMEM, ForcePCIe;
if (xf86ReturnOptValBool(info->Options, OPTION_CLOCK_GATING, FALSE)) {
info->pm.clock_gating_enabled = TRUE;
@@ -819,24 +823,50 @@
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Power Management Disabled\n");
}
- if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_LOW_POWER, FALSE)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Force Low Power Mode Enabled\n");
- info->pm.force_low_power_enabled = TRUE;
+ if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_STATIC_POWER, FALSE)) {
+
+ ForceGPU = info->pm.mode[0].sclk;
+ if (xf86GetOptValInteger(info->Options, OPTION_FORCE_STATIC_GPU, &ForceGPU)) {
+ ForceGPU = ForceGPU * 100;
+ if (ForceGPU < info->pm.mode[0].sclk / 4) ForceGPU = info->pm.mode[0].sclk / 4;
+ if (ForceGPU > info->pm.mode[0].sclk) ForceGPU = info->pm.mode[0].sclk;
+ }
+
+ ForceMEM = info->pm.mode[0].mclk;
+ if (info->IsAtomBios) {
+ if (xf86GetOptValInteger(info->Options, OPTION_FORCE_STATIC_MEM, &ForceMEM)) {
+ ForceMEM = ForceMEM * 100;
+ if (ForceMEM < info->pm.mode[0].mclk / 4) ForceMEM = info->pm.mode[0].mclk / 4;
+ if (ForceMEM > info->pm.mode[0].mclk) ForceMEM = info->pm.mode[0].mclk;
+ }
+ }
+
+ ForcePCIe = info->pm.mode[0].pcie_lanes;
+ if (xf86GetOptValInteger(info->Options, OPTION_FORCE_STATIC_PCIE, &ForcePCIe)) {
+ if (ForcePCIe < 1) ForcePCIe = 1;
+ if (ForcePCIe > 16) ForcePCIe = 16;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Force Static Power Mode: GPU %u MHz, Mem %u MHz, %u PCIe lanes\n",
+ ForceGPU / 100, ForceMEM / 100, ForcePCIe);
+
+ info->pm.force_static_power_enabled = TRUE;
if (info->pm.dynamic_mode_enabled) {
info->pm.mode[2].type = POWER_HIGH;
- info->pm.mode[2].sclk = info->pm.mode[0].sclk / 2;
- info->pm.mode[2].mclk = info->pm.mode[0].mclk / 2;
- info->pm.mode[2].pcie_lanes = 4;
+ info->pm.mode[2].sclk = ForceGPU;
+ info->pm.mode[2].mclk = ForceMEM;
+ info->pm.mode[2].pcie_lanes = ForcePCIe;
} else {
info->pm.mode[1].type = POWER_HIGH;
- info->pm.mode[1].sclk = info->pm.mode[0].sclk / 2;
- info->pm.mode[1].mclk = info->pm.mode[0].mclk / 2;
- info->pm.mode[1].pcie_lanes = 4;
+ info->pm.mode[1].sclk = ForceGPU;
+ info->pm.mode[1].mclk = ForceMEM;
+ info->pm.mode[1].pcie_lanes = ForcePCIe;
info->pm.num_modes += 1;
}
RADEONSetStaticPowerMode(pScrn, POWER_HIGH);
} else
- info->pm.force_low_power_enabled = FALSE;
+ info->pm.force_static_power_enabled = FALSE;
RADEONPMQuirks(pScrn);
}
@@ -848,7 +878,7 @@
if (info->pm.clock_gating_enabled)
RADEONSetClockGating(pScrn, info->pm.clock_gating_enabled);
RADEONPMQuirks(pScrn);
- if (info->pm.force_low_power_enabled || info->pm.dynamic_mode_enabled)
+ if (info->pm.force_static_power_enabled || info->pm.dynamic_mode_enabled)
RADEONSetStaticPowerMode(pScrn, POWER_HIGH);
}
@@ -858,7 +888,7 @@
if (info->pm.clock_gating_enabled)
RADEONSetClockGating(pScrn, FALSE);
- if (info->pm.force_low_power_enabled || info->pm.dynamic_mode_enabled)
+ if (info->pm.force_static_power_enabled || info->pm.dynamic_mode_enabled)
RADEONSetStaticPowerMode(pScrn, POWER_DEFAULT);
}
@@ -868,7 +898,7 @@
if (info->pm.clock_gating_enabled)
RADEONSetClockGating(pScrn, FALSE);
- if (info->pm.force_low_power_enabled || info->pm.dynamic_mode_enabled)
+ if (info->pm.force_static_power_enabled || info->pm.dynamic_mode_enabled)
RADEONSetStaticPowerMode(pScrn, POWER_DEFAULT);
}
More information about the xorg-driver-ati
mailing list