Re: [RFC v1 0/2] platform/x86/amd: Add AMD DPTCi driver for TDP control in devices without vendor-specific controls

From: Antheas Kapenekakis

Date: Tue Mar 03 2026 - 14:23:31 EST


On Tue, 3 Mar 2026 at 20:16, Antheas Kapenekakis <lkml@xxxxxxxxxxx> wrote:
>
> 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's
> > 1000% less work to enable PMF. All the values that match the design get
> > stored in BIOS, driver pulls the information and uses it.
>
> From my understanding they do not implement anything and just use
> ryzenadj with their windows vendor software.
>
> > Same approach for Windows and Linux.
> >
> > More comments below.
> >
> > On 3/3/26 12:17 PM, Antheas Kapenekakis wrote:
> > > Many AMD-based handheld PCs (GPD, AYANEO, OneXPlayer, AOKZOE, OrangePi)
> > > 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
> >
> > What is systemd-bios-vendor? I guess I'm not familiar with this and a
> > quick web search didn't turn anything obvious up.
>
> I used some AI assistance to compile this from my userspace
> 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.
>
> > > and modify them without device-specific knowledge.
> > >
> > > * 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.
> >
> > Can you please elaborate where you got all these numbers from? I don't
> > know if they're accurate or not. Someone would probably need to cross
> > reference them to be sure.
>
> Trial and error, research, references from Windows, etc. All of the
> 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.

To be clear here, a userspace implementation using the same limits and
the same interface [1].

This driver is a straight copy of that.

[1] https://github.com/hhd-dev/hhd/blob/master/src/adjustor/core/const.py

> 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.
>
> > > An "expanded" mode exposes the full
> > > 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.
> >
> > This isn't the only interface for setting power limits. How do you make
> > sure that the EC for example isn't stepping on toes on these designs?
>
> For the DMI matched devices it is not. For the ones that are not
> 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.
> >
> > What happens if the vendor enables PMF in a BIOS update? How does this
> > avoid conflicts?
>
> Some manufacturers enable pmf without implementing the tables. From my
> 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.
>
> > >
> > > Device limits are supplied for GPD Win Mini / Win 4 / Win 5 / Win Max 2 /
> > > 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.
> >
> > You should include Shyam (AMD), Denis and Derek (community).
>
> Sure.
>
> > >
> > > ---
> > > 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.
> >
> > AFAIK - fwupd doesn't understand "save_settings" today
>
> Yes, I do not expect it to even allow writing, but at least you can
> 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
> >
> >