[PATCH v2 5/6] cpufreq: intel_pstate: Consolidate HWP P-states initialization
From: Rafael J. Wysocki
Date: Fri Jun 19 2026 - 13:46:46 EST
From: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
After previous changes, intel_pstate_hybrid_hwp_adjust() does not do
much and its name and kerneldoc comment (which is not really necessary
becuase the function is static) have become a bit confusing. Moreover,
the initialization of P-states on systems with HWP enabled is divided
between it and a direct conditional statement branch in
intel_pstate_get_cpu_pstates() which is not super-easy to follow.
Address this by introducing intel_pstate_get_hwp_pstates() for the
entire HWP-specific initialization of P-states and moving the code from
intel_pstate_hybrid_hwp_adjust() into it along with some HWP-related
code from intel_pstate_get_cpu_pstates().
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
---
v1 -> v2: New patch
---
drivers/cpufreq/intel_pstate.c | 103 +++++++++++++++++++----------------------
1 file changed, 50 insertions(+), 53 deletions(-)
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -556,41 +556,6 @@ static int intel_pstate_freq_to_hwp(stru
return intel_pstate_freq_to_hwp_rel(cpu, freq, CPUFREQ_RELATION_L);
}
-/**
- * intel_pstate_hybrid_hwp_adjust - Calibrate HWP performance levels.
- * @cpu: Target CPU.
- *
- * On hybrid processors, HWP may expose more performance levels than there are
- * P-states accessible through the PERF_CTL interface. If that happens, the
- * scaling factor between HWP performance levels and CPU frequency will be less
- * than the scaling factor between P-state values and CPU frequency.
- *
- * In that case, adjust the CPU parameters used in computations accordingly.
- */
-static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu)
-{
- int perf_ctl_max_phys = cpu->pstate.max_pstate_physical;
- int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling;
- int perf_ctl_turbo = pstate_funcs.get_turbo(cpu->cpu);
- int scaling = cpu->pstate.scaling;
- int freq;
-
- pr_debug("CPU%d: PERF_CTL max_phys = %d\n", cpu->cpu, perf_ctl_max_phys);
- pr_debug("CPU%d: PERF_CTL turbo = %d\n", cpu->cpu, perf_ctl_turbo);
- pr_debug("CPU%d: PERF_CTL scaling = %d\n", cpu->cpu, perf_ctl_scaling);
- pr_debug("CPU%d: HWP_CAP guaranteed = %d\n", cpu->cpu, cpu->pstate.max_pstate);
- pr_debug("CPU%d: HWP_CAP highest = %d\n", cpu->cpu, cpu->pstate.turbo_pstate);
- pr_debug("CPU%d: HWP-to-frequency scaling factor: %d\n", cpu->cpu, scaling);
-
- if (scaling == perf_ctl_scaling)
- return;
-
- hwp_is_hybrid = true;
-
- freq = perf_ctl_max_phys * perf_ctl_scaling;
- cpu->pstate.max_pstate_physical = intel_pstate_freq_to_hwp(cpu, freq);
-}
-
static bool turbo_is_disabled(void)
{
u64 misc_en;
@@ -2311,32 +2276,64 @@ static void intel_pstate_set_min_pstate(
intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
}
-static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
+static void intel_pstate_get_hwp_pstates(struct cpudata *cpu)
{
- int perf_ctl_scaling = pstate_funcs.get_scaling();
+ int perf_ctl_max_phys = cpu->pstate.max_pstate_physical;
+ int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling;
+ int perf_ctl_turbo = cpu->pstate.turbo_pstate;
+ int cpuid = cpu->cpu;
+
+ __intel_pstate_get_hwp_cap(cpu);
+
+ if (!pstate_funcs.get_cpu_scaling)
+ return;
+ pr_debug("CPU%d: PERF_CTL max_phys = %d\n", cpuid, perf_ctl_max_phys);
+ pr_debug("CPU%d: PERF_CTL turbo = %d\n", cpuid, perf_ctl_turbo);
+ pr_debug("CPU%d: PERF_CTL scaling = %d\n", cpuid, perf_ctl_scaling);
+ pr_debug("CPU%d: HWP_CAP lowest = %d\n", cpuid, cpu->pstate.min_pstate);
+ pr_debug("CPU%d: HWP_CAP guaranteed = %d\n", cpuid, cpu->pstate.max_pstate);
+ pr_debug("CPU%d: HWP_CAP highest = %d\n", cpuid, cpu->pstate.turbo_pstate);
+
+ cpu->pstate.scaling = pstate_funcs.get_cpu_scaling(cpuid);
+
+ pr_debug("CPU%d: HWP-to-frequency scaling = %d\n", cpuid, cpu->pstate.scaling);
+
+ /*
+ * On hybrid processors, HWP may expose more performance levels than
+ * there are P-states accessible through the PERF_CTL interface. If
+ * that happens, the scaling between HWP performance levels and CPU
+ * frequency will be less than the scaling between P-state values and
+ * CPU frequency. In that case, update the maximum physical non-turbo
+ * performance level accordingly.
+ */
+ if (cpu->pstate.scaling != perf_ctl_scaling) {
+ int freq = perf_ctl_max_phys * perf_ctl_scaling;
+ unsigned int hwp = intel_pstate_freq_to_hwp(cpu, freq);
+
+ cpu->pstate.max_pstate_physical = hwp;
+
+ hwp_is_hybrid = true;
+ }
+ /*
+ * If the CPU is going online for the first time and it was offline
+ * initially, asym capacity scaling needs to be updated.
+ */
+ hybrid_update_capacity(cpu);
+}
+
+static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
+{
cpu->pstate.max_pstate_physical = pstate_funcs.get_max_physical(cpu->cpu);
- cpu->pstate.perf_ctl_scaling = perf_ctl_scaling;
+ cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(cpu->cpu);
+ cpu->pstate.perf_ctl_scaling = pstate_funcs.get_scaling();
+ cpu->pstate.scaling = cpu->pstate.perf_ctl_scaling;
if (hwp_active && !hwp_mode_bdw) {
- __intel_pstate_get_hwp_cap(cpu);
-
- if (pstate_funcs.get_cpu_scaling) {
- cpu->pstate.scaling = pstate_funcs.get_cpu_scaling(cpu->cpu);
- intel_pstate_hybrid_hwp_adjust(cpu);
- } else {
- cpu->pstate.scaling = perf_ctl_scaling;
- }
- /*
- * If the CPU is going online for the first time and it was
- * offline initially, asym capacity scaling needs to be updated.
- */
- hybrid_update_capacity(cpu);
+ intel_pstate_get_hwp_pstates(cpu);
} else {
- cpu->pstate.scaling = perf_ctl_scaling;
cpu->pstate.min_pstate = pstate_funcs.get_min(cpu->cpu);
cpu->pstate.max_pstate = pstate_funcs.get_max(cpu->cpu);
- cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(cpu->cpu);
}
intel_pstate_update_freq_limits(cpu);