Fixing AMD Ryzen CPU Frequency Stuck at 2.9Ghz Base Clock After Suspend on Ubuntu Linux

Screenshot From 2025 12 27 22 29 30

[ 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 mode
  • processor.ignore_ppc=1 – Ignore BIOS _PPC power performance control limits
  • acpi_cpufreq.enable_pcc=false – Disable Platform Communication Channel limits
  • intel_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 cpupower commands

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 pre argument
  • On resume: called with post argument

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=active kernel 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:

  1. Kernel parameters (in /etc/default/grub) – to bypass BIOS limits on boot
  2. 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

Exit mobile version