cpufreq: intel_pstate: Allow model specific EPPs
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Tue, 20 Feb 2024 02:26:06 +0000 (18:26 -0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sat, 24 Feb 2024 14:02:33 +0000 (15:02 +0100)
The current implementation allows model specific EPP override for
balanced_performance. Add feature to allow model specific EPP for all
predefined EPP strings. For example for some CPU models, even changing
performance EPP has benefits

Use a mask of EPPs as driver_data instead of just balanced_performance.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpufreq/intel_pstate.c

index 5ad3542c0e1e2840aa5ec207ea77ba996abb0edc..001f6d95453e2e18839b0939e7c77e430e5a22f6 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/acpi.h>
 #include <linux/vmalloc.h>
 #include <linux/pm_qos.h>
+#include <linux/bitfield.h>
 #include <trace/events/power.h>
 
 #include <asm/cpu.h>
@@ -3401,14 +3402,29 @@ static bool intel_pstate_hwp_is_enabled(void)
        return !!(value & 0x1);
 }
 
-static const struct x86_cpu_id intel_epp_balance_perf[] = {
+#define POWERSAVE_MASK                 GENMASK(7, 0)
+#define BALANCE_POWER_MASK             GENMASK(15, 8)
+#define BALANCE_PERFORMANCE_MASK       GENMASK(23, 16)
+#define PERFORMANCE_MASK               GENMASK(31, 24)
+
+#define HWP_SET_EPP_VALUES(powersave, balance_power, balance_perf, performance) \
+       (FIELD_PREP_CONST(POWERSAVE_MASK, powersave) |\
+        FIELD_PREP_CONST(BALANCE_POWER_MASK, balance_power) |\
+        FIELD_PREP_CONST(BALANCE_PERFORMANCE_MASK, balance_perf) |\
+        FIELD_PREP_CONST(PERFORMANCE_MASK, performance))
+
+#define HWP_SET_DEF_BALANCE_PERF_EPP(balance_perf) \
+       (HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE, HWP_EPP_BALANCE_POWERSAVE,\
+        balance_perf, HWP_EPP_PERFORMANCE))
+
+static const struct x86_cpu_id intel_epp_default[] = {
        /*
         * Set EPP value as 102, this is the max suggested EPP
         * which can result in one core turbo frequency for
         * AlderLake Mobile CPUs.
         */
-       X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, 102),
-       X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, 32),
+       X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, HWP_SET_DEF_BALANCE_PERF_EPP(102)),
+       X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)),
        {}
 };
 
@@ -3506,11 +3522,24 @@ hwp_cpu_matched:
        intel_pstate_sysfs_expose_params();
 
        if (hwp_active) {
-               const struct x86_cpu_id *id = x86_match_cpu(intel_epp_balance_perf);
+               const struct x86_cpu_id *id = x86_match_cpu(intel_epp_default);
                const struct x86_cpu_id *hybrid_id = x86_match_cpu(intel_hybrid_scaling_factor);
 
-               if (id)
-                       epp_values[EPP_INDEX_BALANCE_PERFORMANCE] = id->driver_data;
+               if (id) {
+                       epp_values[EPP_INDEX_POWERSAVE] =
+                                       FIELD_GET(POWERSAVE_MASK, id->driver_data);
+                       epp_values[EPP_INDEX_BALANCE_POWERSAVE] =
+                                       FIELD_GET(BALANCE_POWER_MASK, id->driver_data);
+                       epp_values[EPP_INDEX_BALANCE_PERFORMANCE] =
+                                       FIELD_GET(BALANCE_PERFORMANCE_MASK, id->driver_data);
+                       epp_values[EPP_INDEX_PERFORMANCE] =
+                                       FIELD_GET(PERFORMANCE_MASK, id->driver_data);
+                       pr_debug("Updated EPPs powersave:%x balanced power:%x balanced perf:%x performance:%x\n",
+                                epp_values[EPP_INDEX_POWERSAVE],
+                                epp_values[EPP_INDEX_BALANCE_POWERSAVE],
+                                epp_values[EPP_INDEX_BALANCE_PERFORMANCE],
+                                epp_values[EPP_INDEX_PERFORMANCE]);
+               }
 
                if (hybrid_id) {
                        hybrid_scaling_factor = hybrid_id->driver_data;