Over - / Under-clock AMD Ryzen CPU

NOTE: You can break things doing the procedure below, ranging from locking the machine up so it won't boot, to letting the magic smoke out of your CPU.
DO SO AT YOUR OWN RISK!

Preamble: Long ago and in a galaxy far, far away, the manufacturing process was so perfected that AMD and Intel were making chips that met the requirements for their highest-end CPUs, but the demand for those high-end processors wasn't there, so they de-rated the CPUs and sold them as lower-end CPUs (it's better to make a buck off those CPUs than have them sit in a warehouse unsold). There was a very good chance that you'd get a chip that could be overclocked by quite a bit, and as long as you had the ability to properly cool the CPU, it'd be stable (I actually made a good deal of money overclocking gaming rigs for people back then). As we near the limit of Moore's Law, that's less true today, but CPUs can still be overclocked to get performance gains (or underclocked to lengthen battery run-time and reduce heat generation). And what with the CPUs automatically boosting under load to much-higher frequencies as long as CPU temperature is low, doing so matters less. Still, it's good to know how to do it.

All AMD Ryzen CPUs come from the factory with no restrictions on over- or under-clocking. Windows users have the AMD Ryzen Master Utility, which has yet to be ported to Linux, so we're stuck with using the command line.

Load the msr and cpuid kernel modules:
sudo modprobe msr cpuid

Install git:
sudo apt install git

Clone this git:
git clone https://github.com/r4m0n/ZenStates-Linux.git

Edit the zenstates.py file to change the python path:
gedit /home/owner/ZenStates-Linux/zenstates.py
.. where 'owner' is your username.

Change:
#!/usr/bin/python
to:
#!/usr/bin/env

To use zenstates.py:

usage: zenstates.py [-h] [-l] [-p {0,1,2,3,4,5,6,7}] [--enable] [--disable] [-f FID] [-d DID] [-v VID]

Sets P-States for Ryzen processors

optional arguments:
	-h, --help					show this help message and exit
	-l, --list					List all P-States
	-p {0,1,2,3,4,5,6,7},
	--pstate {0,1,2,3,4,5,6,7}	P-State to set
      --enable					Enable P-State
      --disable					Disable P-State
      -f FID, --fid FID			FID to set (in hex)
      -d DID, --did DID			DID to set (in hex)
      -v VID, --vid VID			VID to set (in hex)
      --c6-enable				Enable C-State C6
      --c6-disable				Disable C-State C6

Run zenstates:
sudo python3 '/home/owner/ZenStates-Linux/zenstates.py' -l
.. where 'owner' is your username.

It will give an output reminiscent to this:

P0 - Enabled - FID = 5C - DID = 8 - VID = 35 - Ratio = 23.00 - vCore = 1.21875
P1 - Enabled - FID = 5A - DID = A - VID = 60 - Ratio = 18.00 - vCore = 0.95000
P2 - Enabled - FID = 60 - DID = C - VID = 66 - Ratio = 16.00 - vCore = 0.91250
P3 - Disabled
P4 - Disabled
P5 - Disabled
P6 - Disabled
P7 - Disabled
C6 State - Package - Enabled
C6 State - Core - Enabled

Where:
FID = Frequency ID in Hexadecimal
VID = Voltage ID in Hexadecimal
DID = Divisor ID in Hexadecimal
Ratio = CPU Clock Ratio * 100Mhz to get Full CPU base frequency
vCore = The actual CPU base voltage (This will vary with Line Load)

The FID, DID and VID above are hex, so you'll have to convert them to decimal.

The CPU ratio is calculated as follows:
FID (decimal) / (DID (decimal) / 2) = CPU ratio

You can find your CPU information via: lscpu

So for my CPU (AMD Ryzen 5 5625U):
FID (5C hex | 92 decimal) / DID ((8 hex | 8 decimal) / 2) = CPU ratio = 23
FID (5A hex | 90 decimal) / DID ((A hex | 10 decimal) / 2) = CPU ratio = 18
FID (60 hex | 96 decimal) / DID ((C hex | 12 decimal) / 2) = CPU ratio = 16

So let's say I wanted to increase the P0 CPU ratio to 25 in order to get a bit more performance out of the CPU. I'll leave the voltage at stock.

FID / (DID / 2) = (64 hex | 100 decimal) / ((8 hex | 8 decimal) / 2) = 25
sudo python3 '/home/owner/ZenStates-Linux/zenstates.py' -p 0 -f 64 -d 8 -v 35
.. where 'owner' is your username.

That gives an output of:

Current P0: Enabled - FID = 5C - DID = 8 - VID = 35 - Ratio = 23.00 - vCore = 1.21875
Setting FID to 64
Setting DID to 8
Setting VID to 35
Locking TSC frequency
New P0: Enabled - FID = 64 - DID = 8 - VID = 35 - Ratio = 25.00 - vCore = 1.21875

To put it back to stock:
sudo python3 '/home/owner/ZenStates-Linux/zenstates.py' -p 0 -f 5c -d 8 -v 35

The settings don't stick between reboots, which is a good thing when you're testing.

If you've thoroughly tested the settings and know they're stable, you can make them permanent by:

sudoedit /etc/modules-load.d/cpu.conf
In that file simply enter these two lines:

msr
cpuid

This ensures that your kernel will load those two modules at startup.

Then copy zenstates.py from the local directory to /usr/local/bin/:
sudo cp '/home/owner/ZenStates-Linux/zenstates.py' /usr/local/bin/
.. where 'owner' is your username.

... and make sure it’s executable:
sudo chmod +x /usr/local/bin/zenstates.py

Then create a shell script that invokes zenstates.py from /usr/local/bin:
sudoedit /usr/local/bin/enable-pstates

Enter the following:

#!/bin/sh
## PUT YOUR DEFAULT CONFIGURATION HERE SO YOU CAN REVERT IF NEEDED:
## P0 - Enabled - FID = 5C - DID = 8 - VID = 35 - Ratio = 23.00 - vCore = 1.21875
## P1 - Enabled - FID = 5A - DID = A - VID = 60 - Ratio = 18.00 - vCore = 0.95000
## P2 - Enabled - FID = 60 - DID = C - VID = 66 - Ratio = 16.00 - vCore = 0.91250
## P3 - Disabled
## P4 - Disabled
## P5 - Disabled
## P6 - Disabled
## P7 - Disabled
## C6 State - Package - Enabled
## C6 State - Core - Enabled

## Boost P0
zenstates.py -p 0 -f 64 -d 8 -v 35

## List the result.
zenstates.py -l

Make that script executable:
sudo chmod +x /usr/local/bin/enable-pstates

Create a new file for the systemd service:
sudoedit /etc/systemd/system/ryzen-boost.service

Enter the following:

[Unit]
Description=Ryzen CPU Boost
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=basic.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/enable-pstates

[Install]
WantedBy=basic.target

Then enable and start the service:
sudo systemctl enable ryzen-boost
sudo systemctl start ryzen-boost

ONLY MAKE THE CHANGES PERMANENT AFTER YOU'VE THOROUGHLY TESTED THE SYSTEM STABILITY!

You'll find that if you undervolt the CPU while leaving the clock speeds at default, you can actually eke out performance gains... under heavy load, the CPU boosts core frequency to maximum then backs off if thermal conditions warrant it... less voltage through the CPU means lower temperatures means higher sustained core frequencies means more processing power.