How to p-state owerclock Ryzen on Linux

in #hardware4 years ago (edited)

In this article I would like to show you how to change voltage and frequency of AMDRyzen processors. This technique does not change the frequency and voltage directly, but exploits model specific registers (MSR) to modify values in the processor p-state table. P-state overclocking, unlike manual OC, retain the processor's power saving capabilities. The processor will automatically scale down the frequency and voltage when the load is light. The next interesting part is that, you do not need p-state overclocking support in your UEFI (a.k.a BIOS), which is often present only on high end motherboards. I think it should work on any family 0x17 chip, but I only tried on 1700.

UEFI Setup

Reboot and go to your Setup program (a.k.a BIOS). Set:

CPU RatioAuto
Core Performance BoostDisabled
CPU Core VoltageAuto
Cool 'n' QuietEnabled

We are setting f&V to Auto, because that is the only way (that I know) to keep the p-state features operational. Disable Boost, because when enabled, CPU ignored my p-state adjustments.


The utility to edit p-state table is called go-zenstates and available github. It is in Go language, so install go and also git.

Debian/ubuntu packages: golang-go git msr-tools
Arch: go git

Then install the zenstates tool:. The tool will be installed in ~/go/bin folder of your home directory.

go get

To use the tool, a "msr" kernel module must be loaded:

modprobe msr

Then you can test the tool:

sudo ~/go/bin/go-zenstates -l

It should print the current p-state table, which looks like this:

Enabled - FID = 8E - DID = 8 - VID = 47 - Ratio = 35.50 - vCore = 1.10625
Enabled - FID = 87 - DID = A - VID = 50 - Ratio = 27.00 - vCore = 1.05000
Enabled - FID = 7C - DID = 10 - VID = 6C - Ratio = 15.50 - vCore = 0.87500

Ryzen CPUs have 8 p-states available, but only 3 are enabled. You could technically enable more of them, but I doubt the acpi-cpufreq driver will use more.

The highest performance state is P0, it is the first in the table. P2 is the third row. P0 is used when the load is high, P2 when the load is low and P1 in the middle. When the core is totally idle, it enters C-states, which use even less power. To overclock, we need to edit the P0 p-state. I do not suggest changing the other states, because the CPU is already pretty efficient when lightly loaded, and you will not beat the C-state power usage, because in C-state the core runs at 0 MHz. Now how to change it and what values to use?

You can set FID, DID and VID. From these values, fClkand and vCore is derived internally.

FID120Frequency IDAffects frequency proportionally
DID8Divisor IDAffects frequency inverse-proportionally
VID58Voltage IDAffects voltage inverse-proportionally

The values are displayed in hex, by the tool, but without the 0x. The tool allows you to specify them in both decimal or hex. Be careful, because if you forget the 0x, you will set different value and shut down your system.

To re-program a P0 row use:

sudo ~/go/bin/go-zenstates -p 0 -fid 120 -did 8 -vid 58 -enable

I suggest to keep the divisor at 8, since it is the default and allows to specify frequency in even 25 MHZ increments. You can adjust the values by feel, or use the formulas. The formulas are the following:

Core Frequency = BCLK*FID/DID
CPU Ratio = 25*FID/(12.5*DID)
Core Voltage = (1.55-0.00625*VID)
1203000 MHz
1403500 MHz
1483700 MHz
561200 mV
721100 mV
881000 mV

Please be careful with the voltage. Setting frequency too high will just halt your system, but overshooting voltage can kill your CPU or Board forever. Also the lower VID you set the higher the voltage!

I encourage you to not only push the highest frequency, but instead be green and push the voltage down. If you have low end motherboard, the VRM will thank you.

Since you can change the settings at runtime, you can set up few scripts as a overclocking profiles.


Here is the output of cpufreq after some adjustments:

$ sudo cpupower frequency-info
analyzing CPU 0:
  driver: acpi-cpufreq
  CPUs which run at the same hardware frequency: 0
  CPUs which need to have their frequency coordinated by software: 0
  maximum transition latency:  Cannot determine or is not supported.
  hardware limits: 1.55 GHz - 3.00 GHz
  available frequency steps:  3.00 GHz, 2.70 GHz, 1.55 GHz
  available cpufreq governors: performance schedutil
  current policy: frequency should be within 1.55 GHz and 3.00 GHz.
                  The governor "schedutil" may decide which speed to use
                  within this range.
  current CPU frequency: 3.00 GHz (asserted by call to hardware)
  boost state support:
    Supported: no
    Active: no
    Boost States: 0
    Total States: 3
    Pstate-P0:  3550MHz
    Pstate-P1:  2700MHz
    Pstate-P2:  1550MHz

Notice how the hardware limits stays at stock values, but the tweaks only affect P0? That is just a display bug. The cpufreq driver (or ACPI?) does not expect p-state table to change at runtime.

Monitoring tools

turbostat allows you to measure real average frequency. The frequency is measured (aperf), instead of reading it from somewhere. This is the most accurate frequency report you can get. It can also measure C-State utilization.

sudo turbostat --Summary --interval 4

RAPL-read-ryzen is capable of measuring power draw of your CPU and individual cores in Watts. It does this by reading energy (joule) counters from core and multiplying by time.
RAPL= Recent Average Power Limit

HWMon interface. You can read varios sensors provided by your motherboard and GPU under /sys/class/hwmon directory. Also sensors command. For example on my board vCore mV can be read using the command:

cat /sys/class/hwmon/hwmon1/in0_input

I am interested in creating a tool to set and monitor various parameters, including power draw.
additional MSR resource

This was @tomasbrod, thank you for attention. Happy hacking. Please, do not burn your fingers on the hot silicon.

Also please suggest tags for this post.


Awesome tutorial Tomas. It was very informative, if I ever go Ryzen and Linux I will remember this tutorial. Keep up the good work.

Coin Marketplace

STEEM 0.27
TRX 0.07
JST 0.034
BTC 24327.57
ETH 1937.47
USDT 1.00
SBD 3.39