13fb4f7cdSSrinivas Pandruvada // SPDX-License-Identifier: GPL-2.0 23fb4f7cdSSrinivas Pandruvada /* 33fb4f7cdSSrinivas Pandruvada * Intel Speed Select -- Enumerate and control features 43fb4f7cdSSrinivas Pandruvada * Copyright (c) 2019 Intel Corporation. 53fb4f7cdSSrinivas Pandruvada */ 63fb4f7cdSSrinivas Pandruvada 73fb4f7cdSSrinivas Pandruvada #include <linux/isst_if.h> 83fb4f7cdSSrinivas Pandruvada 93fb4f7cdSSrinivas Pandruvada #include "isst.h" 103fb4f7cdSSrinivas Pandruvada 113fb4f7cdSSrinivas Pandruvada struct process_cmd_struct { 123fb4f7cdSSrinivas Pandruvada char *feature; 133fb4f7cdSSrinivas Pandruvada char *command; 14ce1326a2SPrarit Bhargava void (*process_fn)(int arg); 15ce1326a2SPrarit Bhargava int arg; 163fb4f7cdSSrinivas Pandruvada }; 173fb4f7cdSSrinivas Pandruvada 185e27cb9bSSrinivas Pandruvada static const char *version_str = "v1.7"; 193fb4f7cdSSrinivas Pandruvada static const int supported_api_ver = 1; 203fb4f7cdSSrinivas Pandruvada static struct isst_if_platform_info isst_platform_info; 213fb4f7cdSSrinivas Pandruvada static char *progname; 223fb4f7cdSSrinivas Pandruvada static int debug_flag; 233fb4f7cdSSrinivas Pandruvada static FILE *outf; 243fb4f7cdSSrinivas Pandruvada 253fb4f7cdSSrinivas Pandruvada static int cpu_model; 261c1d935cSPrarit Bhargava static int cpu_stepping; 273fb4f7cdSSrinivas Pandruvada 28e16ea663SSrinivas Pandruvada #define MAX_CPUS_IN_ONE_REQ 256 293fb4f7cdSSrinivas Pandruvada static short max_target_cpus; 303fb4f7cdSSrinivas Pandruvada static unsigned short target_cpus[MAX_CPUS_IN_ONE_REQ]; 313fb4f7cdSSrinivas Pandruvada 323fb4f7cdSSrinivas Pandruvada static int topo_max_cpus; 333fb4f7cdSSrinivas Pandruvada static size_t present_cpumask_size; 343fb4f7cdSSrinivas Pandruvada static cpu_set_t *present_cpumask; 353fb4f7cdSSrinivas Pandruvada static size_t target_cpumask_size; 363fb4f7cdSSrinivas Pandruvada static cpu_set_t *target_cpumask; 373fb4f7cdSSrinivas Pandruvada static int tdp_level = 0xFF; 383fb4f7cdSSrinivas Pandruvada static int fact_bucket = 0xFF; 393fb4f7cdSSrinivas Pandruvada static int fact_avx = 0xFF; 403fb4f7cdSSrinivas Pandruvada static unsigned long long fact_trl; 413fb4f7cdSSrinivas Pandruvada static int out_format_json; 423fb4f7cdSSrinivas Pandruvada static int cmd_help; 433c64c81aSSrinivas Pandruvada static int force_online_offline; 44354bd06fSSrinivas Pandruvada static int auto_mode; 4514a8aa49SSrinivas Pandruvada static int fact_enable_fail; 463fb4f7cdSSrinivas Pandruvada 47a85a35fcSSrinivas Pandruvada static int mbox_delay; 4832279be7SSrinivas Pandruvada static int mbox_retries = 3; 49a85a35fcSSrinivas Pandruvada 503fb4f7cdSSrinivas Pandruvada /* clos related */ 513fb4f7cdSSrinivas Pandruvada static int current_clos = -1; 523fb4f7cdSSrinivas Pandruvada static int clos_epp = -1; 533fb4f7cdSSrinivas Pandruvada static int clos_prop_prio = -1; 543fb4f7cdSSrinivas Pandruvada static int clos_min = -1; 553fb4f7cdSSrinivas Pandruvada static int clos_max = -1; 563fb4f7cdSSrinivas Pandruvada static int clos_desired = -1; 573fb4f7cdSSrinivas Pandruvada static int clos_priority_type; 583fb4f7cdSSrinivas Pandruvada 593fb4f7cdSSrinivas Pandruvada struct _cpu_map { 603fb4f7cdSSrinivas Pandruvada unsigned short core_id; 613fb4f7cdSSrinivas Pandruvada unsigned short pkg_id; 623fb4f7cdSSrinivas Pandruvada unsigned short die_id; 633fb4f7cdSSrinivas Pandruvada unsigned short punit_cpu; 643fb4f7cdSSrinivas Pandruvada unsigned short punit_cpu_core; 653fb4f7cdSSrinivas Pandruvada }; 663fb4f7cdSSrinivas Pandruvada struct _cpu_map *cpu_map; 673fb4f7cdSSrinivas Pandruvada 68fb186158SSrinivas Pandruvada struct cpu_topology { 69fb186158SSrinivas Pandruvada short cpu; 70fb186158SSrinivas Pandruvada short core_id; 71fb186158SSrinivas Pandruvada short pkg_id; 72fb186158SSrinivas Pandruvada short die_id; 73fb186158SSrinivas Pandruvada }; 74fb186158SSrinivas Pandruvada 7587e115b3SSrinivas Pandruvada FILE *get_output_file(void) 7687e115b3SSrinivas Pandruvada { 7787e115b3SSrinivas Pandruvada return outf; 7887e115b3SSrinivas Pandruvada } 7987e115b3SSrinivas Pandruvada 803fb4f7cdSSrinivas Pandruvada void debug_printf(const char *format, ...) 813fb4f7cdSSrinivas Pandruvada { 823fb4f7cdSSrinivas Pandruvada va_list args; 833fb4f7cdSSrinivas Pandruvada 843fb4f7cdSSrinivas Pandruvada va_start(args, format); 853fb4f7cdSSrinivas Pandruvada 863fb4f7cdSSrinivas Pandruvada if (debug_flag) 873fb4f7cdSSrinivas Pandruvada vprintf(format, args); 883fb4f7cdSSrinivas Pandruvada 893fb4f7cdSSrinivas Pandruvada va_end(args); 903fb4f7cdSSrinivas Pandruvada } 913fb4f7cdSSrinivas Pandruvada 921c1d935cSPrarit Bhargava 931c1d935cSPrarit Bhargava int is_clx_n_platform(void) 941c1d935cSPrarit Bhargava { 951c1d935cSPrarit Bhargava if (cpu_model == 0x55) 961c1d935cSPrarit Bhargava if (cpu_stepping == 0x6 || cpu_stepping == 0x7) 971c1d935cSPrarit Bhargava return 1; 981c1d935cSPrarit Bhargava return 0; 991c1d935cSPrarit Bhargava } 1001c1d935cSPrarit Bhargava 10195f8e569SSrinivas Pandruvada int is_skx_based_platform(void) 10295f8e569SSrinivas Pandruvada { 10395f8e569SSrinivas Pandruvada if (cpu_model == 0x55) 10495f8e569SSrinivas Pandruvada return 1; 10595f8e569SSrinivas Pandruvada 10695f8e569SSrinivas Pandruvada return 0; 10795f8e569SSrinivas Pandruvada } 10895f8e569SSrinivas Pandruvada 1091c1d935cSPrarit Bhargava static int update_cpu_model(void) 1103fb4f7cdSSrinivas Pandruvada { 1113fb4f7cdSSrinivas Pandruvada unsigned int ebx, ecx, edx; 1123fb4f7cdSSrinivas Pandruvada unsigned int fms, family; 1133fb4f7cdSSrinivas Pandruvada 1143fb4f7cdSSrinivas Pandruvada __cpuid(1, fms, ebx, ecx, edx); 1153fb4f7cdSSrinivas Pandruvada family = (fms >> 8) & 0xf; 1163fb4f7cdSSrinivas Pandruvada cpu_model = (fms >> 4) & 0xf; 1173fb4f7cdSSrinivas Pandruvada if (family == 6 || family == 0xf) 1183fb4f7cdSSrinivas Pandruvada cpu_model += ((fms >> 16) & 0xf) << 4; 1191c1d935cSPrarit Bhargava 1201c1d935cSPrarit Bhargava cpu_stepping = fms & 0xf; 1211c1d935cSPrarit Bhargava /* only three CascadeLake-N models are supported */ 1221c1d935cSPrarit Bhargava if (is_clx_n_platform()) { 1231c1d935cSPrarit Bhargava FILE *fp; 1241c1d935cSPrarit Bhargava size_t n = 0; 1251c1d935cSPrarit Bhargava char *line = NULL; 1261c1d935cSPrarit Bhargava int ret = 1; 1271c1d935cSPrarit Bhargava 1281c1d935cSPrarit Bhargava fp = fopen("/proc/cpuinfo", "r"); 1291c1d935cSPrarit Bhargava if (!fp) 1301c1d935cSPrarit Bhargava err(-1, "cannot open /proc/cpuinfo\n"); 1311c1d935cSPrarit Bhargava 1321c1d935cSPrarit Bhargava while (getline(&line, &n, fp) > 0) { 1331c1d935cSPrarit Bhargava if (strstr(line, "model name")) { 1341c1d935cSPrarit Bhargava if (strstr(line, "6252N") || 1351c1d935cSPrarit Bhargava strstr(line, "6230N") || 1361c1d935cSPrarit Bhargava strstr(line, "5218N")) 1371c1d935cSPrarit Bhargava ret = 0; 1381c1d935cSPrarit Bhargava break; 1391c1d935cSPrarit Bhargava } 1401c1d935cSPrarit Bhargava } 1411c1d935cSPrarit Bhargava free(line); 1421c1d935cSPrarit Bhargava fclose(fp); 1431c1d935cSPrarit Bhargava return ret; 1441c1d935cSPrarit Bhargava } 1451c1d935cSPrarit Bhargava return 0; 1463fb4f7cdSSrinivas Pandruvada } 1473fb4f7cdSSrinivas Pandruvada 1483fb4f7cdSSrinivas Pandruvada /* Open a file, and exit on failure */ 1493fb4f7cdSSrinivas Pandruvada static FILE *fopen_or_exit(const char *path, const char *mode) 1503fb4f7cdSSrinivas Pandruvada { 1513fb4f7cdSSrinivas Pandruvada FILE *filep = fopen(path, mode); 1523fb4f7cdSSrinivas Pandruvada 1533fb4f7cdSSrinivas Pandruvada if (!filep) 1543fb4f7cdSSrinivas Pandruvada err(1, "%s: open failed", path); 1553fb4f7cdSSrinivas Pandruvada 1563fb4f7cdSSrinivas Pandruvada return filep; 1573fb4f7cdSSrinivas Pandruvada } 1583fb4f7cdSSrinivas Pandruvada 1593fb4f7cdSSrinivas Pandruvada /* Parse a file containing a single int */ 1603fb4f7cdSSrinivas Pandruvada static int parse_int_file(int fatal, const char *fmt, ...) 1613fb4f7cdSSrinivas Pandruvada { 1623fb4f7cdSSrinivas Pandruvada va_list args; 1633fb4f7cdSSrinivas Pandruvada char path[PATH_MAX]; 1643fb4f7cdSSrinivas Pandruvada FILE *filep; 1653fb4f7cdSSrinivas Pandruvada int value; 1663fb4f7cdSSrinivas Pandruvada 1673fb4f7cdSSrinivas Pandruvada va_start(args, fmt); 1683fb4f7cdSSrinivas Pandruvada vsnprintf(path, sizeof(path), fmt, args); 1693fb4f7cdSSrinivas Pandruvada va_end(args); 1703fb4f7cdSSrinivas Pandruvada if (fatal) { 1713fb4f7cdSSrinivas Pandruvada filep = fopen_or_exit(path, "r"); 1723fb4f7cdSSrinivas Pandruvada } else { 1733fb4f7cdSSrinivas Pandruvada filep = fopen(path, "r"); 1743fb4f7cdSSrinivas Pandruvada if (!filep) 1753fb4f7cdSSrinivas Pandruvada return -1; 1763fb4f7cdSSrinivas Pandruvada } 1773fb4f7cdSSrinivas Pandruvada if (fscanf(filep, "%d", &value) != 1) 1783fb4f7cdSSrinivas Pandruvada err(1, "%s: failed to parse number from file", path); 1793fb4f7cdSSrinivas Pandruvada fclose(filep); 1803fb4f7cdSSrinivas Pandruvada 1813fb4f7cdSSrinivas Pandruvada return value; 1823fb4f7cdSSrinivas Pandruvada } 1833fb4f7cdSSrinivas Pandruvada 1843fb4f7cdSSrinivas Pandruvada int cpufreq_sysfs_present(void) 1853fb4f7cdSSrinivas Pandruvada { 1863fb4f7cdSSrinivas Pandruvada DIR *dir; 1873fb4f7cdSSrinivas Pandruvada 1883fb4f7cdSSrinivas Pandruvada dir = opendir("/sys/devices/system/cpu/cpu0/cpufreq"); 1893fb4f7cdSSrinivas Pandruvada if (dir) { 1903fb4f7cdSSrinivas Pandruvada closedir(dir); 1913fb4f7cdSSrinivas Pandruvada return 1; 1923fb4f7cdSSrinivas Pandruvada } 1933fb4f7cdSSrinivas Pandruvada 1943fb4f7cdSSrinivas Pandruvada return 0; 1953fb4f7cdSSrinivas Pandruvada } 1963fb4f7cdSSrinivas Pandruvada 1973fb4f7cdSSrinivas Pandruvada int out_format_is_json(void) 1983fb4f7cdSSrinivas Pandruvada { 1993fb4f7cdSSrinivas Pandruvada return out_format_json; 2003fb4f7cdSSrinivas Pandruvada } 2013fb4f7cdSSrinivas Pandruvada 202fb186158SSrinivas Pandruvada static int get_stored_topology_info(int cpu, int *core_id, int *pkg_id, int *die_id) 203fb186158SSrinivas Pandruvada { 204b1d12cefSSrinivas Pandruvada const char *pathname = "/var/run/isst_cpu_topology.dat"; 205fb186158SSrinivas Pandruvada struct cpu_topology cpu_top; 206fb186158SSrinivas Pandruvada FILE *fp; 207fb186158SSrinivas Pandruvada int ret; 208fb186158SSrinivas Pandruvada 209fb186158SSrinivas Pandruvada fp = fopen(pathname, "rb"); 210fb186158SSrinivas Pandruvada if (!fp) 211fb186158SSrinivas Pandruvada return -1; 212fb186158SSrinivas Pandruvada 213fb186158SSrinivas Pandruvada ret = fseek(fp, cpu * sizeof(cpu_top), SEEK_SET); 214fb186158SSrinivas Pandruvada if (ret) 215fb186158SSrinivas Pandruvada goto err_ret; 216fb186158SSrinivas Pandruvada 217fb186158SSrinivas Pandruvada ret = fread(&cpu_top, sizeof(cpu_top), 1, fp); 218fb186158SSrinivas Pandruvada if (ret != 1) { 219fb186158SSrinivas Pandruvada ret = -1; 220fb186158SSrinivas Pandruvada goto err_ret; 221fb186158SSrinivas Pandruvada } 222fb186158SSrinivas Pandruvada 223fb186158SSrinivas Pandruvada *pkg_id = cpu_top.pkg_id; 224fb186158SSrinivas Pandruvada *core_id = cpu_top.core_id; 225fb186158SSrinivas Pandruvada *die_id = cpu_top.die_id; 226fb186158SSrinivas Pandruvada ret = 0; 227fb186158SSrinivas Pandruvada 228fb186158SSrinivas Pandruvada err_ret: 229fb186158SSrinivas Pandruvada fclose(fp); 230fb186158SSrinivas Pandruvada 231fb186158SSrinivas Pandruvada return ret; 232fb186158SSrinivas Pandruvada } 233fb186158SSrinivas Pandruvada 234fb186158SSrinivas Pandruvada static void store_cpu_topology(void) 235fb186158SSrinivas Pandruvada { 236b1d12cefSSrinivas Pandruvada const char *pathname = "/var/run/isst_cpu_topology.dat"; 237fb186158SSrinivas Pandruvada FILE *fp; 238fb186158SSrinivas Pandruvada int i; 239fb186158SSrinivas Pandruvada 240fb186158SSrinivas Pandruvada fp = fopen(pathname, "rb"); 241fb186158SSrinivas Pandruvada if (fp) { 242fb186158SSrinivas Pandruvada /* Mapping already exists */ 243fb186158SSrinivas Pandruvada fclose(fp); 244fb186158SSrinivas Pandruvada return; 245fb186158SSrinivas Pandruvada } 246fb186158SSrinivas Pandruvada 247fb186158SSrinivas Pandruvada fp = fopen(pathname, "wb"); 248fb186158SSrinivas Pandruvada if (!fp) { 249fb186158SSrinivas Pandruvada fprintf(stderr, "Can't create file:%s\n", pathname); 250fb186158SSrinivas Pandruvada return; 251fb186158SSrinivas Pandruvada } 252fb186158SSrinivas Pandruvada 253b1d12cefSSrinivas Pandruvada fprintf(stderr, "Caching topology information\n"); 254b1d12cefSSrinivas Pandruvada 255fb186158SSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) { 256fb186158SSrinivas Pandruvada struct cpu_topology cpu_top; 257fb186158SSrinivas Pandruvada 258fb186158SSrinivas Pandruvada cpu_top.core_id = parse_int_file(0, 259fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/core_id", i); 260fb186158SSrinivas Pandruvada if (cpu_top.core_id < 0) 261fb186158SSrinivas Pandruvada cpu_top.core_id = -1; 262fb186158SSrinivas Pandruvada 263fb186158SSrinivas Pandruvada cpu_top.pkg_id = parse_int_file(0, 264fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", i); 265fb186158SSrinivas Pandruvada if (cpu_top.pkg_id < 0) 266fb186158SSrinivas Pandruvada cpu_top.pkg_id = -1; 267fb186158SSrinivas Pandruvada 268fb186158SSrinivas Pandruvada cpu_top.die_id = parse_int_file(0, 269fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/die_id", i); 270fb186158SSrinivas Pandruvada if (cpu_top.die_id < 0) 271fb186158SSrinivas Pandruvada cpu_top.die_id = -1; 272fb186158SSrinivas Pandruvada 273fb186158SSrinivas Pandruvada cpu_top.cpu = i; 274fb186158SSrinivas Pandruvada 275fb186158SSrinivas Pandruvada if (fwrite(&cpu_top, sizeof(cpu_top), 1, fp) != 1) { 276fb186158SSrinivas Pandruvada fprintf(stderr, "Can't write to:%s\n", pathname); 277fb186158SSrinivas Pandruvada break; 278fb186158SSrinivas Pandruvada } 279fb186158SSrinivas Pandruvada } 280fb186158SSrinivas Pandruvada 281fb186158SSrinivas Pandruvada fclose(fp); 282fb186158SSrinivas Pandruvada } 283fb186158SSrinivas Pandruvada 2843fb4f7cdSSrinivas Pandruvada int get_physical_package_id(int cpu) 2853fb4f7cdSSrinivas Pandruvada { 286fb186158SSrinivas Pandruvada int ret; 287fb186158SSrinivas Pandruvada 288fb186158SSrinivas Pandruvada ret = parse_int_file(0, 289fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", 2903fb4f7cdSSrinivas Pandruvada cpu); 291fb186158SSrinivas Pandruvada if (ret < 0) { 292fb186158SSrinivas Pandruvada int core_id, pkg_id, die_id; 293fb186158SSrinivas Pandruvada 294fb186158SSrinivas Pandruvada ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id); 295fb186158SSrinivas Pandruvada if (!ret) 296fb186158SSrinivas Pandruvada return pkg_id; 297fb186158SSrinivas Pandruvada } 298fb186158SSrinivas Pandruvada 299fb186158SSrinivas Pandruvada return ret; 3003fb4f7cdSSrinivas Pandruvada } 3013fb4f7cdSSrinivas Pandruvada 3023fb4f7cdSSrinivas Pandruvada int get_physical_core_id(int cpu) 3033fb4f7cdSSrinivas Pandruvada { 304fb186158SSrinivas Pandruvada int ret; 305fb186158SSrinivas Pandruvada 306fb186158SSrinivas Pandruvada ret = parse_int_file(0, 307fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/core_id", 308fb186158SSrinivas Pandruvada cpu); 309fb186158SSrinivas Pandruvada if (ret < 0) { 310fb186158SSrinivas Pandruvada int core_id, pkg_id, die_id; 311fb186158SSrinivas Pandruvada 312fb186158SSrinivas Pandruvada ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id); 313fb186158SSrinivas Pandruvada if (!ret) 314fb186158SSrinivas Pandruvada return core_id; 315fb186158SSrinivas Pandruvada } 316fb186158SSrinivas Pandruvada 317fb186158SSrinivas Pandruvada return ret; 3183fb4f7cdSSrinivas Pandruvada } 3193fb4f7cdSSrinivas Pandruvada 3203fb4f7cdSSrinivas Pandruvada int get_physical_die_id(int cpu) 3213fb4f7cdSSrinivas Pandruvada { 3223fb4f7cdSSrinivas Pandruvada int ret; 3233fb4f7cdSSrinivas Pandruvada 324fb186158SSrinivas Pandruvada ret = parse_int_file(0, 325fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/die_id", 3263fb4f7cdSSrinivas Pandruvada cpu); 327fb186158SSrinivas Pandruvada if (ret < 0) { 328fb186158SSrinivas Pandruvada int core_id, pkg_id, die_id; 329fb186158SSrinivas Pandruvada 330fb186158SSrinivas Pandruvada ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id); 3316c483225SSrinivas Pandruvada if (!ret) { 3326c483225SSrinivas Pandruvada if (die_id < 0) 3336c483225SSrinivas Pandruvada die_id = 0; 3346c483225SSrinivas Pandruvada 335fb186158SSrinivas Pandruvada return die_id; 336fb186158SSrinivas Pandruvada } 3376c483225SSrinivas Pandruvada } 338fb186158SSrinivas Pandruvada 3393fb4f7cdSSrinivas Pandruvada if (ret < 0) 3403fb4f7cdSSrinivas Pandruvada ret = 0; 3413fb4f7cdSSrinivas Pandruvada 3423fb4f7cdSSrinivas Pandruvada return ret; 3433fb4f7cdSSrinivas Pandruvada } 3443fb4f7cdSSrinivas Pandruvada 3457af5a95bSSrinivas Pandruvada int get_cpufreq_base_freq(int cpu) 3467af5a95bSSrinivas Pandruvada { 3477af5a95bSSrinivas Pandruvada return parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", cpu); 3487af5a95bSSrinivas Pandruvada } 3497af5a95bSSrinivas Pandruvada 3503fb4f7cdSSrinivas Pandruvada int get_topo_max_cpus(void) 3513fb4f7cdSSrinivas Pandruvada { 3523fb4f7cdSSrinivas Pandruvada return topo_max_cpus; 3533fb4f7cdSSrinivas Pandruvada } 3543fb4f7cdSSrinivas Pandruvada 3553c64c81aSSrinivas Pandruvada static void set_cpu_online_offline(int cpu, int state) 3563c64c81aSSrinivas Pandruvada { 3573c64c81aSSrinivas Pandruvada char buffer[128]; 358abd120e3SSrinivas Pandruvada int fd, ret; 3593c64c81aSSrinivas Pandruvada 3603c64c81aSSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 3613c64c81aSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/online", cpu); 3623c64c81aSSrinivas Pandruvada 3633c64c81aSSrinivas Pandruvada fd = open(buffer, O_WRONLY); 36469669198SSrinivas Pandruvada if (fd < 0) { 36569669198SSrinivas Pandruvada if (!cpu && state) { 36669669198SSrinivas Pandruvada fprintf(stderr, "This system is not configured for CPU 0 online/offline\n"); 36769669198SSrinivas Pandruvada fprintf(stderr, "Ignoring online request for CPU 0 as this is already online\n"); 36869669198SSrinivas Pandruvada return; 36969669198SSrinivas Pandruvada } 3703c64c81aSSrinivas Pandruvada err(-1, "%s open failed", buffer); 37169669198SSrinivas Pandruvada } 3723c64c81aSSrinivas Pandruvada 3733c64c81aSSrinivas Pandruvada if (state) 374abd120e3SSrinivas Pandruvada ret = write(fd, "1\n", 2); 3753c64c81aSSrinivas Pandruvada else 376abd120e3SSrinivas Pandruvada ret = write(fd, "0\n", 2); 377abd120e3SSrinivas Pandruvada 378abd120e3SSrinivas Pandruvada if (ret == -1) 379abd120e3SSrinivas Pandruvada perror("Online/Offline: Operation failed\n"); 3803c64c81aSSrinivas Pandruvada 3813c64c81aSSrinivas Pandruvada close(fd); 3823c64c81aSSrinivas Pandruvada } 3833c64c81aSSrinivas Pandruvada 3843fb4f7cdSSrinivas Pandruvada #define MAX_PACKAGE_COUNT 8 3853fb4f7cdSSrinivas Pandruvada #define MAX_DIE_PER_PACKAGE 2 3863fb4f7cdSSrinivas Pandruvada static void for_each_online_package_in_set(void (*callback)(int, void *, void *, 3873fb4f7cdSSrinivas Pandruvada void *, void *), 3883fb4f7cdSSrinivas Pandruvada void *arg1, void *arg2, void *arg3, 3893fb4f7cdSSrinivas Pandruvada void *arg4) 3903fb4f7cdSSrinivas Pandruvada { 3913fb4f7cdSSrinivas Pandruvada int max_packages[MAX_PACKAGE_COUNT * MAX_PACKAGE_COUNT]; 3923fb4f7cdSSrinivas Pandruvada int pkg_index = 0, i; 3933fb4f7cdSSrinivas Pandruvada 3943fb4f7cdSSrinivas Pandruvada memset(max_packages, 0xff, sizeof(max_packages)); 3953fb4f7cdSSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) { 3963fb4f7cdSSrinivas Pandruvada int j, online, pkg_id, die_id = 0, skip = 0; 3973fb4f7cdSSrinivas Pandruvada 3983fb4f7cdSSrinivas Pandruvada if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) 3993fb4f7cdSSrinivas Pandruvada continue; 4003fb4f7cdSSrinivas Pandruvada if (i) 4013fb4f7cdSSrinivas Pandruvada online = parse_int_file( 4023fb4f7cdSSrinivas Pandruvada 1, "/sys/devices/system/cpu/cpu%d/online", i); 4033fb4f7cdSSrinivas Pandruvada else 4043fb4f7cdSSrinivas Pandruvada online = 4053fb4f7cdSSrinivas Pandruvada 1; /* online entry for CPU 0 needs some special configs */ 4063fb4f7cdSSrinivas Pandruvada 4073fb4f7cdSSrinivas Pandruvada die_id = get_physical_die_id(i); 4083fb4f7cdSSrinivas Pandruvada if (die_id < 0) 4093fb4f7cdSSrinivas Pandruvada die_id = 0; 410fb186158SSrinivas Pandruvada 411fb186158SSrinivas Pandruvada pkg_id = parse_int_file(0, 412fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", i); 413fb186158SSrinivas Pandruvada if (pkg_id < 0) 414f0e0b4d1SSrinivas Pandruvada continue; 415fb186158SSrinivas Pandruvada 4163fb4f7cdSSrinivas Pandruvada /* Create an unique id for package, die combination to store */ 4173fb4f7cdSSrinivas Pandruvada pkg_id = (MAX_PACKAGE_COUNT * pkg_id + die_id); 4183fb4f7cdSSrinivas Pandruvada 4193fb4f7cdSSrinivas Pandruvada for (j = 0; j < pkg_index; ++j) { 4203fb4f7cdSSrinivas Pandruvada if (max_packages[j] == pkg_id) { 4213fb4f7cdSSrinivas Pandruvada skip = 1; 4223fb4f7cdSSrinivas Pandruvada break; 4233fb4f7cdSSrinivas Pandruvada } 4243fb4f7cdSSrinivas Pandruvada } 4253fb4f7cdSSrinivas Pandruvada 4263fb4f7cdSSrinivas Pandruvada if (!skip && online && callback) { 4273fb4f7cdSSrinivas Pandruvada callback(i, arg1, arg2, arg3, arg4); 4283fb4f7cdSSrinivas Pandruvada max_packages[pkg_index++] = pkg_id; 4293fb4f7cdSSrinivas Pandruvada } 4303fb4f7cdSSrinivas Pandruvada } 4313fb4f7cdSSrinivas Pandruvada } 4323fb4f7cdSSrinivas Pandruvada 4333fb4f7cdSSrinivas Pandruvada static void for_each_online_target_cpu_in_set( 4343fb4f7cdSSrinivas Pandruvada void (*callback)(int, void *, void *, void *, void *), void *arg1, 4353fb4f7cdSSrinivas Pandruvada void *arg2, void *arg3, void *arg4) 4363fb4f7cdSSrinivas Pandruvada { 437070fdea1SSrinivas Pandruvada int i, found = 0; 4383fb4f7cdSSrinivas Pandruvada 4393fb4f7cdSSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) { 4403fb4f7cdSSrinivas Pandruvada int online; 4413fb4f7cdSSrinivas Pandruvada 4423fb4f7cdSSrinivas Pandruvada if (!CPU_ISSET_S(i, target_cpumask_size, target_cpumask)) 4433fb4f7cdSSrinivas Pandruvada continue; 4443fb4f7cdSSrinivas Pandruvada if (i) 4453fb4f7cdSSrinivas Pandruvada online = parse_int_file( 4463fb4f7cdSSrinivas Pandruvada 1, "/sys/devices/system/cpu/cpu%d/online", i); 4473fb4f7cdSSrinivas Pandruvada else 4483fb4f7cdSSrinivas Pandruvada online = 4493fb4f7cdSSrinivas Pandruvada 1; /* online entry for CPU 0 needs some special configs */ 4503fb4f7cdSSrinivas Pandruvada 451070fdea1SSrinivas Pandruvada if (online && callback) { 4523fb4f7cdSSrinivas Pandruvada callback(i, arg1, arg2, arg3, arg4); 453070fdea1SSrinivas Pandruvada found = 1; 4543fb4f7cdSSrinivas Pandruvada } 4553fb4f7cdSSrinivas Pandruvada } 4563fb4f7cdSSrinivas Pandruvada 457070fdea1SSrinivas Pandruvada if (!found) 458070fdea1SSrinivas Pandruvada fprintf(stderr, "No valid CPU in the list\n"); 459070fdea1SSrinivas Pandruvada } 460070fdea1SSrinivas Pandruvada 4613fb4f7cdSSrinivas Pandruvada #define BITMASK_SIZE 32 4623fb4f7cdSSrinivas Pandruvada static void set_max_cpu_num(void) 4633fb4f7cdSSrinivas Pandruvada { 4643fb4f7cdSSrinivas Pandruvada FILE *filep; 4653fb4f7cdSSrinivas Pandruvada unsigned long dummy; 466864dc09eSSrinivas Pandruvada int i; 4673fb4f7cdSSrinivas Pandruvada 4683fb4f7cdSSrinivas Pandruvada topo_max_cpus = 0; 469864dc09eSSrinivas Pandruvada for (i = 0; i < 256; ++i) { 470864dc09eSSrinivas Pandruvada char path[256]; 471864dc09eSSrinivas Pandruvada 472864dc09eSSrinivas Pandruvada snprintf(path, sizeof(path), 473864dc09eSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", i); 474864dc09eSSrinivas Pandruvada filep = fopen(path, "r"); 475864dc09eSSrinivas Pandruvada if (filep) 476864dc09eSSrinivas Pandruvada break; 477864dc09eSSrinivas Pandruvada } 478864dc09eSSrinivas Pandruvada 479864dc09eSSrinivas Pandruvada if (!filep) { 480864dc09eSSrinivas Pandruvada fprintf(stderr, "Can't get max cpu number\n"); 481864dc09eSSrinivas Pandruvada exit(0); 482864dc09eSSrinivas Pandruvada } 483864dc09eSSrinivas Pandruvada 4843fb4f7cdSSrinivas Pandruvada while (fscanf(filep, "%lx,", &dummy) == 1) 4853fb4f7cdSSrinivas Pandruvada topo_max_cpus += BITMASK_SIZE; 4863fb4f7cdSSrinivas Pandruvada fclose(filep); 4873fb4f7cdSSrinivas Pandruvada 4883fb4f7cdSSrinivas Pandruvada debug_printf("max cpus %d\n", topo_max_cpus); 4893fb4f7cdSSrinivas Pandruvada } 4903fb4f7cdSSrinivas Pandruvada 4913fb4f7cdSSrinivas Pandruvada size_t alloc_cpu_set(cpu_set_t **cpu_set) 4923fb4f7cdSSrinivas Pandruvada { 4933fb4f7cdSSrinivas Pandruvada cpu_set_t *_cpu_set; 4943fb4f7cdSSrinivas Pandruvada size_t size; 4953fb4f7cdSSrinivas Pandruvada 4963fb4f7cdSSrinivas Pandruvada _cpu_set = CPU_ALLOC((topo_max_cpus + 1)); 4973fb4f7cdSSrinivas Pandruvada if (_cpu_set == NULL) 4983fb4f7cdSSrinivas Pandruvada err(3, "CPU_ALLOC"); 4993fb4f7cdSSrinivas Pandruvada size = CPU_ALLOC_SIZE((topo_max_cpus + 1)); 5003fb4f7cdSSrinivas Pandruvada CPU_ZERO_S(size, _cpu_set); 5013fb4f7cdSSrinivas Pandruvada 5023fb4f7cdSSrinivas Pandruvada *cpu_set = _cpu_set; 5033fb4f7cdSSrinivas Pandruvada return size; 5043fb4f7cdSSrinivas Pandruvada } 5053fb4f7cdSSrinivas Pandruvada 5063fb4f7cdSSrinivas Pandruvada void free_cpu_set(cpu_set_t *cpu_set) 5073fb4f7cdSSrinivas Pandruvada { 5083fb4f7cdSSrinivas Pandruvada CPU_FREE(cpu_set); 5093fb4f7cdSSrinivas Pandruvada } 5103fb4f7cdSSrinivas Pandruvada 5113fb4f7cdSSrinivas Pandruvada static int cpu_cnt[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE]; 512de7f9d3dSSrinivas Pandruvada static long long core_mask[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE]; 5133fb4f7cdSSrinivas Pandruvada static void set_cpu_present_cpu_mask(void) 5143fb4f7cdSSrinivas Pandruvada { 5153fb4f7cdSSrinivas Pandruvada size_t size; 5163fb4f7cdSSrinivas Pandruvada DIR *dir; 5173fb4f7cdSSrinivas Pandruvada int i; 5183fb4f7cdSSrinivas Pandruvada 5193fb4f7cdSSrinivas Pandruvada size = alloc_cpu_set(&present_cpumask); 5203fb4f7cdSSrinivas Pandruvada present_cpumask_size = size; 5213fb4f7cdSSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) { 5223fb4f7cdSSrinivas Pandruvada char buffer[256]; 5233fb4f7cdSSrinivas Pandruvada 5243fb4f7cdSSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 5253fb4f7cdSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d", i); 5263fb4f7cdSSrinivas Pandruvada dir = opendir(buffer); 5273fb4f7cdSSrinivas Pandruvada if (dir) { 5283fb4f7cdSSrinivas Pandruvada int pkg_id, die_id; 5293fb4f7cdSSrinivas Pandruvada 5303fb4f7cdSSrinivas Pandruvada CPU_SET_S(i, size, present_cpumask); 5313fb4f7cdSSrinivas Pandruvada die_id = get_physical_die_id(i); 5323fb4f7cdSSrinivas Pandruvada if (die_id < 0) 5333fb4f7cdSSrinivas Pandruvada die_id = 0; 5343fb4f7cdSSrinivas Pandruvada 5353fb4f7cdSSrinivas Pandruvada pkg_id = get_physical_package_id(i); 536f0e0b4d1SSrinivas Pandruvada if (pkg_id < 0) { 537f0e0b4d1SSrinivas Pandruvada fprintf(stderr, "Failed to get package id, CPU %d may be offline\n", i); 538f0e0b4d1SSrinivas Pandruvada continue; 539f0e0b4d1SSrinivas Pandruvada } 5403fb4f7cdSSrinivas Pandruvada if (pkg_id < MAX_PACKAGE_COUNT && 541de7f9d3dSSrinivas Pandruvada die_id < MAX_DIE_PER_PACKAGE) { 542de7f9d3dSSrinivas Pandruvada int core_id = get_physical_core_id(i); 543de7f9d3dSSrinivas Pandruvada 5443fb4f7cdSSrinivas Pandruvada cpu_cnt[pkg_id][die_id]++; 545de7f9d3dSSrinivas Pandruvada core_mask[pkg_id][die_id] |= (1ULL << core_id); 546de7f9d3dSSrinivas Pandruvada } 5473fb4f7cdSSrinivas Pandruvada } 5483fb4f7cdSSrinivas Pandruvada closedir(dir); 5493fb4f7cdSSrinivas Pandruvada } 5503fb4f7cdSSrinivas Pandruvada } 5513fb4f7cdSSrinivas Pandruvada 5527566616fSJonathan Doman int get_max_punit_core_id(int pkg_id, int die_id) 553de7f9d3dSSrinivas Pandruvada { 5547566616fSJonathan Doman int max_id = 0; 555de7f9d3dSSrinivas Pandruvada int i; 556de7f9d3dSSrinivas Pandruvada 5577566616fSJonathan Doman for (i = 0; i < topo_max_cpus; ++i) 5587566616fSJonathan Doman { 5597566616fSJonathan Doman if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) 5607566616fSJonathan Doman continue; 5617566616fSJonathan Doman 5627566616fSJonathan Doman if (cpu_map[i].pkg_id == pkg_id && 5637566616fSJonathan Doman cpu_map[i].die_id == die_id && 5647566616fSJonathan Doman cpu_map[i].punit_cpu_core > max_id) 5657566616fSJonathan Doman max_id = cpu_map[i].punit_cpu_core; 566de7f9d3dSSrinivas Pandruvada } 567de7f9d3dSSrinivas Pandruvada 5687566616fSJonathan Doman return max_id; 569de7f9d3dSSrinivas Pandruvada } 570de7f9d3dSSrinivas Pandruvada 5713fb4f7cdSSrinivas Pandruvada int get_cpu_count(int pkg_id, int die_id) 5723fb4f7cdSSrinivas Pandruvada { 5733fb4f7cdSSrinivas Pandruvada if (pkg_id < MAX_PACKAGE_COUNT && die_id < MAX_DIE_PER_PACKAGE) 5743ec2aef1SPrarit Bhargava return cpu_cnt[pkg_id][die_id]; 5753fb4f7cdSSrinivas Pandruvada 5763fb4f7cdSSrinivas Pandruvada return 0; 5773fb4f7cdSSrinivas Pandruvada } 5783fb4f7cdSSrinivas Pandruvada 5793fb4f7cdSSrinivas Pandruvada static void set_cpu_target_cpu_mask(void) 5803fb4f7cdSSrinivas Pandruvada { 5813fb4f7cdSSrinivas Pandruvada size_t size; 5823fb4f7cdSSrinivas Pandruvada int i; 5833fb4f7cdSSrinivas Pandruvada 5843fb4f7cdSSrinivas Pandruvada size = alloc_cpu_set(&target_cpumask); 5853fb4f7cdSSrinivas Pandruvada target_cpumask_size = size; 5863fb4f7cdSSrinivas Pandruvada for (i = 0; i < max_target_cpus; ++i) { 5873fb4f7cdSSrinivas Pandruvada if (!CPU_ISSET_S(target_cpus[i], present_cpumask_size, 5883fb4f7cdSSrinivas Pandruvada present_cpumask)) 5893fb4f7cdSSrinivas Pandruvada continue; 5903fb4f7cdSSrinivas Pandruvada 5913fb4f7cdSSrinivas Pandruvada CPU_SET_S(target_cpus[i], size, target_cpumask); 5923fb4f7cdSSrinivas Pandruvada } 5933fb4f7cdSSrinivas Pandruvada } 5943fb4f7cdSSrinivas Pandruvada 5953fb4f7cdSSrinivas Pandruvada static void create_cpu_map(void) 5963fb4f7cdSSrinivas Pandruvada { 5973fb4f7cdSSrinivas Pandruvada const char *pathname = "/dev/isst_interface"; 5983fb4f7cdSSrinivas Pandruvada int i, fd = 0; 5993fb4f7cdSSrinivas Pandruvada struct isst_if_cpu_maps map; 6003fb4f7cdSSrinivas Pandruvada 6013fb4f7cdSSrinivas Pandruvada cpu_map = malloc(sizeof(*cpu_map) * topo_max_cpus); 6023fb4f7cdSSrinivas Pandruvada if (!cpu_map) 6033fb4f7cdSSrinivas Pandruvada err(3, "cpumap"); 6043fb4f7cdSSrinivas Pandruvada 6053fb4f7cdSSrinivas Pandruvada fd = open(pathname, O_RDWR); 6063fb4f7cdSSrinivas Pandruvada if (fd < 0) 6073fb4f7cdSSrinivas Pandruvada err(-1, "%s open failed", pathname); 6083fb4f7cdSSrinivas Pandruvada 6093fb4f7cdSSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) { 6103fb4f7cdSSrinivas Pandruvada if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) 6113fb4f7cdSSrinivas Pandruvada continue; 6123fb4f7cdSSrinivas Pandruvada 6133fb4f7cdSSrinivas Pandruvada map.cmd_count = 1; 6143fb4f7cdSSrinivas Pandruvada map.cpu_map[0].logical_cpu = i; 6153fb4f7cdSSrinivas Pandruvada 6163fb4f7cdSSrinivas Pandruvada debug_printf(" map logical_cpu:%d\n", 6173fb4f7cdSSrinivas Pandruvada map.cpu_map[0].logical_cpu); 6183fb4f7cdSSrinivas Pandruvada if (ioctl(fd, ISST_IF_GET_PHY_ID, &map) == -1) { 6193fb4f7cdSSrinivas Pandruvada perror("ISST_IF_GET_PHY_ID"); 6203fb4f7cdSSrinivas Pandruvada fprintf(outf, "Error: map logical_cpu:%d\n", 6213fb4f7cdSSrinivas Pandruvada map.cpu_map[0].logical_cpu); 6223fb4f7cdSSrinivas Pandruvada continue; 6233fb4f7cdSSrinivas Pandruvada } 6243fb4f7cdSSrinivas Pandruvada cpu_map[i].core_id = get_physical_core_id(i); 6253fb4f7cdSSrinivas Pandruvada cpu_map[i].pkg_id = get_physical_package_id(i); 6263fb4f7cdSSrinivas Pandruvada cpu_map[i].die_id = get_physical_die_id(i); 6273fb4f7cdSSrinivas Pandruvada cpu_map[i].punit_cpu = map.cpu_map[0].physical_cpu; 6283fb4f7cdSSrinivas Pandruvada cpu_map[i].punit_cpu_core = (map.cpu_map[0].physical_cpu >> 6293fb4f7cdSSrinivas Pandruvada 1); // shift to get core id 6303fb4f7cdSSrinivas Pandruvada 6313fb4f7cdSSrinivas Pandruvada debug_printf( 6323fb4f7cdSSrinivas Pandruvada "map logical_cpu:%d core: %d die:%d pkg:%d punit_cpu:%d punit_core:%d\n", 6333fb4f7cdSSrinivas Pandruvada i, cpu_map[i].core_id, cpu_map[i].die_id, 6343fb4f7cdSSrinivas Pandruvada cpu_map[i].pkg_id, cpu_map[i].punit_cpu, 6353fb4f7cdSSrinivas Pandruvada cpu_map[i].punit_cpu_core); 6363fb4f7cdSSrinivas Pandruvada } 6373fb4f7cdSSrinivas Pandruvada 6383fb4f7cdSSrinivas Pandruvada if (fd) 6393fb4f7cdSSrinivas Pandruvada close(fd); 6403fb4f7cdSSrinivas Pandruvada } 6413fb4f7cdSSrinivas Pandruvada 6423fb4f7cdSSrinivas Pandruvada int find_logical_cpu(int pkg_id, int die_id, int punit_core_id) 6433fb4f7cdSSrinivas Pandruvada { 6443fb4f7cdSSrinivas Pandruvada int i; 6453fb4f7cdSSrinivas Pandruvada 6463fb4f7cdSSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) { 6473fb4f7cdSSrinivas Pandruvada if (cpu_map[i].pkg_id == pkg_id && 6483fb4f7cdSSrinivas Pandruvada cpu_map[i].die_id == die_id && 6493fb4f7cdSSrinivas Pandruvada cpu_map[i].punit_cpu_core == punit_core_id) 6503fb4f7cdSSrinivas Pandruvada return i; 6513fb4f7cdSSrinivas Pandruvada } 6523fb4f7cdSSrinivas Pandruvada 6533fb4f7cdSSrinivas Pandruvada return -EINVAL; 6543fb4f7cdSSrinivas Pandruvada } 6553fb4f7cdSSrinivas Pandruvada 6563fb4f7cdSSrinivas Pandruvada void set_cpu_mask_from_punit_coremask(int cpu, unsigned long long core_mask, 6573fb4f7cdSSrinivas Pandruvada size_t core_cpumask_size, 6583fb4f7cdSSrinivas Pandruvada cpu_set_t *core_cpumask, int *cpu_cnt) 6593fb4f7cdSSrinivas Pandruvada { 6603fb4f7cdSSrinivas Pandruvada int i, cnt = 0; 6613fb4f7cdSSrinivas Pandruvada int die_id, pkg_id; 6623fb4f7cdSSrinivas Pandruvada 6633fb4f7cdSSrinivas Pandruvada *cpu_cnt = 0; 6643fb4f7cdSSrinivas Pandruvada die_id = get_physical_die_id(cpu); 6653fb4f7cdSSrinivas Pandruvada pkg_id = get_physical_package_id(cpu); 6663fb4f7cdSSrinivas Pandruvada 6673fb4f7cdSSrinivas Pandruvada for (i = 0; i < 64; ++i) { 668873e391fSSrinivas Pandruvada if (core_mask & BIT_ULL(i)) { 6693fb4f7cdSSrinivas Pandruvada int j; 6703fb4f7cdSSrinivas Pandruvada 6713fb4f7cdSSrinivas Pandruvada for (j = 0; j < topo_max_cpus; ++j) { 67244460efeSYouquan Song if (!CPU_ISSET_S(j, present_cpumask_size, present_cpumask)) 67344460efeSYouquan Song continue; 67444460efeSYouquan Song 6753fb4f7cdSSrinivas Pandruvada if (cpu_map[j].pkg_id == pkg_id && 6763fb4f7cdSSrinivas Pandruvada cpu_map[j].die_id == die_id && 6773fb4f7cdSSrinivas Pandruvada cpu_map[j].punit_cpu_core == i) { 6783fb4f7cdSSrinivas Pandruvada CPU_SET_S(j, core_cpumask_size, 6793fb4f7cdSSrinivas Pandruvada core_cpumask); 6803fb4f7cdSSrinivas Pandruvada ++cnt; 6813fb4f7cdSSrinivas Pandruvada } 6823fb4f7cdSSrinivas Pandruvada } 6833fb4f7cdSSrinivas Pandruvada } 6843fb4f7cdSSrinivas Pandruvada } 6853fb4f7cdSSrinivas Pandruvada 6863fb4f7cdSSrinivas Pandruvada *cpu_cnt = cnt; 6873fb4f7cdSSrinivas Pandruvada } 6883fb4f7cdSSrinivas Pandruvada 6893fb4f7cdSSrinivas Pandruvada int find_phy_core_num(int logical_cpu) 6903fb4f7cdSSrinivas Pandruvada { 6913fb4f7cdSSrinivas Pandruvada if (logical_cpu < topo_max_cpus) 6923fb4f7cdSSrinivas Pandruvada return cpu_map[logical_cpu].punit_cpu_core; 6933fb4f7cdSSrinivas Pandruvada 6943fb4f7cdSSrinivas Pandruvada return -EINVAL; 6953fb4f7cdSSrinivas Pandruvada } 6963fb4f7cdSSrinivas Pandruvada 6973fb4f7cdSSrinivas Pandruvada static int isst_send_mmio_command(unsigned int cpu, unsigned int reg, int write, 6983fb4f7cdSSrinivas Pandruvada unsigned int *value) 6993fb4f7cdSSrinivas Pandruvada { 7003fb4f7cdSSrinivas Pandruvada struct isst_if_io_regs io_regs; 7013fb4f7cdSSrinivas Pandruvada const char *pathname = "/dev/isst_interface"; 7023fb4f7cdSSrinivas Pandruvada int cmd; 7033fb4f7cdSSrinivas Pandruvada int fd; 7043fb4f7cdSSrinivas Pandruvada 7053fb4f7cdSSrinivas Pandruvada debug_printf("mmio_cmd cpu:%d reg:%d write:%d\n", cpu, reg, write); 7063fb4f7cdSSrinivas Pandruvada 7073fb4f7cdSSrinivas Pandruvada fd = open(pathname, O_RDWR); 7083fb4f7cdSSrinivas Pandruvada if (fd < 0) 7093fb4f7cdSSrinivas Pandruvada err(-1, "%s open failed", pathname); 7103fb4f7cdSSrinivas Pandruvada 7113fb4f7cdSSrinivas Pandruvada io_regs.req_count = 1; 7123fb4f7cdSSrinivas Pandruvada io_regs.io_reg[0].logical_cpu = cpu; 7133fb4f7cdSSrinivas Pandruvada io_regs.io_reg[0].reg = reg; 7143fb4f7cdSSrinivas Pandruvada cmd = ISST_IF_IO_CMD; 7153fb4f7cdSSrinivas Pandruvada if (write) { 7163fb4f7cdSSrinivas Pandruvada io_regs.io_reg[0].read_write = 1; 7173fb4f7cdSSrinivas Pandruvada io_regs.io_reg[0].value = *value; 7183fb4f7cdSSrinivas Pandruvada } else { 7193fb4f7cdSSrinivas Pandruvada io_regs.io_reg[0].read_write = 0; 7203fb4f7cdSSrinivas Pandruvada } 7213fb4f7cdSSrinivas Pandruvada 7223fb4f7cdSSrinivas Pandruvada if (ioctl(fd, cmd, &io_regs) == -1) { 72395f8e569SSrinivas Pandruvada if (errno == ENOTTY) { 72495f8e569SSrinivas Pandruvada perror("ISST_IF_IO_COMMAND\n"); 72595f8e569SSrinivas Pandruvada fprintf(stderr, "Check presence of kernel modules: isst_if_mmio\n"); 72695f8e569SSrinivas Pandruvada exit(0); 72795f8e569SSrinivas Pandruvada } 7283fb4f7cdSSrinivas Pandruvada fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n", 7293fb4f7cdSSrinivas Pandruvada cpu, reg, write); 7303fb4f7cdSSrinivas Pandruvada } else { 7313fb4f7cdSSrinivas Pandruvada if (!write) 7323fb4f7cdSSrinivas Pandruvada *value = io_regs.io_reg[0].value; 7333fb4f7cdSSrinivas Pandruvada 7343fb4f7cdSSrinivas Pandruvada debug_printf( 7353fb4f7cdSSrinivas Pandruvada "mmio_cmd response: cpu:%d reg:%x rd_write:%x resp:%x\n", 7363fb4f7cdSSrinivas Pandruvada cpu, reg, write, *value); 7373fb4f7cdSSrinivas Pandruvada } 7383fb4f7cdSSrinivas Pandruvada 7393fb4f7cdSSrinivas Pandruvada close(fd); 7403fb4f7cdSSrinivas Pandruvada 7413fb4f7cdSSrinivas Pandruvada return 0; 7423fb4f7cdSSrinivas Pandruvada } 7433fb4f7cdSSrinivas Pandruvada 7443fb4f7cdSSrinivas Pandruvada int isst_send_mbox_command(unsigned int cpu, unsigned char command, 7453fb4f7cdSSrinivas Pandruvada unsigned char sub_command, unsigned int parameter, 7463fb4f7cdSSrinivas Pandruvada unsigned int req_data, unsigned int *resp) 7473fb4f7cdSSrinivas Pandruvada { 7483fb4f7cdSSrinivas Pandruvada const char *pathname = "/dev/isst_interface"; 74932279be7SSrinivas Pandruvada int fd, retry; 7503fb4f7cdSSrinivas Pandruvada struct isst_if_mbox_cmds mbox_cmds = { 0 }; 7513fb4f7cdSSrinivas Pandruvada 7523fb4f7cdSSrinivas Pandruvada debug_printf( 7533fb4f7cdSSrinivas Pandruvada "mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", 7543fb4f7cdSSrinivas Pandruvada cpu, command, sub_command, parameter, req_data); 7553fb4f7cdSSrinivas Pandruvada 75695f8e569SSrinivas Pandruvada if (!is_skx_based_platform() && command == CONFIG_CLOS && 7578ddbda76SSrinivas Pandruvada sub_command != CLOS_PM_QOS_CONFIG) { 7583fb4f7cdSSrinivas Pandruvada unsigned int value; 7593fb4f7cdSSrinivas Pandruvada int write = 0; 7603fb4f7cdSSrinivas Pandruvada int clos_id, core_id, ret = 0; 7613fb4f7cdSSrinivas Pandruvada 762d2d1f304SSrinivas Pandruvada debug_printf("CPU %d\n", cpu); 7633fb4f7cdSSrinivas Pandruvada 7643fb4f7cdSSrinivas Pandruvada if (parameter & BIT(MBOX_CMD_WRITE_BIT)) { 7653fb4f7cdSSrinivas Pandruvada value = req_data; 7663fb4f7cdSSrinivas Pandruvada write = 1; 7673fb4f7cdSSrinivas Pandruvada } 7683fb4f7cdSSrinivas Pandruvada 7693fb4f7cdSSrinivas Pandruvada switch (sub_command) { 7703fb4f7cdSSrinivas Pandruvada case CLOS_PQR_ASSOC: 7713fb4f7cdSSrinivas Pandruvada core_id = parameter & 0xff; 7723fb4f7cdSSrinivas Pandruvada ret = isst_send_mmio_command( 7733fb4f7cdSSrinivas Pandruvada cpu, PQR_ASSOC_OFFSET + core_id * 4, write, 7743fb4f7cdSSrinivas Pandruvada &value); 7753fb4f7cdSSrinivas Pandruvada if (!ret && !write) 7763fb4f7cdSSrinivas Pandruvada *resp = value; 7773fb4f7cdSSrinivas Pandruvada break; 7783fb4f7cdSSrinivas Pandruvada case CLOS_PM_CLOS: 7793fb4f7cdSSrinivas Pandruvada clos_id = parameter & 0x03; 7803fb4f7cdSSrinivas Pandruvada ret = isst_send_mmio_command( 7813fb4f7cdSSrinivas Pandruvada cpu, PM_CLOS_OFFSET + clos_id * 4, write, 7823fb4f7cdSSrinivas Pandruvada &value); 7833fb4f7cdSSrinivas Pandruvada if (!ret && !write) 7843fb4f7cdSSrinivas Pandruvada *resp = value; 7853fb4f7cdSSrinivas Pandruvada break; 7863fb4f7cdSSrinivas Pandruvada case CLOS_STATUS: 7873fb4f7cdSSrinivas Pandruvada break; 7883fb4f7cdSSrinivas Pandruvada default: 7893fb4f7cdSSrinivas Pandruvada break; 7903fb4f7cdSSrinivas Pandruvada } 7913fb4f7cdSSrinivas Pandruvada return ret; 7923fb4f7cdSSrinivas Pandruvada } 7933fb4f7cdSSrinivas Pandruvada 7943fb4f7cdSSrinivas Pandruvada mbox_cmds.cmd_count = 1; 7953fb4f7cdSSrinivas Pandruvada mbox_cmds.mbox_cmd[0].logical_cpu = cpu; 7963fb4f7cdSSrinivas Pandruvada mbox_cmds.mbox_cmd[0].command = command; 7973fb4f7cdSSrinivas Pandruvada mbox_cmds.mbox_cmd[0].sub_command = sub_command; 7983fb4f7cdSSrinivas Pandruvada mbox_cmds.mbox_cmd[0].parameter = parameter; 7993fb4f7cdSSrinivas Pandruvada mbox_cmds.mbox_cmd[0].req_data = req_data; 8003fb4f7cdSSrinivas Pandruvada 801a85a35fcSSrinivas Pandruvada if (mbox_delay) 802a85a35fcSSrinivas Pandruvada usleep(mbox_delay * 1000); 803a85a35fcSSrinivas Pandruvada 8043fb4f7cdSSrinivas Pandruvada fd = open(pathname, O_RDWR); 8053fb4f7cdSSrinivas Pandruvada if (fd < 0) 8063fb4f7cdSSrinivas Pandruvada err(-1, "%s open failed", pathname); 8073fb4f7cdSSrinivas Pandruvada 80832279be7SSrinivas Pandruvada retry = mbox_retries; 80932279be7SSrinivas Pandruvada 81032279be7SSrinivas Pandruvada do { 8113fb4f7cdSSrinivas Pandruvada if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) { 81295f8e569SSrinivas Pandruvada if (errno == ENOTTY) { 81395f8e569SSrinivas Pandruvada perror("ISST_IF_MBOX_COMMAND\n"); 81495f8e569SSrinivas Pandruvada fprintf(stderr, "Check presence of kernel modules: isst_if_mbox_pci or isst_if_mbox_msr\n"); 81595f8e569SSrinivas Pandruvada exit(0); 81695f8e569SSrinivas Pandruvada } 81795f8e569SSrinivas Pandruvada debug_printf( 81895f8e569SSrinivas Pandruvada "Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x errorno:%d\n", 81995f8e569SSrinivas Pandruvada cpu, command, sub_command, parameter, req_data, errno); 82032279be7SSrinivas Pandruvada --retry; 8213fb4f7cdSSrinivas Pandruvada } else { 8223fb4f7cdSSrinivas Pandruvada *resp = mbox_cmds.mbox_cmd[0].resp_data; 8233fb4f7cdSSrinivas Pandruvada debug_printf( 8243fb4f7cdSSrinivas Pandruvada "mbox_cmd response: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x resp:%x\n", 8253fb4f7cdSSrinivas Pandruvada cpu, command, sub_command, parameter, req_data, *resp); 82632279be7SSrinivas Pandruvada break; 8273fb4f7cdSSrinivas Pandruvada } 82832279be7SSrinivas Pandruvada } while (retry); 8293fb4f7cdSSrinivas Pandruvada 8303fb4f7cdSSrinivas Pandruvada close(fd); 8313fb4f7cdSSrinivas Pandruvada 83232279be7SSrinivas Pandruvada if (!retry) { 83332279be7SSrinivas Pandruvada debug_printf("Failed mbox command even after retries\n"); 83432279be7SSrinivas Pandruvada return -1; 83532279be7SSrinivas Pandruvada 83632279be7SSrinivas Pandruvada } 8373fb4f7cdSSrinivas Pandruvada return 0; 8383fb4f7cdSSrinivas Pandruvada } 8393fb4f7cdSSrinivas Pandruvada 8403fb4f7cdSSrinivas Pandruvada int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write, 8413fb4f7cdSSrinivas Pandruvada unsigned long long *req_resp) 8423fb4f7cdSSrinivas Pandruvada { 8433fb4f7cdSSrinivas Pandruvada struct isst_if_msr_cmds msr_cmds; 8443fb4f7cdSSrinivas Pandruvada const char *pathname = "/dev/isst_interface"; 8453fb4f7cdSSrinivas Pandruvada int fd; 8463fb4f7cdSSrinivas Pandruvada 8473fb4f7cdSSrinivas Pandruvada fd = open(pathname, O_RDWR); 8483fb4f7cdSSrinivas Pandruvada if (fd < 0) 8493fb4f7cdSSrinivas Pandruvada err(-1, "%s open failed", pathname); 8503fb4f7cdSSrinivas Pandruvada 8513fb4f7cdSSrinivas Pandruvada msr_cmds.cmd_count = 1; 8523fb4f7cdSSrinivas Pandruvada msr_cmds.msr_cmd[0].logical_cpu = cpu; 8533fb4f7cdSSrinivas Pandruvada msr_cmds.msr_cmd[0].msr = msr; 8543fb4f7cdSSrinivas Pandruvada msr_cmds.msr_cmd[0].read_write = write; 8553fb4f7cdSSrinivas Pandruvada if (write) 8563fb4f7cdSSrinivas Pandruvada msr_cmds.msr_cmd[0].data = *req_resp; 8573fb4f7cdSSrinivas Pandruvada 8583fb4f7cdSSrinivas Pandruvada if (ioctl(fd, ISST_IF_MSR_COMMAND, &msr_cmds) == -1) { 8599945a247SMasanari Iida perror("ISST_IF_MSR_COMMAND"); 8603fb4f7cdSSrinivas Pandruvada fprintf(outf, "Error: msr_cmd cpu:%d msr:%x read_write:%d\n", 8613fb4f7cdSSrinivas Pandruvada cpu, msr, write); 8623fb4f7cdSSrinivas Pandruvada } else { 8633fb4f7cdSSrinivas Pandruvada if (!write) 8643fb4f7cdSSrinivas Pandruvada *req_resp = msr_cmds.msr_cmd[0].data; 8653fb4f7cdSSrinivas Pandruvada 8663fb4f7cdSSrinivas Pandruvada debug_printf( 8673fb4f7cdSSrinivas Pandruvada "msr_cmd response: cpu:%d msr:%x rd_write:%x resp:%llx %llx\n", 8683fb4f7cdSSrinivas Pandruvada cpu, msr, write, *req_resp, msr_cmds.msr_cmd[0].data); 8693fb4f7cdSSrinivas Pandruvada } 8703fb4f7cdSSrinivas Pandruvada 8713fb4f7cdSSrinivas Pandruvada close(fd); 8723fb4f7cdSSrinivas Pandruvada 8733fb4f7cdSSrinivas Pandruvada return 0; 8743fb4f7cdSSrinivas Pandruvada } 8753fb4f7cdSSrinivas Pandruvada 8763fb4f7cdSSrinivas Pandruvada static int isst_fill_platform_info(void) 8773fb4f7cdSSrinivas Pandruvada { 8783fb4f7cdSSrinivas Pandruvada const char *pathname = "/dev/isst_interface"; 8793fb4f7cdSSrinivas Pandruvada int fd; 8803fb4f7cdSSrinivas Pandruvada 8813fb4f7cdSSrinivas Pandruvada fd = open(pathname, O_RDWR); 8823fb4f7cdSSrinivas Pandruvada if (fd < 0) 8833fb4f7cdSSrinivas Pandruvada err(-1, "%s open failed", pathname); 8843fb4f7cdSSrinivas Pandruvada 8853fb4f7cdSSrinivas Pandruvada if (ioctl(fd, ISST_IF_GET_PLATFORM_INFO, &isst_platform_info) == -1) { 8863fb4f7cdSSrinivas Pandruvada perror("ISST_IF_GET_PLATFORM_INFO"); 8873fb4f7cdSSrinivas Pandruvada close(fd); 8883fb4f7cdSSrinivas Pandruvada return -1; 8893fb4f7cdSSrinivas Pandruvada } 8903fb4f7cdSSrinivas Pandruvada 8913fb4f7cdSSrinivas Pandruvada close(fd); 8923fb4f7cdSSrinivas Pandruvada 8933bc3d30cSPrarit Bhargava if (isst_platform_info.api_version > supported_api_ver) { 8943bc3d30cSPrarit Bhargava printf("Incompatible API versions; Upgrade of tool is required\n"); 8953bc3d30cSPrarit Bhargava return -1; 8963bc3d30cSPrarit Bhargava } 8973fb4f7cdSSrinivas Pandruvada return 0; 8983fb4f7cdSSrinivas Pandruvada } 8993fb4f7cdSSrinivas Pandruvada 9001ba148aeSSrinivas Pandruvada static void isst_print_extended_platform_info(void) 9011ba148aeSSrinivas Pandruvada { 9021ba148aeSSrinivas Pandruvada int cp_state, cp_cap, fact_support = 0, pbf_support = 0; 9031ba148aeSSrinivas Pandruvada struct isst_pkg_ctdp_level_info ctdp_level; 9041ba148aeSSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev; 9051ba148aeSSrinivas Pandruvada int ret, i, j; 9061ba148aeSSrinivas Pandruvada FILE *filep; 9071ba148aeSSrinivas Pandruvada 9081ba148aeSSrinivas Pandruvada for (i = 0; i < 256; ++i) { 9091ba148aeSSrinivas Pandruvada char path[256]; 9101ba148aeSSrinivas Pandruvada 9111ba148aeSSrinivas Pandruvada snprintf(path, sizeof(path), 9121ba148aeSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", i); 9131ba148aeSSrinivas Pandruvada filep = fopen(path, "r"); 9141ba148aeSSrinivas Pandruvada if (filep) 9151ba148aeSSrinivas Pandruvada break; 9161ba148aeSSrinivas Pandruvada } 9171ba148aeSSrinivas Pandruvada 9181ba148aeSSrinivas Pandruvada if (!filep) 9191ba148aeSSrinivas Pandruvada return; 9201ba148aeSSrinivas Pandruvada 9211ba148aeSSrinivas Pandruvada fclose(filep); 9221ba148aeSSrinivas Pandruvada 9231ba148aeSSrinivas Pandruvada ret = isst_get_ctdp_levels(i, &pkg_dev); 9241ba148aeSSrinivas Pandruvada if (ret) 9251ba148aeSSrinivas Pandruvada return; 9261ba148aeSSrinivas Pandruvada 9271ba148aeSSrinivas Pandruvada if (pkg_dev.enabled) { 9281ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-PP (feature perf-profile) is supported\n"); 9291ba148aeSSrinivas Pandruvada } else { 9301ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-PP (feature perf-profile) is not supported\n"); 9311ba148aeSSrinivas Pandruvada fprintf(outf, "Only performance level 0 (base level) is present\n"); 9321ba148aeSSrinivas Pandruvada } 9331ba148aeSSrinivas Pandruvada 9341ba148aeSSrinivas Pandruvada if (pkg_dev.locked) 9351ba148aeSSrinivas Pandruvada fprintf(outf, "TDP level change control is locked\n"); 9361ba148aeSSrinivas Pandruvada else 9371ba148aeSSrinivas Pandruvada fprintf(outf, "TDP level change control is unlocked, max level: %d \n", pkg_dev.levels); 9381ba148aeSSrinivas Pandruvada 9391ba148aeSSrinivas Pandruvada for (j = 0; j <= pkg_dev.levels; ++j) { 9401ba148aeSSrinivas Pandruvada ret = isst_get_ctdp_control(i, j, &ctdp_level); 9411ba148aeSSrinivas Pandruvada if (ret) 9421ba148aeSSrinivas Pandruvada continue; 9431ba148aeSSrinivas Pandruvada 9441ba148aeSSrinivas Pandruvada if (!fact_support && ctdp_level.fact_support) 9451ba148aeSSrinivas Pandruvada fact_support = 1; 9461ba148aeSSrinivas Pandruvada 9471ba148aeSSrinivas Pandruvada if (!pbf_support && ctdp_level.pbf_support) 9481ba148aeSSrinivas Pandruvada pbf_support = 1; 9491ba148aeSSrinivas Pandruvada } 9501ba148aeSSrinivas Pandruvada 9511ba148aeSSrinivas Pandruvada if (fact_support) 9521ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-TF (feature turbo-freq) is supported\n"); 9531ba148aeSSrinivas Pandruvada else 9541ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-TF (feature turbo-freq) is not supported\n"); 9551ba148aeSSrinivas Pandruvada 9561ba148aeSSrinivas Pandruvada if (pbf_support) 9571ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-BF (feature base-freq) is supported\n"); 9581ba148aeSSrinivas Pandruvada else 9591ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-BF (feature base-freq) is not supported\n"); 9601ba148aeSSrinivas Pandruvada 9611ba148aeSSrinivas Pandruvada ret = isst_read_pm_config(i, &cp_state, &cp_cap); 9621ba148aeSSrinivas Pandruvada if (cp_cap) 9631ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-CP (feature core-power) is supported\n"); 9641ba148aeSSrinivas Pandruvada else 9651ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-CP (feature core-power) is not supported\n"); 9661ba148aeSSrinivas Pandruvada } 9671ba148aeSSrinivas Pandruvada 9683fb4f7cdSSrinivas Pandruvada static void isst_print_platform_information(void) 9693fb4f7cdSSrinivas Pandruvada { 9703fb4f7cdSSrinivas Pandruvada struct isst_if_platform_info platform_info; 9713fb4f7cdSSrinivas Pandruvada const char *pathname = "/dev/isst_interface"; 9723fb4f7cdSSrinivas Pandruvada int fd; 9733fb4f7cdSSrinivas Pandruvada 9741ba148aeSSrinivas Pandruvada if (is_clx_n_platform()) { 9751ba148aeSSrinivas Pandruvada fprintf(stderr, "\nThis option in not supported on this platform\n"); 9761ba148aeSSrinivas Pandruvada exit(0); 9771ba148aeSSrinivas Pandruvada } 9781ba148aeSSrinivas Pandruvada 9793fb4f7cdSSrinivas Pandruvada fd = open(pathname, O_RDWR); 9803fb4f7cdSSrinivas Pandruvada if (fd < 0) 9813fb4f7cdSSrinivas Pandruvada err(-1, "%s open failed", pathname); 9823fb4f7cdSSrinivas Pandruvada 9833fb4f7cdSSrinivas Pandruvada if (ioctl(fd, ISST_IF_GET_PLATFORM_INFO, &platform_info) == -1) { 9843fb4f7cdSSrinivas Pandruvada perror("ISST_IF_GET_PLATFORM_INFO"); 9853fb4f7cdSSrinivas Pandruvada } else { 9863fb4f7cdSSrinivas Pandruvada fprintf(outf, "Platform: API version : %d\n", 9873fb4f7cdSSrinivas Pandruvada platform_info.api_version); 9883fb4f7cdSSrinivas Pandruvada fprintf(outf, "Platform: Driver version : %d\n", 9893fb4f7cdSSrinivas Pandruvada platform_info.driver_version); 9903fb4f7cdSSrinivas Pandruvada fprintf(outf, "Platform: mbox supported : %d\n", 9913fb4f7cdSSrinivas Pandruvada platform_info.mbox_supported); 9923fb4f7cdSSrinivas Pandruvada fprintf(outf, "Platform: mmio supported : %d\n", 9933fb4f7cdSSrinivas Pandruvada platform_info.mmio_supported); 9941ba148aeSSrinivas Pandruvada isst_print_extended_platform_info(); 9953fb4f7cdSSrinivas Pandruvada } 9963fb4f7cdSSrinivas Pandruvada 9973fb4f7cdSSrinivas Pandruvada close(fd); 9983fb4f7cdSSrinivas Pandruvada 9993fb4f7cdSSrinivas Pandruvada exit(0); 10003fb4f7cdSSrinivas Pandruvada } 10013fb4f7cdSSrinivas Pandruvada 10023d1a8579SSrinivas Pandruvada static char *local_str0, *local_str1; 10033fb4f7cdSSrinivas Pandruvada static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3, 10043fb4f7cdSSrinivas Pandruvada void *arg4) 10053fb4f7cdSSrinivas Pandruvada { 10063fb4f7cdSSrinivas Pandruvada int (*fn_ptr)(int cpu, void *arg); 10073fb4f7cdSSrinivas Pandruvada int ret; 10083fb4f7cdSSrinivas Pandruvada 10093fb4f7cdSSrinivas Pandruvada fn_ptr = arg1; 10103fb4f7cdSSrinivas Pandruvada ret = fn_ptr(cpu, arg2); 10113fb4f7cdSSrinivas Pandruvada if (ret) 10123d1a8579SSrinivas Pandruvada isst_display_error_info_message(1, "get_tdp_* failed", 0, 0); 10133fb4f7cdSSrinivas Pandruvada else 1014b3abfd77SSrinivas Pandruvada isst_ctdp_display_core_info(cpu, outf, arg3, 10153d1a8579SSrinivas Pandruvada *(unsigned int *)arg4, 10163d1a8579SSrinivas Pandruvada local_str0, local_str1); 10173fb4f7cdSSrinivas Pandruvada } 10183fb4f7cdSSrinivas Pandruvada 10193d1a8579SSrinivas Pandruvada #define _get_tdp_level(desc, suffix, object, help, str0, str1) \ 1020ce1326a2SPrarit Bhargava static void get_tdp_##object(int arg) \ 10213fb4f7cdSSrinivas Pandruvada { \ 10223fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp ctdp; \ 10233fb4f7cdSSrinivas Pandruvada \ 10243fb4f7cdSSrinivas Pandruvada if (cmd_help) { \ 10253fb4f7cdSSrinivas Pandruvada fprintf(stderr, \ 10263fb4f7cdSSrinivas Pandruvada "Print %s [No command arguments are required]\n", \ 10273fb4f7cdSSrinivas Pandruvada help); \ 10283fb4f7cdSSrinivas Pandruvada exit(0); \ 10293fb4f7cdSSrinivas Pandruvada } \ 10303d1a8579SSrinivas Pandruvada local_str0 = str0; \ 10313d1a8579SSrinivas Pandruvada local_str1 = str1; \ 10323fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); \ 10333fb4f7cdSSrinivas Pandruvada if (max_target_cpus) \ 10343fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set( \ 10353fb4f7cdSSrinivas Pandruvada exec_on_get_ctdp_cpu, isst_get_ctdp_##suffix, \ 10363fb4f7cdSSrinivas Pandruvada &ctdp, desc, &ctdp.object); \ 10373fb4f7cdSSrinivas Pandruvada else \ 10383fb4f7cdSSrinivas Pandruvada for_each_online_package_in_set(exec_on_get_ctdp_cpu, \ 10393fb4f7cdSSrinivas Pandruvada isst_get_ctdp_##suffix, \ 10403fb4f7cdSSrinivas Pandruvada &ctdp, desc, \ 10413fb4f7cdSSrinivas Pandruvada &ctdp.object); \ 10423fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); \ 10433fb4f7cdSSrinivas Pandruvada } 10443fb4f7cdSSrinivas Pandruvada 10453d1a8579SSrinivas Pandruvada _get_tdp_level("get-config-levels", levels, levels, "Max TDP level", NULL, NULL); 10463d1a8579SSrinivas Pandruvada _get_tdp_level("get-config-version", levels, version, "TDP version", NULL, NULL); 10473d1a8579SSrinivas Pandruvada _get_tdp_level("get-config-enabled", levels, enabled, "perf-profile enable status", "disabled", "enabled"); 10483fb4f7cdSSrinivas Pandruvada _get_tdp_level("get-config-current_level", levels, current_level, 10493d1a8579SSrinivas Pandruvada "Current TDP Level", NULL, NULL); 10503d1a8579SSrinivas Pandruvada _get_tdp_level("get-lock-status", levels, locked, "TDP lock status", "unlocked", "locked"); 10513fb4f7cdSSrinivas Pandruvada 1052062e4aacSPrarit Bhargava struct isst_pkg_ctdp clx_n_pkg_dev; 1053062e4aacSPrarit Bhargava 1054062e4aacSPrarit Bhargava static int clx_n_get_base_ratio(void) 1055062e4aacSPrarit Bhargava { 1056062e4aacSPrarit Bhargava FILE *fp; 1057062e4aacSPrarit Bhargava char *begin, *end, *line = NULL; 1058062e4aacSPrarit Bhargava char number[5]; 1059062e4aacSPrarit Bhargava float value = 0; 1060062e4aacSPrarit Bhargava size_t n = 0; 1061062e4aacSPrarit Bhargava 1062062e4aacSPrarit Bhargava fp = fopen("/proc/cpuinfo", "r"); 1063062e4aacSPrarit Bhargava if (!fp) 1064062e4aacSPrarit Bhargava err(-1, "cannot open /proc/cpuinfo\n"); 1065062e4aacSPrarit Bhargava 1066062e4aacSPrarit Bhargava while (getline(&line, &n, fp) > 0) { 1067062e4aacSPrarit Bhargava if (strstr(line, "model name")) { 1068062e4aacSPrarit Bhargava /* this is true for CascadeLake-N */ 1069062e4aacSPrarit Bhargava begin = strstr(line, "@ ") + 2; 1070062e4aacSPrarit Bhargava end = strstr(line, "GHz"); 1071062e4aacSPrarit Bhargava strncpy(number, begin, end - begin); 1072062e4aacSPrarit Bhargava value = atof(number) * 10; 1073062e4aacSPrarit Bhargava break; 1074062e4aacSPrarit Bhargava } 1075062e4aacSPrarit Bhargava } 1076062e4aacSPrarit Bhargava free(line); 1077062e4aacSPrarit Bhargava fclose(fp); 1078062e4aacSPrarit Bhargava 1079062e4aacSPrarit Bhargava return (int)(value); 1080062e4aacSPrarit Bhargava } 1081062e4aacSPrarit Bhargava 1082062e4aacSPrarit Bhargava static int clx_n_config(int cpu) 1083062e4aacSPrarit Bhargava { 1084062e4aacSPrarit Bhargava int i, ret, pkg_id, die_id; 1085062e4aacSPrarit Bhargava unsigned long cpu_bf; 1086062e4aacSPrarit Bhargava struct isst_pkg_ctdp_level_info *ctdp_level; 1087062e4aacSPrarit Bhargava struct isst_pbf_info *pbf_info; 1088062e4aacSPrarit Bhargava 1089062e4aacSPrarit Bhargava ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; 1090062e4aacSPrarit Bhargava pbf_info = &ctdp_level->pbf_info; 1091062e4aacSPrarit Bhargava ctdp_level->core_cpumask_size = 1092062e4aacSPrarit Bhargava alloc_cpu_set(&ctdp_level->core_cpumask); 1093062e4aacSPrarit Bhargava 1094062e4aacSPrarit Bhargava /* find the frequency base ratio */ 1095062e4aacSPrarit Bhargava ctdp_level->tdp_ratio = clx_n_get_base_ratio(); 1096062e4aacSPrarit Bhargava if (ctdp_level->tdp_ratio == 0) { 1097062e4aacSPrarit Bhargava debug_printf("CLX: cn base ratio is zero\n"); 1098062e4aacSPrarit Bhargava ret = -1; 1099062e4aacSPrarit Bhargava goto error_ret; 1100062e4aacSPrarit Bhargava } 1101062e4aacSPrarit Bhargava 1102062e4aacSPrarit Bhargava /* find the high and low priority frequencies */ 1103062e4aacSPrarit Bhargava pbf_info->p1_high = 0; 1104062e4aacSPrarit Bhargava pbf_info->p1_low = ~0; 1105062e4aacSPrarit Bhargava 1106062e4aacSPrarit Bhargava pkg_id = get_physical_package_id(cpu); 1107062e4aacSPrarit Bhargava die_id = get_physical_die_id(cpu); 1108062e4aacSPrarit Bhargava 1109062e4aacSPrarit Bhargava for (i = 0; i < topo_max_cpus; i++) { 1110062e4aacSPrarit Bhargava if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) 1111062e4aacSPrarit Bhargava continue; 1112062e4aacSPrarit Bhargava 1113062e4aacSPrarit Bhargava if (pkg_id != get_physical_package_id(i) || 1114062e4aacSPrarit Bhargava die_id != get_physical_die_id(i)) 1115062e4aacSPrarit Bhargava continue; 1116062e4aacSPrarit Bhargava 1117062e4aacSPrarit Bhargava CPU_SET_S(i, ctdp_level->core_cpumask_size, 1118062e4aacSPrarit Bhargava ctdp_level->core_cpumask); 1119062e4aacSPrarit Bhargava 1120062e4aacSPrarit Bhargava cpu_bf = parse_int_file(1, 1121062e4aacSPrarit Bhargava "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", 1122062e4aacSPrarit Bhargava i); 1123062e4aacSPrarit Bhargava if (cpu_bf > pbf_info->p1_high) 1124062e4aacSPrarit Bhargava pbf_info->p1_high = cpu_bf; 1125062e4aacSPrarit Bhargava if (cpu_bf < pbf_info->p1_low) 1126062e4aacSPrarit Bhargava pbf_info->p1_low = cpu_bf; 1127062e4aacSPrarit Bhargava } 1128062e4aacSPrarit Bhargava 1129062e4aacSPrarit Bhargava if (pbf_info->p1_high == ~0UL) { 1130062e4aacSPrarit Bhargava debug_printf("CLX: maximum base frequency not set\n"); 1131062e4aacSPrarit Bhargava ret = -1; 1132062e4aacSPrarit Bhargava goto error_ret; 1133062e4aacSPrarit Bhargava } 1134062e4aacSPrarit Bhargava 1135062e4aacSPrarit Bhargava if (pbf_info->p1_low == 0) { 1136062e4aacSPrarit Bhargava debug_printf("CLX: minimum base frequency not set\n"); 1137062e4aacSPrarit Bhargava ret = -1; 1138062e4aacSPrarit Bhargava goto error_ret; 1139062e4aacSPrarit Bhargava } 1140062e4aacSPrarit Bhargava 1141062e4aacSPrarit Bhargava /* convert frequencies back to ratios */ 114291d92814SSrinivas Pandruvada pbf_info->p1_high = pbf_info->p1_high / 100000; 114391d92814SSrinivas Pandruvada pbf_info->p1_low = pbf_info->p1_low / 100000; 1144062e4aacSPrarit Bhargava 1145062e4aacSPrarit Bhargava /* create high priority cpu mask */ 1146062e4aacSPrarit Bhargava pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask); 1147062e4aacSPrarit Bhargava for (i = 0; i < topo_max_cpus; i++) { 1148062e4aacSPrarit Bhargava if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) 1149062e4aacSPrarit Bhargava continue; 1150062e4aacSPrarit Bhargava 1151062e4aacSPrarit Bhargava if (pkg_id != get_physical_package_id(i) || 1152062e4aacSPrarit Bhargava die_id != get_physical_die_id(i)) 1153062e4aacSPrarit Bhargava continue; 1154062e4aacSPrarit Bhargava 1155062e4aacSPrarit Bhargava cpu_bf = parse_int_file(1, 1156062e4aacSPrarit Bhargava "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", 1157062e4aacSPrarit Bhargava i); 115891d92814SSrinivas Pandruvada cpu_bf = cpu_bf / 100000; 1159062e4aacSPrarit Bhargava if (cpu_bf == pbf_info->p1_high) 1160062e4aacSPrarit Bhargava CPU_SET_S(i, pbf_info->core_cpumask_size, 1161062e4aacSPrarit Bhargava pbf_info->core_cpumask); 1162062e4aacSPrarit Bhargava } 1163062e4aacSPrarit Bhargava 1164062e4aacSPrarit Bhargava /* extra ctdp & pbf struct parameters */ 1165062e4aacSPrarit Bhargava ctdp_level->processed = 1; 1166062e4aacSPrarit Bhargava ctdp_level->pbf_support = 1; /* PBF is always supported and enabled */ 1167062e4aacSPrarit Bhargava ctdp_level->pbf_enabled = 1; 1168062e4aacSPrarit Bhargava ctdp_level->fact_support = 0; /* FACT is never supported */ 1169062e4aacSPrarit Bhargava ctdp_level->fact_enabled = 0; 1170062e4aacSPrarit Bhargava 1171062e4aacSPrarit Bhargava return 0; 1172062e4aacSPrarit Bhargava 1173062e4aacSPrarit Bhargava error_ret: 1174062e4aacSPrarit Bhargava free_cpu_set(ctdp_level->core_cpumask); 1175062e4aacSPrarit Bhargava return ret; 1176062e4aacSPrarit Bhargava } 1177062e4aacSPrarit Bhargava 1178062e4aacSPrarit Bhargava static void dump_clx_n_config_for_cpu(int cpu, void *arg1, void *arg2, 1179062e4aacSPrarit Bhargava void *arg3, void *arg4) 1180062e4aacSPrarit Bhargava { 1181062e4aacSPrarit Bhargava int ret; 1182062e4aacSPrarit Bhargava 1183ac9d05eaSSrinivas Pandruvada if (tdp_level != 0xff && tdp_level != 0) { 1184ac9d05eaSSrinivas Pandruvada isst_display_error_info_message(1, "Invalid level", 1, tdp_level); 1185ac9d05eaSSrinivas Pandruvada exit(0); 1186ac9d05eaSSrinivas Pandruvada } 1187ac9d05eaSSrinivas Pandruvada 1188062e4aacSPrarit Bhargava ret = clx_n_config(cpu); 1189062e4aacSPrarit Bhargava if (ret) { 11907fc9fefdSSrinivas Pandruvada debug_printf("clx_n_config failed"); 1191062e4aacSPrarit Bhargava } else { 1192062e4aacSPrarit Bhargava struct isst_pkg_ctdp_level_info *ctdp_level; 1193062e4aacSPrarit Bhargava struct isst_pbf_info *pbf_info; 1194062e4aacSPrarit Bhargava 1195062e4aacSPrarit Bhargava ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; 1196062e4aacSPrarit Bhargava pbf_info = &ctdp_level->pbf_info; 119728c59ae6SPrarit Bhargava clx_n_pkg_dev.processed = 1; 1198062e4aacSPrarit Bhargava isst_ctdp_display_information(cpu, outf, tdp_level, &clx_n_pkg_dev); 1199062e4aacSPrarit Bhargava free_cpu_set(ctdp_level->core_cpumask); 1200062e4aacSPrarit Bhargava free_cpu_set(pbf_info->core_cpumask); 1201062e4aacSPrarit Bhargava } 1202062e4aacSPrarit Bhargava } 1203062e4aacSPrarit Bhargava 12043fb4f7cdSSrinivas Pandruvada static void dump_isst_config_for_cpu(int cpu, void *arg1, void *arg2, 12053fb4f7cdSSrinivas Pandruvada void *arg3, void *arg4) 12063fb4f7cdSSrinivas Pandruvada { 12073fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev; 12083fb4f7cdSSrinivas Pandruvada int ret; 12093fb4f7cdSSrinivas Pandruvada 12103fb4f7cdSSrinivas Pandruvada memset(&pkg_dev, 0, sizeof(pkg_dev)); 12113fb4f7cdSSrinivas Pandruvada ret = isst_get_process_ctdp(cpu, tdp_level, &pkg_dev); 12123fb4f7cdSSrinivas Pandruvada if (ret) { 1213ac9d05eaSSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get perf-profile info on cpu", 1, cpu); 1214ac9d05eaSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 1215ac9d05eaSSrinivas Pandruvada exit(1); 12163fb4f7cdSSrinivas Pandruvada } else { 12173fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information(cpu, outf, tdp_level, &pkg_dev); 12183fb4f7cdSSrinivas Pandruvada isst_get_process_ctdp_complete(cpu, &pkg_dev); 12193fb4f7cdSSrinivas Pandruvada } 12203fb4f7cdSSrinivas Pandruvada } 12213fb4f7cdSSrinivas Pandruvada 1222ce1326a2SPrarit Bhargava static void dump_isst_config(int arg) 12233fb4f7cdSSrinivas Pandruvada { 1224062e4aacSPrarit Bhargava void *fn; 1225062e4aacSPrarit Bhargava 12263fb4f7cdSSrinivas Pandruvada if (cmd_help) { 12273fb4f7cdSSrinivas Pandruvada fprintf(stderr, 12283fb4f7cdSSrinivas Pandruvada "Print Intel(R) Speed Select Technology Performance profile configuration\n"); 12293fb4f7cdSSrinivas Pandruvada fprintf(stderr, 12303fb4f7cdSSrinivas Pandruvada "including base frequency and turbo frequency configurations\n"); 12313fb4f7cdSSrinivas Pandruvada fprintf(stderr, "Optional: -l|--level : Specify tdp level\n"); 12323fb4f7cdSSrinivas Pandruvada fprintf(stderr, 12333fb4f7cdSSrinivas Pandruvada "\tIf no arguments, dump information for all TDP levels\n"); 12343fb4f7cdSSrinivas Pandruvada exit(0); 12353fb4f7cdSSrinivas Pandruvada } 12363fb4f7cdSSrinivas Pandruvada 1237062e4aacSPrarit Bhargava if (!is_clx_n_platform()) 1238062e4aacSPrarit Bhargava fn = dump_isst_config_for_cpu; 1239062e4aacSPrarit Bhargava else 1240062e4aacSPrarit Bhargava fn = dump_clx_n_config_for_cpu; 1241062e4aacSPrarit Bhargava 12423fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 12433fb4f7cdSSrinivas Pandruvada 12443fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 1245062e4aacSPrarit Bhargava for_each_online_target_cpu_in_set(fn, NULL, NULL, NULL, NULL); 12463fb4f7cdSSrinivas Pandruvada else 1247062e4aacSPrarit Bhargava for_each_online_package_in_set(fn, NULL, NULL, NULL, NULL); 12483fb4f7cdSSrinivas Pandruvada 12493fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 12503fb4f7cdSSrinivas Pandruvada } 12513fb4f7cdSSrinivas Pandruvada 1252f981dc17SSrinivas Pandruvada static void adjust_scaling_max_from_base_freq(int cpu); 1253f981dc17SSrinivas Pandruvada 12543fb4f7cdSSrinivas Pandruvada static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, 12553fb4f7cdSSrinivas Pandruvada void *arg4) 12563fb4f7cdSSrinivas Pandruvada { 12573fb4f7cdSSrinivas Pandruvada int ret; 12583fb4f7cdSSrinivas Pandruvada 12593fb4f7cdSSrinivas Pandruvada ret = isst_set_tdp_level(cpu, tdp_level); 1260ac9d05eaSSrinivas Pandruvada if (ret) { 1261ac9d05eaSSrinivas Pandruvada isst_display_error_info_message(1, "Set TDP level failed", 0, 0); 1262ac9d05eaSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 1263ac9d05eaSSrinivas Pandruvada exit(1); 1264ac9d05eaSSrinivas Pandruvada } else { 12653fb4f7cdSSrinivas Pandruvada isst_display_result(cpu, outf, "perf-profile", "set_tdp_level", 12663fb4f7cdSSrinivas Pandruvada ret); 12673c64c81aSSrinivas Pandruvada if (force_online_offline) { 12683c64c81aSSrinivas Pandruvada struct isst_pkg_ctdp_level_info ctdp_level; 12693c64c81aSSrinivas Pandruvada int pkg_id = get_physical_package_id(cpu); 12703c64c81aSSrinivas Pandruvada int die_id = get_physical_die_id(cpu); 12713c64c81aSSrinivas Pandruvada 1272f981dc17SSrinivas Pandruvada /* Wait for updated base frequencies */ 1273f981dc17SSrinivas Pandruvada usleep(2000); 1274f981dc17SSrinivas Pandruvada 12753c64c81aSSrinivas Pandruvada fprintf(stderr, "Option is set to online/offline\n"); 12763c64c81aSSrinivas Pandruvada ctdp_level.core_cpumask_size = 12773c64c81aSSrinivas Pandruvada alloc_cpu_set(&ctdp_level.core_cpumask); 12786374de84SSrinivas Pandruvada ret = isst_get_coremask_info(cpu, tdp_level, &ctdp_level); 12796374de84SSrinivas Pandruvada if (ret) { 12806374de84SSrinivas Pandruvada isst_display_error_info_message(1, "Can't get coremask, online/offline option is ignored", 0, 0); 12816374de84SSrinivas Pandruvada return; 12826374de84SSrinivas Pandruvada } 12833c64c81aSSrinivas Pandruvada if (ctdp_level.cpu_count) { 12843c64c81aSSrinivas Pandruvada int i, max_cpus = get_topo_max_cpus(); 12853c64c81aSSrinivas Pandruvada for (i = 0; i < max_cpus; ++i) { 12863c64c81aSSrinivas Pandruvada if (pkg_id != get_physical_package_id(i) || die_id != get_physical_die_id(i)) 12873c64c81aSSrinivas Pandruvada continue; 12883c64c81aSSrinivas Pandruvada if (CPU_ISSET_S(i, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask)) { 12893c64c81aSSrinivas Pandruvada fprintf(stderr, "online cpu %d\n", i); 12903c64c81aSSrinivas Pandruvada set_cpu_online_offline(i, 1); 1291f981dc17SSrinivas Pandruvada adjust_scaling_max_from_base_freq(i); 12923c64c81aSSrinivas Pandruvada } else { 12933c64c81aSSrinivas Pandruvada fprintf(stderr, "offline cpu %d\n", i); 12943c64c81aSSrinivas Pandruvada set_cpu_online_offline(i, 0); 12953c64c81aSSrinivas Pandruvada } 12963c64c81aSSrinivas Pandruvada } 12973c64c81aSSrinivas Pandruvada } 12983c64c81aSSrinivas Pandruvada } 12993c64c81aSSrinivas Pandruvada } 13003fb4f7cdSSrinivas Pandruvada } 13013fb4f7cdSSrinivas Pandruvada 1302ce1326a2SPrarit Bhargava static void set_tdp_level(int arg) 13033fb4f7cdSSrinivas Pandruvada { 13043fb4f7cdSSrinivas Pandruvada if (cmd_help) { 13053fb4f7cdSSrinivas Pandruvada fprintf(stderr, "Set Config TDP level\n"); 13063fb4f7cdSSrinivas Pandruvada fprintf(stderr, 13073fb4f7cdSSrinivas Pandruvada "\t Arguments: -l|--level : Specify tdp level\n"); 13083c64c81aSSrinivas Pandruvada fprintf(stderr, 13093c64c81aSSrinivas Pandruvada "\t Optional Arguments: -o | online : online/offline for the tdp level\n"); 1310ac9d05eaSSrinivas Pandruvada fprintf(stderr, 1311ac9d05eaSSrinivas Pandruvada "\t online/offline operation has limitations, refer to Linux hotplug documentation\n"); 13123fb4f7cdSSrinivas Pandruvada exit(0); 13133fb4f7cdSSrinivas Pandruvada } 13143fb4f7cdSSrinivas Pandruvada 13153fb4f7cdSSrinivas Pandruvada if (tdp_level == 0xff) { 1316ac9d05eaSSrinivas Pandruvada isst_display_error_info_message(1, "Invalid command: specify tdp_level", 0, 0); 13173fb4f7cdSSrinivas Pandruvada exit(1); 13183fb4f7cdSSrinivas Pandruvada } 13193fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 13203fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 13213fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(set_tdp_level_for_cpu, NULL, 13223fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 13233fb4f7cdSSrinivas Pandruvada else 13243fb4f7cdSSrinivas Pandruvada for_each_online_package_in_set(set_tdp_level_for_cpu, NULL, 13253fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 13263fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 13273fb4f7cdSSrinivas Pandruvada } 13283fb4f7cdSSrinivas Pandruvada 13291aa7177cSPrarit Bhargava static void clx_n_dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, 13301aa7177cSPrarit Bhargava void *arg3, void *arg4) 13311aa7177cSPrarit Bhargava { 13321aa7177cSPrarit Bhargava int ret; 13331aa7177cSPrarit Bhargava 13341aa7177cSPrarit Bhargava ret = clx_n_config(cpu); 13351aa7177cSPrarit Bhargava if (ret) { 133639bae0fcSSrinivas Pandruvada isst_display_error_info_message(1, "clx_n_config failed", 0, 0); 13371aa7177cSPrarit Bhargava } else { 13381aa7177cSPrarit Bhargava struct isst_pkg_ctdp_level_info *ctdp_level; 13391aa7177cSPrarit Bhargava struct isst_pbf_info *pbf_info; 13401aa7177cSPrarit Bhargava 13411aa7177cSPrarit Bhargava ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; 13421aa7177cSPrarit Bhargava pbf_info = &ctdp_level->pbf_info; 13431aa7177cSPrarit Bhargava isst_pbf_display_information(cpu, outf, tdp_level, pbf_info); 13441aa7177cSPrarit Bhargava free_cpu_set(ctdp_level->core_cpumask); 13451aa7177cSPrarit Bhargava free_cpu_set(pbf_info->core_cpumask); 13461aa7177cSPrarit Bhargava } 13471aa7177cSPrarit Bhargava } 13481aa7177cSPrarit Bhargava 13493fb4f7cdSSrinivas Pandruvada static void dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, 13503fb4f7cdSSrinivas Pandruvada void *arg4) 13513fb4f7cdSSrinivas Pandruvada { 13523fb4f7cdSSrinivas Pandruvada struct isst_pbf_info pbf_info; 13533fb4f7cdSSrinivas Pandruvada int ret; 13543fb4f7cdSSrinivas Pandruvada 13553fb4f7cdSSrinivas Pandruvada ret = isst_get_pbf_info(cpu, tdp_level, &pbf_info); 13563fb4f7cdSSrinivas Pandruvada if (ret) { 135739bae0fcSSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get base-freq info at this level", 1, tdp_level); 135839bae0fcSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 135939bae0fcSSrinivas Pandruvada exit(1); 13603fb4f7cdSSrinivas Pandruvada } else { 13613fb4f7cdSSrinivas Pandruvada isst_pbf_display_information(cpu, outf, tdp_level, &pbf_info); 13623fb4f7cdSSrinivas Pandruvada isst_get_pbf_info_complete(&pbf_info); 13633fb4f7cdSSrinivas Pandruvada } 13643fb4f7cdSSrinivas Pandruvada } 13653fb4f7cdSSrinivas Pandruvada 1366ce1326a2SPrarit Bhargava static void dump_pbf_config(int arg) 13673fb4f7cdSSrinivas Pandruvada { 13681aa7177cSPrarit Bhargava void *fn; 13691aa7177cSPrarit Bhargava 13703fb4f7cdSSrinivas Pandruvada if (cmd_help) { 13713fb4f7cdSSrinivas Pandruvada fprintf(stderr, 13723fb4f7cdSSrinivas Pandruvada "Print Intel(R) Speed Select Technology base frequency configuration for a TDP level\n"); 13733fb4f7cdSSrinivas Pandruvada fprintf(stderr, 13743fb4f7cdSSrinivas Pandruvada "\tArguments: -l|--level : Specify tdp level\n"); 13753fb4f7cdSSrinivas Pandruvada exit(0); 13763fb4f7cdSSrinivas Pandruvada } 13773fb4f7cdSSrinivas Pandruvada 13783fb4f7cdSSrinivas Pandruvada if (tdp_level == 0xff) { 137939bae0fcSSrinivas Pandruvada isst_display_error_info_message(1, "Invalid command: specify tdp_level", 0, 0); 13803fb4f7cdSSrinivas Pandruvada exit(1); 13813fb4f7cdSSrinivas Pandruvada } 13823fb4f7cdSSrinivas Pandruvada 13831aa7177cSPrarit Bhargava if (!is_clx_n_platform()) 13841aa7177cSPrarit Bhargava fn = dump_pbf_config_for_cpu; 13853fb4f7cdSSrinivas Pandruvada else 13861aa7177cSPrarit Bhargava fn = clx_n_dump_pbf_config_for_cpu; 13871aa7177cSPrarit Bhargava 13881aa7177cSPrarit Bhargava isst_ctdp_display_information_start(outf); 13891aa7177cSPrarit Bhargava 13901aa7177cSPrarit Bhargava if (max_target_cpus) 13911aa7177cSPrarit Bhargava for_each_online_target_cpu_in_set(fn, NULL, NULL, NULL, NULL); 13921aa7177cSPrarit Bhargava else 13931aa7177cSPrarit Bhargava for_each_online_package_in_set(fn, NULL, NULL, NULL, NULL); 13941aa7177cSPrarit Bhargava 13953fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 13963fb4f7cdSSrinivas Pandruvada } 13973fb4f7cdSSrinivas Pandruvada 1398354bd06fSSrinivas Pandruvada static int set_clos_param(int cpu, int clos, int epp, int wt, int min, int max) 1399354bd06fSSrinivas Pandruvada { 1400354bd06fSSrinivas Pandruvada struct isst_clos_config clos_config; 1401354bd06fSSrinivas Pandruvada int ret; 1402354bd06fSSrinivas Pandruvada 1403354bd06fSSrinivas Pandruvada ret = isst_pm_get_clos(cpu, clos, &clos_config); 1404354bd06fSSrinivas Pandruvada if (ret) { 1405fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_pm_get_clos failed", 0, 0); 1406354bd06fSSrinivas Pandruvada return ret; 1407354bd06fSSrinivas Pandruvada } 1408354bd06fSSrinivas Pandruvada clos_config.clos_min = min; 1409354bd06fSSrinivas Pandruvada clos_config.clos_max = max; 1410354bd06fSSrinivas Pandruvada clos_config.epp = epp; 1411354bd06fSSrinivas Pandruvada clos_config.clos_prop_prio = wt; 1412354bd06fSSrinivas Pandruvada ret = isst_set_clos(cpu, clos, &clos_config); 1413354bd06fSSrinivas Pandruvada if (ret) { 1414fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_set_clos failed", 0, 0); 1415354bd06fSSrinivas Pandruvada return ret; 1416354bd06fSSrinivas Pandruvada } 1417354bd06fSSrinivas Pandruvada 1418354bd06fSSrinivas Pandruvada return 0; 1419354bd06fSSrinivas Pandruvada } 1420354bd06fSSrinivas Pandruvada 1421a9b2f8e2SSrinivas Pandruvada static int set_cpufreq_scaling_min_max(int cpu, int max, int freq) 1422a9b2f8e2SSrinivas Pandruvada { 1423a9b2f8e2SSrinivas Pandruvada char buffer[128], freq_str[16]; 1424a9b2f8e2SSrinivas Pandruvada int fd, ret, len; 1425a9b2f8e2SSrinivas Pandruvada 1426a9b2f8e2SSrinivas Pandruvada if (max) 1427a9b2f8e2SSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1428a9b2f8e2SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); 1429a9b2f8e2SSrinivas Pandruvada else 1430a9b2f8e2SSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1431a9b2f8e2SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); 1432a9b2f8e2SSrinivas Pandruvada 1433a9b2f8e2SSrinivas Pandruvada fd = open(buffer, O_WRONLY); 1434a9b2f8e2SSrinivas Pandruvada if (fd < 0) 1435a9b2f8e2SSrinivas Pandruvada return fd; 1436a9b2f8e2SSrinivas Pandruvada 1437a9b2f8e2SSrinivas Pandruvada snprintf(freq_str, sizeof(freq_str), "%d", freq); 1438a9b2f8e2SSrinivas Pandruvada len = strlen(freq_str); 1439a9b2f8e2SSrinivas Pandruvada ret = write(fd, freq_str, len); 1440a9b2f8e2SSrinivas Pandruvada if (ret == -1) { 1441a9b2f8e2SSrinivas Pandruvada close(fd); 1442a9b2f8e2SSrinivas Pandruvada return ret; 1443a9b2f8e2SSrinivas Pandruvada } 1444a9b2f8e2SSrinivas Pandruvada close(fd); 1445a9b2f8e2SSrinivas Pandruvada 1446a9b2f8e2SSrinivas Pandruvada return 0; 1447a9b2f8e2SSrinivas Pandruvada } 1448a9b2f8e2SSrinivas Pandruvada 1449f981dc17SSrinivas Pandruvada static int no_turbo(void) 1450f981dc17SSrinivas Pandruvada { 1451f981dc17SSrinivas Pandruvada return parse_int_file(0, "/sys/devices/system/cpu/intel_pstate/no_turbo"); 1452f981dc17SSrinivas Pandruvada } 1453f981dc17SSrinivas Pandruvada 1454f981dc17SSrinivas Pandruvada static void adjust_scaling_max_from_base_freq(int cpu) 1455f981dc17SSrinivas Pandruvada { 1456f981dc17SSrinivas Pandruvada int base_freq, scaling_max_freq; 1457f981dc17SSrinivas Pandruvada 1458f981dc17SSrinivas Pandruvada scaling_max_freq = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); 1459f981dc17SSrinivas Pandruvada base_freq = get_cpufreq_base_freq(cpu); 1460f981dc17SSrinivas Pandruvada if (scaling_max_freq < base_freq || no_turbo()) 1461f981dc17SSrinivas Pandruvada set_cpufreq_scaling_min_max(cpu, 1, base_freq); 1462f981dc17SSrinivas Pandruvada } 1463f981dc17SSrinivas Pandruvada 1464bbaa2e95SSrinivas Pandruvada static void adjust_scaling_min_from_base_freq(int cpu) 1465bbaa2e95SSrinivas Pandruvada { 1466bbaa2e95SSrinivas Pandruvada int base_freq, scaling_min_freq; 1467bbaa2e95SSrinivas Pandruvada 1468bbaa2e95SSrinivas Pandruvada scaling_min_freq = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); 1469bbaa2e95SSrinivas Pandruvada base_freq = get_cpufreq_base_freq(cpu); 1470bbaa2e95SSrinivas Pandruvada if (scaling_min_freq < base_freq) 1471bbaa2e95SSrinivas Pandruvada set_cpufreq_scaling_min_max(cpu, 0, base_freq); 1472bbaa2e95SSrinivas Pandruvada } 1473bbaa2e95SSrinivas Pandruvada 1474a9b2f8e2SSrinivas Pandruvada static int set_clx_pbf_cpufreq_scaling_min_max(int cpu) 1475a9b2f8e2SSrinivas Pandruvada { 1476a9b2f8e2SSrinivas Pandruvada struct isst_pkg_ctdp_level_info *ctdp_level; 1477a9b2f8e2SSrinivas Pandruvada struct isst_pbf_info *pbf_info; 1478a9b2f8e2SSrinivas Pandruvada int i, pkg_id, die_id, freq, freq_high, freq_low; 1479a9b2f8e2SSrinivas Pandruvada int ret; 1480a9b2f8e2SSrinivas Pandruvada 1481a9b2f8e2SSrinivas Pandruvada ret = clx_n_config(cpu); 1482a9b2f8e2SSrinivas Pandruvada if (ret) { 14837fc9fefdSSrinivas Pandruvada debug_printf("cpufreq_scaling_min_max failed for CLX"); 1484a9b2f8e2SSrinivas Pandruvada return ret; 1485a9b2f8e2SSrinivas Pandruvada } 1486a9b2f8e2SSrinivas Pandruvada 1487a9b2f8e2SSrinivas Pandruvada ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; 1488a9b2f8e2SSrinivas Pandruvada pbf_info = &ctdp_level->pbf_info; 1489a9b2f8e2SSrinivas Pandruvada freq_high = pbf_info->p1_high * 100000; 1490a9b2f8e2SSrinivas Pandruvada freq_low = pbf_info->p1_low * 100000; 1491a9b2f8e2SSrinivas Pandruvada 1492a9b2f8e2SSrinivas Pandruvada pkg_id = get_physical_package_id(cpu); 1493a9b2f8e2SSrinivas Pandruvada die_id = get_physical_die_id(cpu); 1494a9b2f8e2SSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 1495a9b2f8e2SSrinivas Pandruvada if (pkg_id != get_physical_package_id(i) || 1496a9b2f8e2SSrinivas Pandruvada die_id != get_physical_die_id(i)) 1497a9b2f8e2SSrinivas Pandruvada continue; 1498a9b2f8e2SSrinivas Pandruvada 1499a9b2f8e2SSrinivas Pandruvada if (CPU_ISSET_S(i, pbf_info->core_cpumask_size, 1500a9b2f8e2SSrinivas Pandruvada pbf_info->core_cpumask)) 1501a9b2f8e2SSrinivas Pandruvada freq = freq_high; 1502a9b2f8e2SSrinivas Pandruvada else 1503a9b2f8e2SSrinivas Pandruvada freq = freq_low; 1504a9b2f8e2SSrinivas Pandruvada 1505a9b2f8e2SSrinivas Pandruvada set_cpufreq_scaling_min_max(i, 1, freq); 1506a9b2f8e2SSrinivas Pandruvada set_cpufreq_scaling_min_max(i, 0, freq); 1507a9b2f8e2SSrinivas Pandruvada } 1508a9b2f8e2SSrinivas Pandruvada 1509a9b2f8e2SSrinivas Pandruvada return 0; 1510a9b2f8e2SSrinivas Pandruvada } 1511a9b2f8e2SSrinivas Pandruvada 1512a9b2f8e2SSrinivas Pandruvada static int set_cpufreq_scaling_min_max_from_cpuinfo(int cpu, int cpuinfo_max, int scaling_max) 1513354bd06fSSrinivas Pandruvada { 1514354bd06fSSrinivas Pandruvada char buffer[128], min_freq[16]; 1515354bd06fSSrinivas Pandruvada int fd, ret, len; 1516354bd06fSSrinivas Pandruvada 1517354bd06fSSrinivas Pandruvada if (!CPU_ISSET_S(cpu, present_cpumask_size, present_cpumask)) 1518354bd06fSSrinivas Pandruvada return -1; 1519354bd06fSSrinivas Pandruvada 1520a9b2f8e2SSrinivas Pandruvada if (cpuinfo_max) 1521354bd06fSSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1522354bd06fSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", cpu); 1523354bd06fSSrinivas Pandruvada else 1524354bd06fSSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1525354bd06fSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_min_freq", cpu); 1526354bd06fSSrinivas Pandruvada 1527354bd06fSSrinivas Pandruvada fd = open(buffer, O_RDONLY); 1528354bd06fSSrinivas Pandruvada if (fd < 0) 1529354bd06fSSrinivas Pandruvada return fd; 1530354bd06fSSrinivas Pandruvada 1531354bd06fSSrinivas Pandruvada len = read(fd, min_freq, sizeof(min_freq)); 1532354bd06fSSrinivas Pandruvada close(fd); 1533354bd06fSSrinivas Pandruvada 1534354bd06fSSrinivas Pandruvada if (len < 0) 1535354bd06fSSrinivas Pandruvada return len; 1536354bd06fSSrinivas Pandruvada 1537a9b2f8e2SSrinivas Pandruvada if (scaling_max) 1538a9b2f8e2SSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1539a9b2f8e2SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); 1540a9b2f8e2SSrinivas Pandruvada else 1541354bd06fSSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1542354bd06fSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); 1543354bd06fSSrinivas Pandruvada 1544354bd06fSSrinivas Pandruvada fd = open(buffer, O_WRONLY); 1545354bd06fSSrinivas Pandruvada if (fd < 0) 1546354bd06fSSrinivas Pandruvada return fd; 1547354bd06fSSrinivas Pandruvada 1548354bd06fSSrinivas Pandruvada len = strlen(min_freq); 1549354bd06fSSrinivas Pandruvada ret = write(fd, min_freq, len); 1550354bd06fSSrinivas Pandruvada if (ret == -1) { 1551354bd06fSSrinivas Pandruvada close(fd); 1552354bd06fSSrinivas Pandruvada return ret; 1553354bd06fSSrinivas Pandruvada } 1554354bd06fSSrinivas Pandruvada close(fd); 1555354bd06fSSrinivas Pandruvada 1556354bd06fSSrinivas Pandruvada return 0; 1557354bd06fSSrinivas Pandruvada } 1558354bd06fSSrinivas Pandruvada 1559354bd06fSSrinivas Pandruvada static void set_scaling_min_to_cpuinfo_max(int cpu) 1560354bd06fSSrinivas Pandruvada { 1561354bd06fSSrinivas Pandruvada int i, pkg_id, die_id; 1562354bd06fSSrinivas Pandruvada 1563354bd06fSSrinivas Pandruvada pkg_id = get_physical_package_id(cpu); 1564354bd06fSSrinivas Pandruvada die_id = get_physical_die_id(cpu); 1565354bd06fSSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 1566354bd06fSSrinivas Pandruvada if (pkg_id != get_physical_package_id(i) || 1567354bd06fSSrinivas Pandruvada die_id != get_physical_die_id(i)) 1568354bd06fSSrinivas Pandruvada continue; 1569354bd06fSSrinivas Pandruvada 1570a9b2f8e2SSrinivas Pandruvada set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 0); 1571bbaa2e95SSrinivas Pandruvada adjust_scaling_min_from_base_freq(i); 1572354bd06fSSrinivas Pandruvada } 1573354bd06fSSrinivas Pandruvada } 1574354bd06fSSrinivas Pandruvada 1575354bd06fSSrinivas Pandruvada static void set_scaling_min_to_cpuinfo_min(int cpu) 1576354bd06fSSrinivas Pandruvada { 1577354bd06fSSrinivas Pandruvada int i, pkg_id, die_id; 1578354bd06fSSrinivas Pandruvada 1579354bd06fSSrinivas Pandruvada pkg_id = get_physical_package_id(cpu); 1580354bd06fSSrinivas Pandruvada die_id = get_physical_die_id(cpu); 1581354bd06fSSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 1582354bd06fSSrinivas Pandruvada if (pkg_id != get_physical_package_id(i) || 1583354bd06fSSrinivas Pandruvada die_id != get_physical_die_id(i)) 1584354bd06fSSrinivas Pandruvada continue; 1585354bd06fSSrinivas Pandruvada 1586a9b2f8e2SSrinivas Pandruvada set_cpufreq_scaling_min_max_from_cpuinfo(i, 0, 0); 1587a9b2f8e2SSrinivas Pandruvada } 1588a9b2f8e2SSrinivas Pandruvada } 1589a9b2f8e2SSrinivas Pandruvada 1590a9b2f8e2SSrinivas Pandruvada static void set_scaling_max_to_cpuinfo_max(int cpu) 1591a9b2f8e2SSrinivas Pandruvada { 1592a9b2f8e2SSrinivas Pandruvada int i, pkg_id, die_id; 1593a9b2f8e2SSrinivas Pandruvada 1594a9b2f8e2SSrinivas Pandruvada pkg_id = get_physical_package_id(cpu); 1595a9b2f8e2SSrinivas Pandruvada die_id = get_physical_die_id(cpu); 1596a9b2f8e2SSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 1597a9b2f8e2SSrinivas Pandruvada if (pkg_id != get_physical_package_id(i) || 1598a9b2f8e2SSrinivas Pandruvada die_id != get_physical_die_id(i)) 1599a9b2f8e2SSrinivas Pandruvada continue; 1600a9b2f8e2SSrinivas Pandruvada 1601a9b2f8e2SSrinivas Pandruvada set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 1); 1602354bd06fSSrinivas Pandruvada } 1603354bd06fSSrinivas Pandruvada } 1604354bd06fSSrinivas Pandruvada 1605354bd06fSSrinivas Pandruvada static int set_core_priority_and_min(int cpu, int mask_size, 1606354bd06fSSrinivas Pandruvada cpu_set_t *cpu_mask, int min_high, 1607354bd06fSSrinivas Pandruvada int min_low) 1608354bd06fSSrinivas Pandruvada { 1609354bd06fSSrinivas Pandruvada int pkg_id, die_id, ret, i; 1610354bd06fSSrinivas Pandruvada 1611354bd06fSSrinivas Pandruvada if (!CPU_COUNT_S(mask_size, cpu_mask)) 1612354bd06fSSrinivas Pandruvada return -1; 1613354bd06fSSrinivas Pandruvada 1614354bd06fSSrinivas Pandruvada ret = set_clos_param(cpu, 0, 0, 0, min_high, 0xff); 1615354bd06fSSrinivas Pandruvada if (ret) 1616354bd06fSSrinivas Pandruvada return ret; 1617354bd06fSSrinivas Pandruvada 161821c3390dSSrinivas Pandruvada ret = set_clos_param(cpu, 1, 15, 15, min_low, 0xff); 1619354bd06fSSrinivas Pandruvada if (ret) 1620354bd06fSSrinivas Pandruvada return ret; 1621354bd06fSSrinivas Pandruvada 162221c3390dSSrinivas Pandruvada ret = set_clos_param(cpu, 2, 15, 15, min_low, 0xff); 1623354bd06fSSrinivas Pandruvada if (ret) 1624354bd06fSSrinivas Pandruvada return ret; 1625354bd06fSSrinivas Pandruvada 162621c3390dSSrinivas Pandruvada ret = set_clos_param(cpu, 3, 15, 15, min_low, 0xff); 1627354bd06fSSrinivas Pandruvada if (ret) 1628354bd06fSSrinivas Pandruvada return ret; 1629354bd06fSSrinivas Pandruvada 1630354bd06fSSrinivas Pandruvada pkg_id = get_physical_package_id(cpu); 1631354bd06fSSrinivas Pandruvada die_id = get_physical_die_id(cpu); 1632354bd06fSSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 1633354bd06fSSrinivas Pandruvada int clos; 1634354bd06fSSrinivas Pandruvada 1635354bd06fSSrinivas Pandruvada if (pkg_id != get_physical_package_id(i) || 1636354bd06fSSrinivas Pandruvada die_id != get_physical_die_id(i)) 1637354bd06fSSrinivas Pandruvada continue; 1638354bd06fSSrinivas Pandruvada 1639354bd06fSSrinivas Pandruvada if (CPU_ISSET_S(i, mask_size, cpu_mask)) 1640354bd06fSSrinivas Pandruvada clos = 0; 1641354bd06fSSrinivas Pandruvada else 1642354bd06fSSrinivas Pandruvada clos = 3; 1643354bd06fSSrinivas Pandruvada 1644354bd06fSSrinivas Pandruvada debug_printf("Associate cpu: %d clos: %d\n", i, clos); 1645354bd06fSSrinivas Pandruvada ret = isst_clos_associate(i, clos); 1646354bd06fSSrinivas Pandruvada if (ret) { 1647fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_clos_associate failed", 0, 0); 1648354bd06fSSrinivas Pandruvada return ret; 1649354bd06fSSrinivas Pandruvada } 1650354bd06fSSrinivas Pandruvada } 1651354bd06fSSrinivas Pandruvada 1652354bd06fSSrinivas Pandruvada return 0; 1653354bd06fSSrinivas Pandruvada } 1654354bd06fSSrinivas Pandruvada 1655354bd06fSSrinivas Pandruvada static int set_pbf_core_power(int cpu) 1656354bd06fSSrinivas Pandruvada { 1657354bd06fSSrinivas Pandruvada struct isst_pbf_info pbf_info; 1658354bd06fSSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev; 1659354bd06fSSrinivas Pandruvada int ret; 1660354bd06fSSrinivas Pandruvada 1661354bd06fSSrinivas Pandruvada ret = isst_get_ctdp_levels(cpu, &pkg_dev); 1662354bd06fSSrinivas Pandruvada if (ret) { 1663fe6fb216SSrinivas Pandruvada debug_printf("isst_get_ctdp_levels failed"); 1664354bd06fSSrinivas Pandruvada return ret; 1665354bd06fSSrinivas Pandruvada } 1666354bd06fSSrinivas Pandruvada debug_printf("Current_level: %d\n", pkg_dev.current_level); 1667354bd06fSSrinivas Pandruvada 1668354bd06fSSrinivas Pandruvada ret = isst_get_pbf_info(cpu, pkg_dev.current_level, &pbf_info); 1669354bd06fSSrinivas Pandruvada if (ret) { 1670fe6fb216SSrinivas Pandruvada debug_printf("isst_get_pbf_info failed"); 1671354bd06fSSrinivas Pandruvada return ret; 1672354bd06fSSrinivas Pandruvada } 1673354bd06fSSrinivas Pandruvada debug_printf("p1_high: %d p1_low: %d\n", pbf_info.p1_high, 1674354bd06fSSrinivas Pandruvada pbf_info.p1_low); 1675354bd06fSSrinivas Pandruvada 1676354bd06fSSrinivas Pandruvada ret = set_core_priority_and_min(cpu, pbf_info.core_cpumask_size, 1677354bd06fSSrinivas Pandruvada pbf_info.core_cpumask, 1678354bd06fSSrinivas Pandruvada pbf_info.p1_high, pbf_info.p1_low); 1679354bd06fSSrinivas Pandruvada if (ret) { 1680fe6fb216SSrinivas Pandruvada debug_printf("set_core_priority_and_min failed"); 1681354bd06fSSrinivas Pandruvada return ret; 1682354bd06fSSrinivas Pandruvada } 1683354bd06fSSrinivas Pandruvada 1684354bd06fSSrinivas Pandruvada ret = isst_pm_qos_config(cpu, 1, 1); 1685354bd06fSSrinivas Pandruvada if (ret) { 1686fe6fb216SSrinivas Pandruvada debug_printf("isst_pm_qos_config failed"); 1687354bd06fSSrinivas Pandruvada return ret; 1688354bd06fSSrinivas Pandruvada } 1689354bd06fSSrinivas Pandruvada 1690354bd06fSSrinivas Pandruvada return 0; 1691354bd06fSSrinivas Pandruvada } 1692354bd06fSSrinivas Pandruvada 16933fb4f7cdSSrinivas Pandruvada static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, 16943fb4f7cdSSrinivas Pandruvada void *arg4) 16953fb4f7cdSSrinivas Pandruvada { 16963d904f06SSrinivas Pandruvada struct isst_pkg_ctdp_level_info ctdp_level; 16973d904f06SSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev; 16983fb4f7cdSSrinivas Pandruvada int ret; 16993fb4f7cdSSrinivas Pandruvada int status = *(int *)arg4; 17003fb4f7cdSSrinivas Pandruvada 17011aa7177cSPrarit Bhargava if (is_clx_n_platform()) { 17021aa7177cSPrarit Bhargava ret = 0; 17037fc9fefdSSrinivas Pandruvada if (status) { 1704a9b2f8e2SSrinivas Pandruvada set_clx_pbf_cpufreq_scaling_min_max(cpu); 1705a9b2f8e2SSrinivas Pandruvada 1706a9b2f8e2SSrinivas Pandruvada } else { 1707a9b2f8e2SSrinivas Pandruvada set_scaling_max_to_cpuinfo_max(cpu); 1708a9b2f8e2SSrinivas Pandruvada set_scaling_min_to_cpuinfo_min(cpu); 1709a9b2f8e2SSrinivas Pandruvada } 17101aa7177cSPrarit Bhargava goto disp_result; 17111aa7177cSPrarit Bhargava } 17121aa7177cSPrarit Bhargava 17133d904f06SSrinivas Pandruvada ret = isst_get_ctdp_levels(cpu, &pkg_dev); 17143d904f06SSrinivas Pandruvada if (ret) { 17153d904f06SSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get number of levels", 0, 0); 17163d904f06SSrinivas Pandruvada goto disp_result; 17173d904f06SSrinivas Pandruvada } 17183d904f06SSrinivas Pandruvada 17193d904f06SSrinivas Pandruvada ret = isst_get_ctdp_control(cpu, pkg_dev.current_level, &ctdp_level); 17203d904f06SSrinivas Pandruvada if (ret) { 17213d904f06SSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get current level", 0, 0); 17223d904f06SSrinivas Pandruvada goto disp_result; 17233d904f06SSrinivas Pandruvada } 17243d904f06SSrinivas Pandruvada 17253d904f06SSrinivas Pandruvada if (!ctdp_level.pbf_support) { 17263d904f06SSrinivas Pandruvada isst_display_error_info_message(1, "base-freq feature is not present at this level", 1, pkg_dev.current_level); 17273d904f06SSrinivas Pandruvada ret = -1; 17283d904f06SSrinivas Pandruvada goto disp_result; 17293d904f06SSrinivas Pandruvada } 17303d904f06SSrinivas Pandruvada 1731097a5222SSrinivas Pandruvada if (auto_mode && status) { 1732354bd06fSSrinivas Pandruvada ret = set_pbf_core_power(cpu); 1733354bd06fSSrinivas Pandruvada if (ret) 1734354bd06fSSrinivas Pandruvada goto disp_result; 1735354bd06fSSrinivas Pandruvada } 1736354bd06fSSrinivas Pandruvada 17373fb4f7cdSSrinivas Pandruvada ret = isst_set_pbf_fact_status(cpu, 1, status); 17383fb4f7cdSSrinivas Pandruvada if (ret) { 173939bae0fcSSrinivas Pandruvada debug_printf("isst_set_pbf_fact_status failed"); 1740354bd06fSSrinivas Pandruvada if (auto_mode) 1741354bd06fSSrinivas Pandruvada isst_pm_qos_config(cpu, 0, 0); 17423fb4f7cdSSrinivas Pandruvada } else { 1743354bd06fSSrinivas Pandruvada if (auto_mode) { 1744354bd06fSSrinivas Pandruvada if (status) 1745354bd06fSSrinivas Pandruvada set_scaling_min_to_cpuinfo_max(cpu); 1746354bd06fSSrinivas Pandruvada else 1747354bd06fSSrinivas Pandruvada set_scaling_min_to_cpuinfo_min(cpu); 1748354bd06fSSrinivas Pandruvada } 1749354bd06fSSrinivas Pandruvada } 1750354bd06fSSrinivas Pandruvada 1751097a5222SSrinivas Pandruvada if (auto_mode && !status) 1752fe6fb216SSrinivas Pandruvada isst_pm_qos_config(cpu, 0, 1); 1753097a5222SSrinivas Pandruvada 1754354bd06fSSrinivas Pandruvada disp_result: 17553fb4f7cdSSrinivas Pandruvada if (status) 17563fb4f7cdSSrinivas Pandruvada isst_display_result(cpu, outf, "base-freq", "enable", 17573fb4f7cdSSrinivas Pandruvada ret); 17583fb4f7cdSSrinivas Pandruvada else 17593fb4f7cdSSrinivas Pandruvada isst_display_result(cpu, outf, "base-freq", "disable", 17603fb4f7cdSSrinivas Pandruvada ret); 17613fb4f7cdSSrinivas Pandruvada } 17623fb4f7cdSSrinivas Pandruvada 1763ce1326a2SPrarit Bhargava static void set_pbf_enable(int arg) 17643fb4f7cdSSrinivas Pandruvada { 1765ce1326a2SPrarit Bhargava int enable = arg; 17663fb4f7cdSSrinivas Pandruvada 17673fb4f7cdSSrinivas Pandruvada if (cmd_help) { 1768ce1326a2SPrarit Bhargava if (enable) { 17693fb4f7cdSSrinivas Pandruvada fprintf(stderr, 1770354bd06fSSrinivas Pandruvada "Enable Intel Speed Select Technology base frequency feature\n"); 177139bae0fcSSrinivas Pandruvada if (is_clx_n_platform()) { 177239bae0fcSSrinivas Pandruvada fprintf(stderr, 177339bae0fcSSrinivas Pandruvada "\tOn this platform this command doesn't enable feature in the hardware.\n"); 177439bae0fcSSrinivas Pandruvada fprintf(stderr, 177539bae0fcSSrinivas Pandruvada "\tIt updates the cpufreq scaling_min_freq to match cpufreq base_frequency.\n"); 177639bae0fcSSrinivas Pandruvada exit(0); 177739bae0fcSSrinivas Pandruvada 177839bae0fcSSrinivas Pandruvada } 1779354bd06fSSrinivas Pandruvada fprintf(stderr, 1780354bd06fSSrinivas Pandruvada "\tOptional Arguments: -a|--auto : Use priority of cores to set core-power associations\n"); 1781ce1326a2SPrarit Bhargava } else { 1782354bd06fSSrinivas Pandruvada 178339bae0fcSSrinivas Pandruvada if (is_clx_n_platform()) { 178439bae0fcSSrinivas Pandruvada fprintf(stderr, 178539bae0fcSSrinivas Pandruvada "\tOn this platform this command doesn't disable feature in the hardware.\n"); 178639bae0fcSSrinivas Pandruvada fprintf(stderr, 178739bae0fcSSrinivas Pandruvada "\tIt updates the cpufreq scaling_min_freq to match cpuinfo_min_freq\n"); 178839bae0fcSSrinivas Pandruvada exit(0); 178939bae0fcSSrinivas Pandruvada } 17903fb4f7cdSSrinivas Pandruvada fprintf(stderr, 1791354bd06fSSrinivas Pandruvada "Disable Intel Speed Select Technology base frequency feature\n"); 1792354bd06fSSrinivas Pandruvada fprintf(stderr, 1793354bd06fSSrinivas Pandruvada "\tOptional Arguments: -a|--auto : Also disable core-power associations\n"); 1794ce1326a2SPrarit Bhargava } 17953fb4f7cdSSrinivas Pandruvada exit(0); 17963fb4f7cdSSrinivas Pandruvada } 17973fb4f7cdSSrinivas Pandruvada 17983fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 17993fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 18003fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL, 1801ce1326a2SPrarit Bhargava NULL, &enable); 18023fb4f7cdSSrinivas Pandruvada else 18033fb4f7cdSSrinivas Pandruvada for_each_online_package_in_set(set_pbf_for_cpu, NULL, NULL, 1804ce1326a2SPrarit Bhargava NULL, &enable); 18053fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 18063fb4f7cdSSrinivas Pandruvada } 18073fb4f7cdSSrinivas Pandruvada 18083fb4f7cdSSrinivas Pandruvada static void dump_fact_config_for_cpu(int cpu, void *arg1, void *arg2, 18093fb4f7cdSSrinivas Pandruvada void *arg3, void *arg4) 18103fb4f7cdSSrinivas Pandruvada { 18113fb4f7cdSSrinivas Pandruvada struct isst_fact_info fact_info; 18123fb4f7cdSSrinivas Pandruvada int ret; 18133fb4f7cdSSrinivas Pandruvada 1814a9fd6ae7SSrinivas Pandruvada ret = isst_get_fact_info(cpu, tdp_level, fact_bucket, &fact_info); 1815a9fd6ae7SSrinivas Pandruvada if (ret) { 1816a9fd6ae7SSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get turbo-freq info at this level", 1, tdp_level); 1817a9fd6ae7SSrinivas Pandruvada isst_ctdp_display_information_end(outf); 1818a9fd6ae7SSrinivas Pandruvada exit(1); 1819a9fd6ae7SSrinivas Pandruvada } else { 18203fb4f7cdSSrinivas Pandruvada isst_fact_display_information(cpu, outf, tdp_level, fact_bucket, 18213fb4f7cdSSrinivas Pandruvada fact_avx, &fact_info); 18223fb4f7cdSSrinivas Pandruvada } 1823a9fd6ae7SSrinivas Pandruvada } 18243fb4f7cdSSrinivas Pandruvada 1825ce1326a2SPrarit Bhargava static void dump_fact_config(int arg) 18263fb4f7cdSSrinivas Pandruvada { 18273fb4f7cdSSrinivas Pandruvada if (cmd_help) { 18283fb4f7cdSSrinivas Pandruvada fprintf(stderr, 18293fb4f7cdSSrinivas Pandruvada "Print complete Intel Speed Select Technology turbo frequency configuration for a TDP level. Other arguments are optional.\n"); 18303fb4f7cdSSrinivas Pandruvada fprintf(stderr, 18313fb4f7cdSSrinivas Pandruvada "\tArguments: -l|--level : Specify tdp level\n"); 18323fb4f7cdSSrinivas Pandruvada fprintf(stderr, 18333fb4f7cdSSrinivas Pandruvada "\tArguments: -b|--bucket : Bucket index to dump\n"); 18343fb4f7cdSSrinivas Pandruvada fprintf(stderr, 18353fb4f7cdSSrinivas Pandruvada "\tArguments: -r|--trl-type : Specify trl type: sse|avx2|avx512\n"); 18363fb4f7cdSSrinivas Pandruvada exit(0); 18373fb4f7cdSSrinivas Pandruvada } 18383fb4f7cdSSrinivas Pandruvada 18393fb4f7cdSSrinivas Pandruvada if (tdp_level == 0xff) { 1840a9fd6ae7SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid command: specify tdp_level\n", 0, 0); 18413fb4f7cdSSrinivas Pandruvada exit(1); 18423fb4f7cdSSrinivas Pandruvada } 18433fb4f7cdSSrinivas Pandruvada 18443fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 18453fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 18463fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(dump_fact_config_for_cpu, 18473fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL, NULL); 18483fb4f7cdSSrinivas Pandruvada else 18493fb4f7cdSSrinivas Pandruvada for_each_online_package_in_set(dump_fact_config_for_cpu, NULL, 18503fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 18513fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 18523fb4f7cdSSrinivas Pandruvada } 18533fb4f7cdSSrinivas Pandruvada 18543fb4f7cdSSrinivas Pandruvada static void set_fact_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, 18553fb4f7cdSSrinivas Pandruvada void *arg4) 18563fb4f7cdSSrinivas Pandruvada { 18573d904f06SSrinivas Pandruvada struct isst_pkg_ctdp_level_info ctdp_level; 18583d904f06SSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev; 18593fb4f7cdSSrinivas Pandruvada int ret; 18603fb4f7cdSSrinivas Pandruvada int status = *(int *)arg4; 18613fb4f7cdSSrinivas Pandruvada 18623d904f06SSrinivas Pandruvada ret = isst_get_ctdp_levels(cpu, &pkg_dev); 18633d904f06SSrinivas Pandruvada if (ret) { 18643d904f06SSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get number of levels", 0, 0); 18653d904f06SSrinivas Pandruvada goto disp_results; 18663d904f06SSrinivas Pandruvada } 18673d904f06SSrinivas Pandruvada 18683d904f06SSrinivas Pandruvada ret = isst_get_ctdp_control(cpu, pkg_dev.current_level, &ctdp_level); 18693d904f06SSrinivas Pandruvada if (ret) { 18703d904f06SSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get current level", 0, 0); 18713d904f06SSrinivas Pandruvada goto disp_results; 18723d904f06SSrinivas Pandruvada } 18733d904f06SSrinivas Pandruvada 18743d904f06SSrinivas Pandruvada if (!ctdp_level.fact_support) { 18753d904f06SSrinivas Pandruvada isst_display_error_info_message(1, "turbo-freq feature is not present at this level", 1, pkg_dev.current_level); 18763d904f06SSrinivas Pandruvada ret = -1; 18773d904f06SSrinivas Pandruvada goto disp_results; 18783d904f06SSrinivas Pandruvada } 18793d904f06SSrinivas Pandruvada 18807983ed6fSSrinivas Pandruvada if (status) { 1881a6a82f9bSSrinivas Pandruvada ret = isst_pm_qos_config(cpu, 1, 1); 18823fb4f7cdSSrinivas Pandruvada if (ret) 1883a6a82f9bSSrinivas Pandruvada goto disp_results; 1884a6a82f9bSSrinivas Pandruvada } 1885a6a82f9bSSrinivas Pandruvada 1886a6a82f9bSSrinivas Pandruvada ret = isst_set_pbf_fact_status(cpu, 0, status); 1887a6a82f9bSSrinivas Pandruvada if (ret) { 1888a9fd6ae7SSrinivas Pandruvada debug_printf("isst_set_pbf_fact_status failed"); 1889a6a82f9bSSrinivas Pandruvada if (auto_mode) 1890a6a82f9bSSrinivas Pandruvada isst_pm_qos_config(cpu, 0, 0); 1891a6a82f9bSSrinivas Pandruvada 1892a6a82f9bSSrinivas Pandruvada goto disp_results; 1893a6a82f9bSSrinivas Pandruvada } 1894a6a82f9bSSrinivas Pandruvada 1895a6a82f9bSSrinivas Pandruvada /* Set TRL */ 18963fb4f7cdSSrinivas Pandruvada if (status) { 18973fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev; 18983fb4f7cdSSrinivas Pandruvada 18993fb4f7cdSSrinivas Pandruvada ret = isst_get_ctdp_levels(cpu, &pkg_dev); 1900a6a82f9bSSrinivas Pandruvada if (!ret) 19013fb4f7cdSSrinivas Pandruvada ret = isst_set_trl(cpu, fact_trl); 1902a6a82f9bSSrinivas Pandruvada if (ret && auto_mode) 1903a6a82f9bSSrinivas Pandruvada isst_pm_qos_config(cpu, 0, 0); 1904097a5222SSrinivas Pandruvada } else { 1905097a5222SSrinivas Pandruvada if (auto_mode) 1906097a5222SSrinivas Pandruvada isst_pm_qos_config(cpu, 0, 0); 1907a6a82f9bSSrinivas Pandruvada } 1908a6a82f9bSSrinivas Pandruvada 1909a6a82f9bSSrinivas Pandruvada disp_results: 1910a6a82f9bSSrinivas Pandruvada if (status) { 1911a6a82f9bSSrinivas Pandruvada isst_display_result(cpu, outf, "turbo-freq", "enable", ret); 191214a8aa49SSrinivas Pandruvada if (ret) 191314a8aa49SSrinivas Pandruvada fact_enable_fail = ret; 19143fb4f7cdSSrinivas Pandruvada } else { 19153fb4f7cdSSrinivas Pandruvada /* Since we modified TRL during Fact enable, restore it */ 19163fb4f7cdSSrinivas Pandruvada isst_set_trl_from_current_tdp(cpu, fact_trl); 1917a6a82f9bSSrinivas Pandruvada isst_display_result(cpu, outf, "turbo-freq", "disable", ret); 19183fb4f7cdSSrinivas Pandruvada } 19193fb4f7cdSSrinivas Pandruvada } 19203fb4f7cdSSrinivas Pandruvada 1921ce1326a2SPrarit Bhargava static void set_fact_enable(int arg) 19223fb4f7cdSSrinivas Pandruvada { 1923ce1326a2SPrarit Bhargava int i, ret, enable = arg; 19243fb4f7cdSSrinivas Pandruvada 19253fb4f7cdSSrinivas Pandruvada if (cmd_help) { 1926ce1326a2SPrarit Bhargava if (enable) { 19273fb4f7cdSSrinivas Pandruvada fprintf(stderr, 19283fb4f7cdSSrinivas Pandruvada "Enable Intel Speed Select Technology Turbo frequency feature\n"); 19293fb4f7cdSSrinivas Pandruvada fprintf(stderr, 19303fb4f7cdSSrinivas Pandruvada "Optional: -t|--trl : Specify turbo ratio limit\n"); 1931a6a82f9bSSrinivas Pandruvada fprintf(stderr, 1932a6a82f9bSSrinivas Pandruvada "\tOptional Arguments: -a|--auto : Designate specified target CPUs with"); 1933ce1326a2SPrarit Bhargava fprintf(stderr, 1934ce1326a2SPrarit Bhargava "-C|--cpu option as as high priority using core-power feature\n"); 1935ce1326a2SPrarit Bhargava } else { 1936ce1326a2SPrarit Bhargava fprintf(stderr, 1937ce1326a2SPrarit Bhargava "Disable Intel Speed Select Technology turbo frequency feature\n"); 1938ce1326a2SPrarit Bhargava fprintf(stderr, 1939ce1326a2SPrarit Bhargava "Optional: -t|--trl : Specify turbo ratio limit\n"); 1940ce1326a2SPrarit Bhargava fprintf(stderr, 1941ce1326a2SPrarit Bhargava "\tOptional Arguments: -a|--auto : Also disable core-power associations\n"); 1942ce1326a2SPrarit Bhargava } 19433fb4f7cdSSrinivas Pandruvada exit(0); 19443fb4f7cdSSrinivas Pandruvada } 19453fb4f7cdSSrinivas Pandruvada 19463fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 19473fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 19483fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL, 1949ce1326a2SPrarit Bhargava NULL, &enable); 19503fb4f7cdSSrinivas Pandruvada else 19513fb4f7cdSSrinivas Pandruvada for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL, 1952ce1326a2SPrarit Bhargava NULL, &enable); 19533fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 1954a6a82f9bSSrinivas Pandruvada 195514a8aa49SSrinivas Pandruvada if (!fact_enable_fail && enable && auto_mode) { 1956a6a82f9bSSrinivas Pandruvada /* 1957a6a82f9bSSrinivas Pandruvada * When we adjust CLOS param, we have to set for siblings also. 1958a6a82f9bSSrinivas Pandruvada * So for the each user specified CPU, also add the sibling 1959a6a82f9bSSrinivas Pandruvada * in the present_cpu_mask. 1960a6a82f9bSSrinivas Pandruvada */ 1961a6a82f9bSSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 1962a6a82f9bSSrinivas Pandruvada char buffer[128], sibling_list[128], *cpu_str; 1963a6a82f9bSSrinivas Pandruvada int fd, len; 1964a6a82f9bSSrinivas Pandruvada 1965a6a82f9bSSrinivas Pandruvada if (!CPU_ISSET_S(i, target_cpumask_size, target_cpumask)) 1966a6a82f9bSSrinivas Pandruvada continue; 1967a6a82f9bSSrinivas Pandruvada 1968a6a82f9bSSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1969a6a82f9bSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", i); 1970a6a82f9bSSrinivas Pandruvada 1971a6a82f9bSSrinivas Pandruvada fd = open(buffer, O_RDONLY); 1972a6a82f9bSSrinivas Pandruvada if (fd < 0) 1973a6a82f9bSSrinivas Pandruvada continue; 1974a6a82f9bSSrinivas Pandruvada 1975a6a82f9bSSrinivas Pandruvada len = read(fd, sibling_list, sizeof(sibling_list)); 1976a6a82f9bSSrinivas Pandruvada close(fd); 1977a6a82f9bSSrinivas Pandruvada 1978a6a82f9bSSrinivas Pandruvada if (len < 0) 1979a6a82f9bSSrinivas Pandruvada continue; 1980a6a82f9bSSrinivas Pandruvada 1981a6a82f9bSSrinivas Pandruvada cpu_str = strtok(sibling_list, ","); 1982a6a82f9bSSrinivas Pandruvada while (cpu_str != NULL) { 1983a6a82f9bSSrinivas Pandruvada int cpu; 1984a6a82f9bSSrinivas Pandruvada 1985a6a82f9bSSrinivas Pandruvada sscanf(cpu_str, "%d", &cpu); 1986a6a82f9bSSrinivas Pandruvada CPU_SET_S(cpu, target_cpumask_size, target_cpumask); 1987a6a82f9bSSrinivas Pandruvada cpu_str = strtok(NULL, ","); 1988a6a82f9bSSrinivas Pandruvada } 1989a6a82f9bSSrinivas Pandruvada } 1990a6a82f9bSSrinivas Pandruvada 1991a6a82f9bSSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 1992a6a82f9bSSrinivas Pandruvada int clos; 1993a6a82f9bSSrinivas Pandruvada 1994a6a82f9bSSrinivas Pandruvada if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) 1995a6a82f9bSSrinivas Pandruvada continue; 1996a6a82f9bSSrinivas Pandruvada 1997a6a82f9bSSrinivas Pandruvada ret = set_clos_param(i, 0, 0, 0, 0, 0xff); 1998a6a82f9bSSrinivas Pandruvada if (ret) 1999a6a82f9bSSrinivas Pandruvada goto error_disp; 2000a6a82f9bSSrinivas Pandruvada 200121c3390dSSrinivas Pandruvada ret = set_clos_param(i, 1, 15, 15, 0, 0xff); 2002a6a82f9bSSrinivas Pandruvada if (ret) 2003a6a82f9bSSrinivas Pandruvada goto error_disp; 2004a6a82f9bSSrinivas Pandruvada 200521c3390dSSrinivas Pandruvada ret = set_clos_param(i, 2, 15, 15, 0, 0xff); 2006a6a82f9bSSrinivas Pandruvada if (ret) 2007a6a82f9bSSrinivas Pandruvada goto error_disp; 2008a6a82f9bSSrinivas Pandruvada 200921c3390dSSrinivas Pandruvada ret = set_clos_param(i, 3, 15, 15, 0, 0xff); 2010a6a82f9bSSrinivas Pandruvada if (ret) 2011a6a82f9bSSrinivas Pandruvada goto error_disp; 2012a6a82f9bSSrinivas Pandruvada 2013a6a82f9bSSrinivas Pandruvada if (CPU_ISSET_S(i, target_cpumask_size, target_cpumask)) 2014a6a82f9bSSrinivas Pandruvada clos = 0; 2015a6a82f9bSSrinivas Pandruvada else 2016a6a82f9bSSrinivas Pandruvada clos = 3; 2017a6a82f9bSSrinivas Pandruvada 2018a6a82f9bSSrinivas Pandruvada debug_printf("Associate cpu: %d clos: %d\n", i, clos); 2019a6a82f9bSSrinivas Pandruvada ret = isst_clos_associate(i, clos); 2020a6a82f9bSSrinivas Pandruvada if (ret) 2021a6a82f9bSSrinivas Pandruvada goto error_disp; 2022a6a82f9bSSrinivas Pandruvada } 202378e77b7dSSrinivas Pandruvada isst_display_result(-1, outf, "turbo-freq --auto", "enable", 0); 2024a6a82f9bSSrinivas Pandruvada } 2025a6a82f9bSSrinivas Pandruvada 2026a6a82f9bSSrinivas Pandruvada return; 2027a6a82f9bSSrinivas Pandruvada 2028a6a82f9bSSrinivas Pandruvada error_disp: 2029a6a82f9bSSrinivas Pandruvada isst_display_result(i, outf, "turbo-freq --auto", "enable", ret); 2030a6a82f9bSSrinivas Pandruvada 20313fb4f7cdSSrinivas Pandruvada } 20323fb4f7cdSSrinivas Pandruvada 20333fb4f7cdSSrinivas Pandruvada static void enable_clos_qos_config(int cpu, void *arg1, void *arg2, void *arg3, 20343fb4f7cdSSrinivas Pandruvada void *arg4) 20353fb4f7cdSSrinivas Pandruvada { 20363fb4f7cdSSrinivas Pandruvada int ret; 20373fb4f7cdSSrinivas Pandruvada int status = *(int *)arg4; 20383fb4f7cdSSrinivas Pandruvada 2039fe6fb216SSrinivas Pandruvada if (is_skx_based_platform()) 2040fe6fb216SSrinivas Pandruvada clos_priority_type = 1; 2041fe6fb216SSrinivas Pandruvada 20423fb4f7cdSSrinivas Pandruvada ret = isst_pm_qos_config(cpu, status, clos_priority_type); 2043a6a82f9bSSrinivas Pandruvada if (ret) 2044fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_pm_qos_config failed", 0, 0); 2045a6a82f9bSSrinivas Pandruvada 20463fb4f7cdSSrinivas Pandruvada if (status) 20473fb4f7cdSSrinivas Pandruvada isst_display_result(cpu, outf, "core-power", "enable", 20483fb4f7cdSSrinivas Pandruvada ret); 20493fb4f7cdSSrinivas Pandruvada else 20503fb4f7cdSSrinivas Pandruvada isst_display_result(cpu, outf, "core-power", "disable", 20513fb4f7cdSSrinivas Pandruvada ret); 20523fb4f7cdSSrinivas Pandruvada } 20533fb4f7cdSSrinivas Pandruvada 2054ce1326a2SPrarit Bhargava static void set_clos_enable(int arg) 20553fb4f7cdSSrinivas Pandruvada { 2056ce1326a2SPrarit Bhargava int enable = arg; 20573fb4f7cdSSrinivas Pandruvada 20583fb4f7cdSSrinivas Pandruvada if (cmd_help) { 2059ce1326a2SPrarit Bhargava if (enable) { 2060ce1326a2SPrarit Bhargava fprintf(stderr, 2061ce1326a2SPrarit Bhargava "Enable core-power for a package/die\n"); 2062fe6fb216SSrinivas Pandruvada if (!is_skx_based_platform()) { 20633fb4f7cdSSrinivas Pandruvada fprintf(stderr, 20643fb4f7cdSSrinivas Pandruvada "\tClos Enable: Specify priority type with [--priority|-p]\n"); 20653fb4f7cdSSrinivas Pandruvada fprintf(stderr, "\t\t 0: Proportional, 1: Ordered\n"); 2066fe6fb216SSrinivas Pandruvada } 2067ce1326a2SPrarit Bhargava } else { 2068ce1326a2SPrarit Bhargava fprintf(stderr, 2069ce1326a2SPrarit Bhargava "Disable core-power: [No command arguments are required]\n"); 2070ce1326a2SPrarit Bhargava } 20713fb4f7cdSSrinivas Pandruvada exit(0); 20723fb4f7cdSSrinivas Pandruvada } 20733fb4f7cdSSrinivas Pandruvada 2074ce1326a2SPrarit Bhargava if (enable && cpufreq_sysfs_present()) { 20753fb4f7cdSSrinivas Pandruvada fprintf(stderr, 20763fb4f7cdSSrinivas Pandruvada "cpufreq subsystem and core-power enable will interfere with each other!\n"); 20773fb4f7cdSSrinivas Pandruvada } 20783fb4f7cdSSrinivas Pandruvada 20793fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 20803fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 20813fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL, 2082ce1326a2SPrarit Bhargava NULL, NULL, &enable); 20833fb4f7cdSSrinivas Pandruvada else 20843fb4f7cdSSrinivas Pandruvada for_each_online_package_in_set(enable_clos_qos_config, NULL, 2085ce1326a2SPrarit Bhargava NULL, NULL, &enable); 20863fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 20873fb4f7cdSSrinivas Pandruvada } 20883fb4f7cdSSrinivas Pandruvada 20893fb4f7cdSSrinivas Pandruvada static void dump_clos_config_for_cpu(int cpu, void *arg1, void *arg2, 20903fb4f7cdSSrinivas Pandruvada void *arg3, void *arg4) 20913fb4f7cdSSrinivas Pandruvada { 20923fb4f7cdSSrinivas Pandruvada struct isst_clos_config clos_config; 20933fb4f7cdSSrinivas Pandruvada int ret; 20943fb4f7cdSSrinivas Pandruvada 20953fb4f7cdSSrinivas Pandruvada ret = isst_pm_get_clos(cpu, current_clos, &clos_config); 20963fb4f7cdSSrinivas Pandruvada if (ret) 2097fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_pm_get_clos failed", 0, 0); 20983fb4f7cdSSrinivas Pandruvada else 20993fb4f7cdSSrinivas Pandruvada isst_clos_display_information(cpu, outf, current_clos, 21003fb4f7cdSSrinivas Pandruvada &clos_config); 21013fb4f7cdSSrinivas Pandruvada } 21023fb4f7cdSSrinivas Pandruvada 2103ce1326a2SPrarit Bhargava static void dump_clos_config(int arg) 21043fb4f7cdSSrinivas Pandruvada { 21053fb4f7cdSSrinivas Pandruvada if (cmd_help) { 21063fb4f7cdSSrinivas Pandruvada fprintf(stderr, 21073fb4f7cdSSrinivas Pandruvada "Print Intel Speed Select Technology core power configuration\n"); 21083fb4f7cdSSrinivas Pandruvada fprintf(stderr, 21093fb4f7cdSSrinivas Pandruvada "\tArguments: [-c | --clos]: Specify clos id\n"); 21103fb4f7cdSSrinivas Pandruvada exit(0); 21113fb4f7cdSSrinivas Pandruvada } 21123fb4f7cdSSrinivas Pandruvada if (current_clos < 0 || current_clos > 3) { 2113fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid clos id\n", 0, 0); 2114fe6fb216SSrinivas Pandruvada isst_ctdp_display_information_end(outf); 21153fb4f7cdSSrinivas Pandruvada exit(0); 21163fb4f7cdSSrinivas Pandruvada } 21173fb4f7cdSSrinivas Pandruvada 21183fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 21193fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 21203fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(dump_clos_config_for_cpu, 21213fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL, NULL); 21223fb4f7cdSSrinivas Pandruvada else 21233fb4f7cdSSrinivas Pandruvada for_each_online_package_in_set(dump_clos_config_for_cpu, NULL, 21243fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 21253fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 21263fb4f7cdSSrinivas Pandruvada } 21273fb4f7cdSSrinivas Pandruvada 2128188afed9SSrinivas Pandruvada static void get_clos_info_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, 2129188afed9SSrinivas Pandruvada void *arg4) 2130188afed9SSrinivas Pandruvada { 2131188afed9SSrinivas Pandruvada int enable, ret, prio_type; 2132188afed9SSrinivas Pandruvada 2133188afed9SSrinivas Pandruvada ret = isst_clos_get_clos_information(cpu, &enable, &prio_type); 2134188afed9SSrinivas Pandruvada if (ret) 2135fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_clos_get_info failed", 0, 0); 2136143ad322SSrinivas Pandruvada else { 2137143ad322SSrinivas Pandruvada int cp_state, cp_cap; 2138143ad322SSrinivas Pandruvada 2139143ad322SSrinivas Pandruvada isst_read_pm_config(cpu, &cp_state, &cp_cap); 2140143ad322SSrinivas Pandruvada isst_clos_display_clos_information(cpu, outf, enable, prio_type, 2141143ad322SSrinivas Pandruvada cp_state, cp_cap); 2142143ad322SSrinivas Pandruvada } 2143188afed9SSrinivas Pandruvada } 2144188afed9SSrinivas Pandruvada 2145ce1326a2SPrarit Bhargava static void dump_clos_info(int arg) 2146188afed9SSrinivas Pandruvada { 2147188afed9SSrinivas Pandruvada if (cmd_help) { 2148188afed9SSrinivas Pandruvada fprintf(stderr, 2149188afed9SSrinivas Pandruvada "Print Intel Speed Select Technology core power information\n"); 2150f5205f49SSrinivas Pandruvada fprintf(stderr, "\t Optionally specify targeted cpu id with [--cpu|-c]\n"); 2151188afed9SSrinivas Pandruvada exit(0); 2152188afed9SSrinivas Pandruvada } 2153188afed9SSrinivas Pandruvada 2154188afed9SSrinivas Pandruvada isst_ctdp_display_information_start(outf); 2155f5205f49SSrinivas Pandruvada if (max_target_cpus) 2156188afed9SSrinivas Pandruvada for_each_online_target_cpu_in_set(get_clos_info_for_cpu, NULL, 2157188afed9SSrinivas Pandruvada NULL, NULL, NULL); 2158f5205f49SSrinivas Pandruvada else 2159f5205f49SSrinivas Pandruvada for_each_online_package_in_set(get_clos_info_for_cpu, NULL, 2160f5205f49SSrinivas Pandruvada NULL, NULL, NULL); 2161188afed9SSrinivas Pandruvada isst_ctdp_display_information_end(outf); 2162188afed9SSrinivas Pandruvada 2163188afed9SSrinivas Pandruvada } 2164188afed9SSrinivas Pandruvada 21653fb4f7cdSSrinivas Pandruvada static void set_clos_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, 21663fb4f7cdSSrinivas Pandruvada void *arg4) 21673fb4f7cdSSrinivas Pandruvada { 21683fb4f7cdSSrinivas Pandruvada struct isst_clos_config clos_config; 21693fb4f7cdSSrinivas Pandruvada int ret; 21703fb4f7cdSSrinivas Pandruvada 21713fb4f7cdSSrinivas Pandruvada clos_config.pkg_id = get_physical_package_id(cpu); 21723fb4f7cdSSrinivas Pandruvada clos_config.die_id = get_physical_die_id(cpu); 21733fb4f7cdSSrinivas Pandruvada 21743fb4f7cdSSrinivas Pandruvada clos_config.epp = clos_epp; 21753fb4f7cdSSrinivas Pandruvada clos_config.clos_prop_prio = clos_prop_prio; 21763fb4f7cdSSrinivas Pandruvada clos_config.clos_min = clos_min; 21773fb4f7cdSSrinivas Pandruvada clos_config.clos_max = clos_max; 21783fb4f7cdSSrinivas Pandruvada clos_config.clos_desired = clos_desired; 21793fb4f7cdSSrinivas Pandruvada ret = isst_set_clos(cpu, current_clos, &clos_config); 21803fb4f7cdSSrinivas Pandruvada if (ret) 2181fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_set_clos failed", 0, 0); 21823fb4f7cdSSrinivas Pandruvada else 21833fb4f7cdSSrinivas Pandruvada isst_display_result(cpu, outf, "core-power", "config", ret); 21843fb4f7cdSSrinivas Pandruvada } 21853fb4f7cdSSrinivas Pandruvada 2186ce1326a2SPrarit Bhargava static void set_clos_config(int arg) 21873fb4f7cdSSrinivas Pandruvada { 21883fb4f7cdSSrinivas Pandruvada if (cmd_help) { 21893fb4f7cdSSrinivas Pandruvada fprintf(stderr, 21903fb4f7cdSSrinivas Pandruvada "Set core-power configuration for one of the four clos ids\n"); 21913fb4f7cdSSrinivas Pandruvada fprintf(stderr, 21923fb4f7cdSSrinivas Pandruvada "\tSpecify targeted clos id with [--clos|-c]\n"); 2193fe6fb216SSrinivas Pandruvada if (!is_skx_based_platform()) { 21943fb4f7cdSSrinivas Pandruvada fprintf(stderr, "\tSpecify clos EPP with [--epp|-e]\n"); 21953fb4f7cdSSrinivas Pandruvada fprintf(stderr, 21963fb4f7cdSSrinivas Pandruvada "\tSpecify clos Proportional Priority [--weight|-w]\n"); 2197fe6fb216SSrinivas Pandruvada } 219840dee9ddSSrinivas Pandruvada fprintf(stderr, "\tSpecify clos min in MHz with [--min|-n]\n"); 219940dee9ddSSrinivas Pandruvada fprintf(stderr, "\tSpecify clos max in MHz with [--max|-m]\n"); 22003fb4f7cdSSrinivas Pandruvada exit(0); 22013fb4f7cdSSrinivas Pandruvada } 22023fb4f7cdSSrinivas Pandruvada 22033fb4f7cdSSrinivas Pandruvada if (current_clos < 0 || current_clos > 3) { 2204fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid clos id\n", 0, 0); 22053fb4f7cdSSrinivas Pandruvada exit(0); 22063fb4f7cdSSrinivas Pandruvada } 2207fe6fb216SSrinivas Pandruvada if (!is_skx_based_platform() && (clos_epp < 0 || clos_epp > 0x0F)) { 2208fe6fb216SSrinivas Pandruvada fprintf(stderr, "clos epp is not specified or invalid, default: 0\n"); 22093fb4f7cdSSrinivas Pandruvada clos_epp = 0; 22103fb4f7cdSSrinivas Pandruvada } 2211fe6fb216SSrinivas Pandruvada if (!is_skx_based_platform() && (clos_prop_prio < 0 || clos_prop_prio > 0x0F)) { 22123fb4f7cdSSrinivas Pandruvada fprintf(stderr, 2213fe6fb216SSrinivas Pandruvada "clos frequency weight is not specified or invalid, default: 0\n"); 22143fb4f7cdSSrinivas Pandruvada clos_prop_prio = 0; 22153fb4f7cdSSrinivas Pandruvada } 22163fb4f7cdSSrinivas Pandruvada if (clos_min < 0) { 22173fb4f7cdSSrinivas Pandruvada fprintf(stderr, "clos min is not specified, default: 0\n"); 22183fb4f7cdSSrinivas Pandruvada clos_min = 0; 22193fb4f7cdSSrinivas Pandruvada } 22203fb4f7cdSSrinivas Pandruvada if (clos_max < 0) { 2221fe6fb216SSrinivas Pandruvada fprintf(stderr, "clos max is not specified, default: Max frequency (ratio 0xff)\n"); 22223fb4f7cdSSrinivas Pandruvada clos_max = 0xff; 22233fb4f7cdSSrinivas Pandruvada } 2224fe6fb216SSrinivas Pandruvada if (clos_desired) { 2225fe6fb216SSrinivas Pandruvada fprintf(stderr, "clos desired is not supported on this platform\n"); 22263fb4f7cdSSrinivas Pandruvada clos_desired = 0x00; 22273fb4f7cdSSrinivas Pandruvada } 22283fb4f7cdSSrinivas Pandruvada 22293fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 22303fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 22313fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(set_clos_config_for_cpu, NULL, 22323fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 22333fb4f7cdSSrinivas Pandruvada else 22343fb4f7cdSSrinivas Pandruvada for_each_online_package_in_set(set_clos_config_for_cpu, NULL, 22353fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 22363fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 22373fb4f7cdSSrinivas Pandruvada } 22383fb4f7cdSSrinivas Pandruvada 22393fb4f7cdSSrinivas Pandruvada static void set_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, 22403fb4f7cdSSrinivas Pandruvada void *arg4) 22413fb4f7cdSSrinivas Pandruvada { 22423fb4f7cdSSrinivas Pandruvada int ret; 22433fb4f7cdSSrinivas Pandruvada 22443fb4f7cdSSrinivas Pandruvada ret = isst_clos_associate(cpu, current_clos); 22453fb4f7cdSSrinivas Pandruvada if (ret) 2246fe6fb216SSrinivas Pandruvada debug_printf("isst_clos_associate failed"); 22473fb4f7cdSSrinivas Pandruvada else 22483fb4f7cdSSrinivas Pandruvada isst_display_result(cpu, outf, "core-power", "assoc", ret); 22493fb4f7cdSSrinivas Pandruvada } 22503fb4f7cdSSrinivas Pandruvada 2251ce1326a2SPrarit Bhargava static void set_clos_assoc(int arg) 22523fb4f7cdSSrinivas Pandruvada { 22533fb4f7cdSSrinivas Pandruvada if (cmd_help) { 22543fb4f7cdSSrinivas Pandruvada fprintf(stderr, "Associate a clos id to a CPU\n"); 22553fb4f7cdSSrinivas Pandruvada fprintf(stderr, 22563fb4f7cdSSrinivas Pandruvada "\tSpecify targeted clos id with [--clos|-c]\n"); 225768e2f109SSrinivas Pandruvada fprintf(stderr, 225868e2f109SSrinivas Pandruvada "\tFor example to associate clos 1 to CPU 0: issue\n"); 225968e2f109SSrinivas Pandruvada fprintf(stderr, 226068e2f109SSrinivas Pandruvada "\tintel-speed-select --cpu 0 core-power assoc --clos 1\n"); 22613fb4f7cdSSrinivas Pandruvada exit(0); 22623fb4f7cdSSrinivas Pandruvada } 22633fb4f7cdSSrinivas Pandruvada 22643fb4f7cdSSrinivas Pandruvada if (current_clos < 0 || current_clos > 3) { 2265fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid clos id\n", 0, 0); 22663fb4f7cdSSrinivas Pandruvada exit(0); 22673fb4f7cdSSrinivas Pandruvada } 22683fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 22693fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(set_clos_assoc_for_cpu, NULL, 22703fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 22713fb4f7cdSSrinivas Pandruvada else { 2272fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid target cpu. Specify with [-c|--cpu]", 0, 0); 22733fb4f7cdSSrinivas Pandruvada } 22743fb4f7cdSSrinivas Pandruvada } 22753fb4f7cdSSrinivas Pandruvada 22763fb4f7cdSSrinivas Pandruvada static void get_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, 22773fb4f7cdSSrinivas Pandruvada void *arg4) 22783fb4f7cdSSrinivas Pandruvada { 22793fb4f7cdSSrinivas Pandruvada int clos, ret; 22803fb4f7cdSSrinivas Pandruvada 22813fb4f7cdSSrinivas Pandruvada ret = isst_clos_get_assoc_status(cpu, &clos); 22823fb4f7cdSSrinivas Pandruvada if (ret) 2283fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_clos_get_assoc_status failed", 0, 0); 22843fb4f7cdSSrinivas Pandruvada else 2285e118fbe3SSrinivas Pandruvada isst_clos_display_assoc_information(cpu, outf, clos); 22863fb4f7cdSSrinivas Pandruvada } 22873fb4f7cdSSrinivas Pandruvada 2288ce1326a2SPrarit Bhargava static void get_clos_assoc(int arg) 22893fb4f7cdSSrinivas Pandruvada { 22903fb4f7cdSSrinivas Pandruvada if (cmd_help) { 22913fb4f7cdSSrinivas Pandruvada fprintf(stderr, "Get associate clos id to a CPU\n"); 22923fb4f7cdSSrinivas Pandruvada fprintf(stderr, "\tSpecify targeted cpu id with [--cpu|-c]\n"); 22933fb4f7cdSSrinivas Pandruvada exit(0); 22943fb4f7cdSSrinivas Pandruvada } 2295e118fbe3SSrinivas Pandruvada 2296e118fbe3SSrinivas Pandruvada if (!max_target_cpus) { 2297fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid target cpu. Specify with [-c|--cpu]", 0, 0); 2298e118fbe3SSrinivas Pandruvada exit(0); 22993fb4f7cdSSrinivas Pandruvada } 2300e118fbe3SSrinivas Pandruvada 2301e118fbe3SSrinivas Pandruvada isst_ctdp_display_information_start(outf); 2302e118fbe3SSrinivas Pandruvada for_each_online_target_cpu_in_set(get_clos_assoc_for_cpu, NULL, 2303e118fbe3SSrinivas Pandruvada NULL, NULL, NULL); 2304e118fbe3SSrinivas Pandruvada isst_ctdp_display_information_end(outf); 23053fb4f7cdSSrinivas Pandruvada } 23063fb4f7cdSSrinivas Pandruvada 2307*006050a6SSrinivas Pandruvada static void set_turbo_mode_for_cpu(int cpu, int status) 2308*006050a6SSrinivas Pandruvada { 2309*006050a6SSrinivas Pandruvada int base_freq; 2310*006050a6SSrinivas Pandruvada 2311*006050a6SSrinivas Pandruvada if (status) { 2312*006050a6SSrinivas Pandruvada base_freq = get_cpufreq_base_freq(cpu); 2313*006050a6SSrinivas Pandruvada set_cpufreq_scaling_min_max(cpu, 1, base_freq); 2314*006050a6SSrinivas Pandruvada } else { 2315*006050a6SSrinivas Pandruvada set_scaling_max_to_cpuinfo_max(cpu); 2316*006050a6SSrinivas Pandruvada } 2317*006050a6SSrinivas Pandruvada 2318*006050a6SSrinivas Pandruvada if (status) { 2319*006050a6SSrinivas Pandruvada isst_display_result(cpu, outf, "turbo-mode", "enable", 0); 2320*006050a6SSrinivas Pandruvada } else { 2321*006050a6SSrinivas Pandruvada isst_display_result(cpu, outf, "turbo-mode", "disable", 0); 2322*006050a6SSrinivas Pandruvada } 2323*006050a6SSrinivas Pandruvada } 2324*006050a6SSrinivas Pandruvada 2325*006050a6SSrinivas Pandruvada static void set_turbo_mode(int arg) 2326*006050a6SSrinivas Pandruvada { 2327*006050a6SSrinivas Pandruvada int i, enable = arg; 2328*006050a6SSrinivas Pandruvada 2329*006050a6SSrinivas Pandruvada if (cmd_help) { 2330*006050a6SSrinivas Pandruvada if (enable) 2331*006050a6SSrinivas Pandruvada fprintf(stderr, "Set turbo mode enable\n"); 2332*006050a6SSrinivas Pandruvada else 2333*006050a6SSrinivas Pandruvada fprintf(stderr, "Set turbo mode disable\n"); 2334*006050a6SSrinivas Pandruvada exit(0); 2335*006050a6SSrinivas Pandruvada } 2336*006050a6SSrinivas Pandruvada 2337*006050a6SSrinivas Pandruvada isst_ctdp_display_information_start(outf); 2338*006050a6SSrinivas Pandruvada 2339*006050a6SSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) { 2340*006050a6SSrinivas Pandruvada int online; 2341*006050a6SSrinivas Pandruvada 2342*006050a6SSrinivas Pandruvada if (i) 2343*006050a6SSrinivas Pandruvada online = parse_int_file( 2344*006050a6SSrinivas Pandruvada 1, "/sys/devices/system/cpu/cpu%d/online", i); 2345*006050a6SSrinivas Pandruvada else 2346*006050a6SSrinivas Pandruvada online = 2347*006050a6SSrinivas Pandruvada 1; /* online entry for CPU 0 needs some special configs */ 2348*006050a6SSrinivas Pandruvada 2349*006050a6SSrinivas Pandruvada if (online) 2350*006050a6SSrinivas Pandruvada set_turbo_mode_for_cpu(i, enable); 2351*006050a6SSrinivas Pandruvada 2352*006050a6SSrinivas Pandruvada } 2353*006050a6SSrinivas Pandruvada isst_ctdp_display_information_end(outf); 2354*006050a6SSrinivas Pandruvada } 2355*006050a6SSrinivas Pandruvada 2356c829f0efSPrarit Bhargava static struct process_cmd_struct clx_n_cmds[] = { 2357062e4aacSPrarit Bhargava { "perf-profile", "info", dump_isst_config, 0 }, 23581aa7177cSPrarit Bhargava { "base-freq", "info", dump_pbf_config, 0 }, 23591aa7177cSPrarit Bhargava { "base-freq", "enable", set_pbf_enable, 1 }, 23601aa7177cSPrarit Bhargava { "base-freq", "disable", set_pbf_enable, 0 }, 2361c829f0efSPrarit Bhargava { NULL, NULL, NULL, 0 } 2362c829f0efSPrarit Bhargava }; 2363c829f0efSPrarit Bhargava 23643fb4f7cdSSrinivas Pandruvada static struct process_cmd_struct isst_cmds[] = { 2365ce1326a2SPrarit Bhargava { "perf-profile", "get-lock-status", get_tdp_locked, 0 }, 2366ce1326a2SPrarit Bhargava { "perf-profile", "get-config-levels", get_tdp_levels, 0 }, 2367ce1326a2SPrarit Bhargava { "perf-profile", "get-config-version", get_tdp_version, 0 }, 2368ce1326a2SPrarit Bhargava { "perf-profile", "get-config-enabled", get_tdp_enabled, 0 }, 2369ce1326a2SPrarit Bhargava { "perf-profile", "get-config-current-level", get_tdp_current_level, 2370ce1326a2SPrarit Bhargava 0 }, 2371ce1326a2SPrarit Bhargava { "perf-profile", "set-config-level", set_tdp_level, 0 }, 2372ce1326a2SPrarit Bhargava { "perf-profile", "info", dump_isst_config, 0 }, 2373ce1326a2SPrarit Bhargava { "base-freq", "info", dump_pbf_config, 0 }, 2374ce1326a2SPrarit Bhargava { "base-freq", "enable", set_pbf_enable, 1 }, 2375ce1326a2SPrarit Bhargava { "base-freq", "disable", set_pbf_enable, 0 }, 2376ce1326a2SPrarit Bhargava { "turbo-freq", "info", dump_fact_config, 0 }, 2377ce1326a2SPrarit Bhargava { "turbo-freq", "enable", set_fact_enable, 1 }, 2378ce1326a2SPrarit Bhargava { "turbo-freq", "disable", set_fact_enable, 0 }, 2379ce1326a2SPrarit Bhargava { "core-power", "info", dump_clos_info, 0 }, 2380ce1326a2SPrarit Bhargava { "core-power", "enable", set_clos_enable, 1 }, 2381ce1326a2SPrarit Bhargava { "core-power", "disable", set_clos_enable, 0 }, 2382ce1326a2SPrarit Bhargava { "core-power", "config", set_clos_config, 0 }, 2383ce1326a2SPrarit Bhargava { "core-power", "get-config", dump_clos_config, 0 }, 2384ce1326a2SPrarit Bhargava { "core-power", "assoc", set_clos_assoc, 0 }, 2385ce1326a2SPrarit Bhargava { "core-power", "get-assoc", get_clos_assoc, 0 }, 2386*006050a6SSrinivas Pandruvada { "turbo-mode", "enable", set_turbo_mode, 0 }, 2387*006050a6SSrinivas Pandruvada { "turbo-mode", "disable", set_turbo_mode, 1 }, 23883fb4f7cdSSrinivas Pandruvada { NULL, NULL, NULL } 23893fb4f7cdSSrinivas Pandruvada }; 23903fb4f7cdSSrinivas Pandruvada 23913fb4f7cdSSrinivas Pandruvada /* 23923fb4f7cdSSrinivas Pandruvada * parse cpuset with following syntax 23933fb4f7cdSSrinivas Pandruvada * 1,2,4..6,8-10 and set bits in cpu_subset 23943fb4f7cdSSrinivas Pandruvada */ 23953fb4f7cdSSrinivas Pandruvada void parse_cpu_command(char *optarg) 23963fb4f7cdSSrinivas Pandruvada { 23973fb4f7cdSSrinivas Pandruvada unsigned int start, end; 23983fb4f7cdSSrinivas Pandruvada char *next; 23993fb4f7cdSSrinivas Pandruvada 24003fb4f7cdSSrinivas Pandruvada next = optarg; 24013fb4f7cdSSrinivas Pandruvada 24023fb4f7cdSSrinivas Pandruvada while (next && *next) { 24033fb4f7cdSSrinivas Pandruvada if (*next == '-') /* no negative cpu numbers */ 24043fb4f7cdSSrinivas Pandruvada goto error; 24053fb4f7cdSSrinivas Pandruvada 24063fb4f7cdSSrinivas Pandruvada start = strtoul(next, &next, 10); 24073fb4f7cdSSrinivas Pandruvada 24083fb4f7cdSSrinivas Pandruvada if (max_target_cpus < MAX_CPUS_IN_ONE_REQ) 24093fb4f7cdSSrinivas Pandruvada target_cpus[max_target_cpus++] = start; 24103fb4f7cdSSrinivas Pandruvada 24113fb4f7cdSSrinivas Pandruvada if (*next == '\0') 24123fb4f7cdSSrinivas Pandruvada break; 24133fb4f7cdSSrinivas Pandruvada 24143fb4f7cdSSrinivas Pandruvada if (*next == ',') { 24153fb4f7cdSSrinivas Pandruvada next += 1; 24163fb4f7cdSSrinivas Pandruvada continue; 24173fb4f7cdSSrinivas Pandruvada } 24183fb4f7cdSSrinivas Pandruvada 24193fb4f7cdSSrinivas Pandruvada if (*next == '-') { 24203fb4f7cdSSrinivas Pandruvada next += 1; /* start range */ 24213fb4f7cdSSrinivas Pandruvada } else if (*next == '.') { 24223fb4f7cdSSrinivas Pandruvada next += 1; 24233fb4f7cdSSrinivas Pandruvada if (*next == '.') 24243fb4f7cdSSrinivas Pandruvada next += 1; /* start range */ 24253fb4f7cdSSrinivas Pandruvada else 24263fb4f7cdSSrinivas Pandruvada goto error; 24273fb4f7cdSSrinivas Pandruvada } 24283fb4f7cdSSrinivas Pandruvada 24293fb4f7cdSSrinivas Pandruvada end = strtoul(next, &next, 10); 24303fb4f7cdSSrinivas Pandruvada if (end <= start) 24313fb4f7cdSSrinivas Pandruvada goto error; 24323fb4f7cdSSrinivas Pandruvada 24333fb4f7cdSSrinivas Pandruvada while (++start <= end) { 24343fb4f7cdSSrinivas Pandruvada if (max_target_cpus < MAX_CPUS_IN_ONE_REQ) 24353fb4f7cdSSrinivas Pandruvada target_cpus[max_target_cpus++] = start; 24363fb4f7cdSSrinivas Pandruvada } 24373fb4f7cdSSrinivas Pandruvada 24383fb4f7cdSSrinivas Pandruvada if (*next == ',') 24393fb4f7cdSSrinivas Pandruvada next += 1; 24403fb4f7cdSSrinivas Pandruvada else if (*next != '\0') 24413fb4f7cdSSrinivas Pandruvada goto error; 24423fb4f7cdSSrinivas Pandruvada } 24433fb4f7cdSSrinivas Pandruvada 24443fb4f7cdSSrinivas Pandruvada #ifdef DEBUG 24453fb4f7cdSSrinivas Pandruvada { 24463fb4f7cdSSrinivas Pandruvada int i; 24473fb4f7cdSSrinivas Pandruvada 24483fb4f7cdSSrinivas Pandruvada for (i = 0; i < max_target_cpus; ++i) 24493fb4f7cdSSrinivas Pandruvada printf("cpu [%d] in arg\n", target_cpus[i]); 24503fb4f7cdSSrinivas Pandruvada } 24513fb4f7cdSSrinivas Pandruvada #endif 24523fb4f7cdSSrinivas Pandruvada return; 24533fb4f7cdSSrinivas Pandruvada 24543fb4f7cdSSrinivas Pandruvada error: 24553fb4f7cdSSrinivas Pandruvada fprintf(stderr, "\"--cpu %s\" malformed\n", optarg); 24563fb4f7cdSSrinivas Pandruvada exit(-1); 24573fb4f7cdSSrinivas Pandruvada } 24583fb4f7cdSSrinivas Pandruvada 24593fb4f7cdSSrinivas Pandruvada static void parse_cmd_args(int argc, int start, char **argv) 24603fb4f7cdSSrinivas Pandruvada { 24613fb4f7cdSSrinivas Pandruvada int opt; 24623fb4f7cdSSrinivas Pandruvada int option_index; 24633fb4f7cdSSrinivas Pandruvada 24643fb4f7cdSSrinivas Pandruvada static struct option long_options[] = { 24653fb4f7cdSSrinivas Pandruvada { "bucket", required_argument, 0, 'b' }, 24663fb4f7cdSSrinivas Pandruvada { "level", required_argument, 0, 'l' }, 24673c64c81aSSrinivas Pandruvada { "online", required_argument, 0, 'o' }, 24683fb4f7cdSSrinivas Pandruvada { "trl-type", required_argument, 0, 'r' }, 24693fb4f7cdSSrinivas Pandruvada { "trl", required_argument, 0, 't' }, 24703fb4f7cdSSrinivas Pandruvada { "help", no_argument, 0, 'h' }, 24713fb4f7cdSSrinivas Pandruvada { "clos", required_argument, 0, 'c' }, 24723fb4f7cdSSrinivas Pandruvada { "desired", required_argument, 0, 'd' }, 24733fb4f7cdSSrinivas Pandruvada { "epp", required_argument, 0, 'e' }, 24743fb4f7cdSSrinivas Pandruvada { "min", required_argument, 0, 'n' }, 24753fb4f7cdSSrinivas Pandruvada { "max", required_argument, 0, 'm' }, 24763fb4f7cdSSrinivas Pandruvada { "priority", required_argument, 0, 'p' }, 24773fb4f7cdSSrinivas Pandruvada { "weight", required_argument, 0, 'w' }, 2478354bd06fSSrinivas Pandruvada { "auto", no_argument, 0, 'a' }, 24793fb4f7cdSSrinivas Pandruvada { 0, 0, 0, 0 } 24803fb4f7cdSSrinivas Pandruvada }; 24813fb4f7cdSSrinivas Pandruvada 24823fb4f7cdSSrinivas Pandruvada option_index = start; 24833fb4f7cdSSrinivas Pandruvada 24843fb4f7cdSSrinivas Pandruvada optind = start + 1; 2485b86639e1SSrinivas Pandruvada while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:r:hoa", 24863fb4f7cdSSrinivas Pandruvada long_options, &option_index)) != -1) { 24873fb4f7cdSSrinivas Pandruvada switch (opt) { 2488354bd06fSSrinivas Pandruvada case 'a': 2489354bd06fSSrinivas Pandruvada auto_mode = 1; 2490354bd06fSSrinivas Pandruvada break; 24913fb4f7cdSSrinivas Pandruvada case 'b': 24923fb4f7cdSSrinivas Pandruvada fact_bucket = atoi(optarg); 24933fb4f7cdSSrinivas Pandruvada break; 24943fb4f7cdSSrinivas Pandruvada case 'h': 24953fb4f7cdSSrinivas Pandruvada cmd_help = 1; 24963fb4f7cdSSrinivas Pandruvada break; 24973fb4f7cdSSrinivas Pandruvada case 'l': 24983fb4f7cdSSrinivas Pandruvada tdp_level = atoi(optarg); 24993fb4f7cdSSrinivas Pandruvada break; 25003c64c81aSSrinivas Pandruvada case 'o': 25013c64c81aSSrinivas Pandruvada force_online_offline = 1; 25023c64c81aSSrinivas Pandruvada break; 25033fb4f7cdSSrinivas Pandruvada case 't': 25043fb4f7cdSSrinivas Pandruvada sscanf(optarg, "0x%llx", &fact_trl); 25053fb4f7cdSSrinivas Pandruvada break; 25063fb4f7cdSSrinivas Pandruvada case 'r': 25073fb4f7cdSSrinivas Pandruvada if (!strncmp(optarg, "sse", 3)) { 25083fb4f7cdSSrinivas Pandruvada fact_avx = 0x01; 25093fb4f7cdSSrinivas Pandruvada } else if (!strncmp(optarg, "avx2", 4)) { 25103fb4f7cdSSrinivas Pandruvada fact_avx = 0x02; 2511b86639e1SSrinivas Pandruvada } else if (!strncmp(optarg, "avx512", 6)) { 25123fb4f7cdSSrinivas Pandruvada fact_avx = 0x04; 25133fb4f7cdSSrinivas Pandruvada } else { 25143fb4f7cdSSrinivas Pandruvada fprintf(outf, "Invalid sse,avx options\n"); 25153fb4f7cdSSrinivas Pandruvada exit(1); 25163fb4f7cdSSrinivas Pandruvada } 25173fb4f7cdSSrinivas Pandruvada break; 25183fb4f7cdSSrinivas Pandruvada /* CLOS related */ 25193fb4f7cdSSrinivas Pandruvada case 'c': 25203fb4f7cdSSrinivas Pandruvada current_clos = atoi(optarg); 25213fb4f7cdSSrinivas Pandruvada break; 25223fb4f7cdSSrinivas Pandruvada case 'd': 25233fb4f7cdSSrinivas Pandruvada clos_desired = atoi(optarg); 252440dee9ddSSrinivas Pandruvada clos_desired /= DISP_FREQ_MULTIPLIER; 25253fb4f7cdSSrinivas Pandruvada break; 25263fb4f7cdSSrinivas Pandruvada case 'e': 25273fb4f7cdSSrinivas Pandruvada clos_epp = atoi(optarg); 2528fe6fb216SSrinivas Pandruvada if (is_skx_based_platform()) { 2529fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "epp can't be specified on this platform", 0, 0); 2530fe6fb216SSrinivas Pandruvada exit(0); 2531fe6fb216SSrinivas Pandruvada } 25323fb4f7cdSSrinivas Pandruvada break; 25333fb4f7cdSSrinivas Pandruvada case 'n': 25343fb4f7cdSSrinivas Pandruvada clos_min = atoi(optarg); 253540dee9ddSSrinivas Pandruvada clos_min /= DISP_FREQ_MULTIPLIER; 25363fb4f7cdSSrinivas Pandruvada break; 25373fb4f7cdSSrinivas Pandruvada case 'm': 25383fb4f7cdSSrinivas Pandruvada clos_max = atoi(optarg); 253940dee9ddSSrinivas Pandruvada clos_max /= DISP_FREQ_MULTIPLIER; 25403fb4f7cdSSrinivas Pandruvada break; 25413fb4f7cdSSrinivas Pandruvada case 'p': 25423fb4f7cdSSrinivas Pandruvada clos_priority_type = atoi(optarg); 2543fe6fb216SSrinivas Pandruvada if (is_skx_based_platform() && !clos_priority_type) { 2544fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid clos priority type: proportional for this platform", 0, 0); 2545fe6fb216SSrinivas Pandruvada exit(0); 2546fe6fb216SSrinivas Pandruvada } 25473fb4f7cdSSrinivas Pandruvada break; 25483fb4f7cdSSrinivas Pandruvada case 'w': 25493fb4f7cdSSrinivas Pandruvada clos_prop_prio = atoi(optarg); 2550fe6fb216SSrinivas Pandruvada if (is_skx_based_platform()) { 2551fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "weight can't be specified on this platform", 0, 0); 2552fe6fb216SSrinivas Pandruvada exit(0); 2553fe6fb216SSrinivas Pandruvada } 25543fb4f7cdSSrinivas Pandruvada break; 25553fb4f7cdSSrinivas Pandruvada default: 25564a960353SSrinivas Pandruvada printf("Unknown option: ignore\n"); 25573fb4f7cdSSrinivas Pandruvada } 25583fb4f7cdSSrinivas Pandruvada } 25594a960353SSrinivas Pandruvada 25604a960353SSrinivas Pandruvada if (argv[optind]) 25614a960353SSrinivas Pandruvada printf("Garbage at the end of command: ignore\n"); 25623fb4f7cdSSrinivas Pandruvada } 25633fb4f7cdSSrinivas Pandruvada 25643fb4f7cdSSrinivas Pandruvada static void isst_help(void) 25653fb4f7cdSSrinivas Pandruvada { 25663fb4f7cdSSrinivas Pandruvada printf("perf-profile:\tAn architectural mechanism that allows multiple optimized \n\ 25673fb4f7cdSSrinivas Pandruvada performance profiles per system via static and/or dynamic\n\ 25683fb4f7cdSSrinivas Pandruvada adjustment of core count, workload, Tjmax, and\n\ 25693fb4f7cdSSrinivas Pandruvada TDP, etc.\n"); 25703fb4f7cdSSrinivas Pandruvada printf("\nCommands : For feature=perf-profile\n"); 25713fb4f7cdSSrinivas Pandruvada printf("\tinfo\n"); 2572c829f0efSPrarit Bhargava 2573c829f0efSPrarit Bhargava if (!is_clx_n_platform()) { 25743fb4f7cdSSrinivas Pandruvada printf("\tget-lock-status\n"); 25753fb4f7cdSSrinivas Pandruvada printf("\tget-config-levels\n"); 25763fb4f7cdSSrinivas Pandruvada printf("\tget-config-version\n"); 25773fb4f7cdSSrinivas Pandruvada printf("\tget-config-enabled\n"); 25783fb4f7cdSSrinivas Pandruvada printf("\tget-config-current-level\n"); 25793fb4f7cdSSrinivas Pandruvada printf("\tset-config-level\n"); 25803fb4f7cdSSrinivas Pandruvada } 2581c829f0efSPrarit Bhargava } 25823fb4f7cdSSrinivas Pandruvada 25833fb4f7cdSSrinivas Pandruvada static void pbf_help(void) 25843fb4f7cdSSrinivas Pandruvada { 25853fb4f7cdSSrinivas Pandruvada printf("base-freq:\tEnables users to increase guaranteed base frequency\n\ 25863fb4f7cdSSrinivas Pandruvada on certain cores (high priority cores) in exchange for lower\n\ 25873fb4f7cdSSrinivas Pandruvada base frequency on remaining cores (low priority cores).\n"); 25883fb4f7cdSSrinivas Pandruvada printf("\tcommand : info\n"); 25893fb4f7cdSSrinivas Pandruvada printf("\tcommand : enable\n"); 25903fb4f7cdSSrinivas Pandruvada printf("\tcommand : disable\n"); 25913fb4f7cdSSrinivas Pandruvada } 25923fb4f7cdSSrinivas Pandruvada 25933fb4f7cdSSrinivas Pandruvada static void fact_help(void) 25943fb4f7cdSSrinivas Pandruvada { 25953fb4f7cdSSrinivas Pandruvada printf("turbo-freq:\tEnables the ability to set different turbo ratio\n\ 25963fb4f7cdSSrinivas Pandruvada limits to cores based on priority.\n"); 25973fb4f7cdSSrinivas Pandruvada printf("\nCommand: For feature=turbo-freq\n"); 25983fb4f7cdSSrinivas Pandruvada printf("\tcommand : info\n"); 25993fb4f7cdSSrinivas Pandruvada printf("\tcommand : enable\n"); 26003fb4f7cdSSrinivas Pandruvada printf("\tcommand : disable\n"); 26013fb4f7cdSSrinivas Pandruvada } 26023fb4f7cdSSrinivas Pandruvada 2603*006050a6SSrinivas Pandruvada static void turbo_mode_help(void) 2604*006050a6SSrinivas Pandruvada { 2605*006050a6SSrinivas Pandruvada printf("turbo-mode:\tEnables users to enable/disable turbo mode by adjusting frequency settings\n"); 2606*006050a6SSrinivas Pandruvada printf("\tcommand : enable\n"); 2607*006050a6SSrinivas Pandruvada printf("\tcommand : disable\n"); 2608*006050a6SSrinivas Pandruvada } 2609*006050a6SSrinivas Pandruvada 2610*006050a6SSrinivas Pandruvada 26113fb4f7cdSSrinivas Pandruvada static void core_power_help(void) 26123fb4f7cdSSrinivas Pandruvada { 26133fb4f7cdSSrinivas Pandruvada printf("core-power:\tInterface that allows user to define per core/tile\n\ 26143fb4f7cdSSrinivas Pandruvada priority.\n"); 26153fb4f7cdSSrinivas Pandruvada printf("\nCommands : For feature=core-power\n"); 26163fb4f7cdSSrinivas Pandruvada printf("\tinfo\n"); 26173fb4f7cdSSrinivas Pandruvada printf("\tenable\n"); 26183fb4f7cdSSrinivas Pandruvada printf("\tdisable\n"); 26193fb4f7cdSSrinivas Pandruvada printf("\tconfig\n"); 2620188afed9SSrinivas Pandruvada printf("\tget-config\n"); 26213fb4f7cdSSrinivas Pandruvada printf("\tassoc\n"); 26223fb4f7cdSSrinivas Pandruvada printf("\tget-assoc\n"); 26233fb4f7cdSSrinivas Pandruvada } 26243fb4f7cdSSrinivas Pandruvada 26253fb4f7cdSSrinivas Pandruvada struct process_cmd_help_struct { 26263fb4f7cdSSrinivas Pandruvada char *feature; 26273fb4f7cdSSrinivas Pandruvada void (*process_fn)(void); 26283fb4f7cdSSrinivas Pandruvada }; 26293fb4f7cdSSrinivas Pandruvada 26303fb4f7cdSSrinivas Pandruvada static struct process_cmd_help_struct isst_help_cmds[] = { 26313fb4f7cdSSrinivas Pandruvada { "perf-profile", isst_help }, 26323fb4f7cdSSrinivas Pandruvada { "base-freq", pbf_help }, 26333fb4f7cdSSrinivas Pandruvada { "turbo-freq", fact_help }, 26343fb4f7cdSSrinivas Pandruvada { "core-power", core_power_help }, 2635*006050a6SSrinivas Pandruvada { "turbo-mode", turbo_mode_help }, 26363fb4f7cdSSrinivas Pandruvada { NULL, NULL } 26373fb4f7cdSSrinivas Pandruvada }; 26383fb4f7cdSSrinivas Pandruvada 2639c829f0efSPrarit Bhargava static struct process_cmd_help_struct clx_n_help_cmds[] = { 2640c829f0efSPrarit Bhargava { "perf-profile", isst_help }, 2641c829f0efSPrarit Bhargava { "base-freq", pbf_help }, 2642c829f0efSPrarit Bhargava { NULL, NULL } 2643c829f0efSPrarit Bhargava }; 2644c829f0efSPrarit Bhargava 2645210369dcSPrarit Bhargava void process_command(int argc, char **argv, 2646210369dcSPrarit Bhargava struct process_cmd_help_struct *help_cmds, 2647210369dcSPrarit Bhargava struct process_cmd_struct *cmds) 26483fb4f7cdSSrinivas Pandruvada { 26493fb4f7cdSSrinivas Pandruvada int i = 0, matched = 0; 26503fb4f7cdSSrinivas Pandruvada char *feature = argv[optind]; 26513fb4f7cdSSrinivas Pandruvada char *cmd = argv[optind + 1]; 26523fb4f7cdSSrinivas Pandruvada 26533fb4f7cdSSrinivas Pandruvada if (!feature || !cmd) 26543fb4f7cdSSrinivas Pandruvada return; 26553fb4f7cdSSrinivas Pandruvada 26563fb4f7cdSSrinivas Pandruvada debug_printf("feature name [%s] command [%s]\n", feature, cmd); 26573fb4f7cdSSrinivas Pandruvada if (!strcmp(cmd, "-h") || !strcmp(cmd, "--help")) { 2658210369dcSPrarit Bhargava while (help_cmds[i].feature) { 2659210369dcSPrarit Bhargava if (!strcmp(help_cmds[i].feature, feature)) { 2660210369dcSPrarit Bhargava help_cmds[i].process_fn(); 26613fb4f7cdSSrinivas Pandruvada exit(0); 26623fb4f7cdSSrinivas Pandruvada } 26633fb4f7cdSSrinivas Pandruvada ++i; 26643fb4f7cdSSrinivas Pandruvada } 26653fb4f7cdSSrinivas Pandruvada } 26663fb4f7cdSSrinivas Pandruvada 2667062e4aacSPrarit Bhargava if (!is_clx_n_platform()) 26683fb4f7cdSSrinivas Pandruvada create_cpu_map(); 26693fb4f7cdSSrinivas Pandruvada 26703fb4f7cdSSrinivas Pandruvada i = 0; 2671210369dcSPrarit Bhargava while (cmds[i].feature) { 2672210369dcSPrarit Bhargava if (!strcmp(cmds[i].feature, feature) && 2673210369dcSPrarit Bhargava !strcmp(cmds[i].command, cmd)) { 26743fb4f7cdSSrinivas Pandruvada parse_cmd_args(argc, optind + 1, argv); 2675210369dcSPrarit Bhargava cmds[i].process_fn(cmds[i].arg); 26763fb4f7cdSSrinivas Pandruvada matched = 1; 26773fb4f7cdSSrinivas Pandruvada break; 26783fb4f7cdSSrinivas Pandruvada } 26793fb4f7cdSSrinivas Pandruvada ++i; 26803fb4f7cdSSrinivas Pandruvada } 26813fb4f7cdSSrinivas Pandruvada 26823fb4f7cdSSrinivas Pandruvada if (!matched) 26833fb4f7cdSSrinivas Pandruvada fprintf(stderr, "Invalid command\n"); 26843fb4f7cdSSrinivas Pandruvada } 26853fb4f7cdSSrinivas Pandruvada 26863fb4f7cdSSrinivas Pandruvada static void usage(void) 26873fb4f7cdSSrinivas Pandruvada { 2688addd116dSSrinivas Pandruvada if (is_clx_n_platform()) { 2689addd116dSSrinivas Pandruvada fprintf(stderr, "\nThere is limited support of Intel Speed Select features on this platform.\n"); 2690addd116dSSrinivas Pandruvada fprintf(stderr, "Everything is pre-configured using BIOS options, this tool can't enable any feature in the hardware.\n\n"); 2691addd116dSSrinivas Pandruvada } 2692addd116dSSrinivas Pandruvada 26933fb4f7cdSSrinivas Pandruvada printf("\nUsage:\n"); 26943fb4f7cdSSrinivas Pandruvada printf("intel-speed-select [OPTIONS] FEATURE COMMAND COMMAND_ARGUMENTS\n"); 2695addd116dSSrinivas Pandruvada printf("\nUse this tool to enumerate and control the Intel Speed Select Technology features:\n"); 2696addd116dSSrinivas Pandruvada if (is_clx_n_platform()) 2697addd116dSSrinivas Pandruvada printf("\nFEATURE : [perf-profile|base-freq]\n"); 2698addd116dSSrinivas Pandruvada else 2699*006050a6SSrinivas Pandruvada printf("\nFEATURE : [perf-profile|base-freq|turbo-freq|core-power|turbo-mode]\n"); 270043774c0dSPrarit Bhargava printf("\nFor help on each feature, use -h|--help\n"); 27013fb4f7cdSSrinivas Pandruvada printf("\tFor example: intel-speed-select perf-profile -h\n"); 27023fb4f7cdSSrinivas Pandruvada 27033fb4f7cdSSrinivas Pandruvada printf("\nFor additional help on each command for a feature, use --h|--help\n"); 27043fb4f7cdSSrinivas Pandruvada printf("\tFor example: intel-speed-select perf-profile get-lock-status -h\n"); 27053fb4f7cdSSrinivas Pandruvada printf("\t\t This will print help for the command \"get-lock-status\" for the feature \"perf-profile\"\n"); 27063fb4f7cdSSrinivas Pandruvada 27073fb4f7cdSSrinivas Pandruvada printf("\nOPTIONS\n"); 27083fb4f7cdSSrinivas Pandruvada printf("\t[-c|--cpu] : logical cpu number\n"); 27093fb4f7cdSSrinivas Pandruvada printf("\t\tDefault: Die scoped for all dies in the system with multiple dies/package\n"); 27103fb4f7cdSSrinivas Pandruvada printf("\t\t\t Or Package scoped for all Packages when each package contains one die\n"); 27113fb4f7cdSSrinivas Pandruvada printf("\t[-d|--debug] : Debug mode\n"); 2712addd116dSSrinivas Pandruvada printf("\t[-f|--format] : output format [json|text]. Default: text\n"); 27133fb4f7cdSSrinivas Pandruvada printf("\t[-h|--help] : Print help\n"); 27143fb4f7cdSSrinivas Pandruvada printf("\t[-i|--info] : Print platform information\n"); 27153fb4f7cdSSrinivas Pandruvada printf("\t[-o|--out] : Output file\n"); 27163fb4f7cdSSrinivas Pandruvada printf("\t\t\tDefault : stderr\n"); 2717a85a35fcSSrinivas Pandruvada printf("\t[-p|--pause] : Delay between two mail box commands in milliseconds\n"); 271832279be7SSrinivas Pandruvada printf("\t[-r|--retry] : Retry count for mail box commands on failure, default 3\n"); 27193fb4f7cdSSrinivas Pandruvada printf("\t[-v|--version] : Print version\n"); 27203fb4f7cdSSrinivas Pandruvada 27213fb4f7cdSSrinivas Pandruvada printf("\nResult format\n"); 27223fb4f7cdSSrinivas Pandruvada printf("\tResult display uses a common format for each command:\n"); 27233fb4f7cdSSrinivas Pandruvada printf("\tResults are formatted in text/JSON with\n"); 27243fb4f7cdSSrinivas Pandruvada printf("\t\tPackage, Die, CPU, and command specific results.\n"); 2725addd116dSSrinivas Pandruvada 2726addd116dSSrinivas Pandruvada printf("\nExamples\n"); 2727addd116dSSrinivas Pandruvada printf("\tTo get platform information:\n"); 2728addd116dSSrinivas Pandruvada printf("\t\tintel-speed-select --info\n"); 2729addd116dSSrinivas Pandruvada printf("\tTo get full perf-profile information dump:\n"); 2730addd116dSSrinivas Pandruvada printf("\t\tintel-speed-select perf-profile info\n"); 2731addd116dSSrinivas Pandruvada printf("\tTo get full base-freq information dump:\n"); 2732addd116dSSrinivas Pandruvada printf("\t\tintel-speed-select base-freq info -l 0\n"); 2733addd116dSSrinivas Pandruvada if (!is_clx_n_platform()) { 2734addd116dSSrinivas Pandruvada printf("\tTo get full turbo-freq information dump:\n"); 2735addd116dSSrinivas Pandruvada printf("\t\tintel-speed-select turbo-freq info -l 0\n"); 2736addd116dSSrinivas Pandruvada } 27373fb4f7cdSSrinivas Pandruvada exit(1); 27383fb4f7cdSSrinivas Pandruvada } 27393fb4f7cdSSrinivas Pandruvada 27403fb4f7cdSSrinivas Pandruvada static void print_version(void) 27413fb4f7cdSSrinivas Pandruvada { 27423fb4f7cdSSrinivas Pandruvada fprintf(outf, "Version %s\n", version_str); 27433fb4f7cdSSrinivas Pandruvada fprintf(outf, "Build date %s time %s\n", __DATE__, __TIME__); 27443fb4f7cdSSrinivas Pandruvada exit(0); 27453fb4f7cdSSrinivas Pandruvada } 27463fb4f7cdSSrinivas Pandruvada 27473fb4f7cdSSrinivas Pandruvada static void cmdline(int argc, char **argv) 27483fb4f7cdSSrinivas Pandruvada { 2749f362cdccSSrinivas Pandruvada const char *pathname = "/dev/isst_interface"; 2750a85a35fcSSrinivas Pandruvada char *ptr; 2751f362cdccSSrinivas Pandruvada FILE *fp; 27523fb4f7cdSSrinivas Pandruvada int opt; 27533fb4f7cdSSrinivas Pandruvada int option_index = 0; 27543bc3d30cSPrarit Bhargava int ret; 27553fb4f7cdSSrinivas Pandruvada 27563fb4f7cdSSrinivas Pandruvada static struct option long_options[] = { 27573fb4f7cdSSrinivas Pandruvada { "cpu", required_argument, 0, 'c' }, 27583fb4f7cdSSrinivas Pandruvada { "debug", no_argument, 0, 'd' }, 27593fb4f7cdSSrinivas Pandruvada { "format", required_argument, 0, 'f' }, 27603fb4f7cdSSrinivas Pandruvada { "help", no_argument, 0, 'h' }, 27613fb4f7cdSSrinivas Pandruvada { "info", no_argument, 0, 'i' }, 2762a85a35fcSSrinivas Pandruvada { "pause", required_argument, 0, 'p' }, 27633fb4f7cdSSrinivas Pandruvada { "out", required_argument, 0, 'o' }, 276432279be7SSrinivas Pandruvada { "retry", required_argument, 0, 'r' }, 27653fb4f7cdSSrinivas Pandruvada { "version", no_argument, 0, 'v' }, 27663fb4f7cdSSrinivas Pandruvada { 0, 0, 0, 0 } 27673fb4f7cdSSrinivas Pandruvada }; 27683fb4f7cdSSrinivas Pandruvada 2769f362cdccSSrinivas Pandruvada if (geteuid() != 0) { 2770f362cdccSSrinivas Pandruvada fprintf(stderr, "Must run as root\n"); 2771f362cdccSSrinivas Pandruvada exit(0); 2772f362cdccSSrinivas Pandruvada } 2773f362cdccSSrinivas Pandruvada 2774f362cdccSSrinivas Pandruvada ret = update_cpu_model(); 2775f362cdccSSrinivas Pandruvada if (ret) 2776f362cdccSSrinivas Pandruvada err(-1, "Invalid CPU model (%d)\n", cpu_model); 2777f362cdccSSrinivas Pandruvada printf("Intel(R) Speed Select Technology\n"); 2778f362cdccSSrinivas Pandruvada printf("Executing on CPU model:%d[0x%x]\n", cpu_model, cpu_model); 2779f362cdccSSrinivas Pandruvada 2780f362cdccSSrinivas Pandruvada if (!is_clx_n_platform()) { 2781f362cdccSSrinivas Pandruvada fp = fopen(pathname, "rb"); 2782f362cdccSSrinivas Pandruvada if (!fp) { 2783f362cdccSSrinivas Pandruvada fprintf(stderr, "Intel speed select drivers are not loaded on this system.\n"); 2784f362cdccSSrinivas Pandruvada fprintf(stderr, "Verify that kernel config includes CONFIG_INTEL_SPEED_SELECT_INTERFACE.\n"); 2785f362cdccSSrinivas Pandruvada fprintf(stderr, "If the config is included then this is not a supported platform.\n"); 2786f362cdccSSrinivas Pandruvada exit(0); 2787f362cdccSSrinivas Pandruvada } 2788f362cdccSSrinivas Pandruvada fclose(fp); 2789f362cdccSSrinivas Pandruvada } 2790f362cdccSSrinivas Pandruvada 27913fb4f7cdSSrinivas Pandruvada progname = argv[0]; 27923fb4f7cdSSrinivas Pandruvada while ((opt = getopt_long_only(argc, argv, "+c:df:hio:v", long_options, 27933fb4f7cdSSrinivas Pandruvada &option_index)) != -1) { 27943fb4f7cdSSrinivas Pandruvada switch (opt) { 27953fb4f7cdSSrinivas Pandruvada case 'c': 27963fb4f7cdSSrinivas Pandruvada parse_cpu_command(optarg); 27973fb4f7cdSSrinivas Pandruvada break; 27983fb4f7cdSSrinivas Pandruvada case 'd': 27993fb4f7cdSSrinivas Pandruvada debug_flag = 1; 28003fb4f7cdSSrinivas Pandruvada printf("Debug Mode ON\n"); 28013fb4f7cdSSrinivas Pandruvada break; 28023fb4f7cdSSrinivas Pandruvada case 'f': 28033fb4f7cdSSrinivas Pandruvada if (!strncmp(optarg, "json", 4)) 28043fb4f7cdSSrinivas Pandruvada out_format_json = 1; 28053fb4f7cdSSrinivas Pandruvada break; 28063fb4f7cdSSrinivas Pandruvada case 'h': 28073fb4f7cdSSrinivas Pandruvada usage(); 28083fb4f7cdSSrinivas Pandruvada break; 28093fb4f7cdSSrinivas Pandruvada case 'i': 28103fb4f7cdSSrinivas Pandruvada isst_print_platform_information(); 28113fb4f7cdSSrinivas Pandruvada break; 28123fb4f7cdSSrinivas Pandruvada case 'o': 28133fb4f7cdSSrinivas Pandruvada if (outf) 28143fb4f7cdSSrinivas Pandruvada fclose(outf); 28153fb4f7cdSSrinivas Pandruvada outf = fopen_or_exit(optarg, "w"); 28163fb4f7cdSSrinivas Pandruvada break; 2817a85a35fcSSrinivas Pandruvada case 'p': 2818a85a35fcSSrinivas Pandruvada ret = strtol(optarg, &ptr, 10); 2819a85a35fcSSrinivas Pandruvada if (!ret) 2820a85a35fcSSrinivas Pandruvada fprintf(stderr, "Invalid pause interval, ignore\n"); 2821a85a35fcSSrinivas Pandruvada else 2822a85a35fcSSrinivas Pandruvada mbox_delay = ret; 2823a85a35fcSSrinivas Pandruvada break; 282432279be7SSrinivas Pandruvada case 'r': 282532279be7SSrinivas Pandruvada ret = strtol(optarg, &ptr, 10); 282632279be7SSrinivas Pandruvada if (!ret) 282732279be7SSrinivas Pandruvada fprintf(stderr, "Invalid retry count, ignore\n"); 282832279be7SSrinivas Pandruvada else 282932279be7SSrinivas Pandruvada mbox_retries = ret; 283032279be7SSrinivas Pandruvada break; 28313fb4f7cdSSrinivas Pandruvada case 'v': 28323fb4f7cdSSrinivas Pandruvada print_version(); 28333fb4f7cdSSrinivas Pandruvada break; 28343fb4f7cdSSrinivas Pandruvada default: 28353fb4f7cdSSrinivas Pandruvada usage(); 28363fb4f7cdSSrinivas Pandruvada } 28373fb4f7cdSSrinivas Pandruvada } 28383fb4f7cdSSrinivas Pandruvada 28393fb4f7cdSSrinivas Pandruvada if (optind > (argc - 2)) { 2840addd116dSSrinivas Pandruvada usage(); 28413fb4f7cdSSrinivas Pandruvada exit(0); 28423fb4f7cdSSrinivas Pandruvada } 28433fb4f7cdSSrinivas Pandruvada set_max_cpu_num(); 2844fb186158SSrinivas Pandruvada store_cpu_topology(); 28453fb4f7cdSSrinivas Pandruvada set_cpu_present_cpu_mask(); 28463fb4f7cdSSrinivas Pandruvada set_cpu_target_cpu_mask(); 2847c829f0efSPrarit Bhargava 2848c829f0efSPrarit Bhargava if (!is_clx_n_platform()) { 28493bc3d30cSPrarit Bhargava ret = isst_fill_platform_info(); 28503bc3d30cSPrarit Bhargava if (ret) 28513bc3d30cSPrarit Bhargava goto out; 2852210369dcSPrarit Bhargava process_command(argc, argv, isst_help_cmds, isst_cmds); 2853c829f0efSPrarit Bhargava } else { 2854c829f0efSPrarit Bhargava process_command(argc, argv, clx_n_help_cmds, clx_n_cmds); 2855c829f0efSPrarit Bhargava } 28563bc3d30cSPrarit Bhargava out: 28573bc3d30cSPrarit Bhargava free_cpu_set(present_cpumask); 28583bc3d30cSPrarit Bhargava free_cpu_set(target_cpumask); 28593fb4f7cdSSrinivas Pandruvada } 28603fb4f7cdSSrinivas Pandruvada 28613fb4f7cdSSrinivas Pandruvada int main(int argc, char **argv) 28623fb4f7cdSSrinivas Pandruvada { 28633fb4f7cdSSrinivas Pandruvada outf = stderr; 28643fb4f7cdSSrinivas Pandruvada cmdline(argc, argv); 28653fb4f7cdSSrinivas Pandruvada return 0; 28663fb4f7cdSSrinivas Pandruvada } 2867