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

Antheas Kapenekakis posted 4 patches 4 weeks ago
There is a newer version of this series
.../testing/sysfs-class-firmware-attributes   |   41 +-
MAINTAINERS                                   |    6 +
drivers/platform/x86/amd/Kconfig              |   15 +
drivers/platform/x86/amd/Makefile             |    2 +
drivers/platform/x86/amd/dptc.c               | 1264 +++++++++++++++++
5 files changed, 1313 insertions(+), 15 deletions(-)
create mode 100644 drivers/platform/x86/amd/dptc.c
[RFC v3 0/4] platform/x86/amd: Add AMD DPTCi driver for TDP control in devices without vendor-specific controls
Posted by Antheas Kapenekakis 4 weeks ago
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.

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 v3:
  - Split single driver patch into 3: core driver, platform profile,
    device entries
  - Rename DRIVER_NAME from "amd_dptc" to "amd-dptc" (match subsystem
    convention for platform drivers and firmware-attributes devices)
  - Add scale field to dptc_param_desc: sysfs values in user units (W, C),
    driver multiplies by scale (1000 for mW) before sending to ALIB
  - Rename struct fields: min/smin/smax/max ->
    expanded_min/device_min/device_max/expanded_max
  - Remove comment "ALIB parameter IDs (AGESA spec Appendix E.5, Table
    E-52)"
  - Move ALIB method check after SoC/DMI validation, change pr_debug to
    pr_warn
  - Reorder local variable declaration in dptc_init (dptc after other vars)
  - Add commit subject prefix "dptc:" to all driver patches
  - Remove early-return for empty save in dptc_alib_save; let
    dptc_alib_call return -EINVAL (matches documentation)
  - Remove max_power as we do not do DC/AC validation in the driver
  - Fix Ayaneo AIR device matches to reflect their wattage, add 15W profile
    for original AIR. Cheers to the AIR Plus user who had helped tune the
    AIR Plus profile so it was correct.

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

V2: https://lore.kernel.org/all/20260305181751.3642846-1-lkml@antheas.dev/
V1: https://lore.kernel.org/all/20260303181707.2920261-1-lkml@antheas.dev/

Antheas Kapenekakis (4):
  Documentation: firmware-attributes: generalize save_settings entry
  platform/x86/amd: dptc: Add AMD DPTCi driver
  platform/x86/amd: dptc: Add platform profile support
  platform/x86/amd: dptc: Add device entries for handheld PCs

 .../testing/sysfs-class-firmware-attributes   |   41 +-
 MAINTAINERS                                   |    6 +
 drivers/platform/x86/amd/Kconfig              |   15 +
 drivers/platform/x86/amd/Makefile             |    2 +
 drivers/platform/x86/amd/dptc.c               | 1264 +++++++++++++++++
 5 files changed, 1313 insertions(+), 15 deletions(-)
 create mode 100644 drivers/platform/x86/amd/dptc.c


base-commit: 298ec5fe3c6a91f61dd971f9aa7e22e79c9ec024
-- 
2.52.0