[ Dec 2025 Update ] If you’re running an AMD Ryzen laptop on Linux ( Ubuntu ) and noticed your CPU is stuck at base clock speeds after waking from suspend, you’re not alone. This is a known bug with the amd-pstate-epp driver that affects many Ryzen mobile processors.
Background: The BIOS Frequency Cap Problem
Many AMD Ryzen laptops (especially ASUS models) have BIOS-imposed power limits that prevent the CPU from reaching its full boost frequency. The default acpi-cpufreq driver respects these limits, leaving you stuck at lower clocks.
The fix is to use the amd-pstate driver with kernel parameters that bypass these limits:
# /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash amd_pstate=active processor.ignore_ppc=1 acpi_cpufreq.enable_pcc=false intel_pstate=disable"
What these do:
amd_pstate=active– Use AMD’s modern pstate driver in autonomous modeprocessor.ignore_ppc=1– Ignore BIOS _PPC power performance control limitsacpi_cpufreq.enable_pcc=false– Disable Platform Communication Channel limitsintel_pstate=disable– Prevent Intel driver from loading (AMD system)
After adding these, run sudo update-grub and reboot.
This gets your CPU boosting to full speed on fresh boot. But then comes the suspend bug…
The Problem
After resuming from suspend, my AMD Ryzen 7 4800H was locked at 2.9 GHz instead of boosting to its full 4.3 GHz. The system felt sluggish, and checking the frequencies confirmed the issue:
$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
2901000
That’s 2.9 GHz – the base clock. The CPU should be capable of:
$ cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
4300902
4.3 GHz boost was completely unavailable after suspend.
Diagnosis
The culprit is the amd-pstate-epp driver running in “active” mode:
$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
amd-pstate-epp
$ cat /sys/devices/system/cpu/amd_pstate/status
active
In active mode, the hardware autonomously manages frequency scaling. After suspend, something breaks in this handoff and the driver fails to restore the full frequency range.
What Doesn’t Work
- Writing directly to
scaling_max_freq– ignored by the driver - Toggling CPU boost off/on
- Cycling power profiles
- Restarting power-profiles-daemon
- Using
cpupowercommands
The Solution
The fix is surprisingly simple: cycle the amd-pstate mode from active to passive and back:
echo passive | sudo tee /sys/devices/system/cpu/amd_pstate/status
sleep 1
echo active | sudo tee /sys/devices/system/cpu/amd_pstate/status
This forces the driver to reinitialize and properly restore the frequency limits.
Making It Permanent
Create a script that runs automatically after resume:
sudo tee /lib/systemd/system-sleep/cpu-freq-restore << 'EOF'
#!/bin/bash
case $1 in
post)
# Fix amd-pstate-epp bug after resume
/usr/bin/echo passive > /sys/devices/system/cpu/amd_pstate/status 2>/dev/null
/bin/sleep 1
/usr/bin/echo active > /sys/devices/system/cpu/amd_pstate/status 2>/dev/null
# Set performance EPP
for epp in /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference; do
/usr/bin/echo performance > "$epp" 2>/dev/null
done
;;
esac
exit 0
EOF
sudo chmod 755 /lib/systemd/system-sleep/cpu-freq-restore
Scripts in /lib/systemd/system-sleep/ are automatically executed by systemd:
- On suspend: called with
preargument - On resume: called with
postargument
The script runs as root, so no authentication prompts will appear.
Verification
After your next suspend/resume cycle, verify the fix:
# Check max frequency is restored
$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
4300902
# Check actual frequencies (should see boost clocks under load)
$ grep "MHz" /proc/cpuinfo | head -4
cpu MHz : 4290.553
cpu MHz : 4270.657
cpu MHz : 4290.130
cpu MHz : 1113.175
Why This Happens
The amd-pstate-epp driver in “active” mode relies on the CPU’s internal firmware (CPPC – Collaborative Processor Performance Control) to manage frequencies. During suspend, the CPU state is saved, but on resume, the CPPC negotiation between the OS and firmware doesn’t properly restore the upper frequency limits.
Cycling through “passive” mode forces a complete reinitialization of the driver’s frequency tables, which correctly queries the hardware capabilities again.
Affected Systems
This bug appears to affect:
- AMD Ryzen 4000/5000/6000/7000 series mobile processors
- Linux kernels with amd-pstate-epp driver (5.17+)
- Systems using
amd_pstate=activekernel parameter - ASUS laptops with restrictive BIOS power limits (ROG, TUF, Zephyrus series)
The Full Picture
If you have an AMD Ryzen laptop that won’t boost properly, you likely need both fixes:
- Kernel parameters (in
/etc/default/grub) – to bypass BIOS limits on boot - Resume script (in
/lib/systemd/system-sleep/) – to restore frequencies after suspend
Without the kernel parameters, you’re stuck at base clock all the time. Without the resume script, you lose boost after every suspend cycle.
Alternative: Use Passive Mode Permanently
If you prefer, you can run in passive mode permanently by adding to your kernel parameters:
amd_pstate=passive
In passive mode, the OS has more direct control over frequency scaling, and the suspend bug doesn’t occur. However, active mode generally provides better power efficiency when working correctly.
Tested on ASUS TUF Gaming A17 (FA706IC) with AMD Ryzen 7 4800H, running Ubuntu 25.10 and kernel 6.18.1
