Re: [RFC v4 0/4] platform/x86/amd: Add AMD DPTCi driver for TDP control in devices without vendor-specific controls
From: Mario Limonciello
Date: Thu Oct 15 2026 - 11:27:38 EST
On 10/15/26 09:55, Antheas Kapenekakis wrote:
On Thu, 15 Oct 2026 at 16:37, Mario Limonciello
<mario.limonciello@xxxxxxx> wrote:
On 10/15/26 04:35, Antheas Kapenekakis wrote:
On Tue, 10 Mar 2026 at 08:59, Antheas Kapenekakis <lkml@xxxxxxxxxxx> wrote:By "something similar" do you mean the AMD overclocking driver posted
On Tue, 10 Mar 2026 at 03:43, Mario Limonciello
<mario.limonciello@xxxxxxx> wrote:
On 3/9/2026 3:51 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:
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.
* 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, 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.
Responsible disclosure: The development of this driver is AI assisted.
This includes its writing, testing, reviewing, and readmes. The driver was
manually reviewed line by line, but there may still be 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.
I'll tell you where the most immediate limit is. Humans can't review
RFC changes that go in daily.
Over my weekend I see multiple copies of the series in my inbox. To me
they must have obviously been garbage because you sent them so quickly
instead of waiting for feedback. So I'll delete those from my inbox and
review the most recent one.
That's somewhat tongue in cheek. I know you're excited for this series,
but please make sure you take time to gather and take feedback into
account before posting another series.
It's true, I've been having a bit of fun. But the series is stabilized
now, I don't plan to send another version soon unless I messed up
something.
V3 incorporated your feedback/derek's and V4 incorporated rong's
feedback. V4 is minor, it is just nits.
Maybe you can pass this to a robot and it
can give you actionable feedback, but a human sitting down and reviewing
a patch series in a serious way takes time.
I'm using this series as a testbed to make some tooling for this,
maybe I will post it soon.
Opus 4.6 was something. Anyway. @Mario v4 of this driver as it stands
is pretty good for prod. Since then, I kept adding devices and
adjusting devices based on user feedback but I did not have to touch
the driver otherwise. It has been tested on most APUs and around 30
device models now.
One thing this driver does not do is AC/DC limits and it would be good
if it did. That way presets could be pushed higher for AC but that is
only mildly necessary for AI Max platforms. 45W is more than enough
for all of them anyway, but we could go to 55W e.g. (after that they
saturate so it is unnecessary strain). But the updated limits I have
are conservative enough where it is not an issue. I also found myself
not using the commit option, so I think it can be removed.
The only issue with this driver is that steam maxes out TDP when you
disable the TDP slider and as the custom limit is generic for both
AC/DC it can strain the battery. This is an architectural issue with
steamos manager as before steam used the _default tdp value in AMD
sysfs but dropped the notion of default when transitioning to steamos
manager. But this is a downstream problem unrelated to the driver
where special DC limits could help a bit.
This is because I heard you might be working on something similar. So
let's prevent some duplicative work. Should I repost a cleaned up V5?
Best,
Antheas
recently [1]?
Does that happen to work on any of this hardware?
95F20B61-3D44-41F8-87E1-03CBF94C4E8F returns nothing on my ACPI dumps.
There are functions which contain the e.g., 0x00020026 on a lot of
ssdts but no WMI with the GUID that series provides.
The WMI GUID of those functions is
ABBC0F6A-8EA1-11D1-00A0-C90629100000. If the interface is the same,
consider adding it to that driver.
OK - It shouldn't be the same.
You may reference to check yourself [2]
Here is what my LLM told me about that GUID:
| Dump | GUID present |
|---|---|
| Legion Go `N3CN26WW` | No |
| Legion Go `N3CN28WW` / `28WW-beta` | No |
| Legion Go `N3CN29WW` and later versions here | Yes |
| ROG Ally | No |
| Ally X | Yes |
| GPD Win 4 / Win Mini | No |
| One Xplayer / F1 Pro | Yes |
So very mixed, and perhaps not an alternative to what this series
provides to these devices. Fine by me to go through
If it doesn't; sure please post your v5 that has incorporated feedback
from this thread after the merge window at the start of the next kernel
cycle and we can review it again.
I was specifically asking about this interface. Not in a rush, just
bumping this a bit so it does not end up getting re-implemented. I
might not be able to fix all of the issues but I will try the best I
can.
It seems this interface is so universal the CPU check might be bogus,
but I managed to collect 99% of the CPUs, I only get a straggler
reported every month or so. So it should be ok to stay.
I'll admit this series hasn't been top of mind for me in a while. (So I might have some page faults while trying to remember things about it).
Earlier in the discussion for this series that as long as this is tied to SMBIOS strings to *only* load on intended hardware that should be sufficient. If two systems use the same SMBIOS strings between generations then you'll have to add CPU disambiguation.
BTW I think this version was last posted before Sashiko started
reviewing patches too. If you can; please run a local Sashiko review
cycle on it before posting your v5.
Sigh, if I figure out I will
No worries if you can't. I was just looking for an opportunity for less back and forth in case it flags something.
[2] https://github.com/hhd-dev/hwinfo
https://lore.kernel.org/all/20261010190543.563161-1-Shyam-sundar.S-k@xxxxxxx/
[1]