HOWTO undervolt the AMD RX 4XX and RX 5XX GPUs
You may or may not to manually adjust the clockspeeds on AMD GPUs and you can do it fairly easily if you are using the
amdgpu driver on GNU/Linux.
Kernel parameters required
You need to add
amdgpu.ppfeaturemask=0xfffd7fff to your kernel command-line to enable "overdrive" so you can manually fool around with GPU clocks. It is also possible to use
amdgpu.ppfeaturemask=0xffffffff but that higher setting causes artifacts on many cards (mainly RX 470/570). Booting with this will make a special file called
/sys/class/drm/card0/device/pp_od_clk_voltage appear. You can write values to this file and activate them.
HOWTO do it yourself - the manual labor way
Changing the clocks and voltages for individual GPU states
s maxpstate GPU-clock voltatewill change the GPU clock for a specific p-state.
m max-memory-pstate memory-clock memory-voltateto change the memory clock for a p-state.
There are eight (0-7) GPU clock states and two (0-1) OR three (0-2) memory states on AMD RX GPUs.
This example changes the values for the highest CPU core and memory states:
echo "s 7 1209 900" > /sys/class/drm/card0/device/pp_od_clk_voltage
echo "m 2 1850 850" > /sys/class/drm/card0/device/pp_od_clk_voltage
The first line would set a maximum pstate of 7, set MHz to 1209 and a 900mV voltage. The second line would set the maximum memory pstate to 2, memory clock to 1850 and voltage to 850.
You can activate the settings written by writing
echo "c" > /sys/class/drm/card0/device/pp_od_clk_voltage
You can re-set to default settings by writing
echo "r" > /sys/class/drm/card0/device/pp_od_clk_voltage
You can force your card to only use selected GPU pstates by sending whole numbers to
echo "5 6 7" > /sys/class/drm/card0/device/pp_dpm_sclk
You can look at your
/sys/class/drm/card0/device/pp_od_clk_voltage with cat and see what you have available:
This will give you an output like this:
OD_SCLK: 0: 300MHz 800mV 1: 466MHz 818mV 2: 751MHz 824mV 3: 1019MHz 950mV 4: 1074MHz 1000mV 5: 1126MHz 1050mV 6: 1169MHz 1093mV 7: 1242MHz 1150mV OD_MCLK: 0: 300MHz 800mV 1: 1650MHz 1000mV OD_RANGE: SCLK: 300MHz 2000MHz MCLK: 300MHz 2100MHz VDDC: 800mV 1175mV
Putting it all together
Here is an example of a complete underclock of a RX 580 done with a script file:
And here's an example for the RX 570:
A script like that, once created, would be activated on each boot by making a simple systemd service script:
systemctl daemon-reload then
systemctl enable tunegpu.service to activate.