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