diff options
author | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> | 2019-11-04 12:02:40 +0100 |
---|---|---|
committer | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2019-11-07 18:00:25 +0100 |
commit | a9b2f8e2fa6c0f791f2345afb826d47c6a0f0e2c (patch) | |
tree | 3b852660d3bef6131500b6ab79ea0c26cd05dc96 /tools/power | |
parent | tools/power/x86/intel-speed-select: Correct CLX-N frequency units (diff) | |
download | linux-a9b2f8e2fa6c0f791f2345afb826d47c6a0f0e2c.tar.xz linux-a9b2f8e2fa6c0f791f2345afb826d47c6a0f0e2c.zip |
tools/power/x86/intel-speed-select: Auto mode for CLX
There is an expectation in the CLX platform for SST base-freq feature that
Scaling min frequency be different for high and low priority cores.
This is the way the firmware will understand the priority.
So this change will look at high priority and low priority cores, and set
scaling_min_freq to P1High for high priority cores and P1Low to low
priority cores.
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Diffstat (limited to 'tools/power')
-rw-r--r-- | tools/power/x86/intel-speed-select/isst-config.c | 112 |
1 files changed, 100 insertions, 12 deletions
diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index bfa42fc6c4d2..c563ecaf44e1 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1095,7 +1095,73 @@ static int set_clos_param(int cpu, int clos, int epp, int wt, int min, int max) return 0; } -static int set_cpufreq_cpuinfo_scaling_min(int cpu, int max) +static int set_cpufreq_scaling_min_max(int cpu, int max, int freq) +{ + char buffer[128], freq_str[16]; + int fd, ret, len; + + if (max) + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); + else + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); + + fd = open(buffer, O_WRONLY); + if (fd < 0) + return fd; + + snprintf(freq_str, sizeof(freq_str), "%d", freq); + len = strlen(freq_str); + ret = write(fd, freq_str, len); + if (ret == -1) { + close(fd); + return ret; + } + close(fd); + + return 0; +} + +static int set_clx_pbf_cpufreq_scaling_min_max(int cpu) +{ + struct isst_pkg_ctdp_level_info *ctdp_level; + struct isst_pbf_info *pbf_info; + int i, pkg_id, die_id, freq, freq_high, freq_low; + int ret; + + ret = clx_n_config(cpu); + if (ret) { + perror("set_clx_pbf_cpufreq_scaling_min_max"); + return ret; + } + + ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; + pbf_info = &ctdp_level->pbf_info; + freq_high = pbf_info->p1_high * 100000; + freq_low = pbf_info->p1_low * 100000; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + if (CPU_ISSET_S(i, pbf_info->core_cpumask_size, + pbf_info->core_cpumask)) + freq = freq_high; + else + freq = freq_low; + + set_cpufreq_scaling_min_max(i, 1, freq); + set_cpufreq_scaling_min_max(i, 0, freq); + } + + return 0; +} + +static int set_cpufreq_scaling_min_max_from_cpuinfo(int cpu, int cpuinfo_max, int scaling_max) { char buffer[128], min_freq[16]; int fd, ret, len; @@ -1103,7 +1169,7 @@ static int set_cpufreq_cpuinfo_scaling_min(int cpu, int max) if (!CPU_ISSET_S(cpu, present_cpumask_size, present_cpumask)) return -1; - if (max) + if (cpuinfo_max) snprintf(buffer, sizeof(buffer), "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", cpu); else @@ -1120,8 +1186,12 @@ static int set_cpufreq_cpuinfo_scaling_min(int cpu, int max) if (len < 0) return len; - snprintf(buffer, sizeof(buffer), - "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); + if (scaling_max) + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); + else + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); fd = open(buffer, O_WRONLY); if (fd < 0) @@ -1149,7 +1219,7 @@ static void set_scaling_min_to_cpuinfo_max(int cpu) die_id != get_physical_die_id(i)) continue; - set_cpufreq_cpuinfo_scaling_min(i, 1); + set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 0); } } @@ -1164,7 +1234,22 @@ static void set_scaling_min_to_cpuinfo_min(int cpu) die_id != get_physical_die_id(i)) continue; - set_cpufreq_cpuinfo_scaling_min(i, 0); + set_cpufreq_scaling_min_max_from_cpuinfo(i, 0, 0); + } +} + +static void set_scaling_max_to_cpuinfo_max(int cpu) +{ + int i, pkg_id, die_id; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 1); } } @@ -1263,14 +1348,17 @@ static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, int status = *(int *)arg4; if (is_clx_n_platform()) { - if (status == 0) { - ret = -1; - if (auto_mode) - set_scaling_min_to_cpuinfo_min(cpu); - } else { + if (status) { ret = 0; if (auto_mode) - set_scaling_min_to_cpuinfo_max(cpu); + set_clx_pbf_cpufreq_scaling_min_max(cpu); + + } else { + ret = -1; + if (auto_mode) { + set_scaling_max_to_cpuinfo_max(cpu); + set_scaling_min_to_cpuinfo_min(cpu); + } } goto disp_result; } |