Radeon Dynamic Power Management (DPM)

Radeon DPM support is finally here. This post is an overview of how it works and what you can do with it right now. First some background. Each card has a specific set of power states stored in the vbios. Each power state has some number of performance levels. A performance level consists of some combination of engine and memory clocks and voltages. When you are in a specific power state, the hardware switches between the performance levels automatically based on the load on the GPU. The power states represent high level usage scenarios like battery or performance. There are also some internal states for specific purposes (e.g., UVD video playback and thermal events). The driver uses these states internally in specific cases. In addition to power states, the driver also enables clock gating, and, on certain asics, power gating.

Here is an example of the power states from a mobile APU system:

[ 2.532273] == power state 0 ==
[ 2.532275] ui class: none
[ 2.532276] internal class: uvd_sd
[ 2.532278] caps:
[ 2.532286] uvd vclk: 30000 dclk: 24828
[ 2.532289] power level 0 sclk: 27693 vddc: 887
[ 2.532291] power level 1 sclk: 33489 vddc: 1012
[ 2.532292] status:
[ 2.532294] == power state 1 ==
[ 2.532294] ui class: none
[ 2.532296] internal class: uvd_hd
[ 2.532297] caps:
[ 2.532299] uvd vclk: 40000 dclk: 30000
[ 2.532301] power level 0 sclk: 33489 vddc: 1012
[ 2.532302] status:
[ 2.532303] == power state 2 ==
[ 2.532304] ui class: none
[ 2.532305] internal class: uvd
[ 2.532307] caps:
[ 2.532308] uvd vclk: 72000 dclk: 60000
[ 2.532310] power level 0 sclk: 49656 vddc: 1087
[ 2.532312] power level 1 sclk: 68572 vddc: 1174
[ 2.532313] status:
[ 2.532314] == power state 3 ==
[ 2.532315] ui class: none
[ 2.532316] internal class: uvd_mvc
[ 2.532317] caps:
[ 2.532319] uvd vclk: 72000 dclk: 60000
[ 2.532321] power level 0 sclk: 49656 vddc: 1087
[ 2.532369] power level 1 sclk: 68572 vddc: 1174
[ 2.532370] status:
[ 2.532371] == power state 4 ==
[ 2.532372] ui class: battery
[ 2.532373] internal class: none
[ 2.532374] caps:
[ 2.532376] uvd vclk: 0 dclk: 0
[ 2.532378] power level 0 sclk: 27693 vddc: 887
[ 2.532380] power level 1 sclk: 33489 vddc: 1012
[ 2.532380] status:
[ 2.532382] == power state 5 ==
[ 2.532382] ui class: performance
[ 2.532384] internal class: none
[ 2.532385] caps:
[ 2.532386] uvd vclk: 0 dclk: 0
[ 2.532388] power level 0 sclk: 33489 vddc: 1012
[ 2.532390] power level 1 sclk: 49656 vddc: 1087
[ 2.532392] power level 2 sclk: 68572 vddc: 1174
[ 2.532393] status:
[ 2.532394] == power state 6 ==
[ 2.532395] ui class: none
[ 2.532396] internal class: boot
[ 2.532397] caps:
[ 2.532399] uvd vclk: 0 dclk: 0
[ 2.532401] power level 0 sclk: 20000 vddc: 1174
[ 2.532401] status: c r b
[ 2.532404] == power state 7 ==
[ 2.532405] ui class: none
[ 2.532406] internal class: thermal
[ 2.532407] caps:
[ 2.532408] uvd vclk: 0 dclk: 0
[ 2.532410] power level 0 sclk: 20000 vddc: 887
[ 2.532411] status:

Power states 0-3 are UVD states. The driver selects these automatically when UVD playback is active. Power state 6 is the boot state. This is the state that the system comes up in at boot time. State 7 is the thermal state. Power state 4 is the battery state and power state 5 is the performance state. These two are the ones in use most often. The battery state has two performance levels that are relatively low. When the battery state is selected, the GPU will automatically switch between these performance levels. The performance state has three performance levels with higher clocks and voltages compared to the battery state. The GPU automatically switches between these performance levels when that power state is selected.

From the user’s perspective, there are three power states to choose from:
- battery: a set of performance levels targeted for optimal operation on battery
- balanced: a set of performance levels targeted for optimal every day use
- performance: a set of performance levels targeted for the highest GPU performance
You can select between these power states via sysfs:

/sys/class/drm/card0/device/power_dpm_state

The default is the balanced power state. If you unplug the AC adapter, and wish to use the laptop on battery power, you can echo battery to power_dpm_state and that will switch to the battery state. If you are on AC power and want to play some 3D games with optimal performance, you can select the performance state.  Note that not all systems have all states.  On those systems, different power_dpm_state settings may map to the same actual power state in the driver.

You can use debugfs to to track what state the GPU is in at any given moment. e.g.,

/sys/kernel/debug/dri/64/radeon_pm_info

E.g., when the performance state is selected and the GPU is idle, you will be in the lowest performance level:

uvd vclk: 0 dclk: 0
power level 0 sclk: 33489 vddc: 1012

If you start up a 3D game, the performance level will rise with GPU load:

uvd vclk: 0 dclk: 0
power level 2 sclk: 68572 vddc: 1174

Within a power state, you can force specific performance levels. This is useful for testing or if you need to limit performance to meet specific power requirements. You can force performance levels via sysfs:

/sys/class/drm/card0/device/power_dpm_force_performance_level

There are three force options to choose from:
- auto: disables forced levels; the hw uses all levels in the power state
- low: forces the hardware to the lowest performance level in the power state
- high: forces the hardware to the highest performance level in the power state

The new DPM code will be included in the 3.11 kernel. To enable it, set the dpm module parameter to 1. E.g., add:

radeon.dpm=1

to the kernel command line in grub.

Comments are closed.