[RFC v2 0/2] platform/x86/amd: Add AMD DPTCi driver for TDP control in devices without vendor-specific controls
From: Antheas Kapenekakis
Date: Thu Mar 05 2026 - 13:20:27 EST
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:
sustained power limit (SPL/STAPM + skin), slow PPT, fast PPT, and the
thermal control target.
Unlike mainstream AMD laptops, these devices do not implement vendor-
specific WMI or EC hooks for TDP control. The ones that do, use DPTCi
under the hood. For these devices, ALIB is the only viable mechanism for
the OS to adjust power limits, making a dedicated kernel driver the
correct approach rather than relying on the out-of-tree acpi_call module
or ryzenadj.
The driver provides two layers of control:
* Platform profile integration (low-power / balanced / performance /
custom), with per-device preset tunings derived from thermal envelope
data. Selecting a non-custom profile applies values immediately and
locks the individual tunables to read-only. The default profile is
"custom", leaving the device at firmware defaults until userspace
explicitly selects a profile. Certain profiles feature a "max_power"
preset when it is deemed that using the maximum values for performance
would lead to a degraded user experience (e.g. excessive fan noise)
* Four firmware-attributes tunables (ppt_pl1_spl, ppt_pl2_sppt,
ppt_pl3_fppt, cpu_temp) that become writable in "custom" mode.
Values are enforced against per-device limits (smin..smax), with an
"expanded_limits" toggle that widens the range to the full hardware-
validated envelope (min..max). A save_settings attribute controls
whether writes commit immediately ("single") or are staged for an
explicit bulk "save".
On resume, the active profile or staged values are re-applied so that
suspend/resume cycles do not silently revert to firmware defaults unless
in custom and in bulk mode. In that case, defer to userspace.
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.
I expand the CC list here to include Sasha (you might be interested,
feel free to ask to be dropped), Derek + Shyam + Denis as requested.
Responsible disclosure: The development of this driver is AI assisted.
This includes its writing, testing, and readmes. The driver was manually
reviewed line by line, but there still may small leftover quirks. This is
an RFC, not a final version. Let's push these tools to their limits and
see where it takes us.
Assisted-by: Claude:claude-opus-4-6
---
Changes in v2:
- Use a platform_device base instead of raw inits + exit, hook into devm
helpers referencing samsung-galaxybook
- Add platform_profile support (low-power / balanced / performance /
custom) with per-device energy presets; non-custom profiles lock
tunables to read-only. We default to custom to avoid writing values
- Reduce exposed parameters from seven to four (ppt_pl1_spl,
ppt_pl2_sppt, ppt_pl3_fppt, cpu_temp); drop time constants and
separate skin/STAPM limits in favour of a single SPL that sets both.
For devices where the max tdp offers thermals that are not suitable
for day to day use (e.g., excessive fan noise), MAX_POWER is added
- Remove CONFIG_AMD_DPTC_EXTENDED and the "soc"/"unbound" limit tiers;
keep only device (smin..smax) and expanded (min..max) and soc match
(certain devices ship multiple SoCs on the same motherboard/thermal
envelope, make sure we only hook into validated SoCs)
- Rename "commit" attribute to "save_settings" per firmware-attributes
ABI; rename limit_mode to expanded_limits
- Change expanded_limits attribute type from "enumeration" to "integer"
(min=0, max=1) since firmware-attributes has no bool type
- Remove all global vars, limit _dev access to init and exit
- Use u32 accessors to set values for ALIB call
- Clean up verbose comments throughout
- Add Ayn Loki Max / Tectoy Zeenix Pro
V1: https://lore.kernel.org/all/20260303181707.2920261-1-lkml@xxxxxxxxxxx/
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 | 16 +
drivers/platform/x86/amd/Makefile | 2 +
drivers/platform/x86/amd/dptc.c | 1255 +++++++++++++++++
5 files changed, 1305 insertions(+), 15 deletions(-)
create mode 100644 drivers/platform/x86/amd/dptc.c
base-commit: c89ce241c1909d2c2bdde88334c33f3000d364fb
--
2.52.0