[PATCH 2/2] cpufreq: cppc: Add update_limits support for Highest Performance changes
From: Xueqin Luo
Date: Fri May 08 2026 - 06:27:57 EST
ACPI CPPC specification requires OSPM to re-evaluate the Highest
Performance register when Notify(0x85) is received for a processor
device.
Implement cppc_cpufreq_update_limits() to refresh the cached
highest_perf capability through cppc_get_highest_perf() and update
policy->cpuinfo.max_freq accordingly.
When autonomous selection mode is enabled, reprogram the runtime
MIN_PERF/MAX_PERF envelope against the updated Highest Performance
capability through cppc_cpufreq_set_autonomous_perf().
Signed-off-by: Xueqin Luo <luoxueqin@xxxxxxxxxx>
---
drivers/cpufreq/cppc_cpufreq.c | 45 ++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index 7ddf4296c474..fc0fc27342c1 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -873,6 +873,50 @@ static int cppc_cpufreq_set_autonomous_perf(struct cpufreq_policy *policy)
return 0;
}
+static void cppc_cpufreq_update_limits(struct cpufreq_policy *policy)
+{
+ struct cppc_cpudata *cpu_data = policy->driver_data;
+ u32 prev_highest_perf;
+ u32 highest_perf;
+ int ret;
+
+ guard(cpufreq_policy_write)(policy);
+
+ prev_highest_perf = cpu_data->perf_caps.highest_perf;
+
+ ret = cppc_get_highest_perf(policy->cpu, &highest_perf);
+ if (ret)
+ return;
+
+ if (highest_perf == prev_highest_perf)
+ return;
+
+ cpu_data->perf_caps.highest_perf = highest_perf;
+ if (cpu_data->perf_caps.nomianl_perf > highest_perf)
+ cpu_data->perf_caps.nomianl_perf = highest_perf;
+
+ policy->max = cppc_perf_to_khz(&cpu_data->perf_caps,
+ policy->boost_enabled ?
+ highest_perf :
+ cpu_data->perf_caps.nominal_perf);
+
+ policy->cpuinfo.max_freq = policy->max;
+
+ /*
+ * Autonomous selection mode uses MIN/MAX performance as runtime
+ * hardware control bounds.
+ *
+ * Re-program them when highest_perf changes.
+ */
+ if (cpu_data->perf_ctrls.auto_sel)
+ cppc_cpufreq_set_autonomous_perf(policy);
+
+ pr_debug("CPU%d: highest_perf updated %llu -> %llu\n",
+ policy->cpu,
+ prev_highest_perf,
+ highest_perf);
+}
+
static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf)
{
struct cppc_cpudata *cpu_data = policy->driver_data;
@@ -1027,6 +1071,7 @@ static struct cpufreq_driver cppc_cpufreq_driver = {
.init = cppc_cpufreq_cpu_init,
.exit = cppc_cpufreq_cpu_exit,
.set_boost = cppc_cpufreq_set_boost,
+ .update_limits = cppc_cpufreq_update_limits,
.attr = cppc_cpufreq_attr,
.name = "cppc_cpufreq",
};
--
2.43.0