mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Christian Loehle <christian.loehle@arm.com>
To: Sumit Gupta <sumitg@nvidia.com>,
	rafael@kernel.org, viresh.kumar@linaro.org,
	zhanjie9@hisilicon.com, zhenglifeng1@huawei.com,
	pierre.gondois@arm.com, ionela.voinescu@arm.com,
	mario.limonciello@amd.com, maciej.wieczor-retman@intel.com,
	pawel.chmielewski@intel.com, lenb@kernel.org, corbet@lwn.net,
	skhan@linuxfoundation.org, rdunlap@infradead.org,
	linux-pm@vger.kernel.org, linux-acpi@vger.kernel.org,
	acpica-devel@lists.linux.dev, linux-tegra@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org
Cc: treding@nvidia.com, jonathanh@nvidia.com, vsethi@nvidia.com,
	ksitaraman@nvidia.com, sanjayc@nvidia.com, mochs@nvidia.com,
	bbasu@nvidia.com
Subject: Re: [PATCH v6 RESEND] cpufreq: CPPC: Add autonomous mode boot parameter support
Date: Thu, 12 Nov 2026 13:14:16 +0000	[thread overview]
Message-ID: <8d335175-7d1e-4e12-b28b-d6f2ee13edee@arm.com> (raw)
In-Reply-To: <20261112080442.4007723-1-sumitg@nvidia.com>

On 11/12/26 08:04, Sumit Gupta wrote:
> Configuring autonomous selection and Energy Performance Preference (EPP)
> at every boot currently requires per-policy sysfs writes.
> 
> Add the 'cppc_cpufreq.auto_sel_mode' boot parameter to enable autonomous
> selection during policy initialization and optionally set EPP. In
> autonomous mode, the platform selects the performance level within the
> MIN and MAX limits, which the driver sets from the policy limits. The EPP
> hint guides that selection.
> 
> The parameter accepts:
> - performance: enable autonomous selection and set EPP to 0x00
> - balance_performance: enable it and set EPP to 0x80
> - balance_power: enable it and set EPP to 0xc0
> - power: enable it and set EPP to 0xff
> - default_epp: enable it and preserve firmware EPP
> - disabled: preserve the firmware configuration (default)
> 
> Warn about unrecognized values and ignore them.
> 
> Skip policies without autonomous-selection support. The driver enables
> autonomous selection before writing EPP, as the platform may ignore EPP
> while autonomous selection is disabled.
> 
> Record successful writes so the existing online and resume paths reapply
> the requested values. The offline and suspend paths restore the saved
> firmware values, including during driver unload.
> 
> Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
> ---
> Resending v6 with base-commit info and Pierre added to Cc.
> No changes to the code or commit message.
> 
> This is based on the "Preserve OSPM-set registers" [1] and
> "ospm_nominal_perf" [2] series, which are applied for 7.5.

I've sent out
https://lore.kernel.org/lkml/20261112113204.778904-1-christian.loehle@arm.com/
as a follow up, if it looks sound to you, feel free to pick it up
as a series to go in before $SUBJECT?

> 
> v5 -> v6:
> - Split "Set CPPC Enable register in cpu_init" into a separate fix [3].
> - Accept strings only (Pierre [4]).
> - Move the setup into cppc_cpufreq_setup_auto_sel_mode() and check
>   autonomous selection support first (Pierre [4]).
> - Drop the last_governor check, as init() now runs only for a new
>   policy (Pierre [4]).
> - Drop the MIN/MAX seeding, Desired hint and policy->min/max override,
>   as init() and the governor already set valid values (Pierre [4]).
> - Apply the parameter at the end of init(), after the usual
>   performance controls write.
> - Save auto_sel and EPP through the saved-register code from [1]
>   (Sashiko [5]).
> - Drop the cppc_cpufreq_exit() loop that cleared auto_sel on all
>   present CPUs (Pierre [4], Sashiko [5]).
> - Enable autonomous selection before writing EPP.
> - Set EPP also when firmware has already enabled autonomous selection.
> - Add the balance_power (0xc0) and power (0xff) modes.
> - Ignore an unrecognized value instead of treating it as disabled.
> 
> v5: https://lore.kernel.org/lkml/20260623080652.3353386-1-sumitg@nvidia.com/
> [1] https://lore.kernel.org/lkml/20261106193304.3347374-1-sumitg@nvidia.com/
> [2] https://lore.kernel.org/lkml/20261109195400.3600561-1-sumitg@nvidia.com/
> [3] https://lore.kernel.org/lkml/20261110101246.3665797-1-sumitg@nvidia.com/
> [4] https://lore.kernel.org/lkml/f61f592a-bc9c-4a83-bde1-e999c8101c36@nvidia.com/
> [5] https://sashiko.dev/#/patchset/20260623080652.3353386-1-sumitg@nvidia.com
> 
>  .../admin-guide/kernel-parameters.txt         |  26 ++++
>  drivers/cpufreq/cppc_cpufreq.c                | 120 ++++++++++++++++++
>  include/acpi/cppc_acpi.h                      |   2 +
>  3 files changed, 148 insertions(+)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 0b3c140babd9..5714c0d30fce 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -1015,6 +1015,32 @@ Kernel parameters
>  			Format:
>  			<first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
>  
> +	cppc_cpufreq.auto_sel_mode=
> +			[ACPI,CPU_FREQ] Enable ACPI CPPC autonomous performance
> +			selection on all CPUs at boot. In autonomous mode, the
> +			platform selects the performance level within the CPPC
> +			Minimum and Maximum Performance limits. The driver sets
> +			these limits from scaling_min_freq and scaling_max_freq.
> +			The Energy Performance Preference (EPP) hint guides the
> +			platform toward performance (0x00) or energy efficiency
> +			(0xff).
> +			Requires the ACPI CPPC Autonomous Selection Enable
> +			register. EPP is set only if the platform implements it.
> +			Format: <string>
> +			  performance:
> +				  enable autonomous selection, set EPP to 0x00
> +			  balance_performance:
> +				  enable autonomous selection, set EPP to 0x80
> +			  balance_power:
> +				  enable autonomous selection, set EPP to 0xc0
> +			  power:
> +				  enable autonomous selection, set EPP to 0xff
> +			  default_epp:
> +				  enable autonomous selection, keep firmware EPP
> +			  disabled:
> +				  keep the firmware configuration (default)
> +			An unrecognized value is ignored with a warning.
> +
>  	cpuidle.off=1	[CPU_IDLE]
>  			disable the cpuidle sub-system
>  
> diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
> index a62589c0674f..c9bed93cf0c9 100644
> --- a/drivers/cpufreq/cppc_cpufreq.c
> +++ b/drivers/cpufreq/cppc_cpufreq.c
> @@ -238,6 +238,58 @@ static void cppc_cpufreq_apply_saved_regs(struct cpufreq_policy *policy,
>  					     saved_type);
>  }
>  
> +/* Autonomous Selection boot parameter modes */
> +enum {
> +	AUTO_SEL_MODE_DISABLED,
> +	AUTO_SEL_MODE_PERFORMANCE,
> +	AUTO_SEL_MODE_BALANCE_PERFORMANCE,
> +	AUTO_SEL_MODE_BALANCE_POWER,
> +	AUTO_SEL_MODE_POWER,
> +	AUTO_SEL_MODE_DEFAULT_EPP,
> +};
> +
> +static const char * const auto_sel_mode_names[] = {
> +	[AUTO_SEL_MODE_DISABLED]		= "disabled",
> +	[AUTO_SEL_MODE_PERFORMANCE]		= "performance",
> +	[AUTO_SEL_MODE_BALANCE_PERFORMANCE]	= "balance_performance",
> +	[AUTO_SEL_MODE_BALANCE_POWER]		= "balance_power",
> +	[AUTO_SEL_MODE_POWER]			= "power",
> +	[AUTO_SEL_MODE_DEFAULT_EPP]		= "default_epp",
> +};
> +
> +static int auto_sel_mode;
> +
> +static int auto_sel_mode_set(const char *val, const struct kernel_param *kp)
> +{
> +	int *mode = kp->arg;
> +	int ret;
> +
> +	ret = sysfs_match_string(auto_sel_mode_names, val);
> +	if (ret < 0) {
> +		pr_warn("Invalid auto_sel_mode \"%s\", ignoring it\n", val);
> +		return 0;
> +	}
> +
> +	*mode = ret;
> +	return 0;
> +}
> +
> +static int auto_sel_mode_get(char *buffer, const struct kernel_param *kp)
> +{
> +	int *mode = kp->arg;
> +
> +	return sysfs_emit(buffer, "%s\n", auto_sel_mode_names[*mode]);
> +}
> +
> +static const struct kernel_param_ops auto_sel_mode_ops = {
> +	.set = auto_sel_mode_set,
> +	.get = auto_sel_mode_get,
> +};
> +
> +module_param_cb(auto_sel_mode, &auto_sel_mode_ops, &auto_sel_mode, 0444);
> +MODULE_PARM_DESC(auto_sel_mode,
> +		 "Autonomous selection mode: performance, balance_performance, balance_power, power, default_epp, disabled");
> +
>  #ifdef CONFIG_ACPI_CPPC_CPUFREQ_FIE
>  static enum {
>  	FIE_UNSET = -1,
> @@ -938,6 +990,72 @@ static u32 cppc_cpufreq_effective_nominal(struct cpufreq_policy *policy)
>  	return (u32)ospm_nominal;
>  }
>  
> +/*
> + * Apply the auto_sel_mode boot parameter in init(). Enable autonomous
> + * selection unless it is already enabled. Then set EPP for the selected mode.
> + *
> + * Enable auto_sel before writing EPP, as the platform may ignore EPP while
> + * autonomous selection is disabled. Save each value written, so that online()
> + * and resume() write it again.
> + */
> +static void cppc_cpufreq_setup_auto_sel_mode(struct cpufreq_policy *policy)
> +{
> +	struct cppc_policy_state *st = cppc_cpufreq_policy_state(policy);
> +	struct cppc_cpudata *cpu_data = policy->driver_data;
> +	unsigned int cpu = policy->cpu;
> +	u64 auto_sel, epp;
> +	int ret;
> +
> +	if (auto_sel_mode == AUTO_SEL_MODE_DISABLED)
> +		return;
> +
> +	/* U64_MAX means the platform does not implement the register. */
> +	auto_sel = st->regs[CPPC_SAVED_AUTO_SEL][CPPC_SAVED_FIRMWARE];
> +	if (auto_sel == U64_MAX) {
> +		pr_info_once("Autonomous selection is not supported, ignoring auto_sel_mode\n");
> +		return;
> +	}
> +
> +	if (!auto_sel) {
> +		ret = cppc_set_auto_sel(cpu, true);
> +		if (ret) {
> +			pr_warn("Failed to enable auto_sel for CPU%u (%d)\n",
> +				cpu, ret);
> +			return;
> +		}
> +		cppc_cpufreq_save_requested(policy, CPPC_SAVED_AUTO_SEL, true);
> +	}
> +	cpu_data->perf_ctrls.auto_sel = true;
> +
> +	switch (auto_sel_mode) {
> +	case AUTO_SEL_MODE_PERFORMANCE:
> +		epp = CPPC_EPP_PERFORMANCE_PREF;
> +		break;
> +	case AUTO_SEL_MODE_BALANCE_PERFORMANCE:
> +		epp = CPPC_EPP_BALANCE_PERFORMANCE_PREF;
> +		break;
> +	case AUTO_SEL_MODE_BALANCE_POWER:
> +		epp = CPPC_EPP_BALANCE_POWER_PREF;
> +		break;
> +	case AUTO_SEL_MODE_POWER:
> +		epp = CPPC_EPP_ENERGY_EFFICIENCY_PREF;
> +		break;
> +	default:
> +		/* default_epp keeps the EPP value set by firmware. */
> +		return;
> +	}
> +
> +	/* EPP is optional. */
> +	ret = cppc_set_epp(cpu, epp);
> +	if (ret) {
> +		if (ret != -EOPNOTSUPP)
> +			pr_warn("Failed to set EPP for CPU%u (%d)\n", cpu, ret);
> +		return;
> +	}
> +	cpu_data->perf_ctrls.energy_perf = epp;

So EPP is also allowed to be 4 or 6 bits wide and we might wanna account
for that either here or in acpi-cppc.
That being said that's already not working, I usually think all these
technically compliant platforms should just be filtered out on
acpi-cppc probe and we don't support EPP then and not worry about it.
That being said amd-pstate requires EPP for active mode and in this case
just handling the read/writes seems the pass of less resistance:
https://lore.kernel.org/all/20261112131316.827708-1-christian.loehle@arm.com/


> +	cppc_cpufreq_save_requested(policy, CPPC_SAVED_EPP, epp);
> +}
> +
>  static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
>  {
>  	unsigned int cpu = policy->cpu;
> @@ -1058,6 +1176,8 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
>  	}
>  	cpu_data->perf_limits_valid = true;
>  
> +	cppc_cpufreq_setup_auto_sel_mode(policy);
> +
>  	cppc_cpufreq_cpu_fie_init(policy);
>  	return 0;
>  
> diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
> index 2cec54b4d2e2..3d47c07f494b 100644
> --- a/include/acpi/cppc_acpi.h
> +++ b/include/acpi/cppc_acpi.h
> @@ -42,6 +42,8 @@
>  #define CPPC_AUTO_ACT_WINDOW_SIG_CARRY_THRESH 129
>  
>  #define CPPC_EPP_PERFORMANCE_PREF		0x00
> +#define CPPC_EPP_BALANCE_PERFORMANCE_PREF	0x80
> +#define CPPC_EPP_BALANCE_POWER_PREF		0xC0
>  #define CPPC_EPP_ENERGY_EFFICIENCY_PREF		0xFF
>  
>  #define CPPC_PERF_LIMITED_DESIRED_EXCURSION	BIT(0)
> 
> base-commit: a917b5968c17196b98b514158de800194d09e505

Actual $SUBJECT looks okay to me, I'd wait with the R-b for the
series, though.

      reply	other threads:[~2026-11-12 13:14 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-12  8:04 Sumit Gupta
2026-11-12 13:14 ` Christian Loehle [this message]

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=8d335175-7d1e-4e12-b28b-d6f2ee13edee@arm.com \
    --to=christian.loehle@arm.com \
    --cc=acpica-devel@lists.linux.dev \
    --cc=bbasu@nvidia.com \
    --cc=corbet@lwn.net \
    --cc=ionela.voinescu@arm.com \
    --cc=jonathanh@nvidia.com \
    --cc=ksitaraman@nvidia.com \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=maciej.wieczor-retman@intel.com \
    --cc=mario.limonciello@amd.com \
    --cc=mochs@nvidia.com \
    --cc=pawel.chmielewski@intel.com \
    --cc=pierre.gondois@arm.com \
    --cc=rafael@kernel.org \
    --cc=rdunlap@infradead.org \
    --cc=sanjayc@nvidia.com \
    --cc=skhan@linuxfoundation.org \
    --cc=sumitg@nvidia.com \
    --cc=treding@nvidia.com \
    --cc=viresh.kumar@linaro.org \
    --cc=vsethi@nvidia.com \
    --cc=zhanjie9@hisilicon.com \
    --cc=zhenglifeng1@huawei.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®