Skip to content

Framework 13 (Ryzen AI 300): all cores clamped to 605 MHz after s2idle resume on AC, firmware ignores OS P-state requests until PSU replug #241

Description

@ZachGoldberg

Device Information

Disclaimer: This entire bug report, as well as the diagnosis process, was driven by Claude Opus.

I, Zach, a human, wrote this disclaimer and read all AI-generated content in this ticket before posting it to GitHub and can confirm,
to the best of my knowledge/capability, its accurate and details are real and not hallucinated. I am not an expert in
laptop CPU power management, so my ability to double check Claude on the finer details in that domain is limited.

System Model or SKU

  • Framework Laptop 12 (13th Gen Intel® Core™)
  • Framework Laptop 13 (11th Gen Intel® Core™)
  • Framework Laptop 13 (12th Gen Intel® Core™)
  • Framework Laptop 13 (13th Gen Intel® Core™)
  • Framework Laptop 13 (AMD Ryzen™ 7040 Series)
  • Framework Laptop 13 (AMD Ryzen™ AI 300 Series)
  • Framework Laptop 13 (Intel® Core™ Ultra Series 1)
  • Framework Laptop 16 (AMD Ryzen™ 7040 Series)
  • Framework Laptop 16 (AMD Ryzen™ AI 300 Series)
  • Framework Desktop (AMD Ryzen™ AI 300 PRO Series)

CPU: AMD Ryzen AI 9 HX 370 w/ Radeon 890M (12 cores / 24 threads)
Board: FRANMGCP09, version A9

BIOS VERSION

04.02 (release date 06/09/2026)

$ sudo dmidecode --string bios-version
04.02

fwupdmgr reports System Firmware 0.0.4.2 and confirms this is the latest
available version — there is no pending update.

DIY Edition information

Memory: 2 × 32 GB A-DATA Technology AD5S560032G-B (DDR5 SODIMM, dual-rank,
running at 5600 MT/s) — 64 GB total
Storage: Western Digital WD_BLACK SN850X 1000GB (NVMe, firmware 620331WD)

Port/Peripheral information

The charger is central to this bug, so port detail is included:

  • Charger: 100W USB-C PD (negotiated 20V @ 5A). The kernel exposes it as
    ucsi-source-psy-USBC000:004, online=1, the only port sourcing power.
  • Expansion cards installed:
    1. Framework HDMI Expansion Card (32ac:0002)
    2. USB-C (charging port, see above)
    3. USB-C
    4. USB-A

Nothing was hotplugged around the time the fault appeared. Power delivery was
healthy throughout — see "What this is NOT" below.

Standalone Operation (Laptop Only)

  • Yes
  • No

Describe the bug

After resuming from s2idle suspend while on AC power, every core is clamped to
605 MHz
— exactly amd_pstate_lowest_nonlinear_freq — against a 5157 MHz
maximum, and stays there indefinitely under full load. This is roughly an
8.5x slowdown, and it presents as pervasive UI stutter (typing latency,
slow tab switching) rather than as anything obviously CPU-related, which makes
it easy to misattribute to the desktop or browser.

The decisive observation: the OS is requesting maximum frequency and the
hardware is not delivering it.
With amd_pstate in passive mode and the
performance governor — which pins min_perf = max_perf, a hard request
rather than a hint — scaling_cur_freq read 3289–5157 MHz while measured
throughput via synthetic benchmark stayed at roughly 600 MHz worth of work.

Measurements

Two independent benchmarks, before and after the fix, on an otherwise idle
system:

Measure Clamped After PSU replug Ratio
Python 8M-iteration loop 2.60 s 0.30 s 8.7x
openssl speed sha256 (8 KiB block) 283 MB/s 2440 MB/s 8.6x
Delivered clock under load (/proc/cpuinfo, APERF/MPERF) 605 MHz 4833 MHz 8.0x

The ~8.5x measured throughput ratio matches the 605 → 5157 MHz frequency ratio,
confirming the clock reading reflects real delivered performance.

What this is NOT

Ruled out by direct measurement while the fault was active:

  • Not thermal. All ACPI thermal zones read 34–47 °C. Nowhere near throttling.
  • Not power starvation. Charger negotiated and held 20V @ 5A (100W); battery
    charging normally at 93%.
  • Not a policy/governor setting. scaling_max_freq remained 5157000
    throughout. Setting EPP to performance (via powerprofilesctl set performance) changed nothing. Neither did the performance governor in
    passive mode.
  • Not RAPL/powercap. No power constraints enabled.
  • Not a stale sensor reading. Confirmed independently by wall-clock
    benchmarks, not just by scaling_cur_freq.

Diagnostic note for whoever picks this up

scaling_cur_freq is not a reliable indicator for this bug — it reports the
driver's setpoint, and during the clamp in passive mode it read 3289 MHz while
the silicon delivered 605. /proc/cpuinfo's cpu MHz, which is APERF/MPERF-derived,
reports the true delivered clock. Any monitoring or triage that keys off
scaling_cur_freq will show a healthy system through the entire failure.

Steps To Reproduce

(This has not yet been confirmed, below is Claude's best guess)

  1. Boot with AC (USB-C PD) connected and leave it connected throughout.
  2. Suspend (s2idle) and leave the machine suspended for an extended period —
    in my case the long cycles were 76, 53, and 52 minutes.
  3. Resume.
  4. Put any sustained load on the CPU and observe the delivered clock:
    grep "cpu MHz" /proc/cpuinfo | sort -t: -k2 -rn | head
    
    All cores sit at ~605 MHz and never rise.

Honest caveat on reproducibility: I observed this once, during normal use,
and diagnosed it live rather than under controlled conditions. I have not yet
done a deliberate A/B to isolate the trigger, so "long suspend on AC" is a
strong inference from the pattern (and from the matching conditions in #91),
not something I have proven. Eight suspend/resume cycles occurred over the
~4.5 hours before the fault surfaced. I'm happy to attempt a controlled
reproduction if that would help — see below.

Expected behavior

After resume, cores should scale up to the boost range under load, as they do
on a fresh boot. At minimum, an explicit request for maximum performance
(passive mode + performance governor) should be honoured by firmware.

Workaround

Physically unplug the USB-C charger and plug it back in. Recovery is
immediate and complete — the full 8.6x throughput came back instantly, with no
reboot and no configuration change.

This matches the workaround reported in #91 ("Disconnecting and reconnecting the
PSU immediately resolves the throttling") and is consistent with the fault being
cleared by a PD renegotiation resetting the EC/SMU power limits.

Operating System

  • OS/Distribution: Ubuntu 25.04
  • Version: 25.04 (GNOME 48.0, Wayland)
  • Linux Kernel Version: 6.14.4-061404-generic

Note: this is a mainline kernel, not Ubuntu's stock kernel — flagging it
since it's an obvious variable. The affected machine had no amd_pstate=
override on the kernel command line; the driver was in its default
amd-pstate-epp / powersave / EPP balance_performance configuration when
the fault appeared. power-profiles-daemon active; TLP, tuned, thermald all
inactive.

Kernel command line:

BOOT_IMAGE=/boot/vmlinuz-6.14.4-061404-generic root=UUID=... ro quiet splash
rtc_cmos.use_acpi_alarm=1 crashkernel=2G-4G:320M,4G-32G:512M,32G-64G:1024M,64G-128G:2048M,128G-:4096M vt.handoff=7

Additional context

Possibly related: amdgpu ring failure on the same resume

The resume immediately preceding the fault also logged a GPU compute ring
failure:

Aug 06 10:51:22 kernel: amdgpu 0000:c1:00.0: amdgpu: SMU is resuming...
Aug 06 10:51:22 kernel: amdgpu 0000:c1:00.0: amdgpu: SMU is resumed successfully!
Aug 06 10:51:22 kernel: amdgpu 0000:c1:00.0: [drm:amdgpu_ring_test_helper [amdgpu]] *ERROR* ring compute_32775.2.2 test failed (-110)

Since the SMU governs power management for both the CPU and the integrated GPU
on these APUs, a shared SMU resume failure would explain both symptoms. I want
to be clear this is a hypothesis on my part, not something I've established —
it may simply be coincident.

Relationship to existing issues

Every existing frequency-clamp report I could find in this tracker is Laptop 16
or Ryzen 7040:

I could not find an existing report for Laptop 13 / Ryzen AI 300, which is
why I'm filing separately rather than commenting on #91. If you'd prefer this
consolidated there, happy to move it.

Worth noting the clamp frequency differs per platform in a way that fits the
mechanism: 0.55 GHz on 7040, 605 MHz here — each is that chip's
lowest_nonlinear P-state, not a fixed value.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions