Re: [RFC v1 0/2] platform/x86/amd: Add AMD DPTCi driver for TDP control in devices without vendor-specific controls
From: Armin Wolf
Date: Tue Mar 03 2026 - 14:27:26 EST
Am 03.03.26 um 20:16 schrieb Antheas Kapenekakis:
On Tue, 3 Mar 2026 at 19:59, Mario Limonciello <superm1@xxxxxxxxxx> wrote:
A high level question - why aren't these vendors implementing PMF? It'sFrom my understanding they do not implement anything and just use
1000% less work to enable PMF. All the values that match the design get
stored in BIOS, driver pulls the information and uses it.
ryzenadj with their windows vendor software.
Do they implement a WMI ACPI device called "AOD"? AFAIK this WMI device
is used by the Ryzen Master utility, so it could also allow users to change
the TDP limits in a reasonable safe way.
If they indeed only use ryzenadj, then shame on them.
Thanks,
Armin Wolf
Same approach for Windows and Linux.I used some AI assistance to compile this from my userspace
More comments below.
On 3/3/26 12:17 PM, Antheas Kapenekakis wrote:
Many AMD-based handheld PCs (GPD, AYANEO, OneXPlayer, AOKZOE, OrangePi)What is systemd-bios-vendor? I guess I'm not familiar with this and a
ship with the AGESA ALIB method at \_SB.ALIB, which accepts Function 0x0C
(the Dynamic Power and Thermal Configuration Interface, DPTCi). This
allows software to adjust APU power and thermal parameters at runtime:
STAPM limit, fast/slow PPT limits, skin-temperature TDP limit, slow/STAPM
time constants, and the thermal control target.
Until now userspace has reached this interface through the acpi_call out-
of-tree module or ryzenadj, which carry no ABI guarantees and no per-device
safety limits. This driver replaces that with a proper in-kernel
implementation that:
* Exposes all seven parameters through the firmware-attributes sysfs ABI,
so that standard tools (fwupd, systemd-bios-vendor, etc.) can enumerate
quick web search didn't turn anything obvious up.
implementation and the ASEGA pdf from the AMD site. I need to go
through _everything_ before this moves to non-RFC. Same with
copyright year. I focused on the implementation doing the things I
want it to do for now.
Trial and error, research, references from Windows, etc. All of theand modify them without device-specific knowledge.Can you please elaborate where you got all these numbers from? I don't
* Enforces tiered per-device and per-SoC limits. The default "device"
mode restricts writes to a curated safe range (smin..smax) derived from
the device's thermal design.
know if they're accurate or not. Someone would probably need to cross
reference them to be sure.
devices in this driver have been tested with a userspace
implementation using the same limits for ppt/sppt/fppt. Nobody has
complained about them. To be honest, I usually do not set tctl slow
and fast time limits, so those are referenced from the Legion Go and
for tctl I go lower than what manufacturers usually set. Users like
tctl because some of them like their device to stay cooler.
The big idea for this driver is to allow locking /dev/mem and ACPI.
Other than the legion go fan curves, and the Zotac Zone driver which
needs a cleanup, everything else is handled in the kernel now.
But this approach works fine for the Zotac Zone as they seem to be
using a very simple WMI shim.
For the DMI matched devices it is not. For the ones that are notAn "expanded" mode exposes the fullThis isn't the only interface for setting power limits. How do you make
hardware-validated range. An optional CONFIG_AMD_DPTC_EXTENDED Kconfig
adds "soc" (raw ALIB_PARAMS envelope) and "unbound" tiers for advanced
use. The active tier is itself a firmware-attribute, switchable at
runtime.
* Stages values and commits them atomically in a single ALIB call,
matching the protocol's intended bulk-update semantics. A save_settings
attribute (per firmware-attributes ABI) controls whether writes commit
immediately ("single" mode) or are held until an explicit "save".
* When in "single" mode, re-applies staged values after system resume,
so suspend/resume cycles do not silently revert to firmware defaults.
sure that the EC for example isn't stepping on toes on these designs?
matched, the driver does not autoload and needs a kconfig parameter to
even load.
OneXPlayer is a bit more complex with their turbo button doing TDP
swaps but turbo takeover in oxpec takes care of that and then you are
supposed use ryzenadj.
I /guess/ it always will need to be opt-in a device by device basis.Some manufacturers enable pmf without implementing the tables. From my
What happens if the vendor enables PMF in a BIOS update? How does this
avoid conflicts?
understanding none of them implement pmf with limits. If a
manufacturer wants to move to pmf, we can amend the DMI entry with a
bios match. However, from my understanding, there is no TDP slider
equivalent for PMF.
Sure.Device limits are supplied for GPD Win Mini / Win 4 / Win 5 / Win Max 2 /You should include Shyam (AMD), Denis and Derek (community).
Duo / Pocket 4, OrangePi NEO-01, AOKZOE A1/A2, OneXPlayer F1/2/X1/G1,
and numerous AYANEO models. The SoC table covers Ryzen 5000, 6000, 7040,
8000, Z1, AI 9 HX 370, and the Ryzen AI MAX series.
Tested on a GPD Win 5 (Ryzen AI MAX+ 395). Confirmed with ryzenadj -i
that committed values are applied to hardware, and that fast/slow PPT
limits are honoured under a full-CPU stress load.
@Mario: can you suggest a CC list for V2? Thanks. Even if not merged, this
driver is still good for downstream use.
Yes, I do not expect it to even allow writing, but at least you can---AFAIK - fwupd doesn't understand "save_settings" today
Usage
-----
List all exposed attributes (read-only, no root required):
$ fwupdmgr get-bios-settings
This enumerates every attribute under /sys/class/firmware-attributes/,
including current_value, default_value, min_value, max_value, and
display_name for each DPTCi parameter.
preview the values which is useful. And from what I saw defaults are
not shown either.
Antheas
Sysfs direct usage
------------------
All paths are under:
ATTR=/sys/class/firmware-attributes/amd_dptc/attributes
Inspect a parameter (no root needed):
$ cat $ATTR/stapm_limit/{display_name,min_value,max_value,default_value,current_value}
Sustained TDP (mW)
4000
85000
25000
<- empty: nothing staged yet
Stage values (held in memory, not yet sent to firmware):
$ echo 25000 | sudo tee $ATTR/stapm_limit/current_value
$ echo 40000 | sudo tee $ATTR/fast_limit/current_value
$ echo 27000 | sudo tee $ATTR/slow_limit/current_value
$ echo 25000 | sudo tee $ATTR/skin_limit/current_value
$ echo 85 | sudo tee $ATTR/temp_target/current_value
Commit all staged values in one ALIB call:
$ echo save | sudo tee $ATTR/save_settings
Switch to auto-commit (each write commits immediately):
$ echo single | sudo tee $ATTR/save_settings
Return to bulk mode:
$ echo bulk | sudo tee $ATTR/save_settings
Clear a staged value without committing:
$ echo | sudo tee $ATTR/stapm_limit/current_value
Query or change the active limit tier (device/expanded/soc/unbound):
$ cat $ATTR/limit_mode/possible_values
device;expanded;soc;unbound
$ echo expanded | sudo tee $ATTR/limit_mode/current_value
Switching tiers clears all staged values (old values may fall outside the
new range). Stages and commits must be redone after a mode switch.
Antheas Kapenekakis (2):
Documentation: firmware-attributes: generalize save_settings entry
platform/x86/amd: Add AMD DPTCi driver
.../testing/sysfs-class-firmware-attributes | 41 +-
MAINTAINERS | 6 +
drivers/platform/x86/amd/Kconfig | 27 +
drivers/platform/x86/amd/Makefile | 2 +
drivers/platform/x86/amd/dptc.c | 1325 +++++++++++++++++
5 files changed, 1386 insertions(+), 15 deletions(-)
create mode 100644 drivers/platform/x86/amd/dptc.c
base-commit: c89ce241c1909d2c2bdde88334c33f3000d364fb