cpufreq: CPPC: Add support for autonomous selection
authorLifeng Zheng <zhenglifeng1@huawei.com>
Wed, 7 May 2025 03:19:41 +0000 (11:19 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 21 May 2025 20:47:44 +0000 (22:47 +0200)
Add sysfs interfaces for CPPC autonomous selection in the cppc_cpufreq
driver.

Signed-off-by: Lifeng Zheng <zhenglifeng1@huawei.com>
Reviewed-by: Sumit Gupta <sumitg@nvidia.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Link: https://patch.msgid.link/20250507031941.2812701-1-zhenglifeng1@huawei.com
[ rjw: Subject edits ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Documentation/ABI/testing/sysfs-devices-system-cpu
drivers/cpufreq/cppc_cpufreq.c

index 206079d..37065e1 100644 (file)
@@ -268,6 +268,60 @@ Description:       Discover CPUs in the same CPU frequency coordination domain
                This file is only present if the acpi-cpufreq or the cppc-cpufreq
                drivers are in use.
 
+What:          /sys/devices/system/cpu/cpuX/cpufreq/auto_select
+Date:          May 2025
+Contact:       linux-pm@vger.kernel.org
+Description:   Autonomous selection enable
+
+               Read/write interface to control autonomous selection enable
+                       Read returns autonomous selection status:
+                               0: autonomous selection is disabled
+                               1: autonomous selection is enabled
+
+                       Write 'y' or '1' or 'on' to enable autonomous selection.
+                       Write 'n' or '0' or 'off' to disable autonomous selection.
+
+               This file is only present if the cppc-cpufreq driver is in use.
+
+What:          /sys/devices/system/cpu/cpuX/cpufreq/auto_act_window
+Date:          May 2025
+Contact:       linux-pm@vger.kernel.org
+Description:   Autonomous activity window
+
+               This file indicates a moving utilization sensitivity window to
+               the platform's autonomous selection policy.
+
+               Read/write an integer represents autonomous activity window (in
+               microseconds) from/to this file. The max value to write is
+               1270000000 but the max significand is 127. This means that if 128
+               is written to this file, 127 will be stored. If the value is
+               greater than 130, only the first two digits will be saved as
+               significand.
+
+               Writing a zero value to this file enable the platform to
+               determine an appropriate Activity Window depending on the workload.
+
+               Writing to this file only has meaning when Autonomous Selection is
+               enabled.
+
+               This file is only present if the cppc-cpufreq driver is in use.
+
+What:          /sys/devices/system/cpu/cpuX/cpufreq/energy_performance_preference_val
+Date:          May 2025
+Contact:       linux-pm@vger.kernel.org
+Description:   Energy performance preference
+
+               Read/write an 8-bit integer from/to this file. This file
+               represents a range of values from 0 (performance preference) to
+               0xFF (energy efficiency preference) that influences the rate of
+               performance increase/decrease and the result of the hardware's
+               energy efficiency and performance optimization policies.
+
+               Writing to this file only has meaning when Autonomous Selection is
+               enabled.
+
+               This file is only present if the cppc-cpufreq driver is in use.
+
 
 What:          /sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1}
 Date:          August 2008
index cb93f00..b7c688a 100644 (file)
@@ -808,10 +808,119 @@ static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf)
 
        return cpufreq_show_cpus(cpu_data->shared_cpu_map, buf);
 }
+
+static ssize_t show_auto_select(struct cpufreq_policy *policy, char *buf)
+{
+       bool val;
+       int ret;
+
+       ret = cppc_get_auto_sel(policy->cpu, &val);
+
+       /* show "<unsupported>" when this register is not supported by cpc */
+       if (ret == -EOPNOTSUPP)
+               return sysfs_emit(buf, "<unsupported>\n");
+
+       if (ret)
+               return ret;
+
+       return sysfs_emit(buf, "%d\n", val);
+}
+
+static ssize_t store_auto_select(struct cpufreq_policy *policy,
+                                const char *buf, size_t count)
+{
+       bool val;
+       int ret;
+
+       ret = kstrtobool(buf, &val);
+       if (ret)
+               return ret;
+
+       ret = cppc_set_auto_sel(policy->cpu, val);
+       if (ret)
+               return ret;
+
+       return count;
+}
+
+static ssize_t show_auto_act_window(struct cpufreq_policy *policy, char *buf)
+{
+       u64 val;
+       int ret;
+
+       ret = cppc_get_auto_act_window(policy->cpu, &val);
+
+       /* show "<unsupported>" when this register is not supported by cpc */
+       if (ret == -EOPNOTSUPP)
+               return sysfs_emit(buf, "<unsupported>\n");
+
+       if (ret)
+               return ret;
+
+       return sysfs_emit(buf, "%llu\n", val);
+}
+
+static ssize_t store_auto_act_window(struct cpufreq_policy *policy,
+                                    const char *buf, size_t count)
+{
+       u64 usec;
+       int ret;
+
+       ret = kstrtou64(buf, 0, &usec);
+       if (ret)
+               return ret;
+
+       ret = cppc_set_auto_act_window(policy->cpu, usec);
+       if (ret)
+               return ret;
+
+       return count;
+}
+
+static ssize_t show_energy_performance_preference_val(struct cpufreq_policy *policy, char *buf)
+{
+       u64 val;
+       int ret;
+
+       ret = cppc_get_epp_perf(policy->cpu, &val);
+
+       /* show "<unsupported>" when this register is not supported by cpc */
+       if (ret == -EOPNOTSUPP)
+               return sysfs_emit(buf, "<unsupported>\n");
+
+       if (ret)
+               return ret;
+
+       return sysfs_emit(buf, "%llu\n", val);
+}
+
+static ssize_t store_energy_performance_preference_val(struct cpufreq_policy *policy,
+                                                      const char *buf, size_t count)
+{
+       u64 val;
+       int ret;
+
+       ret = kstrtou64(buf, 0, &val);
+       if (ret)
+               return ret;
+
+       ret = cppc_set_epp(policy->cpu, val);
+       if (ret)
+               return ret;
+
+       return count;
+}
+
 cpufreq_freq_attr_ro(freqdomain_cpus);
+cpufreq_freq_attr_rw(auto_select);
+cpufreq_freq_attr_rw(auto_act_window);
+cpufreq_freq_attr_rw(energy_performance_preference_val);
 
 static struct freq_attr *cppc_cpufreq_attr[] = {
        &freqdomain_cpus,
+       &auto_select,
+       &auto_act_window,
+       &energy_performance_preference_val,
        NULL,
 };