From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A4EC23976B2; Tue, 3 Mar 2026 19:51:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772567463; cv=none; b=kqVGMXPV4icW+/iy6kwfPbx2UHD6PNQ3oFNMLhPQgQGJKpvGBdhIYCnJl4NleUOkurx1XN5Wle3yp1o/yJ8jvaWU3UiOQk6KnCMohAZQMUMPk+2PfvJ7V/qIL0DGoKoSWyk/Q6keZ+2/cwfnRshWwNMi3VboKMQ7wq9vTc0kXOI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772567463; c=relaxed/simple; bh=IlCG+TDhqJGmcbk3EBx4zdLarqbeFFJBsDRq1R1dNuc=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=mCt055VdJTmWvT/ruY0YAe7evaJPfNrEwkQymwEFgNxnVOpaa8tl0UH9jGBlHIGuPHVTloabELTmYRDtrZRIxU9C4gBO/hV0Iv+1szYqXIR+Z1wd9jL7fcbr1TIkK9mYkycsKJN0xvh34oaN3Th0gz6xFcrm8tJYFf7mPYAXEig= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=B1mb/q6g; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="B1mb/q6g" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 08B4DC116C6; Tue, 3 Mar 2026 19:51:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772567463; bh=IlCG+TDhqJGmcbk3EBx4zdLarqbeFFJBsDRq1R1dNuc=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=B1mb/q6g++PS3GmKmvmpdXPVG+Z3H9haTxiDu8vnFgfovmtEbe3dYs60nta7ngteb lF4Teh593i+uVQX5A3i0yZ8yJd3l1k9+7DmK71s3hfXI1ZDZx8oV2z/7eoiL6ffCOM wZGxn04aMwjizZJoqYKvv9zy5+/h1PA+cFHkXERVAGvJGYC+GfdyQLRRMvf+PsBG0l 2Zf1XLhQVIT9nXyFrgd6pgeGUhUE/FgPB+FK2nb8lL9nun4PHqx3jaJETxc7KhmAc2 3ZNbWA4vaKgFb/1s+Wk9JRPoXhpQWwQ2DyRCNCPFBhqBMNzBKwhzHCt2H6obpim36l D4AovkgoTwe0g== Message-ID: <061b13d9-2415-46e0-8671-26ce0f608c8e@kernel.org> Date: Tue, 3 Mar 2026 13:51:01 -0600 Precedence: bulk X-Mailing-List: platform-driver-x86@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [RFC v1 0/2] platform/x86/amd: Add AMD DPTCi driver for TDP control in devices without vendor-specific controls To: Antheas Kapenekakis Cc: linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org References: <20260303181707.2920261-1-lkml@antheas.dev> <2af36c81-4619-4f90-a04c-c3e5ed7a0cc5@kernel.org> Content-Language: en-US From: "Mario Limonciello (AMD) (kernel.org)" In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 3/3/2026 1:16 PM, Antheas Kapenekakis wrote: > On Tue, 3 Mar 2026 at 19:59, Mario Limonciello 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. Got it; so it's a made up tool :P > >>> 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. > > 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. I mean at a high level I conceptually like the idea of getting rid of the need to use software that manipulates /dev/mem and especially anything that means people relying on out of tree patches. This is a strong balancing act though to ratify interfaces to things that we don't have a stable ABI contract and documentation of the implications on getting it wrong. > >>> 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 >> >> >