All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mario Limonciello <mario.limonciello@amd.com>
To: Antheas Kapenekakis <lkml@antheas.dev>
Cc: W_Armin@gmx.de, sashal@kernel.org, Shyam-Sundar.S-k@amd.com,
	derekjohn.clark@gmail.com, denis.benato@linux.dev, i@rong.moe,
	linux-kernel@vger.kernel.org,
	platform-driver-x86@vger.kernel.org
Subject: Re: [RFC v4 3/4] platform/x86/amd: dptc: Add platform profile support
Date: Mon, 9 Mar 2026 23:07:01 -0500	[thread overview]
Message-ID: <b4f81b6f-8bc6-440d-a9ea-244afe4a3fb8@amd.com> (raw)
In-Reply-To: <20260309205125.293148-4-lkml@antheas.dev>



On 3/9/2026 3:51 PM, Antheas Kapenekakis wrote:
> Register a platform_profile handler so the driver exposes standard
> power profiles (low-power, balanced, performance) alongside the manual
> tunable interface.
> 
> When a non-custom profile is active, parameter writes are blocked
> (-EBUSY) and current_value reflects the profile's preset values.
> Selecting the "custom" profile returns control to the user for manual
> staging and committing. On resume, the active profile is automatically
> re-applied.
> 
> Assisted-by: Claude:claude-opus-4-6
> Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
> ---
>   drivers/platform/x86/amd/Kconfig |   1 +
>   drivers/platform/x86/amd/dptc.c  | 109 ++++++++++++++++++++++++++++++-
>   2 files changed, 108 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/platform/x86/amd/Kconfig b/drivers/platform/x86/amd/Kconfig
> index d610092467fc..41ffbd722524 100644
> --- a/drivers/platform/x86/amd/Kconfig
> +++ b/drivers/platform/x86/amd/Kconfig
> @@ -48,6 +48,7 @@ config AMD_ISP_PLATFORM
>   config AMD_DPTC
>   	tristate "AMD Dynamic Power and Thermal Configuration Interface (DPTCi)"
>   	depends on X86_64 && ACPI && DMI
> +	select ACPI_PLATFORM_PROFILE
>   	select FIRMWARE_ATTRIBUTES_CLASS
>   	help
>   	  Driver for AMD AGESA ALIB Function 0x0C, the Dynamic Power and

Your description doesn't talk about platform profile (which I expect is 
what the default should be for 99% of people).

> diff --git a/drivers/platform/x86/amd/dptc.c b/drivers/platform/x86/amd/dptc.c
> index b884cdfa3f82..f4db95affb1b 100644
> --- a/drivers/platform/x86/amd/dptc.c
> +++ b/drivers/platform/x86/amd/dptc.c
> @@ -23,6 +23,7 @@
>   #include <linux/module.h>
>   #include <linux/mutex.h>
>   #include <linux/platform_device.h>
> +#include <linux/platform_profile.h>
>   #include <linux/processor.h>
>   #include <linux/sysfs.h>
>   #include <linux/unaligned.h>
> @@ -56,8 +57,13 @@ struct dptc_param_limits {
>   	u32 expanded_max;
>   };
>   
> +struct dptc_profile {
> +	u32 vals[DPTC_NUM_PARAMS];	/* 0 = don't set / unstage this param */
> +};
> +
>   struct dptc_device_limits {
>   	struct dptc_param_limits params[DPTC_NUM_PARAMS];
> +	struct dptc_profile profiles[PLATFORM_PROFILE_LAST];
>   };
>   
>   struct dptc_param_desc {
> @@ -88,6 +94,11 @@ static const struct dptc_device_limits limits_maxhh = {
>   		[DPTC_PPT_PL3_FPPT] = {  1,  4, 40,  85, 100 },
>   		[DPTC_CPU_TEMP]     = { 60, 70, 95,  95, 100 },
>   	},
> +	.profiles = {
> +		[PLATFORM_PROFILE_LOW_POWER]   = { .vals = { 15, 15, 25, 0 } },
> +		[PLATFORM_PROFILE_BALANCED]    = { .vals = { 25, 27, 40, 0 } },
> +		[PLATFORM_PROFILE_PERFORMANCE] = { .vals = { 60, 63, 85, 0 } },
> +	},
>   };
>   
>   /* Substring matches against boot_cpu_data.x86_model_id; order matters. */
> @@ -139,11 +150,14 @@ struct dptc_priv {
>   
>   	bool expanded;
>   
> +	enum platform_profile_option profile;
> +	struct device *ppdev;
> +
>   	enum dptc_save_mode save_mode;
>   
>   	u32 staged[DPTC_NUM_PARAMS];
>   
> -	/* Protects staged, expanded, and save_mode */
> +	/* Protects staged, expanded, save_mode, and profile */
>   	struct mutex lock;
>   
>   	struct dptc_attr_sysfs params[DPTC_NUM_PARAMS];
> @@ -271,6 +285,14 @@ static ssize_t dptc_current_value_show(struct kobject *kobj,
>   
>   	guard(mutex)(&dptc->lock);
>   
> +	if (dptc->profile != PLATFORM_PROFILE_CUSTOM) {
> +		u32 val = dptc->dev_limits->profiles[dptc->profile].vals[ps->idx];
> +
> +		if (!val)
> +			return sysfs_emit(buf, "\n");
> +		return sysfs_emit(buf, "%u\n", val);
> +	}
> +
>   	if (!dptc->staged[ps->idx])
>   		return sysfs_emit(buf, "\n");
>   	return sysfs_emit(buf, "%u\n", dptc->staged[ps->idx]);
> @@ -288,6 +310,9 @@ static ssize_t dptc_current_value_store(struct kobject *kobj,
>   
>   	guard(mutex)(&dptc->lock);
>   
> +	if (dptc->profile != PLATFORM_PROFILE_CUSTOM)
> +		return -EBUSY;
> +
>   	if (count == 1 && buf[0] == '\n') {
>   		dptc->staged[ps->idx] = 0;
>   		return count;
> @@ -425,6 +450,9 @@ static ssize_t dptc_expanded_current_value_store(struct kobject *kobj,
>   
>   	guard(mutex)(&dptc->lock);
>   
> +	if (dptc->profile != PLATFORM_PROFILE_CUSTOM)
> +		return -EBUSY;
> +
>   	dptc->expanded = val;
>   	/* Clear staged values: limits changed, old values may be out of range */
>   	memset(dptc->staged, 0, sizeof(dptc->staged));
> @@ -593,6 +621,75 @@ static void dptc_kset_unregister(void *data)
>   	kset_unregister(data);
>   }
>   
> +/* Platform profile */
> +
> +static int dptc_apply_profile(struct dptc_priv *dptc,
> +			      enum platform_profile_option profile)
> +{
> +	const struct dptc_profile *pp;
> +	int i;
> +
> +	memset(dptc->staged, 0, sizeof(dptc->staged));
> +
> +	if (profile == PLATFORM_PROFILE_CUSTOM)
> +		return 0;
> +
> +	pp = &dptc->dev_limits->profiles[profile];
> +	for (i = 0; i < DPTC_NUM_PARAMS; i++) {
> +		if (!pp->vals[i])
> +			continue;
> +		dptc->staged[i] = pp->vals[i];
> +	}
> +
> +	return dptc_alib_save(dptc);
> +}
> +
> +static int dptc_pp_probe(void *drvdata, unsigned long *choices)
> +{
> +	struct dptc_priv *dptc = drvdata;
> +	int i, j;
> +
> +	set_bit(PLATFORM_PROFILE_CUSTOM, choices);
> +	for (i = 0; i < PLATFORM_PROFILE_LAST; i++) {
> +		for (j = 0; j < DPTC_NUM_PARAMS; j++) {
> +			if (dptc->dev_limits->profiles[i].vals[j]) {
> +				set_bit(i, choices);
> +				break;
> +			}
> +		}
> +	}
> +	return 0;
> +}
> +
> +static int dptc_pp_get(struct device *dev,
> +		       enum platform_profile_option *profile)
> +{
> +	struct dptc_priv *dptc = dev_get_drvdata(dev);
> +
> +	guard(mutex)(&dptc->lock);
> +
> +	*profile = dptc->profile;
> +	return 0;
> +}
> +
> +static int dptc_pp_set(struct device *dev,
> +		       enum platform_profile_option profile)
> +{
> +	struct dptc_priv *dptc = dev_get_drvdata(dev);
> +
> +	guard(mutex)(&dptc->lock);
> +
> +	dptc->profile = profile;
> +
> +	return dptc_apply_profile(dptc, profile);
> +}
> +
> +static const struct platform_profile_ops dptc_pp_ops = {
> +	.probe       = dptc_pp_probe,
> +	.profile_get = dptc_pp_get,
> +	.profile_set = dptc_pp_set,
> +};
> +
>   static int dptc_resume(struct device *dev)
>   {
>   	struct dptc_priv *dptc = dev_get_drvdata(dev);
> @@ -601,7 +698,9 @@ static int dptc_resume(struct device *dev)
>   	guard(mutex)(&dptc->lock);
>   
>   	/* In bulk mode, do not use pm ops for userspace flexibility. */
> -	if (dptc->save_mode == SAVE_SINGLE)
> +	if (dptc->profile != PLATFORM_PROFILE_CUSTOM)
> +		ret = dptc_apply_profile(dptc, dptc->profile);
> +	else if (dptc->save_mode == SAVE_SINGLE)
>   		ret = dptc_alib_save(dptc);
>   	else
>   		ret = 0;
> @@ -679,6 +778,12 @@ static int dptc_probe(struct platform_device *pdev)
>   	if (ret)
>   		return ret;
>   
> +	dptc->profile = PLATFORM_PROFILE_CUSTOM;
> +	dptc->ppdev = devm_platform_profile_register(dev, "amd-dptc", dptc,
> +						     &dptc_pp_ops);
> +	if (IS_ERR(dptc->ppdev))
> +		return PTR_ERR(dptc->ppdev);
> +
>   	return 0;
>   }
>   


  reply	other threads:[~2026-03-10  4:07 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-09 20:51 [RFC v4 0/4] platform/x86/amd: Add AMD DPTCi driver for TDP control in devices without vendor-specific controls Antheas Kapenekakis
2026-03-09 20:51 ` [RFC v4 1/4] Documentation: firmware-attributes: generalize save_settings entry Antheas Kapenekakis
2026-03-09 20:51 ` [RFC v4 2/4] platform/x86/amd: dptc: Add AMD DPTCi driver Antheas Kapenekakis
2026-03-10  4:01   ` Mario Limonciello
2026-03-10  8:02     ` Antheas Kapenekakis
2026-03-10 16:26       ` Mario Limonciello
2026-03-11 19:09         ` Antheas Kapenekakis
2026-03-12 13:24           ` Mario Limonciello
2026-03-12 13:47             ` Antheas Kapenekakis
2026-03-12 16:05               ` Mario Limonciello
2026-03-12 16:19                 ` Antheas Kapenekakis
2026-03-09 20:51 ` [RFC v4 3/4] platform/x86/amd: dptc: Add platform profile support Antheas Kapenekakis
2026-03-10  4:07   ` Mario Limonciello [this message]
2026-03-09 20:51 ` [RFC v4 4/4] platform/x86/amd: dptc: Add device entries for handheld PCs Antheas Kapenekakis
2026-03-10  4:11   ` Mario Limonciello
2026-03-10  8:13     ` Antheas Kapenekakis
2026-03-10 16:35       ` Mario Limonciello
2026-03-11 19:13         ` Antheas Kapenekakis
2026-03-12 13:26           ` Mario Limonciello
2026-03-10  2:43 ` [RFC v4 0/4] platform/x86/amd: Add AMD DPTCi driver for TDP control in devices without vendor-specific controls Mario Limonciello
2026-03-10  7:59   ` Antheas Kapenekakis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b4f81b6f-8bc6-440d-a9ea-244afe4a3fb8@amd.com \
    --to=mario.limonciello@amd.com \
    --cc=Shyam-Sundar.S-k@amd.com \
    --cc=W_Armin@gmx.de \
    --cc=denis.benato@linux.dev \
    --cc=derekjohn.clark@gmail.com \
    --cc=i@rong.moe \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lkml@antheas.dev \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=sashal@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.