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 18d1fcb749SSrinivas Pandruvada static const char *version_str = "v1.14"; 19f3874e96SSrinivas Pandruvada 203fb4f7cdSSrinivas Pandruvada static const int supported_api_ver = 1; 213fb4f7cdSSrinivas Pandruvada static struct isst_if_platform_info isst_platform_info; 223fb4f7cdSSrinivas Pandruvada static char *progname; 233fb4f7cdSSrinivas Pandruvada static int debug_flag; 243fb4f7cdSSrinivas Pandruvada static FILE *outf; 253fb4f7cdSSrinivas Pandruvada 263fb4f7cdSSrinivas Pandruvada static int cpu_model; 271c1d935cSPrarit Bhargava static int cpu_stepping; 283fb4f7cdSSrinivas Pandruvada 29e16ea663SSrinivas Pandruvada #define MAX_CPUS_IN_ONE_REQ 256 303fb4f7cdSSrinivas Pandruvada static short max_target_cpus; 313fb4f7cdSSrinivas Pandruvada static unsigned short target_cpus[MAX_CPUS_IN_ONE_REQ]; 323fb4f7cdSSrinivas Pandruvada 333fb4f7cdSSrinivas Pandruvada static int topo_max_cpus; 343fb4f7cdSSrinivas Pandruvada static size_t present_cpumask_size; 353fb4f7cdSSrinivas Pandruvada static cpu_set_t *present_cpumask; 363fb4f7cdSSrinivas Pandruvada static size_t target_cpumask_size; 373fb4f7cdSSrinivas Pandruvada static cpu_set_t *target_cpumask; 383fb4f7cdSSrinivas Pandruvada static int tdp_level = 0xFF; 393fb4f7cdSSrinivas Pandruvada static int fact_bucket = 0xFF; 403fb4f7cdSSrinivas Pandruvada static int fact_avx = 0xFF; 413fb4f7cdSSrinivas Pandruvada static unsigned long long fact_trl; 423fb4f7cdSSrinivas Pandruvada static int out_format_json; 433fb4f7cdSSrinivas Pandruvada static int cmd_help; 443c64c81aSSrinivas Pandruvada static int force_online_offline; 45354bd06fSSrinivas Pandruvada static int auto_mode; 4614a8aa49SSrinivas Pandruvada static int fact_enable_fail; 473fb4f7cdSSrinivas Pandruvada 483fb4f7cdSSrinivas Pandruvada /* clos related */ 493fb4f7cdSSrinivas Pandruvada static int current_clos = -1; 503fb4f7cdSSrinivas Pandruvada static int clos_epp = -1; 513fb4f7cdSSrinivas Pandruvada static int clos_prop_prio = -1; 523fb4f7cdSSrinivas Pandruvada static int clos_min = -1; 533fb4f7cdSSrinivas Pandruvada static int clos_max = -1; 543fb4f7cdSSrinivas Pandruvada static int clos_desired = -1; 553fb4f7cdSSrinivas Pandruvada static int clos_priority_type; 563fb4f7cdSSrinivas Pandruvada 573fb4f7cdSSrinivas Pandruvada struct _cpu_map { 583fb4f7cdSSrinivas Pandruvada unsigned short core_id; 593fb4f7cdSSrinivas Pandruvada unsigned short pkg_id; 603fb4f7cdSSrinivas Pandruvada unsigned short die_id; 61e157c847SZhang Rui unsigned short punit_id; 623fb4f7cdSSrinivas Pandruvada unsigned short punit_cpu; 633fb4f7cdSSrinivas Pandruvada unsigned short punit_cpu_core; 64ca56725dSZhang Rui unsigned short initialized; 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 809798768cSZhang Rui int is_debug_enabled(void) 819798768cSZhang Rui { 829798768cSZhang Rui return debug_flag; 839798768cSZhang Rui } 849798768cSZhang Rui 853fb4f7cdSSrinivas Pandruvada void debug_printf(const char *format, ...) 863fb4f7cdSSrinivas Pandruvada { 873fb4f7cdSSrinivas Pandruvada va_list args; 883fb4f7cdSSrinivas Pandruvada 893fb4f7cdSSrinivas Pandruvada va_start(args, format); 903fb4f7cdSSrinivas Pandruvada 913fb4f7cdSSrinivas Pandruvada if (debug_flag) 923fb4f7cdSSrinivas Pandruvada vprintf(format, args); 933fb4f7cdSSrinivas Pandruvada 943fb4f7cdSSrinivas Pandruvada va_end(args); 953fb4f7cdSSrinivas Pandruvada } 963fb4f7cdSSrinivas Pandruvada 971c1d935cSPrarit Bhargava 981c1d935cSPrarit Bhargava int is_clx_n_platform(void) 991c1d935cSPrarit Bhargava { 1001c1d935cSPrarit Bhargava if (cpu_model == 0x55) 1011c1d935cSPrarit Bhargava if (cpu_stepping == 0x6 || cpu_stepping == 0x7) 1021c1d935cSPrarit Bhargava return 1; 1031c1d935cSPrarit Bhargava return 0; 1041c1d935cSPrarit Bhargava } 1051c1d935cSPrarit Bhargava 10695f8e569SSrinivas Pandruvada int is_skx_based_platform(void) 10795f8e569SSrinivas Pandruvada { 10895f8e569SSrinivas Pandruvada if (cpu_model == 0x55) 10995f8e569SSrinivas Pandruvada return 1; 11095f8e569SSrinivas Pandruvada 11195f8e569SSrinivas Pandruvada return 0; 11295f8e569SSrinivas Pandruvada } 11395f8e569SSrinivas Pandruvada 114159f130fSSrinivas Pandruvada int is_spr_platform(void) 115159f130fSSrinivas Pandruvada { 11661f9fdcdSZhang Rui if (cpu_model == 0x8F || cpu_model == 0xCF) 117159f130fSSrinivas Pandruvada return 1; 118159f130fSSrinivas Pandruvada 119159f130fSSrinivas Pandruvada return 0; 120159f130fSSrinivas Pandruvada } 121159f130fSSrinivas Pandruvada 122159f130fSSrinivas Pandruvada int is_icx_platform(void) 123159f130fSSrinivas Pandruvada { 124159f130fSSrinivas Pandruvada if (cpu_model == 0x6A || cpu_model == 0x6C) 125159f130fSSrinivas Pandruvada return 1; 126159f130fSSrinivas Pandruvada 127159f130fSSrinivas Pandruvada return 0; 128159f130fSSrinivas Pandruvada } 129159f130fSSrinivas Pandruvada 1301c1d935cSPrarit Bhargava static int update_cpu_model(void) 1313fb4f7cdSSrinivas Pandruvada { 1323fb4f7cdSSrinivas Pandruvada unsigned int ebx, ecx, edx; 1333fb4f7cdSSrinivas Pandruvada unsigned int fms, family; 1343fb4f7cdSSrinivas Pandruvada 1353fb4f7cdSSrinivas Pandruvada __cpuid(1, fms, ebx, ecx, edx); 1363fb4f7cdSSrinivas Pandruvada family = (fms >> 8) & 0xf; 1373fb4f7cdSSrinivas Pandruvada cpu_model = (fms >> 4) & 0xf; 1383fb4f7cdSSrinivas Pandruvada if (family == 6 || family == 0xf) 1393fb4f7cdSSrinivas Pandruvada cpu_model += ((fms >> 16) & 0xf) << 4; 1401c1d935cSPrarit Bhargava 1411c1d935cSPrarit Bhargava cpu_stepping = fms & 0xf; 1421c1d935cSPrarit Bhargava /* only three CascadeLake-N models are supported */ 1431c1d935cSPrarit Bhargava if (is_clx_n_platform()) { 1441c1d935cSPrarit Bhargava FILE *fp; 1451c1d935cSPrarit Bhargava size_t n = 0; 1461c1d935cSPrarit Bhargava char *line = NULL; 1471c1d935cSPrarit Bhargava int ret = 1; 1481c1d935cSPrarit Bhargava 1491c1d935cSPrarit Bhargava fp = fopen("/proc/cpuinfo", "r"); 1501c1d935cSPrarit Bhargava if (!fp) 1511c1d935cSPrarit Bhargava err(-1, "cannot open /proc/cpuinfo\n"); 1521c1d935cSPrarit Bhargava 1531c1d935cSPrarit Bhargava while (getline(&line, &n, fp) > 0) { 1541c1d935cSPrarit Bhargava if (strstr(line, "model name")) { 1551c1d935cSPrarit Bhargava if (strstr(line, "6252N") || 1561c1d935cSPrarit Bhargava strstr(line, "6230N") || 1571c1d935cSPrarit Bhargava strstr(line, "5218N")) 1581c1d935cSPrarit Bhargava ret = 0; 1591c1d935cSPrarit Bhargava break; 1601c1d935cSPrarit Bhargava } 1611c1d935cSPrarit Bhargava } 1621c1d935cSPrarit Bhargava free(line); 1631c1d935cSPrarit Bhargava fclose(fp); 1641c1d935cSPrarit Bhargava return ret; 1651c1d935cSPrarit Bhargava } 1661c1d935cSPrarit Bhargava return 0; 1673fb4f7cdSSrinivas Pandruvada } 1683fb4f7cdSSrinivas Pandruvada 169887e5be9SZhang Rui int api_version(void) 170887e5be9SZhang Rui { 171887e5be9SZhang Rui return isst_platform_info.api_version; 172887e5be9SZhang Rui } 173887e5be9SZhang Rui 1743fb4f7cdSSrinivas Pandruvada /* Open a file, and exit on failure */ 1753fb4f7cdSSrinivas Pandruvada static FILE *fopen_or_exit(const char *path, const char *mode) 1763fb4f7cdSSrinivas Pandruvada { 1773fb4f7cdSSrinivas Pandruvada FILE *filep = fopen(path, mode); 1783fb4f7cdSSrinivas Pandruvada 1793fb4f7cdSSrinivas Pandruvada if (!filep) 1803fb4f7cdSSrinivas Pandruvada err(1, "%s: open failed", path); 1813fb4f7cdSSrinivas Pandruvada 1823fb4f7cdSSrinivas Pandruvada return filep; 1833fb4f7cdSSrinivas Pandruvada } 1843fb4f7cdSSrinivas Pandruvada 1853fb4f7cdSSrinivas Pandruvada /* Parse a file containing a single int */ 1863fb4f7cdSSrinivas Pandruvada static int parse_int_file(int fatal, const char *fmt, ...) 1873fb4f7cdSSrinivas Pandruvada { 1883fb4f7cdSSrinivas Pandruvada va_list args; 1893fb4f7cdSSrinivas Pandruvada char path[PATH_MAX]; 1903fb4f7cdSSrinivas Pandruvada FILE *filep; 1913fb4f7cdSSrinivas Pandruvada int value; 1923fb4f7cdSSrinivas Pandruvada 1933fb4f7cdSSrinivas Pandruvada va_start(args, fmt); 1943fb4f7cdSSrinivas Pandruvada vsnprintf(path, sizeof(path), fmt, args); 1953fb4f7cdSSrinivas Pandruvada va_end(args); 1963fb4f7cdSSrinivas Pandruvada if (fatal) { 1973fb4f7cdSSrinivas Pandruvada filep = fopen_or_exit(path, "r"); 1983fb4f7cdSSrinivas Pandruvada } else { 1993fb4f7cdSSrinivas Pandruvada filep = fopen(path, "r"); 2003fb4f7cdSSrinivas Pandruvada if (!filep) 2013fb4f7cdSSrinivas Pandruvada return -1; 2023fb4f7cdSSrinivas Pandruvada } 2033fb4f7cdSSrinivas Pandruvada if (fscanf(filep, "%d", &value) != 1) 2043fb4f7cdSSrinivas Pandruvada err(1, "%s: failed to parse number from file", path); 2053fb4f7cdSSrinivas Pandruvada fclose(filep); 2063fb4f7cdSSrinivas Pandruvada 2073fb4f7cdSSrinivas Pandruvada return value; 2083fb4f7cdSSrinivas Pandruvada } 2093fb4f7cdSSrinivas Pandruvada 2103fb4f7cdSSrinivas Pandruvada int cpufreq_sysfs_present(void) 2113fb4f7cdSSrinivas Pandruvada { 2123fb4f7cdSSrinivas Pandruvada DIR *dir; 2133fb4f7cdSSrinivas Pandruvada 2143fb4f7cdSSrinivas Pandruvada dir = opendir("/sys/devices/system/cpu/cpu0/cpufreq"); 2153fb4f7cdSSrinivas Pandruvada if (dir) { 2163fb4f7cdSSrinivas Pandruvada closedir(dir); 2173fb4f7cdSSrinivas Pandruvada return 1; 2183fb4f7cdSSrinivas Pandruvada } 2193fb4f7cdSSrinivas Pandruvada 2203fb4f7cdSSrinivas Pandruvada return 0; 2213fb4f7cdSSrinivas Pandruvada } 2223fb4f7cdSSrinivas Pandruvada 2233fb4f7cdSSrinivas Pandruvada int out_format_is_json(void) 2243fb4f7cdSSrinivas Pandruvada { 2253fb4f7cdSSrinivas Pandruvada return out_format_json; 2263fb4f7cdSSrinivas Pandruvada } 2273fb4f7cdSSrinivas Pandruvada 228fb186158SSrinivas Pandruvada static int get_stored_topology_info(int cpu, int *core_id, int *pkg_id, int *die_id) 229fb186158SSrinivas Pandruvada { 230b1d12cefSSrinivas Pandruvada const char *pathname = "/var/run/isst_cpu_topology.dat"; 231fb186158SSrinivas Pandruvada struct cpu_topology cpu_top; 232fb186158SSrinivas Pandruvada FILE *fp; 233fb186158SSrinivas Pandruvada int ret; 234fb186158SSrinivas Pandruvada 235fb186158SSrinivas Pandruvada fp = fopen(pathname, "rb"); 236fb186158SSrinivas Pandruvada if (!fp) 237fb186158SSrinivas Pandruvada return -1; 238fb186158SSrinivas Pandruvada 239fb186158SSrinivas Pandruvada ret = fseek(fp, cpu * sizeof(cpu_top), SEEK_SET); 240fb186158SSrinivas Pandruvada if (ret) 241fb186158SSrinivas Pandruvada goto err_ret; 242fb186158SSrinivas Pandruvada 243fb186158SSrinivas Pandruvada ret = fread(&cpu_top, sizeof(cpu_top), 1, fp); 244fb186158SSrinivas Pandruvada if (ret != 1) { 245fb186158SSrinivas Pandruvada ret = -1; 246fb186158SSrinivas Pandruvada goto err_ret; 247fb186158SSrinivas Pandruvada } 248fb186158SSrinivas Pandruvada 249fb186158SSrinivas Pandruvada *pkg_id = cpu_top.pkg_id; 250fb186158SSrinivas Pandruvada *core_id = cpu_top.core_id; 251fb186158SSrinivas Pandruvada *die_id = cpu_top.die_id; 252fb186158SSrinivas Pandruvada ret = 0; 253fb186158SSrinivas Pandruvada 254fb186158SSrinivas Pandruvada err_ret: 255fb186158SSrinivas Pandruvada fclose(fp); 256fb186158SSrinivas Pandruvada 257fb186158SSrinivas Pandruvada return ret; 258fb186158SSrinivas Pandruvada } 259fb186158SSrinivas Pandruvada 260fb186158SSrinivas Pandruvada static void store_cpu_topology(void) 261fb186158SSrinivas Pandruvada { 262b1d12cefSSrinivas Pandruvada const char *pathname = "/var/run/isst_cpu_topology.dat"; 263fb186158SSrinivas Pandruvada FILE *fp; 264fb186158SSrinivas Pandruvada int i; 265fb186158SSrinivas Pandruvada 266fb186158SSrinivas Pandruvada fp = fopen(pathname, "rb"); 267fb186158SSrinivas Pandruvada if (fp) { 268fb186158SSrinivas Pandruvada /* Mapping already exists */ 269fb186158SSrinivas Pandruvada fclose(fp); 270fb186158SSrinivas Pandruvada return; 271fb186158SSrinivas Pandruvada } 272fb186158SSrinivas Pandruvada 273fb186158SSrinivas Pandruvada fp = fopen(pathname, "wb"); 274fb186158SSrinivas Pandruvada if (!fp) { 275fb186158SSrinivas Pandruvada fprintf(stderr, "Can't create file:%s\n", pathname); 276fb186158SSrinivas Pandruvada return; 277fb186158SSrinivas Pandruvada } 278fb186158SSrinivas Pandruvada 279b1d12cefSSrinivas Pandruvada fprintf(stderr, "Caching topology information\n"); 280b1d12cefSSrinivas Pandruvada 281fb186158SSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) { 282fb186158SSrinivas Pandruvada struct cpu_topology cpu_top; 283fb186158SSrinivas Pandruvada 284fb186158SSrinivas Pandruvada cpu_top.core_id = parse_int_file(0, 285fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/core_id", i); 286fb186158SSrinivas Pandruvada if (cpu_top.core_id < 0) 287fb186158SSrinivas Pandruvada cpu_top.core_id = -1; 288fb186158SSrinivas Pandruvada 289fb186158SSrinivas Pandruvada cpu_top.pkg_id = parse_int_file(0, 290fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", i); 291fb186158SSrinivas Pandruvada if (cpu_top.pkg_id < 0) 292fb186158SSrinivas Pandruvada cpu_top.pkg_id = -1; 293fb186158SSrinivas Pandruvada 294fb186158SSrinivas Pandruvada cpu_top.die_id = parse_int_file(0, 295fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/die_id", i); 296fb186158SSrinivas Pandruvada if (cpu_top.die_id < 0) 297fb186158SSrinivas Pandruvada cpu_top.die_id = -1; 298fb186158SSrinivas Pandruvada 299fb186158SSrinivas Pandruvada cpu_top.cpu = i; 300fb186158SSrinivas Pandruvada 301fb186158SSrinivas Pandruvada if (fwrite(&cpu_top, sizeof(cpu_top), 1, fp) != 1) { 302fb186158SSrinivas Pandruvada fprintf(stderr, "Can't write to:%s\n", pathname); 303fb186158SSrinivas Pandruvada break; 304fb186158SSrinivas Pandruvada } 305fb186158SSrinivas Pandruvada } 306fb186158SSrinivas Pandruvada 307fb186158SSrinivas Pandruvada fclose(fp); 308fb186158SSrinivas Pandruvada } 309fb186158SSrinivas Pandruvada 310e616059eSZhang Rui static int get_physical_package_id(int cpu) 3113fb4f7cdSSrinivas Pandruvada { 312fb186158SSrinivas Pandruvada int ret; 313fb186158SSrinivas Pandruvada 314ca56725dSZhang Rui if (cpu < 0) 315ca56725dSZhang Rui return -1; 316ca56725dSZhang Rui 317ca56725dSZhang Rui if (cpu_map && cpu_map[cpu].initialized) 318ca56725dSZhang Rui return cpu_map[cpu].pkg_id; 319ca56725dSZhang Rui 320fb186158SSrinivas Pandruvada ret = parse_int_file(0, 321fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", 3223fb4f7cdSSrinivas Pandruvada cpu); 323fb186158SSrinivas Pandruvada if (ret < 0) { 324fb186158SSrinivas Pandruvada int core_id, pkg_id, die_id; 325fb186158SSrinivas Pandruvada 326fb186158SSrinivas Pandruvada ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id); 327fb186158SSrinivas Pandruvada if (!ret) 328fb186158SSrinivas Pandruvada return pkg_id; 329fb186158SSrinivas Pandruvada } 330fb186158SSrinivas Pandruvada 331fb186158SSrinivas Pandruvada return ret; 3323fb4f7cdSSrinivas Pandruvada } 3333fb4f7cdSSrinivas Pandruvada 334e616059eSZhang Rui static int get_physical_core_id(int cpu) 3353fb4f7cdSSrinivas Pandruvada { 336fb186158SSrinivas Pandruvada int ret; 337fb186158SSrinivas Pandruvada 338ca56725dSZhang Rui if (cpu < 0) 339ca56725dSZhang Rui return -1; 340ca56725dSZhang Rui 341ca56725dSZhang Rui if (cpu_map && cpu_map[cpu].initialized) 342ca56725dSZhang Rui return cpu_map[cpu].core_id; 343ca56725dSZhang Rui 344fb186158SSrinivas Pandruvada ret = parse_int_file(0, 345fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/core_id", 346fb186158SSrinivas Pandruvada cpu); 347fb186158SSrinivas Pandruvada if (ret < 0) { 348fb186158SSrinivas Pandruvada int core_id, pkg_id, die_id; 349fb186158SSrinivas Pandruvada 350fb186158SSrinivas Pandruvada ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id); 351fb186158SSrinivas Pandruvada if (!ret) 352fb186158SSrinivas Pandruvada return core_id; 353fb186158SSrinivas Pandruvada } 354fb186158SSrinivas Pandruvada 355fb186158SSrinivas Pandruvada return ret; 3563fb4f7cdSSrinivas Pandruvada } 3573fb4f7cdSSrinivas Pandruvada 358e616059eSZhang Rui static int get_physical_die_id(int cpu) 3593fb4f7cdSSrinivas Pandruvada { 3603fb4f7cdSSrinivas Pandruvada int ret; 3613fb4f7cdSSrinivas Pandruvada 362ca56725dSZhang Rui if (cpu < 0) 363ca56725dSZhang Rui return -1; 364ca56725dSZhang Rui 365ca56725dSZhang Rui if (cpu_map && cpu_map[cpu].initialized) 366ca56725dSZhang Rui return cpu_map[cpu].die_id; 367ca56725dSZhang Rui 368fb186158SSrinivas Pandruvada ret = parse_int_file(0, 369fb186158SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/die_id", 3703fb4f7cdSSrinivas Pandruvada cpu); 371fb186158SSrinivas Pandruvada if (ret < 0) { 372fb186158SSrinivas Pandruvada int core_id, pkg_id, die_id; 373fb186158SSrinivas Pandruvada 374fb186158SSrinivas Pandruvada ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id); 3756c483225SSrinivas Pandruvada if (!ret) { 3766c483225SSrinivas Pandruvada if (die_id < 0) 3776c483225SSrinivas Pandruvada die_id = 0; 3786c483225SSrinivas Pandruvada 379fb186158SSrinivas Pandruvada return die_id; 380fb186158SSrinivas Pandruvada } 3816c483225SSrinivas Pandruvada } 382fb186158SSrinivas Pandruvada 3833fb4f7cdSSrinivas Pandruvada if (ret < 0) 3843fb4f7cdSSrinivas Pandruvada ret = 0; 3853fb4f7cdSSrinivas Pandruvada 3863fb4f7cdSSrinivas Pandruvada return ret; 3873fb4f7cdSSrinivas Pandruvada } 3883fb4f7cdSSrinivas Pandruvada 389e157c847SZhang Rui static int get_physical_punit_id(int cpu) 390e157c847SZhang Rui { 391e157c847SZhang Rui if (cpu < 0) 392e157c847SZhang Rui return -1; 393e157c847SZhang Rui 394e157c847SZhang Rui if (cpu_map && cpu_map[cpu].initialized) 395e157c847SZhang Rui return cpu_map[cpu].punit_id; 396e157c847SZhang Rui 397e157c847SZhang Rui return -1; 398e157c847SZhang Rui } 399e157c847SZhang Rui 400850337ecSZhang Rui void set_isst_id(struct isst_id *id, int cpu) 401850337ecSZhang Rui { 402850337ecSZhang Rui id->cpu = cpu; 4033ba6a275SZhang Rui 40432d6ab45SZhang Rui id->pkg = get_physical_package_id(cpu); 405507fa17aSZhang Rui if (id->pkg >= MAX_PACKAGE_COUNT) 4063ba6a275SZhang Rui id->pkg = -1; 4073ba6a275SZhang Rui 40832d6ab45SZhang Rui id->die = get_physical_die_id(cpu); 409507fa17aSZhang Rui if (id->die >= MAX_DIE_PER_PACKAGE) 4103ba6a275SZhang Rui id->die = -1; 411e157c847SZhang Rui 412e157c847SZhang Rui id->punit = get_physical_punit_id(cpu); 413e157c847SZhang Rui if (id->punit >= MAX_PUNIT_PER_DIE) 414e157c847SZhang Rui id->punit = -1; 415850337ecSZhang Rui } 416850337ecSZhang Rui 41700bb07dbSZhang Rui int is_cpu_in_power_domain(int cpu, struct isst_id *id) 41800bb07dbSZhang Rui { 41900bb07dbSZhang Rui struct isst_id tid; 42000bb07dbSZhang Rui 42100bb07dbSZhang Rui set_isst_id(&tid, cpu); 42200bb07dbSZhang Rui 423e157c847SZhang Rui if (id->pkg == tid.pkg && id->die == tid.die && id->punit == tid.punit) 42400bb07dbSZhang Rui return 1; 42500bb07dbSZhang Rui 42600bb07dbSZhang Rui return 0; 42700bb07dbSZhang Rui } 42800bb07dbSZhang Rui 4297af5a95bSSrinivas Pandruvada int get_cpufreq_base_freq(int cpu) 4307af5a95bSSrinivas Pandruvada { 4317af5a95bSSrinivas Pandruvada return parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", cpu); 4327af5a95bSSrinivas Pandruvada } 4337af5a95bSSrinivas Pandruvada 4343fb4f7cdSSrinivas Pandruvada int get_topo_max_cpus(void) 4353fb4f7cdSSrinivas Pandruvada { 4363fb4f7cdSSrinivas Pandruvada return topo_max_cpus; 4373fb4f7cdSSrinivas Pandruvada } 4383fb4f7cdSSrinivas Pandruvada 439cf3b8e8fSSrinivas Pandruvada static unsigned int is_cpu_online(int cpu) 440cf3b8e8fSSrinivas Pandruvada { 441cf3b8e8fSSrinivas Pandruvada char buffer[128]; 442cf3b8e8fSSrinivas Pandruvada int fd, ret; 443cf3b8e8fSSrinivas Pandruvada unsigned char online; 444cf3b8e8fSSrinivas Pandruvada 445cf3b8e8fSSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 446cf3b8e8fSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/online", cpu); 447cf3b8e8fSSrinivas Pandruvada 448cf3b8e8fSSrinivas Pandruvada fd = open(buffer, O_RDONLY); 449cf3b8e8fSSrinivas Pandruvada if (fd < 0) 450cf3b8e8fSSrinivas Pandruvada return fd; 451cf3b8e8fSSrinivas Pandruvada 452cf3b8e8fSSrinivas Pandruvada ret = read(fd, &online, sizeof(online)); 453cf3b8e8fSSrinivas Pandruvada close(fd); 454cf3b8e8fSSrinivas Pandruvada 455cf3b8e8fSSrinivas Pandruvada if (ret == -1) 456cf3b8e8fSSrinivas Pandruvada return ret; 457cf3b8e8fSSrinivas Pandruvada 458cf3b8e8fSSrinivas Pandruvada if (online == '1') 459cf3b8e8fSSrinivas Pandruvada online = 1; 460cf3b8e8fSSrinivas Pandruvada else 461cf3b8e8fSSrinivas Pandruvada online = 0; 462cf3b8e8fSSrinivas Pandruvada 463cf3b8e8fSSrinivas Pandruvada return online; 464cf3b8e8fSSrinivas Pandruvada } 465cf3b8e8fSSrinivas Pandruvada 4667fd786dfSSrinivas Pandruvada void set_cpu_online_offline(int cpu, int state) 4673c64c81aSSrinivas Pandruvada { 4683c64c81aSSrinivas Pandruvada char buffer[128]; 469abd120e3SSrinivas Pandruvada int fd, ret; 4703c64c81aSSrinivas Pandruvada 4713c64c81aSSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 4723c64c81aSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/online", cpu); 4733c64c81aSSrinivas Pandruvada 4743c64c81aSSrinivas Pandruvada fd = open(buffer, O_WRONLY); 47569669198SSrinivas Pandruvada if (fd < 0) { 47669669198SSrinivas Pandruvada if (!cpu && state) { 47769669198SSrinivas Pandruvada fprintf(stderr, "This system is not configured for CPU 0 online/offline\n"); 47869669198SSrinivas Pandruvada fprintf(stderr, "Ignoring online request for CPU 0 as this is already online\n"); 47969669198SSrinivas Pandruvada return; 48069669198SSrinivas Pandruvada } 4813c64c81aSSrinivas Pandruvada err(-1, "%s open failed", buffer); 48269669198SSrinivas Pandruvada } 4833c64c81aSSrinivas Pandruvada 4843c64c81aSSrinivas Pandruvada if (state) 485abd120e3SSrinivas Pandruvada ret = write(fd, "1\n", 2); 4863c64c81aSSrinivas Pandruvada else 487abd120e3SSrinivas Pandruvada ret = write(fd, "0\n", 2); 488abd120e3SSrinivas Pandruvada 489abd120e3SSrinivas Pandruvada if (ret == -1) 490abd120e3SSrinivas Pandruvada perror("Online/Offline: Operation failed\n"); 4913c64c81aSSrinivas Pandruvada 4923c64c81aSSrinivas Pandruvada close(fd); 4933c64c81aSSrinivas Pandruvada } 4943c64c81aSSrinivas Pandruvada 4950d3dfd75SSrinivas Pandruvada static void force_all_cpus_online(void) 4960d3dfd75SSrinivas Pandruvada { 4970d3dfd75SSrinivas Pandruvada int i; 4980d3dfd75SSrinivas Pandruvada 4990d3dfd75SSrinivas Pandruvada fprintf(stderr, "Forcing all CPUs online\n"); 5000d3dfd75SSrinivas Pandruvada 5010d3dfd75SSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) 5020d3dfd75SSrinivas Pandruvada set_cpu_online_offline(i, 1); 5030d3dfd75SSrinivas Pandruvada 5040d3dfd75SSrinivas Pandruvada unlink("/var/run/isst_cpu_topology.dat"); 5050d3dfd75SSrinivas Pandruvada } 5060d3dfd75SSrinivas Pandruvada 507c77a8d4aSZhang Rui void for_each_online_power_domain_in_set(void (*callback)(struct isst_id *, void *, void *, 5083fb4f7cdSSrinivas Pandruvada void *, void *), 5093fb4f7cdSSrinivas Pandruvada void *arg1, void *arg2, void *arg3, 5103fb4f7cdSSrinivas Pandruvada void *arg4) 5113fb4f7cdSSrinivas Pandruvada { 512850337ecSZhang Rui struct isst_id id; 513b4edf385SZhang Rui int cpus[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE][MAX_PUNIT_PER_DIE]; 514b4edf385SZhang Rui int valid_mask[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE] = {0}; 515b4edf385SZhang Rui int i, j, k; 5163fb4f7cdSSrinivas Pandruvada 517b4edf385SZhang Rui memset(cpus, -1, sizeof(cpus)); 518b4edf385SZhang Rui 5193fb4f7cdSSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) { 520b4edf385SZhang Rui int online; 5213fb4f7cdSSrinivas Pandruvada 5223fb4f7cdSSrinivas Pandruvada if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) 5233fb4f7cdSSrinivas Pandruvada continue; 524b4edf385SZhang Rui 5253fb4f7cdSSrinivas Pandruvada online = parse_int_file( 526b4edf385SZhang Rui i != 0, "/sys/devices/system/cpu/cpu%d/online", i); 527b4edf385SZhang Rui if (online < 0) 528b4edf385SZhang Rui online = 1; /* online entry for CPU 0 needs some special configs */ 5293fb4f7cdSSrinivas Pandruvada 530b4edf385SZhang Rui if (!online) 531f0e0b4d1SSrinivas Pandruvada continue; 532fb186158SSrinivas Pandruvada 533850337ecSZhang Rui set_isst_id(&id, i); 534b4edf385SZhang Rui 535b4edf385SZhang Rui if (id.pkg < 0 || id.die < 0 || id.punit < 0) 536b4edf385SZhang Rui continue; 537b4edf385SZhang Rui 538b4edf385SZhang Rui valid_mask[id.pkg][id.die] = 1; 539b4edf385SZhang Rui 540b4edf385SZhang Rui if (cpus[id.pkg][id.die][id.punit] == -1) 541b4edf385SZhang Rui cpus[id.pkg][id.die][id.punit] = i; 542b4edf385SZhang Rui } 543b4edf385SZhang Rui 544b4edf385SZhang Rui for (i = 0; i < MAX_PACKAGE_COUNT; i++) { 545b4edf385SZhang Rui for (j = 0; j < MAX_DIE_PER_PACKAGE; j++) { 546b4edf385SZhang Rui /* 547b4edf385SZhang Rui * Fix me: 548b4edf385SZhang Rui * How to check a non-cpu die for a package/die with all cpu offlined? 549b4edf385SZhang Rui */ 550b4edf385SZhang Rui if (!valid_mask[i][j]) 551b4edf385SZhang Rui continue; 552b4edf385SZhang Rui for (k = 0; k < MAX_PUNIT_PER_DIE; k++) { 553b4edf385SZhang Rui id.cpu = cpus[i][j][k]; 554b4edf385SZhang Rui id.pkg = i; 555b4edf385SZhang Rui id.die = j; 556b4edf385SZhang Rui id.punit = k; 557b4edf385SZhang Rui if (isst_is_punit_valid(&id)) 558850337ecSZhang Rui callback(&id, arg1, arg2, arg3, arg4); 559b4edf385SZhang Rui } 5603fb4f7cdSSrinivas Pandruvada } 5613fb4f7cdSSrinivas Pandruvada } 5623fb4f7cdSSrinivas Pandruvada } 5633fb4f7cdSSrinivas Pandruvada 5643fb4f7cdSSrinivas Pandruvada static void for_each_online_target_cpu_in_set( 565850337ecSZhang Rui void (*callback)(struct isst_id *, void *, void *, void *, void *), void *arg1, 5663fb4f7cdSSrinivas Pandruvada void *arg2, void *arg3, void *arg4) 5673fb4f7cdSSrinivas Pandruvada { 568070fdea1SSrinivas Pandruvada int i, found = 0; 569850337ecSZhang Rui struct isst_id id; 5703fb4f7cdSSrinivas Pandruvada 5713fb4f7cdSSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) { 5723fb4f7cdSSrinivas Pandruvada int online; 5733fb4f7cdSSrinivas Pandruvada 5743fb4f7cdSSrinivas Pandruvada if (!CPU_ISSET_S(i, target_cpumask_size, target_cpumask)) 5753fb4f7cdSSrinivas Pandruvada continue; 5763fb4f7cdSSrinivas Pandruvada if (i) 5773fb4f7cdSSrinivas Pandruvada online = parse_int_file( 5783fb4f7cdSSrinivas Pandruvada 1, "/sys/devices/system/cpu/cpu%d/online", i); 5793fb4f7cdSSrinivas Pandruvada else 5803fb4f7cdSSrinivas Pandruvada online = 5813fb4f7cdSSrinivas Pandruvada 1; /* online entry for CPU 0 needs some special configs */ 5823fb4f7cdSSrinivas Pandruvada 583850337ecSZhang Rui set_isst_id(&id, i); 584070fdea1SSrinivas Pandruvada if (online && callback) { 585850337ecSZhang Rui callback(&id, arg1, arg2, arg3, arg4); 586070fdea1SSrinivas Pandruvada found = 1; 5873fb4f7cdSSrinivas Pandruvada } 5883fb4f7cdSSrinivas Pandruvada } 5893fb4f7cdSSrinivas Pandruvada 590070fdea1SSrinivas Pandruvada if (!found) 591070fdea1SSrinivas Pandruvada fprintf(stderr, "No valid CPU in the list\n"); 592070fdea1SSrinivas Pandruvada } 593070fdea1SSrinivas Pandruvada 5943fb4f7cdSSrinivas Pandruvada #define BITMASK_SIZE 32 5953fb4f7cdSSrinivas Pandruvada static void set_max_cpu_num(void) 5963fb4f7cdSSrinivas Pandruvada { 5973fb4f7cdSSrinivas Pandruvada FILE *filep; 5983fb4f7cdSSrinivas Pandruvada unsigned long dummy; 599864dc09eSSrinivas Pandruvada int i; 6003fb4f7cdSSrinivas Pandruvada 6013fb4f7cdSSrinivas Pandruvada topo_max_cpus = 0; 602864dc09eSSrinivas Pandruvada for (i = 0; i < 256; ++i) { 603864dc09eSSrinivas Pandruvada char path[256]; 604864dc09eSSrinivas Pandruvada 605864dc09eSSrinivas Pandruvada snprintf(path, sizeof(path), 606864dc09eSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", i); 607864dc09eSSrinivas Pandruvada filep = fopen(path, "r"); 608864dc09eSSrinivas Pandruvada if (filep) 609864dc09eSSrinivas Pandruvada break; 610864dc09eSSrinivas Pandruvada } 611864dc09eSSrinivas Pandruvada 612864dc09eSSrinivas Pandruvada if (!filep) { 613864dc09eSSrinivas Pandruvada fprintf(stderr, "Can't get max cpu number\n"); 614864dc09eSSrinivas Pandruvada exit(0); 615864dc09eSSrinivas Pandruvada } 616864dc09eSSrinivas Pandruvada 6173fb4f7cdSSrinivas Pandruvada while (fscanf(filep, "%lx,", &dummy) == 1) 6183fb4f7cdSSrinivas Pandruvada topo_max_cpus += BITMASK_SIZE; 6193fb4f7cdSSrinivas Pandruvada fclose(filep); 6203fb4f7cdSSrinivas Pandruvada 6213fb4f7cdSSrinivas Pandruvada debug_printf("max cpus %d\n", topo_max_cpus); 6223fb4f7cdSSrinivas Pandruvada } 6233fb4f7cdSSrinivas Pandruvada 6243fb4f7cdSSrinivas Pandruvada size_t alloc_cpu_set(cpu_set_t **cpu_set) 6253fb4f7cdSSrinivas Pandruvada { 6263fb4f7cdSSrinivas Pandruvada cpu_set_t *_cpu_set; 6273fb4f7cdSSrinivas Pandruvada size_t size; 6283fb4f7cdSSrinivas Pandruvada 6293fb4f7cdSSrinivas Pandruvada _cpu_set = CPU_ALLOC((topo_max_cpus + 1)); 6303fb4f7cdSSrinivas Pandruvada if (_cpu_set == NULL) 6313fb4f7cdSSrinivas Pandruvada err(3, "CPU_ALLOC"); 6323fb4f7cdSSrinivas Pandruvada size = CPU_ALLOC_SIZE((topo_max_cpus + 1)); 6333fb4f7cdSSrinivas Pandruvada CPU_ZERO_S(size, _cpu_set); 6343fb4f7cdSSrinivas Pandruvada 6353fb4f7cdSSrinivas Pandruvada *cpu_set = _cpu_set; 6363fb4f7cdSSrinivas Pandruvada return size; 6373fb4f7cdSSrinivas Pandruvada } 6383fb4f7cdSSrinivas Pandruvada 6393fb4f7cdSSrinivas Pandruvada void free_cpu_set(cpu_set_t *cpu_set) 6403fb4f7cdSSrinivas Pandruvada { 6413fb4f7cdSSrinivas Pandruvada CPU_FREE(cpu_set); 6423fb4f7cdSSrinivas Pandruvada } 6433fb4f7cdSSrinivas Pandruvada 644b4edf385SZhang Rui static int cpu_cnt[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE][MAX_PUNIT_PER_DIE]; 6453fb4f7cdSSrinivas Pandruvada 64630e0600eSZhang Rui int get_max_punit_core_id(struct isst_id *id) 647de7f9d3dSSrinivas Pandruvada { 6487566616fSJonathan Doman int max_id = 0; 649de7f9d3dSSrinivas Pandruvada int i; 650de7f9d3dSSrinivas Pandruvada 6517566616fSJonathan Doman for (i = 0; i < topo_max_cpus; ++i) 6527566616fSJonathan Doman { 6537566616fSJonathan Doman if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) 6547566616fSJonathan Doman continue; 6557566616fSJonathan Doman 65600bb07dbSZhang Rui if (is_cpu_in_power_domain(i, id) && 6577566616fSJonathan Doman cpu_map[i].punit_cpu_core > max_id) 6587566616fSJonathan Doman max_id = cpu_map[i].punit_cpu_core; 659de7f9d3dSSrinivas Pandruvada } 660de7f9d3dSSrinivas Pandruvada 6617566616fSJonathan Doman return max_id; 662de7f9d3dSSrinivas Pandruvada } 663de7f9d3dSSrinivas Pandruvada 66430e0600eSZhang Rui int get_cpu_count(struct isst_id *id) 6653fb4f7cdSSrinivas Pandruvada { 666b4edf385SZhang Rui if (id->pkg < 0 || id->die < 0 || id->punit < 0) 6673fb4f7cdSSrinivas Pandruvada return 0; 6683ba6a275SZhang Rui 669b4edf385SZhang Rui return cpu_cnt[id->pkg][id->die][id->punit]; 6703fb4f7cdSSrinivas Pandruvada } 6713fb4f7cdSSrinivas Pandruvada 672a0ca5a09SSrinivas Pandruvada static void update_punit_cpu_info(__u32 physical_cpu, struct _cpu_map *cpu_map) 673a0ca5a09SSrinivas Pandruvada { 674a0ca5a09SSrinivas Pandruvada if (api_version() > 1) { 675a0ca5a09SSrinivas Pandruvada /* 676a0ca5a09SSrinivas Pandruvada * MSR 0x54 format 677a0ca5a09SSrinivas Pandruvada * [15:11] PM_DOMAIN_ID 678a0ca5a09SSrinivas Pandruvada * [10:3] MODULE_ID (aka IDI_AGENT_ID) 679a0ca5a09SSrinivas Pandruvada * [2:0] LP_ID (We don't care about these bits we only 680a0ca5a09SSrinivas Pandruvada * care die and core id 681a0ca5a09SSrinivas Pandruvada * For Atom: 682a0ca5a09SSrinivas Pandruvada * [2] Always 0 683a0ca5a09SSrinivas Pandruvada * [1:0] core ID within module 684a0ca5a09SSrinivas Pandruvada * For Core 685a0ca5a09SSrinivas Pandruvada * [2:1] Always 0 686a0ca5a09SSrinivas Pandruvada * [0] thread ID 687a0ca5a09SSrinivas Pandruvada */ 688a0ca5a09SSrinivas Pandruvada cpu_map->punit_id = (physical_cpu >> 11) & 0x1f; 689a0ca5a09SSrinivas Pandruvada cpu_map->punit_cpu_core = (physical_cpu >> 3) & 0xff; 690a0ca5a09SSrinivas Pandruvada cpu_map->punit_cpu = physical_cpu & 0x7ff; 691a0ca5a09SSrinivas Pandruvada } else { 692a0ca5a09SSrinivas Pandruvada int punit_id; 693a0ca5a09SSrinivas Pandruvada 694a0ca5a09SSrinivas Pandruvada /* 695a0ca5a09SSrinivas Pandruvada * MSR 0x53 format 696a0ca5a09SSrinivas Pandruvada * Format 697a0ca5a09SSrinivas Pandruvada * Bit 0 – thread ID 698a0ca5a09SSrinivas Pandruvada * Bit 8:1 – core ID 699a0ca5a09SSrinivas Pandruvada * Bit 13:9 – punit ID 700a0ca5a09SSrinivas Pandruvada */ 701a0ca5a09SSrinivas Pandruvada cpu_map->punit_cpu = physical_cpu & 0x1ff; 702a0ca5a09SSrinivas Pandruvada cpu_map->punit_cpu_core = (cpu_map->punit_cpu >> 1); // shift to get core id 703a0ca5a09SSrinivas Pandruvada punit_id = (physical_cpu >> 9) & 0x1f; 704a0ca5a09SSrinivas Pandruvada 705a0ca5a09SSrinivas Pandruvada if (punit_id >= MAX_PUNIT_PER_DIE) 706a0ca5a09SSrinivas Pandruvada punit_id = 0; 707a0ca5a09SSrinivas Pandruvada 708a0ca5a09SSrinivas Pandruvada cpu_map->punit_id = punit_id; 709a0ca5a09SSrinivas Pandruvada } 710a0ca5a09SSrinivas Pandruvada } 711a0ca5a09SSrinivas Pandruvada 7123fb4f7cdSSrinivas Pandruvada static void create_cpu_map(void) 7133fb4f7cdSSrinivas Pandruvada { 7143fb4f7cdSSrinivas Pandruvada const char *pathname = "/dev/isst_interface"; 715921604b4SZhang Rui size_t size; 716921604b4SZhang Rui DIR *dir; 7173fb4f7cdSSrinivas Pandruvada int i, fd = 0; 7183fb4f7cdSSrinivas Pandruvada struct isst_if_cpu_maps map; 7193fb4f7cdSSrinivas Pandruvada 720ca56725dSZhang Rui /* Use calloc to make sure the memory is initialized to Zero */ 721ca56725dSZhang Rui cpu_map = calloc(topo_max_cpus, sizeof(*cpu_map)); 7223fb4f7cdSSrinivas Pandruvada if (!cpu_map) 7233fb4f7cdSSrinivas Pandruvada err(3, "cpumap"); 7243fb4f7cdSSrinivas Pandruvada 7253fb4f7cdSSrinivas Pandruvada fd = open(pathname, O_RDWR); 726ca56725dSZhang Rui if (fd < 0 && !is_clx_n_platform()) 7273fb4f7cdSSrinivas Pandruvada err(-1, "%s open failed", pathname); 7283fb4f7cdSSrinivas Pandruvada 729921604b4SZhang Rui size = alloc_cpu_set(&present_cpumask); 730921604b4SZhang Rui present_cpumask_size = size; 731921604b4SZhang Rui 7323fb4f7cdSSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) { 733921604b4SZhang Rui char buffer[256]; 734e157c847SZhang Rui int pkg_id, die_id, core_id, punit_id; 735921604b4SZhang Rui 736921604b4SZhang Rui /* check if CPU is online */ 737921604b4SZhang Rui snprintf(buffer, sizeof(buffer), 738921604b4SZhang Rui "/sys/devices/system/cpu/cpu%d", i); 739921604b4SZhang Rui dir = opendir(buffer); 740921604b4SZhang Rui if (!dir) 741921604b4SZhang Rui continue; 742921604b4SZhang Rui closedir(dir); 743921604b4SZhang Rui 744921604b4SZhang Rui CPU_SET_S(i, size, present_cpumask); 745921604b4SZhang Rui 746921604b4SZhang Rui pkg_id = get_physical_package_id(i); 747921604b4SZhang Rui die_id = get_physical_die_id(i); 748921604b4SZhang Rui core_id = get_physical_core_id(i); 749921604b4SZhang Rui 750921604b4SZhang Rui if (pkg_id < 0 || die_id < 0 || core_id < 0) 7513fb4f7cdSSrinivas Pandruvada continue; 7523fb4f7cdSSrinivas Pandruvada 753921604b4SZhang Rui cpu_map[i].pkg_id = pkg_id; 754921604b4SZhang Rui cpu_map[i].die_id = die_id; 755921604b4SZhang Rui cpu_map[i].core_id = core_id; 756ca56725dSZhang Rui 757921604b4SZhang Rui 758e157c847SZhang Rui punit_id = 0; 759e157c847SZhang Rui 760e157c847SZhang Rui if (fd >= 0) { 7613fb4f7cdSSrinivas Pandruvada map.cmd_count = 1; 7623fb4f7cdSSrinivas Pandruvada map.cpu_map[0].logical_cpu = i; 7633fb4f7cdSSrinivas Pandruvada debug_printf(" map logical_cpu:%d\n", 7643fb4f7cdSSrinivas Pandruvada map.cpu_map[0].logical_cpu); 7653fb4f7cdSSrinivas Pandruvada if (ioctl(fd, ISST_IF_GET_PHY_ID, &map) == -1) { 7663fb4f7cdSSrinivas Pandruvada perror("ISST_IF_GET_PHY_ID"); 7673fb4f7cdSSrinivas Pandruvada fprintf(outf, "Error: map logical_cpu:%d\n", 7683fb4f7cdSSrinivas Pandruvada map.cpu_map[0].logical_cpu); 769e157c847SZhang Rui } else { 770a0ca5a09SSrinivas Pandruvada update_punit_cpu_info(map.cpu_map[0].physical_cpu, &cpu_map[i]); 771e157c847SZhang Rui } 772e157c847SZhang Rui } 773e157c847SZhang Rui cpu_map[i].initialized = 1; 774e157c847SZhang Rui 775b4edf385SZhang Rui cpu_cnt[pkg_id][die_id][punit_id]++; 7763fb4f7cdSSrinivas Pandruvada 7773fb4f7cdSSrinivas Pandruvada debug_printf( 778e157c847SZhang Rui "map logical_cpu:%d core: %d die:%d pkg:%d punit:%d punit_cpu:%d punit_core:%d\n", 7793fb4f7cdSSrinivas Pandruvada i, cpu_map[i].core_id, cpu_map[i].die_id, 780e157c847SZhang Rui cpu_map[i].pkg_id, cpu_map[i].punit_id, 781e157c847SZhang Rui cpu_map[i].punit_cpu, cpu_map[i].punit_cpu_core); 7823fb4f7cdSSrinivas Pandruvada } 783ca56725dSZhang Rui if (fd >= 0) 7843fb4f7cdSSrinivas Pandruvada close(fd); 785921604b4SZhang Rui 786921604b4SZhang Rui size = alloc_cpu_set(&target_cpumask); 787921604b4SZhang Rui target_cpumask_size = size; 788921604b4SZhang Rui for (i = 0; i < max_target_cpus; ++i) { 789921604b4SZhang Rui if (!CPU_ISSET_S(target_cpus[i], present_cpumask_size, 790921604b4SZhang Rui present_cpumask)) 791921604b4SZhang Rui continue; 792921604b4SZhang Rui 793921604b4SZhang Rui CPU_SET_S(target_cpus[i], size, target_cpumask); 794921604b4SZhang Rui } 7953fb4f7cdSSrinivas Pandruvada } 7963fb4f7cdSSrinivas Pandruvada 797850337ecSZhang Rui void set_cpu_mask_from_punit_coremask(struct isst_id *id, unsigned long long core_mask, 7983fb4f7cdSSrinivas Pandruvada size_t core_cpumask_size, 7993fb4f7cdSSrinivas Pandruvada cpu_set_t *core_cpumask, int *cpu_cnt) 8003fb4f7cdSSrinivas Pandruvada { 8013fb4f7cdSSrinivas Pandruvada int i, cnt = 0; 8023fb4f7cdSSrinivas Pandruvada 803d0e12c46SZhang Rui if (id->cpu < 0) 804d0e12c46SZhang Rui return; 805d0e12c46SZhang Rui 8063fb4f7cdSSrinivas Pandruvada *cpu_cnt = 0; 8073fb4f7cdSSrinivas Pandruvada 8083fb4f7cdSSrinivas Pandruvada for (i = 0; i < 64; ++i) { 809873e391fSSrinivas Pandruvada if (core_mask & BIT_ULL(i)) { 8103fb4f7cdSSrinivas Pandruvada int j; 8113fb4f7cdSSrinivas Pandruvada 8123fb4f7cdSSrinivas Pandruvada for (j = 0; j < topo_max_cpus; ++j) { 81344460efeSYouquan Song if (!CPU_ISSET_S(j, present_cpumask_size, present_cpumask)) 81444460efeSYouquan Song continue; 81544460efeSYouquan Song 81600bb07dbSZhang Rui if (is_cpu_in_power_domain(j, id) && 8173fb4f7cdSSrinivas Pandruvada cpu_map[j].punit_cpu_core == i) { 8183fb4f7cdSSrinivas Pandruvada CPU_SET_S(j, core_cpumask_size, 8193fb4f7cdSSrinivas Pandruvada core_cpumask); 8203fb4f7cdSSrinivas Pandruvada ++cnt; 8213fb4f7cdSSrinivas Pandruvada } 8223fb4f7cdSSrinivas Pandruvada } 8233fb4f7cdSSrinivas Pandruvada } 8243fb4f7cdSSrinivas Pandruvada } 8253fb4f7cdSSrinivas Pandruvada 8263fb4f7cdSSrinivas Pandruvada *cpu_cnt = cnt; 8273fb4f7cdSSrinivas Pandruvada } 8283fb4f7cdSSrinivas Pandruvada 8293fb4f7cdSSrinivas Pandruvada int find_phy_core_num(int logical_cpu) 8303fb4f7cdSSrinivas Pandruvada { 8313fb4f7cdSSrinivas Pandruvada if (logical_cpu < topo_max_cpus) 8323fb4f7cdSSrinivas Pandruvada return cpu_map[logical_cpu].punit_cpu_core; 8333fb4f7cdSSrinivas Pandruvada 8343fb4f7cdSSrinivas Pandruvada return -EINVAL; 8353fb4f7cdSSrinivas Pandruvada } 8363fb4f7cdSSrinivas Pandruvada 8373fb4f7cdSSrinivas Pandruvada 8383fb4f7cdSSrinivas Pandruvada 8393fb4f7cdSSrinivas Pandruvada static int isst_fill_platform_info(void) 8403fb4f7cdSSrinivas Pandruvada { 8413fb4f7cdSSrinivas Pandruvada const char *pathname = "/dev/isst_interface"; 8423fb4f7cdSSrinivas Pandruvada int fd; 8433fb4f7cdSSrinivas Pandruvada 84405aab5b8SZhang Rui if (is_clx_n_platform()) { 84505aab5b8SZhang Rui isst_platform_info.api_version = 1; 846d0d1a603SZhang Rui goto set_platform_ops; 84705aab5b8SZhang Rui } 848e9f79348SZhang Rui 8493fb4f7cdSSrinivas Pandruvada fd = open(pathname, O_RDWR); 8503fb4f7cdSSrinivas Pandruvada if (fd < 0) 8513fb4f7cdSSrinivas Pandruvada err(-1, "%s open failed", pathname); 8523fb4f7cdSSrinivas Pandruvada 8533fb4f7cdSSrinivas Pandruvada if (ioctl(fd, ISST_IF_GET_PLATFORM_INFO, &isst_platform_info) == -1) { 8543fb4f7cdSSrinivas Pandruvada perror("ISST_IF_GET_PLATFORM_INFO"); 8553fb4f7cdSSrinivas Pandruvada close(fd); 8563fb4f7cdSSrinivas Pandruvada return -1; 8573fb4f7cdSSrinivas Pandruvada } 8583fb4f7cdSSrinivas Pandruvada 8593fb4f7cdSSrinivas Pandruvada close(fd); 8603fb4f7cdSSrinivas Pandruvada 8613bc3d30cSPrarit Bhargava if (isst_platform_info.api_version > supported_api_ver) { 8623bc3d30cSPrarit Bhargava printf("Incompatible API versions; Upgrade of tool is required\n"); 8633bc3d30cSPrarit Bhargava return -1; 8643bc3d30cSPrarit Bhargava } 865d0d1a603SZhang Rui 866d0d1a603SZhang Rui set_platform_ops: 86705aab5b8SZhang Rui if (isst_set_platform_ops(isst_platform_info.api_version)) { 868d0d1a603SZhang Rui fprintf(stderr, "Failed to set platform callbacks\n"); 869d0d1a603SZhang Rui exit(0); 870d0d1a603SZhang Rui } 8713fb4f7cdSSrinivas Pandruvada return 0; 8723fb4f7cdSSrinivas Pandruvada } 8733fb4f7cdSSrinivas Pandruvada 874ad7e17fcSZhang Rui void get_isst_status(struct isst_id *id, void *arg1, void *arg2, void *arg3, void *arg4) 8751ba148aeSSrinivas Pandruvada { 8761ba148aeSSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev; 877ad7e17fcSZhang Rui struct isst_id *tid = (struct isst_id *)arg2; 878ad7e17fcSZhang Rui int *mask = (int *)arg3; 879ad7e17fcSZhang Rui int *max_level = (int *)arg4; 880ad7e17fcSZhang Rui int j, ret; 8811ba148aeSSrinivas Pandruvada 882ad7e17fcSZhang Rui /* Only check the first cpu power domain */ 883ad7e17fcSZhang Rui if (id->cpu < 0 || tid->cpu >= 0) 8841ba148aeSSrinivas Pandruvada return; 8851ba148aeSSrinivas Pandruvada 886ad7e17fcSZhang Rui ret = isst_get_ctdp_levels(id, &pkg_dev); 8871ba148aeSSrinivas Pandruvada if (ret) 8881ba148aeSSrinivas Pandruvada return; 8891ba148aeSSrinivas Pandruvada 890ad7e17fcSZhang Rui if (pkg_dev.enabled) 891ad7e17fcSZhang Rui *mask |= BIT(0); 892ad7e17fcSZhang Rui 893ad7e17fcSZhang Rui if (pkg_dev.locked) 894ad7e17fcSZhang Rui *mask |= BIT(1); 895ad7e17fcSZhang Rui 896ad7e17fcSZhang Rui if (*max_level < pkg_dev.levels) 897ad7e17fcSZhang Rui *max_level = pkg_dev.levels; 898ad7e17fcSZhang Rui 899ad7e17fcSZhang Rui for (j = 0; j <= pkg_dev.levels; ++j) { 900ad7e17fcSZhang Rui struct isst_pkg_ctdp_level_info ctdp_level; 901ad7e17fcSZhang Rui 902ad7e17fcSZhang Rui ret = isst_get_ctdp_control(id, j, &ctdp_level); 903ad7e17fcSZhang Rui if (ret) 904ad7e17fcSZhang Rui continue; 905ad7e17fcSZhang Rui 906ad7e17fcSZhang Rui if (ctdp_level.fact_support) 907ad7e17fcSZhang Rui *mask |= BIT(2); 908ad7e17fcSZhang Rui 909ad7e17fcSZhang Rui if (ctdp_level.pbf_support) 910ad7e17fcSZhang Rui *mask |= BIT(3); 911ad7e17fcSZhang Rui } 912ad7e17fcSZhang Rui 913ad7e17fcSZhang Rui tid->cpu = id->cpu; 914ad7e17fcSZhang Rui tid->pkg = id->pkg; 915ad7e17fcSZhang Rui tid->die = id->die; 916ad7e17fcSZhang Rui tid->punit = id->punit; 917ad7e17fcSZhang Rui } 918ad7e17fcSZhang Rui 919ad7e17fcSZhang Rui static void isst_print_extended_platform_info(void) 920ad7e17fcSZhang Rui { 921ad7e17fcSZhang Rui int cp_state, cp_cap; 922ad7e17fcSZhang Rui struct isst_id id; 923ad7e17fcSZhang Rui int mask = 0, max_level = 0; 924ad7e17fcSZhang Rui 925ad7e17fcSZhang Rui id.cpu = -1; 926ad7e17fcSZhang Rui for_each_online_power_domain_in_set(get_isst_status, NULL, &id, &mask, &max_level); 927ad7e17fcSZhang Rui 928ad7e17fcSZhang Rui if (mask & BIT(0)) { 9291ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-PP (feature perf-profile) is supported\n"); 9301ba148aeSSrinivas Pandruvada } else { 9311ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-PP (feature perf-profile) is not supported\n"); 9321ba148aeSSrinivas Pandruvada fprintf(outf, "Only performance level 0 (base level) is present\n"); 9331ba148aeSSrinivas Pandruvada } 9341ba148aeSSrinivas Pandruvada 935ad7e17fcSZhang Rui if (mask & BIT(1)) 9361ba148aeSSrinivas Pandruvada fprintf(outf, "TDP level change control is locked\n"); 9371ba148aeSSrinivas Pandruvada else 938ad7e17fcSZhang Rui fprintf(outf, "TDP level change control is unlocked, max level: %d\n", max_level); 9391ba148aeSSrinivas Pandruvada 940ad7e17fcSZhang Rui if (mask & BIT(2)) 9411ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-TF (feature turbo-freq) is supported\n"); 9421ba148aeSSrinivas Pandruvada else 9431ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-TF (feature turbo-freq) is not supported\n"); 9441ba148aeSSrinivas Pandruvada 945ad7e17fcSZhang Rui if (mask & BIT(3)) 9461ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-BF (feature base-freq) is supported\n"); 9471ba148aeSSrinivas Pandruvada else 9481ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-BF (feature base-freq) is not supported\n"); 9491ba148aeSSrinivas Pandruvada 950ad7e17fcSZhang Rui if (isst_read_pm_config(&id, &cp_state, &cp_cap)) { 951b84733a1SSrinivas Pandruvada fprintf(outf, "Intel(R) SST-CP (feature core-power) status is unknown\n"); 952b84733a1SSrinivas Pandruvada return; 953b84733a1SSrinivas Pandruvada } 954ad7e17fcSZhang Rui 9551ba148aeSSrinivas Pandruvada if (cp_cap) 9561ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-CP (feature core-power) is supported\n"); 9571ba148aeSSrinivas Pandruvada else 9581ba148aeSSrinivas Pandruvada fprintf(outf, "Intel(R) SST-CP (feature core-power) is not supported\n"); 9591ba148aeSSrinivas Pandruvada } 9601ba148aeSSrinivas Pandruvada 9613fb4f7cdSSrinivas Pandruvada static void isst_print_platform_information(void) 9623fb4f7cdSSrinivas Pandruvada { 9631ba148aeSSrinivas Pandruvada if (is_clx_n_platform()) { 9641ba148aeSSrinivas Pandruvada fprintf(stderr, "\nThis option in not supported on this platform\n"); 9651ba148aeSSrinivas Pandruvada exit(0); 9661ba148aeSSrinivas Pandruvada } 9671ba148aeSSrinivas Pandruvada 968ca56725dSZhang Rui /* Early initialization to create working cpu_map */ 969ca56725dSZhang Rui set_max_cpu_num(); 970ca56725dSZhang Rui create_cpu_map(); 971ca56725dSZhang Rui 9723fb4f7cdSSrinivas Pandruvada fprintf(outf, "Platform: API version : %d\n", 973e9f79348SZhang Rui isst_platform_info.api_version); 9743fb4f7cdSSrinivas Pandruvada fprintf(outf, "Platform: Driver version : %d\n", 975e9f79348SZhang Rui isst_platform_info.driver_version); 9763fb4f7cdSSrinivas Pandruvada fprintf(outf, "Platform: mbox supported : %d\n", 977e9f79348SZhang Rui isst_platform_info.mbox_supported); 9783fb4f7cdSSrinivas Pandruvada fprintf(outf, "Platform: mmio supported : %d\n", 979e9f79348SZhang Rui isst_platform_info.mmio_supported); 9801ba148aeSSrinivas Pandruvada isst_print_extended_platform_info(); 9813fb4f7cdSSrinivas Pandruvada 9823fb4f7cdSSrinivas Pandruvada exit(0); 9833fb4f7cdSSrinivas Pandruvada } 9843fb4f7cdSSrinivas Pandruvada 9853d1a8579SSrinivas Pandruvada static char *local_str0, *local_str1; 986850337ecSZhang Rui static void exec_on_get_ctdp_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, 9873fb4f7cdSSrinivas Pandruvada void *arg4) 9883fb4f7cdSSrinivas Pandruvada { 989850337ecSZhang Rui int (*fn_ptr)(struct isst_id *id, void *arg); 9903fb4f7cdSSrinivas Pandruvada int ret; 9913fb4f7cdSSrinivas Pandruvada 9923fb4f7cdSSrinivas Pandruvada fn_ptr = arg1; 993850337ecSZhang Rui ret = fn_ptr(id, arg2); 9943fb4f7cdSSrinivas Pandruvada if (ret) 9953d1a8579SSrinivas Pandruvada isst_display_error_info_message(1, "get_tdp_* failed", 0, 0); 9963fb4f7cdSSrinivas Pandruvada else 997850337ecSZhang Rui isst_ctdp_display_core_info(id, outf, arg3, 9983d1a8579SSrinivas Pandruvada *(unsigned int *)arg4, 9993d1a8579SSrinivas Pandruvada local_str0, local_str1); 10003fb4f7cdSSrinivas Pandruvada } 10013fb4f7cdSSrinivas Pandruvada 10023d1a8579SSrinivas Pandruvada #define _get_tdp_level(desc, suffix, object, help, str0, str1) \ 1003ce1326a2SPrarit Bhargava static void get_tdp_##object(int arg) \ 10043fb4f7cdSSrinivas Pandruvada { \ 10053fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp ctdp; \ 10063fb4f7cdSSrinivas Pandruvada \ 10073fb4f7cdSSrinivas Pandruvada if (cmd_help) { \ 10083fb4f7cdSSrinivas Pandruvada fprintf(stderr, \ 10093fb4f7cdSSrinivas Pandruvada "Print %s [No command arguments are required]\n", \ 10103fb4f7cdSSrinivas Pandruvada help); \ 10113fb4f7cdSSrinivas Pandruvada exit(0); \ 10123fb4f7cdSSrinivas Pandruvada } \ 10133d1a8579SSrinivas Pandruvada local_str0 = str0; \ 10143d1a8579SSrinivas Pandruvada local_str1 = str1; \ 10153fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); \ 10163fb4f7cdSSrinivas Pandruvada if (max_target_cpus) \ 10173fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set( \ 10183fb4f7cdSSrinivas Pandruvada exec_on_get_ctdp_cpu, isst_get_ctdp_##suffix, \ 10193fb4f7cdSSrinivas Pandruvada &ctdp, desc, &ctdp.object); \ 10203fb4f7cdSSrinivas Pandruvada else \ 1021c77a8d4aSZhang Rui for_each_online_power_domain_in_set(exec_on_get_ctdp_cpu, \ 10223fb4f7cdSSrinivas Pandruvada isst_get_ctdp_##suffix, \ 10233fb4f7cdSSrinivas Pandruvada &ctdp, desc, \ 10243fb4f7cdSSrinivas Pandruvada &ctdp.object); \ 10253fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); \ 10263fb4f7cdSSrinivas Pandruvada } 10273fb4f7cdSSrinivas Pandruvada 10283d1a8579SSrinivas Pandruvada _get_tdp_level("get-config-levels", levels, levels, "Max TDP level", NULL, NULL); 10293d1a8579SSrinivas Pandruvada _get_tdp_level("get-config-version", levels, version, "TDP version", NULL, NULL); 10303d1a8579SSrinivas Pandruvada _get_tdp_level("get-config-enabled", levels, enabled, "perf-profile enable status", "disabled", "enabled"); 10313fb4f7cdSSrinivas Pandruvada _get_tdp_level("get-config-current_level", levels, current_level, 10323d1a8579SSrinivas Pandruvada "Current TDP Level", NULL, NULL); 10333d1a8579SSrinivas Pandruvada _get_tdp_level("get-lock-status", levels, locked, "TDP lock status", "unlocked", "locked"); 10343fb4f7cdSSrinivas Pandruvada 1035062e4aacSPrarit Bhargava struct isst_pkg_ctdp clx_n_pkg_dev; 1036062e4aacSPrarit Bhargava 1037062e4aacSPrarit Bhargava static int clx_n_get_base_ratio(void) 1038062e4aacSPrarit Bhargava { 1039062e4aacSPrarit Bhargava FILE *fp; 1040062e4aacSPrarit Bhargava char *begin, *end, *line = NULL; 1041062e4aacSPrarit Bhargava char number[5]; 1042062e4aacSPrarit Bhargava float value = 0; 1043062e4aacSPrarit Bhargava size_t n = 0; 1044062e4aacSPrarit Bhargava 1045062e4aacSPrarit Bhargava fp = fopen("/proc/cpuinfo", "r"); 1046062e4aacSPrarit Bhargava if (!fp) 1047062e4aacSPrarit Bhargava err(-1, "cannot open /proc/cpuinfo\n"); 1048062e4aacSPrarit Bhargava 1049062e4aacSPrarit Bhargava while (getline(&line, &n, fp) > 0) { 1050062e4aacSPrarit Bhargava if (strstr(line, "model name")) { 1051062e4aacSPrarit Bhargava /* this is true for CascadeLake-N */ 1052062e4aacSPrarit Bhargava begin = strstr(line, "@ ") + 2; 1053062e4aacSPrarit Bhargava end = strstr(line, "GHz"); 1054062e4aacSPrarit Bhargava strncpy(number, begin, end - begin); 1055062e4aacSPrarit Bhargava value = atof(number) * 10; 1056062e4aacSPrarit Bhargava break; 1057062e4aacSPrarit Bhargava } 1058062e4aacSPrarit Bhargava } 1059062e4aacSPrarit Bhargava free(line); 1060062e4aacSPrarit Bhargava fclose(fp); 1061062e4aacSPrarit Bhargava 1062062e4aacSPrarit Bhargava return (int)(value); 1063062e4aacSPrarit Bhargava } 1064062e4aacSPrarit Bhargava 1065850337ecSZhang Rui static int clx_n_config(struct isst_id *id) 1066062e4aacSPrarit Bhargava { 106756d64692SZhang Rui int i, ret; 1068062e4aacSPrarit Bhargava unsigned long cpu_bf; 1069062e4aacSPrarit Bhargava struct isst_pkg_ctdp_level_info *ctdp_level; 1070062e4aacSPrarit Bhargava struct isst_pbf_info *pbf_info; 1071062e4aacSPrarit Bhargava 1072062e4aacSPrarit Bhargava ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; 1073062e4aacSPrarit Bhargava pbf_info = &ctdp_level->pbf_info; 1074062e4aacSPrarit Bhargava ctdp_level->core_cpumask_size = 1075062e4aacSPrarit Bhargava alloc_cpu_set(&ctdp_level->core_cpumask); 1076062e4aacSPrarit Bhargava 1077062e4aacSPrarit Bhargava /* find the frequency base ratio */ 1078062e4aacSPrarit Bhargava ctdp_level->tdp_ratio = clx_n_get_base_ratio(); 1079062e4aacSPrarit Bhargava if (ctdp_level->tdp_ratio == 0) { 1080062e4aacSPrarit Bhargava debug_printf("CLX: cn base ratio is zero\n"); 1081062e4aacSPrarit Bhargava ret = -1; 1082062e4aacSPrarit Bhargava goto error_ret; 1083062e4aacSPrarit Bhargava } 1084062e4aacSPrarit Bhargava 1085062e4aacSPrarit Bhargava /* find the high and low priority frequencies */ 1086062e4aacSPrarit Bhargava pbf_info->p1_high = 0; 1087062e4aacSPrarit Bhargava pbf_info->p1_low = ~0; 1088062e4aacSPrarit Bhargava 1089062e4aacSPrarit Bhargava for (i = 0; i < topo_max_cpus; i++) { 1090062e4aacSPrarit Bhargava if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) 1091062e4aacSPrarit Bhargava continue; 1092062e4aacSPrarit Bhargava 109300bb07dbSZhang Rui if (!is_cpu_in_power_domain(i, id)) 1094062e4aacSPrarit Bhargava continue; 1095062e4aacSPrarit Bhargava 1096062e4aacSPrarit Bhargava CPU_SET_S(i, ctdp_level->core_cpumask_size, 1097062e4aacSPrarit Bhargava ctdp_level->core_cpumask); 1098062e4aacSPrarit Bhargava 1099062e4aacSPrarit Bhargava cpu_bf = parse_int_file(1, 1100062e4aacSPrarit Bhargava "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", 1101062e4aacSPrarit Bhargava i); 1102062e4aacSPrarit Bhargava if (cpu_bf > pbf_info->p1_high) 1103062e4aacSPrarit Bhargava pbf_info->p1_high = cpu_bf; 1104062e4aacSPrarit Bhargava if (cpu_bf < pbf_info->p1_low) 1105062e4aacSPrarit Bhargava pbf_info->p1_low = cpu_bf; 1106062e4aacSPrarit Bhargava } 1107062e4aacSPrarit Bhargava 1108062e4aacSPrarit Bhargava if (pbf_info->p1_high == ~0UL) { 1109062e4aacSPrarit Bhargava debug_printf("CLX: maximum base frequency not set\n"); 1110062e4aacSPrarit Bhargava ret = -1; 1111062e4aacSPrarit Bhargava goto error_ret; 1112062e4aacSPrarit Bhargava } 1113062e4aacSPrarit Bhargava 1114062e4aacSPrarit Bhargava if (pbf_info->p1_low == 0) { 1115062e4aacSPrarit Bhargava debug_printf("CLX: minimum base frequency not set\n"); 1116062e4aacSPrarit Bhargava ret = -1; 1117062e4aacSPrarit Bhargava goto error_ret; 1118062e4aacSPrarit Bhargava } 1119062e4aacSPrarit Bhargava 1120062e4aacSPrarit Bhargava /* convert frequencies back to ratios */ 112191d92814SSrinivas Pandruvada pbf_info->p1_high = pbf_info->p1_high / 100000; 112291d92814SSrinivas Pandruvada pbf_info->p1_low = pbf_info->p1_low / 100000; 1123062e4aacSPrarit Bhargava 1124062e4aacSPrarit Bhargava /* create high priority cpu mask */ 1125062e4aacSPrarit Bhargava pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask); 1126062e4aacSPrarit Bhargava for (i = 0; i < topo_max_cpus; i++) { 1127062e4aacSPrarit Bhargava if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) 1128062e4aacSPrarit Bhargava continue; 1129062e4aacSPrarit Bhargava 113000bb07dbSZhang Rui if (!is_cpu_in_power_domain(i, id)) 1131062e4aacSPrarit Bhargava continue; 1132062e4aacSPrarit Bhargava 1133062e4aacSPrarit Bhargava cpu_bf = parse_int_file(1, 1134062e4aacSPrarit Bhargava "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", 1135062e4aacSPrarit Bhargava i); 113691d92814SSrinivas Pandruvada cpu_bf = cpu_bf / 100000; 1137062e4aacSPrarit Bhargava if (cpu_bf == pbf_info->p1_high) 1138062e4aacSPrarit Bhargava CPU_SET_S(i, pbf_info->core_cpumask_size, 1139062e4aacSPrarit Bhargava pbf_info->core_cpumask); 1140062e4aacSPrarit Bhargava } 1141062e4aacSPrarit Bhargava 1142062e4aacSPrarit Bhargava /* extra ctdp & pbf struct parameters */ 1143062e4aacSPrarit Bhargava ctdp_level->processed = 1; 1144062e4aacSPrarit Bhargava ctdp_level->pbf_support = 1; /* PBF is always supported and enabled */ 1145062e4aacSPrarit Bhargava ctdp_level->pbf_enabled = 1; 1146062e4aacSPrarit Bhargava ctdp_level->fact_support = 0; /* FACT is never supported */ 1147062e4aacSPrarit Bhargava ctdp_level->fact_enabled = 0; 1148062e4aacSPrarit Bhargava 1149062e4aacSPrarit Bhargava return 0; 1150062e4aacSPrarit Bhargava 1151062e4aacSPrarit Bhargava error_ret: 1152062e4aacSPrarit Bhargava free_cpu_set(ctdp_level->core_cpumask); 1153062e4aacSPrarit Bhargava return ret; 1154062e4aacSPrarit Bhargava } 1155062e4aacSPrarit Bhargava 1156850337ecSZhang Rui static void dump_clx_n_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, 1157062e4aacSPrarit Bhargava void *arg3, void *arg4) 1158062e4aacSPrarit Bhargava { 1159062e4aacSPrarit Bhargava int ret; 1160062e4aacSPrarit Bhargava 1161ac9d05eaSSrinivas Pandruvada if (tdp_level != 0xff && tdp_level != 0) { 1162ac9d05eaSSrinivas Pandruvada isst_display_error_info_message(1, "Invalid level", 1, tdp_level); 1163ac9d05eaSSrinivas Pandruvada exit(0); 1164ac9d05eaSSrinivas Pandruvada } 1165ac9d05eaSSrinivas Pandruvada 1166850337ecSZhang Rui ret = clx_n_config(id); 1167062e4aacSPrarit Bhargava if (ret) { 11687fc9fefdSSrinivas Pandruvada debug_printf("clx_n_config failed"); 1169062e4aacSPrarit Bhargava } else { 1170062e4aacSPrarit Bhargava struct isst_pkg_ctdp_level_info *ctdp_level; 1171062e4aacSPrarit Bhargava struct isst_pbf_info *pbf_info; 1172062e4aacSPrarit Bhargava 1173062e4aacSPrarit Bhargava ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; 1174062e4aacSPrarit Bhargava pbf_info = &ctdp_level->pbf_info; 117528c59ae6SPrarit Bhargava clx_n_pkg_dev.processed = 1; 1176850337ecSZhang Rui isst_ctdp_display_information(id, outf, tdp_level, &clx_n_pkg_dev); 1177062e4aacSPrarit Bhargava free_cpu_set(ctdp_level->core_cpumask); 1178062e4aacSPrarit Bhargava free_cpu_set(pbf_info->core_cpumask); 1179062e4aacSPrarit Bhargava } 1180062e4aacSPrarit Bhargava } 1181062e4aacSPrarit Bhargava 1182850337ecSZhang Rui static void dump_isst_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, 11833fb4f7cdSSrinivas Pandruvada void *arg3, void *arg4) 11843fb4f7cdSSrinivas Pandruvada { 11853fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev; 11863fb4f7cdSSrinivas Pandruvada int ret; 11873fb4f7cdSSrinivas Pandruvada 11883fb4f7cdSSrinivas Pandruvada memset(&pkg_dev, 0, sizeof(pkg_dev)); 1189850337ecSZhang Rui ret = isst_get_process_ctdp(id, tdp_level, &pkg_dev); 11903fb4f7cdSSrinivas Pandruvada if (ret) { 1191850337ecSZhang Rui isst_display_error_info_message(1, "Failed to get perf-profile info on cpu", 1, id->cpu); 1192ac9d05eaSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 1193ac9d05eaSSrinivas Pandruvada exit(1); 11943fb4f7cdSSrinivas Pandruvada } else { 1195850337ecSZhang Rui isst_ctdp_display_information(id, outf, tdp_level, &pkg_dev); 1196850337ecSZhang Rui isst_get_process_ctdp_complete(id, &pkg_dev); 11973fb4f7cdSSrinivas Pandruvada } 11983fb4f7cdSSrinivas Pandruvada } 11993fb4f7cdSSrinivas Pandruvada 1200ce1326a2SPrarit Bhargava static void dump_isst_config(int arg) 12013fb4f7cdSSrinivas Pandruvada { 1202062e4aacSPrarit Bhargava void *fn; 1203062e4aacSPrarit Bhargava 12043fb4f7cdSSrinivas Pandruvada if (cmd_help) { 12053fb4f7cdSSrinivas Pandruvada fprintf(stderr, 12063fb4f7cdSSrinivas Pandruvada "Print Intel(R) Speed Select Technology Performance profile configuration\n"); 12073fb4f7cdSSrinivas Pandruvada fprintf(stderr, 12083fb4f7cdSSrinivas Pandruvada "including base frequency and turbo frequency configurations\n"); 12093fb4f7cdSSrinivas Pandruvada fprintf(stderr, "Optional: -l|--level : Specify tdp level\n"); 12103fb4f7cdSSrinivas Pandruvada fprintf(stderr, 12113fb4f7cdSSrinivas Pandruvada "\tIf no arguments, dump information for all TDP levels\n"); 12123fb4f7cdSSrinivas Pandruvada exit(0); 12133fb4f7cdSSrinivas Pandruvada } 12143fb4f7cdSSrinivas Pandruvada 1215062e4aacSPrarit Bhargava if (!is_clx_n_platform()) 1216062e4aacSPrarit Bhargava fn = dump_isst_config_for_cpu; 1217062e4aacSPrarit Bhargava else 1218062e4aacSPrarit Bhargava fn = dump_clx_n_config_for_cpu; 1219062e4aacSPrarit Bhargava 12203fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 12213fb4f7cdSSrinivas Pandruvada 12223fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 1223062e4aacSPrarit Bhargava for_each_online_target_cpu_in_set(fn, NULL, NULL, NULL, NULL); 12243fb4f7cdSSrinivas Pandruvada else 1225c77a8d4aSZhang Rui for_each_online_power_domain_in_set(fn, NULL, NULL, NULL, NULL); 12263fb4f7cdSSrinivas Pandruvada 12273fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 12283fb4f7cdSSrinivas Pandruvada } 12293fb4f7cdSSrinivas Pandruvada 1230f981dc17SSrinivas Pandruvada static void adjust_scaling_max_from_base_freq(int cpu); 1231f981dc17SSrinivas Pandruvada 1232850337ecSZhang Rui static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, 12333fb4f7cdSSrinivas Pandruvada void *arg4) 12343fb4f7cdSSrinivas Pandruvada { 123514f0cf6cSZhang Rui struct isst_pkg_ctdp pkg_dev; 12363fb4f7cdSSrinivas Pandruvada int ret; 12373fb4f7cdSSrinivas Pandruvada 123814f0cf6cSZhang Rui ret = isst_get_ctdp_levels(id, &pkg_dev); 123914f0cf6cSZhang Rui if (ret) { 124014f0cf6cSZhang Rui isst_display_error_info_message(1, "Get TDP level failed", 0, 0); 124114f0cf6cSZhang Rui isst_ctdp_display_information_end(outf); 124214f0cf6cSZhang Rui exit(1); 124314f0cf6cSZhang Rui } 124414f0cf6cSZhang Rui 124514f0cf6cSZhang Rui if (pkg_dev.current_level == tdp_level) { 124614f0cf6cSZhang Rui debug_printf("TDP level already set. Skipped\n"); 124714f0cf6cSZhang Rui goto display_result; 124814f0cf6cSZhang Rui } 124914f0cf6cSZhang Rui 1250850337ecSZhang Rui ret = isst_set_tdp_level(id, tdp_level); 1251ac9d05eaSSrinivas Pandruvada if (ret) { 1252ac9d05eaSSrinivas Pandruvada isst_display_error_info_message(1, "Set TDP level failed", 0, 0); 1253ac9d05eaSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 1254ac9d05eaSSrinivas Pandruvada exit(1); 125514f0cf6cSZhang Rui } 125614f0cf6cSZhang Rui 125714f0cf6cSZhang Rui display_result: 125814f0cf6cSZhang Rui isst_display_result(id, outf, "perf-profile", "set_tdp_level", ret); 1259d0e12c46SZhang Rui if (force_online_offline && id->cpu >= 0) { 12603c64c81aSSrinivas Pandruvada struct isst_pkg_ctdp_level_info ctdp_level; 12613c64c81aSSrinivas Pandruvada 1262f981dc17SSrinivas Pandruvada /* Wait for updated base frequencies */ 1263f981dc17SSrinivas Pandruvada usleep(2000); 1264f981dc17SSrinivas Pandruvada 12652612ae59SSrinivas Pandruvada /* Adjusting uncore freq */ 126673452cccSZhang Rui isst_adjust_uncore_freq(id, tdp_level, &ctdp_level); 12672612ae59SSrinivas Pandruvada 12683c64c81aSSrinivas Pandruvada fprintf(stderr, "Option is set to online/offline\n"); 12693c64c81aSSrinivas Pandruvada ctdp_level.core_cpumask_size = 12703c64c81aSSrinivas Pandruvada alloc_cpu_set(&ctdp_level.core_cpumask); 1271850337ecSZhang Rui ret = isst_get_coremask_info(id, tdp_level, &ctdp_level); 12726374de84SSrinivas Pandruvada if (ret) { 12736374de84SSrinivas Pandruvada isst_display_error_info_message(1, "Can't get coremask, online/offline option is ignored", 0, 0); 1274*57797f19SSrinivas Pandruvada goto free_mask; 12756374de84SSrinivas Pandruvada } 12763c64c81aSSrinivas Pandruvada if (ctdp_level.cpu_count) { 12773c64c81aSSrinivas Pandruvada int i, max_cpus = get_topo_max_cpus(); 12783c64c81aSSrinivas Pandruvada for (i = 0; i < max_cpus; ++i) { 127900bb07dbSZhang Rui if (!is_cpu_in_power_domain(i, id)) 12803c64c81aSSrinivas Pandruvada continue; 12813c64c81aSSrinivas Pandruvada if (CPU_ISSET_S(i, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask)) { 12823c64c81aSSrinivas Pandruvada fprintf(stderr, "online cpu %d\n", i); 12833c64c81aSSrinivas Pandruvada set_cpu_online_offline(i, 1); 1284f981dc17SSrinivas Pandruvada adjust_scaling_max_from_base_freq(i); 12853c64c81aSSrinivas Pandruvada } else { 12863c64c81aSSrinivas Pandruvada fprintf(stderr, "offline cpu %d\n", i); 12873c64c81aSSrinivas Pandruvada set_cpu_online_offline(i, 0); 12883c64c81aSSrinivas Pandruvada } 12893c64c81aSSrinivas Pandruvada } 12903c64c81aSSrinivas Pandruvada } 1291*57797f19SSrinivas Pandruvada free_mask: 1292*57797f19SSrinivas Pandruvada free_cpu_set(ctdp_level.core_cpumask); 12933c64c81aSSrinivas Pandruvada } 12943c64c81aSSrinivas Pandruvada } 12953fb4f7cdSSrinivas Pandruvada 1296ce1326a2SPrarit Bhargava static void set_tdp_level(int arg) 12973fb4f7cdSSrinivas Pandruvada { 12983fb4f7cdSSrinivas Pandruvada if (cmd_help) { 12993fb4f7cdSSrinivas Pandruvada fprintf(stderr, "Set Config TDP level\n"); 13003fb4f7cdSSrinivas Pandruvada fprintf(stderr, 13013fb4f7cdSSrinivas Pandruvada "\t Arguments: -l|--level : Specify tdp level\n"); 13023c64c81aSSrinivas Pandruvada fprintf(stderr, 13033c64c81aSSrinivas Pandruvada "\t Optional Arguments: -o | online : online/offline for the tdp level\n"); 1304ac9d05eaSSrinivas Pandruvada fprintf(stderr, 1305ac9d05eaSSrinivas Pandruvada "\t online/offline operation has limitations, refer to Linux hotplug documentation\n"); 13063fb4f7cdSSrinivas Pandruvada exit(0); 13073fb4f7cdSSrinivas Pandruvada } 13083fb4f7cdSSrinivas Pandruvada 13093fb4f7cdSSrinivas Pandruvada if (tdp_level == 0xff) { 1310ac9d05eaSSrinivas Pandruvada isst_display_error_info_message(1, "Invalid command: specify tdp_level", 0, 0); 13113fb4f7cdSSrinivas Pandruvada exit(1); 13123fb4f7cdSSrinivas Pandruvada } 13133fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 13143fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 13153fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(set_tdp_level_for_cpu, NULL, 13163fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 13173fb4f7cdSSrinivas Pandruvada else 1318c77a8d4aSZhang Rui for_each_online_power_domain_in_set(set_tdp_level_for_cpu, NULL, 13193fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 13203fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 13213fb4f7cdSSrinivas Pandruvada } 13223fb4f7cdSSrinivas Pandruvada 1323850337ecSZhang Rui static void clx_n_dump_pbf_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, 13241aa7177cSPrarit Bhargava void *arg3, void *arg4) 13251aa7177cSPrarit Bhargava { 13261aa7177cSPrarit Bhargava int ret; 13271aa7177cSPrarit Bhargava 1328850337ecSZhang Rui ret = clx_n_config(id); 13291aa7177cSPrarit Bhargava if (ret) { 133039bae0fcSSrinivas Pandruvada isst_display_error_info_message(1, "clx_n_config failed", 0, 0); 13311aa7177cSPrarit Bhargava } else { 13321aa7177cSPrarit Bhargava struct isst_pkg_ctdp_level_info *ctdp_level; 13331aa7177cSPrarit Bhargava struct isst_pbf_info *pbf_info; 13341aa7177cSPrarit Bhargava 13351aa7177cSPrarit Bhargava ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; 13361aa7177cSPrarit Bhargava pbf_info = &ctdp_level->pbf_info; 1337850337ecSZhang Rui isst_pbf_display_information(id, outf, tdp_level, pbf_info); 13381aa7177cSPrarit Bhargava free_cpu_set(ctdp_level->core_cpumask); 13391aa7177cSPrarit Bhargava free_cpu_set(pbf_info->core_cpumask); 13401aa7177cSPrarit Bhargava } 13411aa7177cSPrarit Bhargava } 13421aa7177cSPrarit Bhargava 1343850337ecSZhang Rui static void dump_pbf_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, 13443fb4f7cdSSrinivas Pandruvada void *arg4) 13453fb4f7cdSSrinivas Pandruvada { 13463fb4f7cdSSrinivas Pandruvada struct isst_pbf_info pbf_info; 13473fb4f7cdSSrinivas Pandruvada int ret; 13483fb4f7cdSSrinivas Pandruvada 1349850337ecSZhang Rui ret = isst_get_pbf_info(id, tdp_level, &pbf_info); 13503fb4f7cdSSrinivas Pandruvada if (ret) { 135139bae0fcSSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get base-freq info at this level", 1, tdp_level); 135239bae0fcSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 135339bae0fcSSrinivas Pandruvada exit(1); 13543fb4f7cdSSrinivas Pandruvada } else { 1355850337ecSZhang Rui isst_pbf_display_information(id, outf, tdp_level, &pbf_info); 135605ece691SZhang Rui free_cpu_set(pbf_info.core_cpumask); 13573fb4f7cdSSrinivas Pandruvada } 13583fb4f7cdSSrinivas Pandruvada } 13593fb4f7cdSSrinivas Pandruvada 1360ce1326a2SPrarit Bhargava static void dump_pbf_config(int arg) 13613fb4f7cdSSrinivas Pandruvada { 13621aa7177cSPrarit Bhargava void *fn; 13631aa7177cSPrarit Bhargava 13643fb4f7cdSSrinivas Pandruvada if (cmd_help) { 13653fb4f7cdSSrinivas Pandruvada fprintf(stderr, 13663fb4f7cdSSrinivas Pandruvada "Print Intel(R) Speed Select Technology base frequency configuration for a TDP level\n"); 13673fb4f7cdSSrinivas Pandruvada fprintf(stderr, 13683fb4f7cdSSrinivas Pandruvada "\tArguments: -l|--level : Specify tdp level\n"); 13693fb4f7cdSSrinivas Pandruvada exit(0); 13703fb4f7cdSSrinivas Pandruvada } 13713fb4f7cdSSrinivas Pandruvada 13723fb4f7cdSSrinivas Pandruvada if (tdp_level == 0xff) { 137339bae0fcSSrinivas Pandruvada isst_display_error_info_message(1, "Invalid command: specify tdp_level", 0, 0); 13743fb4f7cdSSrinivas Pandruvada exit(1); 13753fb4f7cdSSrinivas Pandruvada } 13763fb4f7cdSSrinivas Pandruvada 13771aa7177cSPrarit Bhargava if (!is_clx_n_platform()) 13781aa7177cSPrarit Bhargava fn = dump_pbf_config_for_cpu; 13793fb4f7cdSSrinivas Pandruvada else 13801aa7177cSPrarit Bhargava fn = clx_n_dump_pbf_config_for_cpu; 13811aa7177cSPrarit Bhargava 13821aa7177cSPrarit Bhargava isst_ctdp_display_information_start(outf); 13831aa7177cSPrarit Bhargava 13841aa7177cSPrarit Bhargava if (max_target_cpus) 13851aa7177cSPrarit Bhargava for_each_online_target_cpu_in_set(fn, NULL, NULL, NULL, NULL); 13861aa7177cSPrarit Bhargava else 1387c77a8d4aSZhang Rui for_each_online_power_domain_in_set(fn, NULL, NULL, NULL, NULL); 13881aa7177cSPrarit Bhargava 13893fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 13903fb4f7cdSSrinivas Pandruvada } 13913fb4f7cdSSrinivas Pandruvada 1392850337ecSZhang Rui static int set_clos_param(struct isst_id *id, int clos, int epp, int wt, int min, int max) 1393354bd06fSSrinivas Pandruvada { 1394354bd06fSSrinivas Pandruvada struct isst_clos_config clos_config; 1395354bd06fSSrinivas Pandruvada int ret; 1396354bd06fSSrinivas Pandruvada 1397850337ecSZhang Rui ret = isst_pm_get_clos(id, clos, &clos_config); 1398354bd06fSSrinivas Pandruvada if (ret) { 1399fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_pm_get_clos failed", 0, 0); 1400354bd06fSSrinivas Pandruvada return ret; 1401354bd06fSSrinivas Pandruvada } 1402354bd06fSSrinivas Pandruvada clos_config.clos_min = min; 1403354bd06fSSrinivas Pandruvada clos_config.clos_max = max; 1404354bd06fSSrinivas Pandruvada clos_config.epp = epp; 1405354bd06fSSrinivas Pandruvada clos_config.clos_prop_prio = wt; 1406850337ecSZhang Rui ret = isst_set_clos(id, clos, &clos_config); 1407354bd06fSSrinivas Pandruvada if (ret) { 1408fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_set_clos failed", 0, 0); 1409354bd06fSSrinivas Pandruvada return ret; 1410354bd06fSSrinivas Pandruvada } 1411354bd06fSSrinivas Pandruvada 1412354bd06fSSrinivas Pandruvada return 0; 1413354bd06fSSrinivas Pandruvada } 1414354bd06fSSrinivas Pandruvada 1415a9b2f8e2SSrinivas Pandruvada static int set_cpufreq_scaling_min_max(int cpu, int max, int freq) 1416a9b2f8e2SSrinivas Pandruvada { 1417a9b2f8e2SSrinivas Pandruvada char buffer[128], freq_str[16]; 1418a9b2f8e2SSrinivas Pandruvada int fd, ret, len; 1419a9b2f8e2SSrinivas Pandruvada 1420a9b2f8e2SSrinivas Pandruvada if (max) 1421a9b2f8e2SSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1422a9b2f8e2SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); 1423a9b2f8e2SSrinivas Pandruvada else 1424a9b2f8e2SSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1425a9b2f8e2SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); 1426a9b2f8e2SSrinivas Pandruvada 1427a9b2f8e2SSrinivas Pandruvada fd = open(buffer, O_WRONLY); 1428a9b2f8e2SSrinivas Pandruvada if (fd < 0) 1429a9b2f8e2SSrinivas Pandruvada return fd; 1430a9b2f8e2SSrinivas Pandruvada 1431a9b2f8e2SSrinivas Pandruvada snprintf(freq_str, sizeof(freq_str), "%d", freq); 1432a9b2f8e2SSrinivas Pandruvada len = strlen(freq_str); 1433a9b2f8e2SSrinivas Pandruvada ret = write(fd, freq_str, len); 1434a9b2f8e2SSrinivas Pandruvada if (ret == -1) { 1435a9b2f8e2SSrinivas Pandruvada close(fd); 1436a9b2f8e2SSrinivas Pandruvada return ret; 1437a9b2f8e2SSrinivas Pandruvada } 1438a9b2f8e2SSrinivas Pandruvada close(fd); 1439a9b2f8e2SSrinivas Pandruvada 1440a9b2f8e2SSrinivas Pandruvada return 0; 1441a9b2f8e2SSrinivas Pandruvada } 1442a9b2f8e2SSrinivas Pandruvada 1443f981dc17SSrinivas Pandruvada static int no_turbo(void) 1444f981dc17SSrinivas Pandruvada { 1445f981dc17SSrinivas Pandruvada return parse_int_file(0, "/sys/devices/system/cpu/intel_pstate/no_turbo"); 1446f981dc17SSrinivas Pandruvada } 1447f981dc17SSrinivas Pandruvada 1448f981dc17SSrinivas Pandruvada static void adjust_scaling_max_from_base_freq(int cpu) 1449f981dc17SSrinivas Pandruvada { 1450f981dc17SSrinivas Pandruvada int base_freq, scaling_max_freq; 1451f981dc17SSrinivas Pandruvada 1452f981dc17SSrinivas Pandruvada scaling_max_freq = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); 1453f981dc17SSrinivas Pandruvada base_freq = get_cpufreq_base_freq(cpu); 1454f981dc17SSrinivas Pandruvada if (scaling_max_freq < base_freq || no_turbo()) 1455f981dc17SSrinivas Pandruvada set_cpufreq_scaling_min_max(cpu, 1, base_freq); 1456f981dc17SSrinivas Pandruvada } 1457f981dc17SSrinivas Pandruvada 1458bbaa2e95SSrinivas Pandruvada static void adjust_scaling_min_from_base_freq(int cpu) 1459bbaa2e95SSrinivas Pandruvada { 1460bbaa2e95SSrinivas Pandruvada int base_freq, scaling_min_freq; 1461bbaa2e95SSrinivas Pandruvada 1462bbaa2e95SSrinivas Pandruvada scaling_min_freq = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); 1463bbaa2e95SSrinivas Pandruvada base_freq = get_cpufreq_base_freq(cpu); 1464bbaa2e95SSrinivas Pandruvada if (scaling_min_freq < base_freq) 1465bbaa2e95SSrinivas Pandruvada set_cpufreq_scaling_min_max(cpu, 0, base_freq); 1466bbaa2e95SSrinivas Pandruvada } 1467bbaa2e95SSrinivas Pandruvada 1468850337ecSZhang Rui static int set_clx_pbf_cpufreq_scaling_min_max(struct isst_id *id) 1469a9b2f8e2SSrinivas Pandruvada { 1470a9b2f8e2SSrinivas Pandruvada struct isst_pkg_ctdp_level_info *ctdp_level; 1471a9b2f8e2SSrinivas Pandruvada struct isst_pbf_info *pbf_info; 147256d64692SZhang Rui int i, freq, freq_high, freq_low; 1473a9b2f8e2SSrinivas Pandruvada int ret; 1474a9b2f8e2SSrinivas Pandruvada 1475850337ecSZhang Rui ret = clx_n_config(id); 1476a9b2f8e2SSrinivas Pandruvada if (ret) { 14777fc9fefdSSrinivas Pandruvada debug_printf("cpufreq_scaling_min_max failed for CLX"); 1478a9b2f8e2SSrinivas Pandruvada return ret; 1479a9b2f8e2SSrinivas Pandruvada } 1480a9b2f8e2SSrinivas Pandruvada 1481a9b2f8e2SSrinivas Pandruvada ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; 1482a9b2f8e2SSrinivas Pandruvada pbf_info = &ctdp_level->pbf_info; 1483a9b2f8e2SSrinivas Pandruvada freq_high = pbf_info->p1_high * 100000; 1484a9b2f8e2SSrinivas Pandruvada freq_low = pbf_info->p1_low * 100000; 1485a9b2f8e2SSrinivas Pandruvada 1486a9b2f8e2SSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 148700bb07dbSZhang Rui if (!is_cpu_in_power_domain(i, id)) 1488a9b2f8e2SSrinivas Pandruvada continue; 1489a9b2f8e2SSrinivas Pandruvada 1490a9b2f8e2SSrinivas Pandruvada if (CPU_ISSET_S(i, pbf_info->core_cpumask_size, 1491a9b2f8e2SSrinivas Pandruvada pbf_info->core_cpumask)) 1492a9b2f8e2SSrinivas Pandruvada freq = freq_high; 1493a9b2f8e2SSrinivas Pandruvada else 1494a9b2f8e2SSrinivas Pandruvada freq = freq_low; 1495a9b2f8e2SSrinivas Pandruvada 1496a9b2f8e2SSrinivas Pandruvada set_cpufreq_scaling_min_max(i, 1, freq); 1497a9b2f8e2SSrinivas Pandruvada set_cpufreq_scaling_min_max(i, 0, freq); 1498a9b2f8e2SSrinivas Pandruvada } 1499a9b2f8e2SSrinivas Pandruvada 1500a9b2f8e2SSrinivas Pandruvada return 0; 1501a9b2f8e2SSrinivas Pandruvada } 1502a9b2f8e2SSrinivas Pandruvada 1503a9b2f8e2SSrinivas Pandruvada static int set_cpufreq_scaling_min_max_from_cpuinfo(int cpu, int cpuinfo_max, int scaling_max) 1504354bd06fSSrinivas Pandruvada { 1505354bd06fSSrinivas Pandruvada char buffer[128], min_freq[16]; 1506354bd06fSSrinivas Pandruvada int fd, ret, len; 1507354bd06fSSrinivas Pandruvada 1508354bd06fSSrinivas Pandruvada if (!CPU_ISSET_S(cpu, present_cpumask_size, present_cpumask)) 1509354bd06fSSrinivas Pandruvada return -1; 1510354bd06fSSrinivas Pandruvada 1511a9b2f8e2SSrinivas Pandruvada if (cpuinfo_max) 1512354bd06fSSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1513354bd06fSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", cpu); 1514354bd06fSSrinivas Pandruvada else 1515354bd06fSSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1516354bd06fSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_min_freq", cpu); 1517354bd06fSSrinivas Pandruvada 1518354bd06fSSrinivas Pandruvada fd = open(buffer, O_RDONLY); 1519354bd06fSSrinivas Pandruvada if (fd < 0) 1520354bd06fSSrinivas Pandruvada return fd; 1521354bd06fSSrinivas Pandruvada 1522354bd06fSSrinivas Pandruvada len = read(fd, min_freq, sizeof(min_freq)); 1523354bd06fSSrinivas Pandruvada close(fd); 1524354bd06fSSrinivas Pandruvada 1525354bd06fSSrinivas Pandruvada if (len < 0) 1526354bd06fSSrinivas Pandruvada return len; 1527354bd06fSSrinivas Pandruvada 1528a9b2f8e2SSrinivas Pandruvada if (scaling_max) 1529a9b2f8e2SSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1530a9b2f8e2SSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); 1531a9b2f8e2SSrinivas Pandruvada else 1532354bd06fSSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1533354bd06fSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); 1534354bd06fSSrinivas Pandruvada 1535354bd06fSSrinivas Pandruvada fd = open(buffer, O_WRONLY); 1536354bd06fSSrinivas Pandruvada if (fd < 0) 1537354bd06fSSrinivas Pandruvada return fd; 1538354bd06fSSrinivas Pandruvada 1539689dfc9eSZhang Rui min_freq[15] = '\0'; 1540354bd06fSSrinivas Pandruvada len = strlen(min_freq); 1541354bd06fSSrinivas Pandruvada ret = write(fd, min_freq, len); 1542354bd06fSSrinivas Pandruvada if (ret == -1) { 1543354bd06fSSrinivas Pandruvada close(fd); 1544354bd06fSSrinivas Pandruvada return ret; 1545354bd06fSSrinivas Pandruvada } 1546354bd06fSSrinivas Pandruvada close(fd); 1547354bd06fSSrinivas Pandruvada 1548354bd06fSSrinivas Pandruvada return 0; 1549354bd06fSSrinivas Pandruvada } 1550354bd06fSSrinivas Pandruvada 1551850337ecSZhang Rui static void set_scaling_min_to_cpuinfo_max(struct isst_id *id) 1552354bd06fSSrinivas Pandruvada { 155356d64692SZhang Rui int i; 1554354bd06fSSrinivas Pandruvada 1555d0e12c46SZhang Rui if (id->cpu < 0) 1556d0e12c46SZhang Rui return; 1557d0e12c46SZhang Rui 1558354bd06fSSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 155900bb07dbSZhang Rui if (!is_cpu_in_power_domain(i, id)) 1560354bd06fSSrinivas Pandruvada continue; 1561354bd06fSSrinivas Pandruvada 1562cf3b8e8fSSrinivas Pandruvada if (is_cpu_online(i) != 1) 1563cf3b8e8fSSrinivas Pandruvada continue; 1564cf3b8e8fSSrinivas Pandruvada 15659734213eSSrinivas Pandruvada adjust_scaling_max_from_base_freq(i); 1566a9b2f8e2SSrinivas Pandruvada set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 0); 1567bbaa2e95SSrinivas Pandruvada adjust_scaling_min_from_base_freq(i); 1568354bd06fSSrinivas Pandruvada } 1569354bd06fSSrinivas Pandruvada } 1570354bd06fSSrinivas Pandruvada 1571850337ecSZhang Rui static void set_scaling_min_to_cpuinfo_min(struct isst_id *id) 1572354bd06fSSrinivas Pandruvada { 157356d64692SZhang Rui int i; 1574354bd06fSSrinivas Pandruvada 1575d0e12c46SZhang Rui if (id->cpu < 0) 1576d0e12c46SZhang Rui return; 1577d0e12c46SZhang Rui 1578354bd06fSSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 157900bb07dbSZhang Rui if (!is_cpu_in_power_domain(i, id)) 1580354bd06fSSrinivas Pandruvada continue; 1581354bd06fSSrinivas Pandruvada 1582cf3b8e8fSSrinivas Pandruvada if (is_cpu_online(i) != 1) 1583cf3b8e8fSSrinivas Pandruvada continue; 1584cf3b8e8fSSrinivas Pandruvada 15859734213eSSrinivas Pandruvada adjust_scaling_max_from_base_freq(i); 1586a9b2f8e2SSrinivas Pandruvada set_cpufreq_scaling_min_max_from_cpuinfo(i, 0, 0); 1587a9b2f8e2SSrinivas Pandruvada } 1588a9b2f8e2SSrinivas Pandruvada } 1589a9b2f8e2SSrinivas Pandruvada 1590850337ecSZhang Rui static void set_scaling_max_to_cpuinfo_max(struct isst_id *id) 1591a9b2f8e2SSrinivas Pandruvada { 159256d64692SZhang Rui int i; 1593a9b2f8e2SSrinivas Pandruvada 1594a9b2f8e2SSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 159500bb07dbSZhang Rui if (!is_cpu_in_power_domain(i, id)) 1596a9b2f8e2SSrinivas Pandruvada continue; 1597a9b2f8e2SSrinivas Pandruvada 1598a9b2f8e2SSrinivas Pandruvada set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 1); 1599354bd06fSSrinivas Pandruvada } 1600354bd06fSSrinivas Pandruvada } 1601354bd06fSSrinivas Pandruvada 1602850337ecSZhang Rui static int set_core_priority_and_min(struct isst_id *id, int mask_size, 1603354bd06fSSrinivas Pandruvada cpu_set_t *cpu_mask, int min_high, 1604354bd06fSSrinivas Pandruvada int min_low) 1605354bd06fSSrinivas Pandruvada { 160656d64692SZhang Rui int ret, i; 1607354bd06fSSrinivas Pandruvada 1608354bd06fSSrinivas Pandruvada if (!CPU_COUNT_S(mask_size, cpu_mask)) 1609354bd06fSSrinivas Pandruvada return -1; 1610354bd06fSSrinivas Pandruvada 1611850337ecSZhang Rui ret = set_clos_param(id, 0, 0, 0, min_high, 0xff); 1612354bd06fSSrinivas Pandruvada if (ret) 1613354bd06fSSrinivas Pandruvada return ret; 1614354bd06fSSrinivas Pandruvada 1615850337ecSZhang Rui ret = set_clos_param(id, 1, 15, 15, min_low, 0xff); 1616354bd06fSSrinivas Pandruvada if (ret) 1617354bd06fSSrinivas Pandruvada return ret; 1618354bd06fSSrinivas Pandruvada 1619850337ecSZhang Rui ret = set_clos_param(id, 2, 15, 15, min_low, 0xff); 1620354bd06fSSrinivas Pandruvada if (ret) 1621354bd06fSSrinivas Pandruvada return ret; 1622354bd06fSSrinivas Pandruvada 1623850337ecSZhang Rui ret = set_clos_param(id, 3, 15, 15, min_low, 0xff); 1624354bd06fSSrinivas Pandruvada if (ret) 1625354bd06fSSrinivas Pandruvada return ret; 1626354bd06fSSrinivas Pandruvada 1627354bd06fSSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 1628354bd06fSSrinivas Pandruvada int clos; 1629850337ecSZhang Rui struct isst_id tid; 1630354bd06fSSrinivas Pandruvada 163100bb07dbSZhang Rui if (!is_cpu_in_power_domain(i, id)) 1632354bd06fSSrinivas Pandruvada continue; 1633354bd06fSSrinivas Pandruvada 1634354bd06fSSrinivas Pandruvada if (CPU_ISSET_S(i, mask_size, cpu_mask)) 1635354bd06fSSrinivas Pandruvada clos = 0; 1636354bd06fSSrinivas Pandruvada else 1637354bd06fSSrinivas Pandruvada clos = 3; 1638354bd06fSSrinivas Pandruvada 1639354bd06fSSrinivas Pandruvada debug_printf("Associate cpu: %d clos: %d\n", i, clos); 1640850337ecSZhang Rui set_isst_id(&tid, i); 1641850337ecSZhang Rui ret = isst_clos_associate(&tid, clos); 1642354bd06fSSrinivas Pandruvada if (ret) { 1643fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_clos_associate failed", 0, 0); 1644354bd06fSSrinivas Pandruvada return ret; 1645354bd06fSSrinivas Pandruvada } 1646354bd06fSSrinivas Pandruvada } 1647354bd06fSSrinivas Pandruvada 1648354bd06fSSrinivas Pandruvada return 0; 1649354bd06fSSrinivas Pandruvada } 1650354bd06fSSrinivas Pandruvada 1651850337ecSZhang Rui static int set_pbf_core_power(struct isst_id *id) 1652354bd06fSSrinivas Pandruvada { 1653354bd06fSSrinivas Pandruvada struct isst_pbf_info pbf_info; 1654354bd06fSSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev; 1655354bd06fSSrinivas Pandruvada int ret; 1656354bd06fSSrinivas Pandruvada 1657d0e12c46SZhang Rui if (id->cpu < 0) 1658d0e12c46SZhang Rui return 0; 1659d0e12c46SZhang Rui 1660850337ecSZhang Rui ret = isst_get_ctdp_levels(id, &pkg_dev); 1661354bd06fSSrinivas Pandruvada if (ret) { 1662fe6fb216SSrinivas Pandruvada debug_printf("isst_get_ctdp_levels failed"); 1663354bd06fSSrinivas Pandruvada return ret; 1664354bd06fSSrinivas Pandruvada } 1665354bd06fSSrinivas Pandruvada debug_printf("Current_level: %d\n", pkg_dev.current_level); 1666354bd06fSSrinivas Pandruvada 1667850337ecSZhang Rui ret = isst_get_pbf_info(id, pkg_dev.current_level, &pbf_info); 1668354bd06fSSrinivas Pandruvada if (ret) { 1669fe6fb216SSrinivas Pandruvada debug_printf("isst_get_pbf_info failed"); 1670354bd06fSSrinivas Pandruvada return ret; 1671354bd06fSSrinivas Pandruvada } 1672354bd06fSSrinivas Pandruvada debug_printf("p1_high: %d p1_low: %d\n", pbf_info.p1_high, 1673354bd06fSSrinivas Pandruvada pbf_info.p1_low); 1674354bd06fSSrinivas Pandruvada 1675850337ecSZhang Rui ret = set_core_priority_and_min(id, pbf_info.core_cpumask_size, 1676354bd06fSSrinivas Pandruvada pbf_info.core_cpumask, 1677354bd06fSSrinivas Pandruvada pbf_info.p1_high, pbf_info.p1_low); 1678354bd06fSSrinivas Pandruvada if (ret) { 1679fe6fb216SSrinivas Pandruvada debug_printf("set_core_priority_and_min failed"); 1680354bd06fSSrinivas Pandruvada return ret; 1681354bd06fSSrinivas Pandruvada } 1682354bd06fSSrinivas Pandruvada 1683850337ecSZhang Rui ret = isst_pm_qos_config(id, 1, 1); 1684354bd06fSSrinivas Pandruvada if (ret) { 1685fe6fb216SSrinivas Pandruvada debug_printf("isst_pm_qos_config failed"); 1686354bd06fSSrinivas Pandruvada return ret; 1687354bd06fSSrinivas Pandruvada } 1688354bd06fSSrinivas Pandruvada 1689354bd06fSSrinivas Pandruvada return 0; 1690354bd06fSSrinivas Pandruvada } 1691354bd06fSSrinivas Pandruvada 1692850337ecSZhang Rui static void set_pbf_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, 16933fb4f7cdSSrinivas Pandruvada void *arg4) 16943fb4f7cdSSrinivas Pandruvada { 16953d904f06SSrinivas Pandruvada struct isst_pkg_ctdp_level_info ctdp_level; 16963d904f06SSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev; 16973fb4f7cdSSrinivas Pandruvada int ret; 16983fb4f7cdSSrinivas Pandruvada int status = *(int *)arg4; 16993fb4f7cdSSrinivas Pandruvada 17001aa7177cSPrarit Bhargava if (is_clx_n_platform()) { 17011aa7177cSPrarit Bhargava ret = 0; 17027fc9fefdSSrinivas Pandruvada if (status) { 1703850337ecSZhang Rui set_clx_pbf_cpufreq_scaling_min_max(id); 1704a9b2f8e2SSrinivas Pandruvada 1705a9b2f8e2SSrinivas Pandruvada } else { 1706850337ecSZhang Rui set_scaling_max_to_cpuinfo_max(id); 1707850337ecSZhang Rui set_scaling_min_to_cpuinfo_min(id); 1708a9b2f8e2SSrinivas Pandruvada } 17091aa7177cSPrarit Bhargava goto disp_result; 17101aa7177cSPrarit Bhargava } 17111aa7177cSPrarit Bhargava 1712850337ecSZhang Rui ret = isst_get_ctdp_levels(id, &pkg_dev); 17133d904f06SSrinivas Pandruvada if (ret) { 17143d904f06SSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get number of levels", 0, 0); 17153d904f06SSrinivas Pandruvada goto disp_result; 17163d904f06SSrinivas Pandruvada } 17173d904f06SSrinivas Pandruvada 1718850337ecSZhang Rui ret = isst_get_ctdp_control(id, pkg_dev.current_level, &ctdp_level); 17193d904f06SSrinivas Pandruvada if (ret) { 17203d904f06SSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get current level", 0, 0); 17213d904f06SSrinivas Pandruvada goto disp_result; 17223d904f06SSrinivas Pandruvada } 17233d904f06SSrinivas Pandruvada 17243d904f06SSrinivas Pandruvada if (!ctdp_level.pbf_support) { 17253d904f06SSrinivas Pandruvada isst_display_error_info_message(1, "base-freq feature is not present at this level", 1, pkg_dev.current_level); 17263d904f06SSrinivas Pandruvada ret = -1; 17273d904f06SSrinivas Pandruvada goto disp_result; 17283d904f06SSrinivas Pandruvada } 17293d904f06SSrinivas Pandruvada 1730097a5222SSrinivas Pandruvada if (auto_mode && status) { 1731850337ecSZhang Rui ret = set_pbf_core_power(id); 1732354bd06fSSrinivas Pandruvada if (ret) 1733354bd06fSSrinivas Pandruvada goto disp_result; 1734354bd06fSSrinivas Pandruvada } 1735354bd06fSSrinivas Pandruvada 1736850337ecSZhang Rui ret = isst_set_pbf_fact_status(id, 1, status); 17373fb4f7cdSSrinivas Pandruvada if (ret) { 173839bae0fcSSrinivas Pandruvada debug_printf("isst_set_pbf_fact_status failed"); 1739354bd06fSSrinivas Pandruvada if (auto_mode) 1740850337ecSZhang Rui isst_pm_qos_config(id, 0, 0); 17413fb4f7cdSSrinivas Pandruvada } else { 1742354bd06fSSrinivas Pandruvada if (auto_mode) { 1743354bd06fSSrinivas Pandruvada if (status) 1744850337ecSZhang Rui set_scaling_min_to_cpuinfo_max(id); 1745354bd06fSSrinivas Pandruvada else 1746850337ecSZhang Rui set_scaling_min_to_cpuinfo_min(id); 1747354bd06fSSrinivas Pandruvada } 1748354bd06fSSrinivas Pandruvada } 1749354bd06fSSrinivas Pandruvada 1750097a5222SSrinivas Pandruvada if (auto_mode && !status) 1751850337ecSZhang Rui isst_pm_qos_config(id, 0, 1); 1752097a5222SSrinivas Pandruvada 1753354bd06fSSrinivas Pandruvada disp_result: 17543fb4f7cdSSrinivas Pandruvada if (status) 1755850337ecSZhang Rui isst_display_result(id, outf, "base-freq", "enable", 17563fb4f7cdSSrinivas Pandruvada ret); 17573fb4f7cdSSrinivas Pandruvada else 1758850337ecSZhang Rui isst_display_result(id, outf, "base-freq", "disable", 17593fb4f7cdSSrinivas Pandruvada ret); 17603fb4f7cdSSrinivas Pandruvada } 17613fb4f7cdSSrinivas Pandruvada 1762ce1326a2SPrarit Bhargava static void set_pbf_enable(int arg) 17633fb4f7cdSSrinivas Pandruvada { 1764ce1326a2SPrarit Bhargava int enable = arg; 17653fb4f7cdSSrinivas Pandruvada 17663fb4f7cdSSrinivas Pandruvada if (cmd_help) { 1767ce1326a2SPrarit Bhargava if (enable) { 17683fb4f7cdSSrinivas Pandruvada fprintf(stderr, 1769354bd06fSSrinivas Pandruvada "Enable Intel Speed Select Technology base frequency feature\n"); 177039bae0fcSSrinivas Pandruvada if (is_clx_n_platform()) { 177139bae0fcSSrinivas Pandruvada fprintf(stderr, 177239bae0fcSSrinivas Pandruvada "\tOn this platform this command doesn't enable feature in the hardware.\n"); 177339bae0fcSSrinivas Pandruvada fprintf(stderr, 177439bae0fcSSrinivas Pandruvada "\tIt updates the cpufreq scaling_min_freq to match cpufreq base_frequency.\n"); 177539bae0fcSSrinivas Pandruvada exit(0); 177639bae0fcSSrinivas Pandruvada 177739bae0fcSSrinivas Pandruvada } 1778354bd06fSSrinivas Pandruvada fprintf(stderr, 1779354bd06fSSrinivas Pandruvada "\tOptional Arguments: -a|--auto : Use priority of cores to set core-power associations\n"); 1780ce1326a2SPrarit Bhargava } else { 1781354bd06fSSrinivas Pandruvada 178239bae0fcSSrinivas Pandruvada if (is_clx_n_platform()) { 178339bae0fcSSrinivas Pandruvada fprintf(stderr, 178439bae0fcSSrinivas Pandruvada "\tOn this platform this command doesn't disable feature in the hardware.\n"); 178539bae0fcSSrinivas Pandruvada fprintf(stderr, 178639bae0fcSSrinivas Pandruvada "\tIt updates the cpufreq scaling_min_freq to match cpuinfo_min_freq\n"); 178739bae0fcSSrinivas Pandruvada exit(0); 178839bae0fcSSrinivas Pandruvada } 17893fb4f7cdSSrinivas Pandruvada fprintf(stderr, 1790354bd06fSSrinivas Pandruvada "Disable Intel Speed Select Technology base frequency feature\n"); 1791354bd06fSSrinivas Pandruvada fprintf(stderr, 1792354bd06fSSrinivas Pandruvada "\tOptional Arguments: -a|--auto : Also disable core-power associations\n"); 1793ce1326a2SPrarit Bhargava } 17943fb4f7cdSSrinivas Pandruvada exit(0); 17953fb4f7cdSSrinivas Pandruvada } 17963fb4f7cdSSrinivas Pandruvada 17973fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 17983fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 17993fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL, 1800ce1326a2SPrarit Bhargava NULL, &enable); 18013fb4f7cdSSrinivas Pandruvada else 1802c77a8d4aSZhang Rui for_each_online_power_domain_in_set(set_pbf_for_cpu, NULL, NULL, 1803ce1326a2SPrarit Bhargava NULL, &enable); 18043fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 18053fb4f7cdSSrinivas Pandruvada } 18063fb4f7cdSSrinivas Pandruvada 1807850337ecSZhang Rui static void dump_fact_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, 18083fb4f7cdSSrinivas Pandruvada void *arg3, void *arg4) 18093fb4f7cdSSrinivas Pandruvada { 18103fb4f7cdSSrinivas Pandruvada struct isst_fact_info fact_info; 18113fb4f7cdSSrinivas Pandruvada int ret; 18123fb4f7cdSSrinivas Pandruvada 1813850337ecSZhang Rui ret = isst_get_fact_info(id, tdp_level, fact_bucket, &fact_info); 1814a9fd6ae7SSrinivas Pandruvada if (ret) { 1815a9fd6ae7SSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get turbo-freq info at this level", 1, tdp_level); 1816a9fd6ae7SSrinivas Pandruvada isst_ctdp_display_information_end(outf); 1817a9fd6ae7SSrinivas Pandruvada exit(1); 1818a9fd6ae7SSrinivas Pandruvada } else { 1819850337ecSZhang Rui isst_fact_display_information(id, outf, tdp_level, fact_bucket, 18203fb4f7cdSSrinivas Pandruvada fact_avx, &fact_info); 18213fb4f7cdSSrinivas Pandruvada } 1822a9fd6ae7SSrinivas Pandruvada } 18233fb4f7cdSSrinivas Pandruvada 1824ce1326a2SPrarit Bhargava static void dump_fact_config(int arg) 18253fb4f7cdSSrinivas Pandruvada { 18263fb4f7cdSSrinivas Pandruvada if (cmd_help) { 18273fb4f7cdSSrinivas Pandruvada fprintf(stderr, 18283fb4f7cdSSrinivas Pandruvada "Print complete Intel Speed Select Technology turbo frequency configuration for a TDP level. Other arguments are optional.\n"); 18293fb4f7cdSSrinivas Pandruvada fprintf(stderr, 18303fb4f7cdSSrinivas Pandruvada "\tArguments: -l|--level : Specify tdp level\n"); 18313fb4f7cdSSrinivas Pandruvada fprintf(stderr, 18323fb4f7cdSSrinivas Pandruvada "\tArguments: -b|--bucket : Bucket index to dump\n"); 18333fb4f7cdSSrinivas Pandruvada fprintf(stderr, 18343fb4f7cdSSrinivas Pandruvada "\tArguments: -r|--trl-type : Specify trl type: sse|avx2|avx512\n"); 18353fb4f7cdSSrinivas Pandruvada exit(0); 18363fb4f7cdSSrinivas Pandruvada } 18373fb4f7cdSSrinivas Pandruvada 18383fb4f7cdSSrinivas Pandruvada if (tdp_level == 0xff) { 1839a9fd6ae7SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid command: specify tdp_level\n", 0, 0); 18403fb4f7cdSSrinivas Pandruvada exit(1); 18413fb4f7cdSSrinivas Pandruvada } 18423fb4f7cdSSrinivas Pandruvada 18433fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 18443fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 18453fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(dump_fact_config_for_cpu, 18463fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL, NULL); 18473fb4f7cdSSrinivas Pandruvada else 1848c77a8d4aSZhang Rui for_each_online_power_domain_in_set(dump_fact_config_for_cpu, NULL, 18493fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 18503fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 18513fb4f7cdSSrinivas Pandruvada } 18523fb4f7cdSSrinivas Pandruvada 1853850337ecSZhang Rui static void set_fact_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, 18543fb4f7cdSSrinivas Pandruvada void *arg4) 18553fb4f7cdSSrinivas Pandruvada { 18563d904f06SSrinivas Pandruvada struct isst_pkg_ctdp_level_info ctdp_level; 18573d904f06SSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev; 18583fb4f7cdSSrinivas Pandruvada int ret; 18593fb4f7cdSSrinivas Pandruvada int status = *(int *)arg4; 18603fb4f7cdSSrinivas Pandruvada 18612da6391dSSrinivas Pandruvada if (status && no_turbo()) { 18622da6391dSSrinivas Pandruvada isst_display_error_info_message(1, "Turbo mode is disabled", 0, 0); 18632da6391dSSrinivas Pandruvada ret = -1; 18642da6391dSSrinivas Pandruvada goto disp_results; 18652da6391dSSrinivas Pandruvada } 18662da6391dSSrinivas Pandruvada 1867850337ecSZhang Rui ret = isst_get_ctdp_levels(id, &pkg_dev); 18683d904f06SSrinivas Pandruvada if (ret) { 18693d904f06SSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get number of levels", 0, 0); 18703d904f06SSrinivas Pandruvada goto disp_results; 18713d904f06SSrinivas Pandruvada } 18723d904f06SSrinivas Pandruvada 1873850337ecSZhang Rui ret = isst_get_ctdp_control(id, pkg_dev.current_level, &ctdp_level); 18743d904f06SSrinivas Pandruvada if (ret) { 18753d904f06SSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get current level", 0, 0); 18763d904f06SSrinivas Pandruvada goto disp_results; 18773d904f06SSrinivas Pandruvada } 18783d904f06SSrinivas Pandruvada 18793d904f06SSrinivas Pandruvada if (!ctdp_level.fact_support) { 18803d904f06SSrinivas Pandruvada isst_display_error_info_message(1, "turbo-freq feature is not present at this level", 1, pkg_dev.current_level); 18813d904f06SSrinivas Pandruvada ret = -1; 18823d904f06SSrinivas Pandruvada goto disp_results; 18833d904f06SSrinivas Pandruvada } 18843d904f06SSrinivas Pandruvada 18857983ed6fSSrinivas Pandruvada if (status) { 1886850337ecSZhang Rui ret = isst_pm_qos_config(id, 1, 1); 18873fb4f7cdSSrinivas Pandruvada if (ret) 1888a6a82f9bSSrinivas Pandruvada goto disp_results; 1889a6a82f9bSSrinivas Pandruvada } 1890a6a82f9bSSrinivas Pandruvada 1891850337ecSZhang Rui ret = isst_set_pbf_fact_status(id, 0, status); 1892a6a82f9bSSrinivas Pandruvada if (ret) { 1893a9fd6ae7SSrinivas Pandruvada debug_printf("isst_set_pbf_fact_status failed"); 1894a6a82f9bSSrinivas Pandruvada if (auto_mode) 1895850337ecSZhang Rui isst_pm_qos_config(id, 0, 0); 1896a6a82f9bSSrinivas Pandruvada 1897a6a82f9bSSrinivas Pandruvada goto disp_results; 1898a6a82f9bSSrinivas Pandruvada } 1899a6a82f9bSSrinivas Pandruvada 1900a6a82f9bSSrinivas Pandruvada /* Set TRL */ 19013fb4f7cdSSrinivas Pandruvada if (status) { 19023fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev; 19033fb4f7cdSSrinivas Pandruvada 1904850337ecSZhang Rui ret = isst_get_ctdp_levels(id, &pkg_dev); 1905d0e12c46SZhang Rui if (!ret && id->cpu >= 0) 1906850337ecSZhang Rui ret = isst_set_trl(id, fact_trl); 1907a6a82f9bSSrinivas Pandruvada if (ret && auto_mode) 1908850337ecSZhang Rui isst_pm_qos_config(id, 0, 0); 1909097a5222SSrinivas Pandruvada } else { 1910097a5222SSrinivas Pandruvada if (auto_mode) 1911850337ecSZhang Rui isst_pm_qos_config(id, 0, 0); 1912a6a82f9bSSrinivas Pandruvada } 1913a6a82f9bSSrinivas Pandruvada 1914a6a82f9bSSrinivas Pandruvada disp_results: 1915a6a82f9bSSrinivas Pandruvada if (status) { 1916850337ecSZhang Rui isst_display_result(id, outf, "turbo-freq", "enable", ret); 191714a8aa49SSrinivas Pandruvada if (ret) 191814a8aa49SSrinivas Pandruvada fact_enable_fail = ret; 19193fb4f7cdSSrinivas Pandruvada } else { 19203fb4f7cdSSrinivas Pandruvada /* Since we modified TRL during Fact enable, restore it */ 1921850337ecSZhang Rui isst_set_trl_from_current_tdp(id, fact_trl); 1922850337ecSZhang Rui isst_display_result(id, outf, "turbo-freq", "disable", ret); 19233fb4f7cdSSrinivas Pandruvada } 19243fb4f7cdSSrinivas Pandruvada } 19253fb4f7cdSSrinivas Pandruvada 1926ce1326a2SPrarit Bhargava static void set_fact_enable(int arg) 19273fb4f7cdSSrinivas Pandruvada { 1928ce1326a2SPrarit Bhargava int i, ret, enable = arg; 1929850337ecSZhang Rui struct isst_id id; 19303fb4f7cdSSrinivas Pandruvada 19313fb4f7cdSSrinivas Pandruvada if (cmd_help) { 1932ce1326a2SPrarit Bhargava if (enable) { 19333fb4f7cdSSrinivas Pandruvada fprintf(stderr, 19343fb4f7cdSSrinivas Pandruvada "Enable Intel Speed Select Technology Turbo frequency feature\n"); 19353fb4f7cdSSrinivas Pandruvada fprintf(stderr, 19363fb4f7cdSSrinivas Pandruvada "Optional: -t|--trl : Specify turbo ratio limit\n"); 1937a6a82f9bSSrinivas Pandruvada fprintf(stderr, 1938a6a82f9bSSrinivas Pandruvada "\tOptional Arguments: -a|--auto : Designate specified target CPUs with"); 1939ce1326a2SPrarit Bhargava fprintf(stderr, 1940ce1326a2SPrarit Bhargava "-C|--cpu option as as high priority using core-power feature\n"); 1941ce1326a2SPrarit Bhargava } else { 1942ce1326a2SPrarit Bhargava fprintf(stderr, 1943ce1326a2SPrarit Bhargava "Disable Intel Speed Select Technology turbo frequency feature\n"); 1944ce1326a2SPrarit Bhargava fprintf(stderr, 1945ce1326a2SPrarit Bhargava "Optional: -t|--trl : Specify turbo ratio limit\n"); 1946ce1326a2SPrarit Bhargava fprintf(stderr, 1947ce1326a2SPrarit Bhargava "\tOptional Arguments: -a|--auto : Also disable core-power associations\n"); 1948ce1326a2SPrarit Bhargava } 19493fb4f7cdSSrinivas Pandruvada exit(0); 19503fb4f7cdSSrinivas Pandruvada } 19513fb4f7cdSSrinivas Pandruvada 19523fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 19533fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 19543fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL, 1955ce1326a2SPrarit Bhargava NULL, &enable); 19563fb4f7cdSSrinivas Pandruvada else 1957c77a8d4aSZhang Rui for_each_online_power_domain_in_set(set_fact_for_cpu, NULL, NULL, 1958ce1326a2SPrarit Bhargava NULL, &enable); 19593fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 1960a6a82f9bSSrinivas Pandruvada 196114a8aa49SSrinivas Pandruvada if (!fact_enable_fail && enable && auto_mode) { 1962a6a82f9bSSrinivas Pandruvada /* 1963a6a82f9bSSrinivas Pandruvada * When we adjust CLOS param, we have to set for siblings also. 1964a6a82f9bSSrinivas Pandruvada * So for the each user specified CPU, also add the sibling 1965a6a82f9bSSrinivas Pandruvada * in the present_cpu_mask. 1966a6a82f9bSSrinivas Pandruvada */ 1967a6a82f9bSSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 1968a6a82f9bSSrinivas Pandruvada char buffer[128], sibling_list[128], *cpu_str; 1969a6a82f9bSSrinivas Pandruvada int fd, len; 1970a6a82f9bSSrinivas Pandruvada 1971a6a82f9bSSrinivas Pandruvada if (!CPU_ISSET_S(i, target_cpumask_size, target_cpumask)) 1972a6a82f9bSSrinivas Pandruvada continue; 1973a6a82f9bSSrinivas Pandruvada 1974a6a82f9bSSrinivas Pandruvada snprintf(buffer, sizeof(buffer), 1975a6a82f9bSSrinivas Pandruvada "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", i); 1976a6a82f9bSSrinivas Pandruvada 1977a6a82f9bSSrinivas Pandruvada fd = open(buffer, O_RDONLY); 1978a6a82f9bSSrinivas Pandruvada if (fd < 0) 1979a6a82f9bSSrinivas Pandruvada continue; 1980a6a82f9bSSrinivas Pandruvada 1981a6a82f9bSSrinivas Pandruvada len = read(fd, sibling_list, sizeof(sibling_list)); 1982a6a82f9bSSrinivas Pandruvada close(fd); 1983a6a82f9bSSrinivas Pandruvada 1984a6a82f9bSSrinivas Pandruvada if (len < 0) 1985a6a82f9bSSrinivas Pandruvada continue; 1986a6a82f9bSSrinivas Pandruvada 1987689dfc9eSZhang Rui sibling_list[127] = '\0'; 1988a6a82f9bSSrinivas Pandruvada cpu_str = strtok(sibling_list, ","); 1989a6a82f9bSSrinivas Pandruvada while (cpu_str != NULL) { 1990a6a82f9bSSrinivas Pandruvada int cpu; 1991a6a82f9bSSrinivas Pandruvada 1992a6a82f9bSSrinivas Pandruvada sscanf(cpu_str, "%d", &cpu); 1993a6a82f9bSSrinivas Pandruvada CPU_SET_S(cpu, target_cpumask_size, target_cpumask); 1994a6a82f9bSSrinivas Pandruvada cpu_str = strtok(NULL, ","); 1995a6a82f9bSSrinivas Pandruvada } 1996a6a82f9bSSrinivas Pandruvada } 1997a6a82f9bSSrinivas Pandruvada 1998a6a82f9bSSrinivas Pandruvada for (i = 0; i < get_topo_max_cpus(); ++i) { 1999a6a82f9bSSrinivas Pandruvada int clos; 2000a6a82f9bSSrinivas Pandruvada 2001a6a82f9bSSrinivas Pandruvada if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) 2002a6a82f9bSSrinivas Pandruvada continue; 2003a6a82f9bSSrinivas Pandruvada 20046ed9e363SSrinivas Pandruvada if (is_cpu_online(i) != 1) 20056ed9e363SSrinivas Pandruvada continue; 20066ed9e363SSrinivas Pandruvada 2007850337ecSZhang Rui set_isst_id(&id, i); 2008850337ecSZhang Rui ret = set_clos_param(&id, 0, 0, 0, 0, 0xff); 2009a6a82f9bSSrinivas Pandruvada if (ret) 2010a6a82f9bSSrinivas Pandruvada goto error_disp; 2011a6a82f9bSSrinivas Pandruvada 2012850337ecSZhang Rui ret = set_clos_param(&id, 1, 15, 15, 0, 0xff); 2013a6a82f9bSSrinivas Pandruvada if (ret) 2014a6a82f9bSSrinivas Pandruvada goto error_disp; 2015a6a82f9bSSrinivas Pandruvada 2016850337ecSZhang Rui ret = set_clos_param(&id, 2, 15, 15, 0, 0xff); 2017a6a82f9bSSrinivas Pandruvada if (ret) 2018a6a82f9bSSrinivas Pandruvada goto error_disp; 2019a6a82f9bSSrinivas Pandruvada 2020850337ecSZhang Rui ret = set_clos_param(&id, 3, 15, 15, 0, 0xff); 2021a6a82f9bSSrinivas Pandruvada if (ret) 2022a6a82f9bSSrinivas Pandruvada goto error_disp; 2023a6a82f9bSSrinivas Pandruvada 2024a6a82f9bSSrinivas Pandruvada if (CPU_ISSET_S(i, target_cpumask_size, target_cpumask)) 2025a6a82f9bSSrinivas Pandruvada clos = 0; 2026a6a82f9bSSrinivas Pandruvada else 2027a6a82f9bSSrinivas Pandruvada clos = 3; 2028a6a82f9bSSrinivas Pandruvada 2029a6a82f9bSSrinivas Pandruvada debug_printf("Associate cpu: %d clos: %d\n", i, clos); 2030850337ecSZhang Rui ret = isst_clos_associate(&id, clos); 2031a6a82f9bSSrinivas Pandruvada if (ret) 2032a6a82f9bSSrinivas Pandruvada goto error_disp; 2033a6a82f9bSSrinivas Pandruvada } 2034850337ecSZhang Rui set_isst_id(&id, -1); 2035850337ecSZhang Rui isst_display_result(&id, outf, "turbo-freq --auto", "enable", 0); 2036a6a82f9bSSrinivas Pandruvada } 2037a6a82f9bSSrinivas Pandruvada 2038a6a82f9bSSrinivas Pandruvada return; 2039a6a82f9bSSrinivas Pandruvada 2040a6a82f9bSSrinivas Pandruvada error_disp: 2041850337ecSZhang Rui isst_display_result(&id, outf, "turbo-freq --auto", "enable", ret); 2042a6a82f9bSSrinivas Pandruvada 20433fb4f7cdSSrinivas Pandruvada } 20443fb4f7cdSSrinivas Pandruvada 2045850337ecSZhang Rui static void enable_clos_qos_config(struct isst_id *id, void *arg1, void *arg2, void *arg3, 20463fb4f7cdSSrinivas Pandruvada void *arg4) 20473fb4f7cdSSrinivas Pandruvada { 20483fb4f7cdSSrinivas Pandruvada int ret; 20493fb4f7cdSSrinivas Pandruvada int status = *(int *)arg4; 20503fb4f7cdSSrinivas Pandruvada 2051fe6fb216SSrinivas Pandruvada if (is_skx_based_platform()) 2052fe6fb216SSrinivas Pandruvada clos_priority_type = 1; 2053fe6fb216SSrinivas Pandruvada 2054850337ecSZhang Rui ret = isst_pm_qos_config(id, status, clos_priority_type); 2055a6a82f9bSSrinivas Pandruvada if (ret) 2056fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_pm_qos_config failed", 0, 0); 2057a6a82f9bSSrinivas Pandruvada 20583fb4f7cdSSrinivas Pandruvada if (status) 2059850337ecSZhang Rui isst_display_result(id, outf, "core-power", "enable", 20603fb4f7cdSSrinivas Pandruvada ret); 20613fb4f7cdSSrinivas Pandruvada else 2062850337ecSZhang Rui isst_display_result(id, outf, "core-power", "disable", 20633fb4f7cdSSrinivas Pandruvada ret); 20643fb4f7cdSSrinivas Pandruvada } 20653fb4f7cdSSrinivas Pandruvada 2066ce1326a2SPrarit Bhargava static void set_clos_enable(int arg) 20673fb4f7cdSSrinivas Pandruvada { 2068ce1326a2SPrarit Bhargava int enable = arg; 20693fb4f7cdSSrinivas Pandruvada 20703fb4f7cdSSrinivas Pandruvada if (cmd_help) { 2071ce1326a2SPrarit Bhargava if (enable) { 2072ce1326a2SPrarit Bhargava fprintf(stderr, 2073ce1326a2SPrarit Bhargava "Enable core-power for a package/die\n"); 2074fe6fb216SSrinivas Pandruvada if (!is_skx_based_platform()) { 20753fb4f7cdSSrinivas Pandruvada fprintf(stderr, 20763fb4f7cdSSrinivas Pandruvada "\tClos Enable: Specify priority type with [--priority|-p]\n"); 20773fb4f7cdSSrinivas Pandruvada fprintf(stderr, "\t\t 0: Proportional, 1: Ordered\n"); 2078fe6fb216SSrinivas Pandruvada } 2079ce1326a2SPrarit Bhargava } else { 2080ce1326a2SPrarit Bhargava fprintf(stderr, 2081ce1326a2SPrarit Bhargava "Disable core-power: [No command arguments are required]\n"); 2082ce1326a2SPrarit Bhargava } 20833fb4f7cdSSrinivas Pandruvada exit(0); 20843fb4f7cdSSrinivas Pandruvada } 20853fb4f7cdSSrinivas Pandruvada 2086ce1326a2SPrarit Bhargava if (enable && cpufreq_sysfs_present()) { 20873fb4f7cdSSrinivas Pandruvada fprintf(stderr, 20883fb4f7cdSSrinivas Pandruvada "cpufreq subsystem and core-power enable will interfere with each other!\n"); 20893fb4f7cdSSrinivas Pandruvada } 20903fb4f7cdSSrinivas Pandruvada 20913fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 20923fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 20933fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL, 2094ce1326a2SPrarit Bhargava NULL, NULL, &enable); 20953fb4f7cdSSrinivas Pandruvada else 2096c77a8d4aSZhang Rui for_each_online_power_domain_in_set(enable_clos_qos_config, NULL, 2097ce1326a2SPrarit Bhargava NULL, NULL, &enable); 20983fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 20993fb4f7cdSSrinivas Pandruvada } 21003fb4f7cdSSrinivas Pandruvada 2101850337ecSZhang Rui static void dump_clos_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, 21023fb4f7cdSSrinivas Pandruvada void *arg3, void *arg4) 21033fb4f7cdSSrinivas Pandruvada { 21043fb4f7cdSSrinivas Pandruvada struct isst_clos_config clos_config; 21053fb4f7cdSSrinivas Pandruvada int ret; 21063fb4f7cdSSrinivas Pandruvada 2107443bf104SZhang Rui if (id->cpu < 0) 2108443bf104SZhang Rui return; 2109443bf104SZhang Rui 2110850337ecSZhang Rui ret = isst_pm_get_clos(id, current_clos, &clos_config); 21113fb4f7cdSSrinivas Pandruvada if (ret) 2112fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_pm_get_clos failed", 0, 0); 21133fb4f7cdSSrinivas Pandruvada else 2114850337ecSZhang Rui isst_clos_display_information(id, outf, current_clos, 21153fb4f7cdSSrinivas Pandruvada &clos_config); 21163fb4f7cdSSrinivas Pandruvada } 21173fb4f7cdSSrinivas Pandruvada 2118ce1326a2SPrarit Bhargava static void dump_clos_config(int arg) 21193fb4f7cdSSrinivas Pandruvada { 21203fb4f7cdSSrinivas Pandruvada if (cmd_help) { 21213fb4f7cdSSrinivas Pandruvada fprintf(stderr, 21223fb4f7cdSSrinivas Pandruvada "Print Intel Speed Select Technology core power configuration\n"); 21233fb4f7cdSSrinivas Pandruvada fprintf(stderr, 21243fb4f7cdSSrinivas Pandruvada "\tArguments: [-c | --clos]: Specify clos id\n"); 21253fb4f7cdSSrinivas Pandruvada exit(0); 21263fb4f7cdSSrinivas Pandruvada } 21273fb4f7cdSSrinivas Pandruvada if (current_clos < 0 || current_clos > 3) { 2128fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid clos id\n", 0, 0); 2129fe6fb216SSrinivas Pandruvada isst_ctdp_display_information_end(outf); 21303fb4f7cdSSrinivas Pandruvada exit(0); 21313fb4f7cdSSrinivas Pandruvada } 21323fb4f7cdSSrinivas Pandruvada 21333fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 21343fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 21353fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(dump_clos_config_for_cpu, 21363fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL, NULL); 21373fb4f7cdSSrinivas Pandruvada else 2138c77a8d4aSZhang Rui for_each_online_power_domain_in_set(dump_clos_config_for_cpu, NULL, 21393fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 21403fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 21413fb4f7cdSSrinivas Pandruvada } 21423fb4f7cdSSrinivas Pandruvada 2143850337ecSZhang Rui static void get_clos_info_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, 2144188afed9SSrinivas Pandruvada void *arg4) 2145188afed9SSrinivas Pandruvada { 2146188afed9SSrinivas Pandruvada int enable, ret, prio_type; 2147188afed9SSrinivas Pandruvada 2148850337ecSZhang Rui ret = isst_clos_get_clos_information(id, &enable, &prio_type); 2149188afed9SSrinivas Pandruvada if (ret) 2150fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_clos_get_info failed", 0, 0); 2151143ad322SSrinivas Pandruvada else { 2152143ad322SSrinivas Pandruvada int cp_state, cp_cap; 2153143ad322SSrinivas Pandruvada 2154850337ecSZhang Rui isst_read_pm_config(id, &cp_state, &cp_cap); 2155850337ecSZhang Rui isst_clos_display_clos_information(id, outf, enable, prio_type, 2156143ad322SSrinivas Pandruvada cp_state, cp_cap); 2157143ad322SSrinivas Pandruvada } 2158188afed9SSrinivas Pandruvada } 2159188afed9SSrinivas Pandruvada 2160ce1326a2SPrarit Bhargava static void dump_clos_info(int arg) 2161188afed9SSrinivas Pandruvada { 2162188afed9SSrinivas Pandruvada if (cmd_help) { 2163188afed9SSrinivas Pandruvada fprintf(stderr, 2164188afed9SSrinivas Pandruvada "Print Intel Speed Select Technology core power information\n"); 2165f5205f49SSrinivas Pandruvada fprintf(stderr, "\t Optionally specify targeted cpu id with [--cpu|-c]\n"); 2166188afed9SSrinivas Pandruvada exit(0); 2167188afed9SSrinivas Pandruvada } 2168188afed9SSrinivas Pandruvada 2169188afed9SSrinivas Pandruvada isst_ctdp_display_information_start(outf); 2170f5205f49SSrinivas Pandruvada if (max_target_cpus) 2171188afed9SSrinivas Pandruvada for_each_online_target_cpu_in_set(get_clos_info_for_cpu, NULL, 2172188afed9SSrinivas Pandruvada NULL, NULL, NULL); 2173f5205f49SSrinivas Pandruvada else 2174c77a8d4aSZhang Rui for_each_online_power_domain_in_set(get_clos_info_for_cpu, NULL, 2175f5205f49SSrinivas Pandruvada NULL, NULL, NULL); 2176188afed9SSrinivas Pandruvada isst_ctdp_display_information_end(outf); 2177188afed9SSrinivas Pandruvada 2178188afed9SSrinivas Pandruvada } 2179188afed9SSrinivas Pandruvada 2180850337ecSZhang Rui static void set_clos_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, 21813fb4f7cdSSrinivas Pandruvada void *arg4) 21823fb4f7cdSSrinivas Pandruvada { 21833fb4f7cdSSrinivas Pandruvada struct isst_clos_config clos_config; 21843fb4f7cdSSrinivas Pandruvada int ret; 21853fb4f7cdSSrinivas Pandruvada 2186443bf104SZhang Rui if (id->cpu < 0) 2187443bf104SZhang Rui return; 2188443bf104SZhang Rui 21893fb4f7cdSSrinivas Pandruvada clos_config.epp = clos_epp; 21903fb4f7cdSSrinivas Pandruvada clos_config.clos_prop_prio = clos_prop_prio; 21913fb4f7cdSSrinivas Pandruvada clos_config.clos_min = clos_min; 21923fb4f7cdSSrinivas Pandruvada clos_config.clos_max = clos_max; 21933fb4f7cdSSrinivas Pandruvada clos_config.clos_desired = clos_desired; 2194850337ecSZhang Rui ret = isst_set_clos(id, current_clos, &clos_config); 21953fb4f7cdSSrinivas Pandruvada if (ret) 2196fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_set_clos failed", 0, 0); 21973fb4f7cdSSrinivas Pandruvada else 2198850337ecSZhang Rui isst_display_result(id, outf, "core-power", "config", ret); 21993fb4f7cdSSrinivas Pandruvada } 22003fb4f7cdSSrinivas Pandruvada 2201ce1326a2SPrarit Bhargava static void set_clos_config(int arg) 22023fb4f7cdSSrinivas Pandruvada { 22033fb4f7cdSSrinivas Pandruvada if (cmd_help) { 22043fb4f7cdSSrinivas Pandruvada fprintf(stderr, 22053fb4f7cdSSrinivas Pandruvada "Set core-power configuration for one of the four clos ids\n"); 22063fb4f7cdSSrinivas Pandruvada fprintf(stderr, 22073fb4f7cdSSrinivas Pandruvada "\tSpecify targeted clos id with [--clos|-c]\n"); 2208fe6fb216SSrinivas Pandruvada if (!is_skx_based_platform()) { 22093fb4f7cdSSrinivas Pandruvada fprintf(stderr, "\tSpecify clos EPP with [--epp|-e]\n"); 22103fb4f7cdSSrinivas Pandruvada fprintf(stderr, 22113fb4f7cdSSrinivas Pandruvada "\tSpecify clos Proportional Priority [--weight|-w]\n"); 2212fe6fb216SSrinivas Pandruvada } 221340dee9ddSSrinivas Pandruvada fprintf(stderr, "\tSpecify clos min in MHz with [--min|-n]\n"); 221440dee9ddSSrinivas Pandruvada fprintf(stderr, "\tSpecify clos max in MHz with [--max|-m]\n"); 22153fb4f7cdSSrinivas Pandruvada exit(0); 22163fb4f7cdSSrinivas Pandruvada } 22173fb4f7cdSSrinivas Pandruvada 22183fb4f7cdSSrinivas Pandruvada if (current_clos < 0 || current_clos > 3) { 2219fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid clos id\n", 0, 0); 22203fb4f7cdSSrinivas Pandruvada exit(0); 22213fb4f7cdSSrinivas Pandruvada } 2222fe6fb216SSrinivas Pandruvada if (!is_skx_based_platform() && (clos_epp < 0 || clos_epp > 0x0F)) { 2223fe6fb216SSrinivas Pandruvada fprintf(stderr, "clos epp is not specified or invalid, default: 0\n"); 22243fb4f7cdSSrinivas Pandruvada clos_epp = 0; 22253fb4f7cdSSrinivas Pandruvada } 2226fe6fb216SSrinivas Pandruvada if (!is_skx_based_platform() && (clos_prop_prio < 0 || clos_prop_prio > 0x0F)) { 22273fb4f7cdSSrinivas Pandruvada fprintf(stderr, 2228fe6fb216SSrinivas Pandruvada "clos frequency weight is not specified or invalid, default: 0\n"); 22293fb4f7cdSSrinivas Pandruvada clos_prop_prio = 0; 22303fb4f7cdSSrinivas Pandruvada } 22313fb4f7cdSSrinivas Pandruvada if (clos_min < 0) { 22323fb4f7cdSSrinivas Pandruvada fprintf(stderr, "clos min is not specified, default: 0\n"); 22333fb4f7cdSSrinivas Pandruvada clos_min = 0; 22343fb4f7cdSSrinivas Pandruvada } 22353fb4f7cdSSrinivas Pandruvada if (clos_max < 0) { 2236fe6fb216SSrinivas Pandruvada fprintf(stderr, "clos max is not specified, default: Max frequency (ratio 0xff)\n"); 22373fb4f7cdSSrinivas Pandruvada clos_max = 0xff; 22383fb4f7cdSSrinivas Pandruvada } 2239fe6fb216SSrinivas Pandruvada if (clos_desired) { 2240fe6fb216SSrinivas Pandruvada fprintf(stderr, "clos desired is not supported on this platform\n"); 22413fb4f7cdSSrinivas Pandruvada clos_desired = 0x00; 22423fb4f7cdSSrinivas Pandruvada } 22433fb4f7cdSSrinivas Pandruvada 22443fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 22453fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 22463fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(set_clos_config_for_cpu, NULL, 22473fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 22483fb4f7cdSSrinivas Pandruvada else 2249c77a8d4aSZhang Rui for_each_online_power_domain_in_set(set_clos_config_for_cpu, NULL, 22503fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 22513fb4f7cdSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 22523fb4f7cdSSrinivas Pandruvada } 22533fb4f7cdSSrinivas Pandruvada 2254850337ecSZhang Rui static void set_clos_assoc_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, 22553fb4f7cdSSrinivas Pandruvada void *arg4) 22563fb4f7cdSSrinivas Pandruvada { 22573fb4f7cdSSrinivas Pandruvada int ret; 22583fb4f7cdSSrinivas Pandruvada 2259850337ecSZhang Rui ret = isst_clos_associate(id, current_clos); 22603fb4f7cdSSrinivas Pandruvada if (ret) 2261fe6fb216SSrinivas Pandruvada debug_printf("isst_clos_associate failed"); 22623fb4f7cdSSrinivas Pandruvada else 2263850337ecSZhang Rui isst_display_result(id, outf, "core-power", "assoc", ret); 22643fb4f7cdSSrinivas Pandruvada } 22653fb4f7cdSSrinivas Pandruvada 2266ce1326a2SPrarit Bhargava static void set_clos_assoc(int arg) 22673fb4f7cdSSrinivas Pandruvada { 22683fb4f7cdSSrinivas Pandruvada if (cmd_help) { 22693fb4f7cdSSrinivas Pandruvada fprintf(stderr, "Associate a clos id to a CPU\n"); 22703fb4f7cdSSrinivas Pandruvada fprintf(stderr, 22713fb4f7cdSSrinivas Pandruvada "\tSpecify targeted clos id with [--clos|-c]\n"); 227268e2f109SSrinivas Pandruvada fprintf(stderr, 227368e2f109SSrinivas Pandruvada "\tFor example to associate clos 1 to CPU 0: issue\n"); 227468e2f109SSrinivas Pandruvada fprintf(stderr, 227568e2f109SSrinivas Pandruvada "\tintel-speed-select --cpu 0 core-power assoc --clos 1\n"); 22763fb4f7cdSSrinivas Pandruvada exit(0); 22773fb4f7cdSSrinivas Pandruvada } 22783fb4f7cdSSrinivas Pandruvada 22793fb4f7cdSSrinivas Pandruvada if (current_clos < 0 || current_clos > 3) { 2280fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid clos id\n", 0, 0); 22813fb4f7cdSSrinivas Pandruvada exit(0); 22823fb4f7cdSSrinivas Pandruvada } 22833fb4f7cdSSrinivas Pandruvada if (max_target_cpus) 22843fb4f7cdSSrinivas Pandruvada for_each_online_target_cpu_in_set(set_clos_assoc_for_cpu, NULL, 22853fb4f7cdSSrinivas Pandruvada NULL, NULL, NULL); 22863fb4f7cdSSrinivas Pandruvada else { 2287fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid target cpu. Specify with [-c|--cpu]", 0, 0); 22883fb4f7cdSSrinivas Pandruvada } 22893fb4f7cdSSrinivas Pandruvada } 22903fb4f7cdSSrinivas Pandruvada 2291850337ecSZhang Rui static void get_clos_assoc_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, 22923fb4f7cdSSrinivas Pandruvada void *arg4) 22933fb4f7cdSSrinivas Pandruvada { 22943fb4f7cdSSrinivas Pandruvada int clos, ret; 22953fb4f7cdSSrinivas Pandruvada 2296850337ecSZhang Rui ret = isst_clos_get_assoc_status(id, &clos); 22973fb4f7cdSSrinivas Pandruvada if (ret) 2298fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "isst_clos_get_assoc_status failed", 0, 0); 22993fb4f7cdSSrinivas Pandruvada else 2300850337ecSZhang Rui isst_clos_display_assoc_information(id, outf, clos); 23013fb4f7cdSSrinivas Pandruvada } 23023fb4f7cdSSrinivas Pandruvada 2303ce1326a2SPrarit Bhargava static void get_clos_assoc(int arg) 23043fb4f7cdSSrinivas Pandruvada { 23053fb4f7cdSSrinivas Pandruvada if (cmd_help) { 23063fb4f7cdSSrinivas Pandruvada fprintf(stderr, "Get associate clos id to a CPU\n"); 23073fb4f7cdSSrinivas Pandruvada fprintf(stderr, "\tSpecify targeted cpu id with [--cpu|-c]\n"); 23083fb4f7cdSSrinivas Pandruvada exit(0); 23093fb4f7cdSSrinivas Pandruvada } 2310e118fbe3SSrinivas Pandruvada 2311e118fbe3SSrinivas Pandruvada if (!max_target_cpus) { 2312fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid target cpu. Specify with [-c|--cpu]", 0, 0); 2313e118fbe3SSrinivas Pandruvada exit(0); 23143fb4f7cdSSrinivas Pandruvada } 2315e118fbe3SSrinivas Pandruvada 2316e118fbe3SSrinivas Pandruvada isst_ctdp_display_information_start(outf); 2317e118fbe3SSrinivas Pandruvada for_each_online_target_cpu_in_set(get_clos_assoc_for_cpu, NULL, 2318e118fbe3SSrinivas Pandruvada NULL, NULL, NULL); 2319e118fbe3SSrinivas Pandruvada isst_ctdp_display_information_end(outf); 23203fb4f7cdSSrinivas Pandruvada } 23213fb4f7cdSSrinivas Pandruvada 2322850337ecSZhang Rui static void set_turbo_mode_for_cpu(struct isst_id *id, int status) 2323006050a6SSrinivas Pandruvada { 2324006050a6SSrinivas Pandruvada int base_freq; 2325006050a6SSrinivas Pandruvada 2326006050a6SSrinivas Pandruvada if (status) { 2327850337ecSZhang Rui base_freq = get_cpufreq_base_freq(id->cpu); 2328850337ecSZhang Rui set_cpufreq_scaling_min_max(id->cpu, 1, base_freq); 2329006050a6SSrinivas Pandruvada } else { 2330850337ecSZhang Rui set_scaling_max_to_cpuinfo_max(id); 2331006050a6SSrinivas Pandruvada } 2332006050a6SSrinivas Pandruvada 2333006050a6SSrinivas Pandruvada if (status) { 2334850337ecSZhang Rui isst_display_result(id, outf, "turbo-mode", "enable", 0); 2335006050a6SSrinivas Pandruvada } else { 2336850337ecSZhang Rui isst_display_result(id, outf, "turbo-mode", "disable", 0); 2337006050a6SSrinivas Pandruvada } 2338006050a6SSrinivas Pandruvada } 2339006050a6SSrinivas Pandruvada 2340006050a6SSrinivas Pandruvada static void set_turbo_mode(int arg) 2341006050a6SSrinivas Pandruvada { 2342006050a6SSrinivas Pandruvada int i, enable = arg; 2343850337ecSZhang Rui struct isst_id id; 2344006050a6SSrinivas Pandruvada 2345006050a6SSrinivas Pandruvada if (cmd_help) { 2346006050a6SSrinivas Pandruvada if (enable) 2347006050a6SSrinivas Pandruvada fprintf(stderr, "Set turbo mode enable\n"); 2348006050a6SSrinivas Pandruvada else 2349006050a6SSrinivas Pandruvada fprintf(stderr, "Set turbo mode disable\n"); 2350006050a6SSrinivas Pandruvada exit(0); 2351006050a6SSrinivas Pandruvada } 2352006050a6SSrinivas Pandruvada 2353006050a6SSrinivas Pandruvada isst_ctdp_display_information_start(outf); 2354006050a6SSrinivas Pandruvada 2355006050a6SSrinivas Pandruvada for (i = 0; i < topo_max_cpus; ++i) { 2356006050a6SSrinivas Pandruvada int online; 2357006050a6SSrinivas Pandruvada 2358006050a6SSrinivas Pandruvada if (i) 2359006050a6SSrinivas Pandruvada online = parse_int_file( 2360006050a6SSrinivas Pandruvada 1, "/sys/devices/system/cpu/cpu%d/online", i); 2361006050a6SSrinivas Pandruvada else 2362006050a6SSrinivas Pandruvada online = 2363006050a6SSrinivas Pandruvada 1; /* online entry for CPU 0 needs some special configs */ 2364006050a6SSrinivas Pandruvada 2365850337ecSZhang Rui if (online) { 2366850337ecSZhang Rui set_isst_id(&id, i); 2367850337ecSZhang Rui set_turbo_mode_for_cpu(&id, enable); 2368850337ecSZhang Rui } 2369006050a6SSrinivas Pandruvada 2370006050a6SSrinivas Pandruvada } 2371006050a6SSrinivas Pandruvada isst_ctdp_display_information_end(outf); 2372006050a6SSrinivas Pandruvada } 2373006050a6SSrinivas Pandruvada 2374850337ecSZhang Rui static void get_set_trl(struct isst_id *id, void *arg1, void *arg2, void *arg3, 23752c7dc57eSSrinivas Pandruvada void *arg4) 23762c7dc57eSSrinivas Pandruvada { 23772c7dc57eSSrinivas Pandruvada unsigned long long trl; 23782c7dc57eSSrinivas Pandruvada int set = *(int *)arg4; 23792c7dc57eSSrinivas Pandruvada int ret; 23802c7dc57eSSrinivas Pandruvada 23812c7dc57eSSrinivas Pandruvada if (set && !fact_trl) { 23822c7dc57eSSrinivas Pandruvada isst_display_error_info_message(1, "Invalid TRL. Specify with [-t|--trl]", 0, 0); 23832c7dc57eSSrinivas Pandruvada exit(0); 23842c7dc57eSSrinivas Pandruvada } 23852c7dc57eSSrinivas Pandruvada 23862c7dc57eSSrinivas Pandruvada if (set) { 2387850337ecSZhang Rui ret = isst_set_trl(id, fact_trl); 2388850337ecSZhang Rui isst_display_result(id, outf, "turbo-mode", "set-trl", ret); 23892c7dc57eSSrinivas Pandruvada return; 23902c7dc57eSSrinivas Pandruvada } 23912c7dc57eSSrinivas Pandruvada 2392850337ecSZhang Rui ret = isst_get_trl(id, &trl); 23932c7dc57eSSrinivas Pandruvada if (ret) 2394850337ecSZhang Rui isst_display_result(id, outf, "turbo-mode", "get-trl", ret); 23952c7dc57eSSrinivas Pandruvada else 2396850337ecSZhang Rui isst_trl_display_information(id, outf, trl); 23972c7dc57eSSrinivas Pandruvada } 23982c7dc57eSSrinivas Pandruvada 23992c7dc57eSSrinivas Pandruvada static void process_trl(int arg) 24002c7dc57eSSrinivas Pandruvada { 24012c7dc57eSSrinivas Pandruvada if (cmd_help) { 24022c7dc57eSSrinivas Pandruvada if (arg) { 24032c7dc57eSSrinivas Pandruvada fprintf(stderr, "Set TRL (turbo ratio limits)\n"); 24042c7dc57eSSrinivas Pandruvada fprintf(stderr, "\t t|--trl: Specify turbo ratio limit for setting TRL\n"); 24052c7dc57eSSrinivas Pandruvada } else { 24062c7dc57eSSrinivas Pandruvada fprintf(stderr, "Get TRL (turbo ratio limits)\n"); 24072c7dc57eSSrinivas Pandruvada } 24082c7dc57eSSrinivas Pandruvada exit(0); 24092c7dc57eSSrinivas Pandruvada } 24102c7dc57eSSrinivas Pandruvada 24112c7dc57eSSrinivas Pandruvada isst_ctdp_display_information_start(outf); 24122c7dc57eSSrinivas Pandruvada if (max_target_cpus) 24132c7dc57eSSrinivas Pandruvada for_each_online_target_cpu_in_set(get_set_trl, NULL, 24142c7dc57eSSrinivas Pandruvada NULL, NULL, &arg); 24152c7dc57eSSrinivas Pandruvada else 2416c77a8d4aSZhang Rui for_each_online_power_domain_in_set(get_set_trl, NULL, 24172c7dc57eSSrinivas Pandruvada NULL, NULL, &arg); 24182c7dc57eSSrinivas Pandruvada isst_ctdp_display_information_end(outf); 24192c7dc57eSSrinivas Pandruvada } 24202c7dc57eSSrinivas Pandruvada 2421c829f0efSPrarit Bhargava static struct process_cmd_struct clx_n_cmds[] = { 2422062e4aacSPrarit Bhargava { "perf-profile", "info", dump_isst_config, 0 }, 24231aa7177cSPrarit Bhargava { "base-freq", "info", dump_pbf_config, 0 }, 24241aa7177cSPrarit Bhargava { "base-freq", "enable", set_pbf_enable, 1 }, 24251aa7177cSPrarit Bhargava { "base-freq", "disable", set_pbf_enable, 0 }, 2426c829f0efSPrarit Bhargava { NULL, NULL, NULL, 0 } 2427c829f0efSPrarit Bhargava }; 2428c829f0efSPrarit Bhargava 24293fb4f7cdSSrinivas Pandruvada static struct process_cmd_struct isst_cmds[] = { 2430ce1326a2SPrarit Bhargava { "perf-profile", "get-lock-status", get_tdp_locked, 0 }, 2431ce1326a2SPrarit Bhargava { "perf-profile", "get-config-levels", get_tdp_levels, 0 }, 2432ce1326a2SPrarit Bhargava { "perf-profile", "get-config-version", get_tdp_version, 0 }, 2433ce1326a2SPrarit Bhargava { "perf-profile", "get-config-enabled", get_tdp_enabled, 0 }, 2434ce1326a2SPrarit Bhargava { "perf-profile", "get-config-current-level", get_tdp_current_level, 2435ce1326a2SPrarit Bhargava 0 }, 2436ce1326a2SPrarit Bhargava { "perf-profile", "set-config-level", set_tdp_level, 0 }, 2437ce1326a2SPrarit Bhargava { "perf-profile", "info", dump_isst_config, 0 }, 2438ce1326a2SPrarit Bhargava { "base-freq", "info", dump_pbf_config, 0 }, 2439ce1326a2SPrarit Bhargava { "base-freq", "enable", set_pbf_enable, 1 }, 2440ce1326a2SPrarit Bhargava { "base-freq", "disable", set_pbf_enable, 0 }, 2441ce1326a2SPrarit Bhargava { "turbo-freq", "info", dump_fact_config, 0 }, 2442ce1326a2SPrarit Bhargava { "turbo-freq", "enable", set_fact_enable, 1 }, 2443ce1326a2SPrarit Bhargava { "turbo-freq", "disable", set_fact_enable, 0 }, 2444ce1326a2SPrarit Bhargava { "core-power", "info", dump_clos_info, 0 }, 2445ce1326a2SPrarit Bhargava { "core-power", "enable", set_clos_enable, 1 }, 2446ce1326a2SPrarit Bhargava { "core-power", "disable", set_clos_enable, 0 }, 2447ce1326a2SPrarit Bhargava { "core-power", "config", set_clos_config, 0 }, 2448ce1326a2SPrarit Bhargava { "core-power", "get-config", dump_clos_config, 0 }, 2449ce1326a2SPrarit Bhargava { "core-power", "assoc", set_clos_assoc, 0 }, 2450ce1326a2SPrarit Bhargava { "core-power", "get-assoc", get_clos_assoc, 0 }, 2451006050a6SSrinivas Pandruvada { "turbo-mode", "enable", set_turbo_mode, 0 }, 2452006050a6SSrinivas Pandruvada { "turbo-mode", "disable", set_turbo_mode, 1 }, 24532c7dc57eSSrinivas Pandruvada { "turbo-mode", "get-trl", process_trl, 0 }, 24542c7dc57eSSrinivas Pandruvada { "turbo-mode", "set-trl", process_trl, 1 }, 24553fb4f7cdSSrinivas Pandruvada { NULL, NULL, NULL } 24563fb4f7cdSSrinivas Pandruvada }; 24573fb4f7cdSSrinivas Pandruvada 24583fb4f7cdSSrinivas Pandruvada /* 24593fb4f7cdSSrinivas Pandruvada * parse cpuset with following syntax 24603fb4f7cdSSrinivas Pandruvada * 1,2,4..6,8-10 and set bits in cpu_subset 24613fb4f7cdSSrinivas Pandruvada */ 24623fb4f7cdSSrinivas Pandruvada void parse_cpu_command(char *optarg) 24633fb4f7cdSSrinivas Pandruvada { 24643fb4f7cdSSrinivas Pandruvada unsigned int start, end; 24653fb4f7cdSSrinivas Pandruvada char *next; 24663fb4f7cdSSrinivas Pandruvada 24673fb4f7cdSSrinivas Pandruvada next = optarg; 24683fb4f7cdSSrinivas Pandruvada 24693fb4f7cdSSrinivas Pandruvada while (next && *next) { 24703fb4f7cdSSrinivas Pandruvada if (*next == '-') /* no negative cpu numbers */ 24713fb4f7cdSSrinivas Pandruvada goto error; 24723fb4f7cdSSrinivas Pandruvada 24733fb4f7cdSSrinivas Pandruvada start = strtoul(next, &next, 10); 24743fb4f7cdSSrinivas Pandruvada 24753fb4f7cdSSrinivas Pandruvada if (max_target_cpus < MAX_CPUS_IN_ONE_REQ) 24763fb4f7cdSSrinivas Pandruvada target_cpus[max_target_cpus++] = start; 24773fb4f7cdSSrinivas Pandruvada 24783fb4f7cdSSrinivas Pandruvada if (*next == '\0') 24793fb4f7cdSSrinivas Pandruvada break; 24803fb4f7cdSSrinivas Pandruvada 24813fb4f7cdSSrinivas Pandruvada if (*next == ',') { 24823fb4f7cdSSrinivas Pandruvada next += 1; 24833fb4f7cdSSrinivas Pandruvada continue; 24843fb4f7cdSSrinivas Pandruvada } 24853fb4f7cdSSrinivas Pandruvada 24863fb4f7cdSSrinivas Pandruvada if (*next == '-') { 24873fb4f7cdSSrinivas Pandruvada next += 1; /* start range */ 24883fb4f7cdSSrinivas Pandruvada } else if (*next == '.') { 24893fb4f7cdSSrinivas Pandruvada next += 1; 24903fb4f7cdSSrinivas Pandruvada if (*next == '.') 24913fb4f7cdSSrinivas Pandruvada next += 1; /* start range */ 24923fb4f7cdSSrinivas Pandruvada else 24933fb4f7cdSSrinivas Pandruvada goto error; 24943fb4f7cdSSrinivas Pandruvada } 24953fb4f7cdSSrinivas Pandruvada 24963fb4f7cdSSrinivas Pandruvada end = strtoul(next, &next, 10); 24973fb4f7cdSSrinivas Pandruvada if (end <= start) 24983fb4f7cdSSrinivas Pandruvada goto error; 24993fb4f7cdSSrinivas Pandruvada 25003fb4f7cdSSrinivas Pandruvada while (++start <= end) { 25013fb4f7cdSSrinivas Pandruvada if (max_target_cpus < MAX_CPUS_IN_ONE_REQ) 25023fb4f7cdSSrinivas Pandruvada target_cpus[max_target_cpus++] = start; 25033fb4f7cdSSrinivas Pandruvada } 25043fb4f7cdSSrinivas Pandruvada 25053fb4f7cdSSrinivas Pandruvada if (*next == ',') 25063fb4f7cdSSrinivas Pandruvada next += 1; 25073fb4f7cdSSrinivas Pandruvada else if (*next != '\0') 25083fb4f7cdSSrinivas Pandruvada goto error; 25093fb4f7cdSSrinivas Pandruvada } 25103fb4f7cdSSrinivas Pandruvada 25113fb4f7cdSSrinivas Pandruvada #ifdef DEBUG 25123fb4f7cdSSrinivas Pandruvada { 25133fb4f7cdSSrinivas Pandruvada int i; 25143fb4f7cdSSrinivas Pandruvada 25153fb4f7cdSSrinivas Pandruvada for (i = 0; i < max_target_cpus; ++i) 25163fb4f7cdSSrinivas Pandruvada printf("cpu [%d] in arg\n", target_cpus[i]); 25173fb4f7cdSSrinivas Pandruvada } 25183fb4f7cdSSrinivas Pandruvada #endif 25193fb4f7cdSSrinivas Pandruvada return; 25203fb4f7cdSSrinivas Pandruvada 25213fb4f7cdSSrinivas Pandruvada error: 25223fb4f7cdSSrinivas Pandruvada fprintf(stderr, "\"--cpu %s\" malformed\n", optarg); 25233fb4f7cdSSrinivas Pandruvada exit(-1); 25243fb4f7cdSSrinivas Pandruvada } 25253fb4f7cdSSrinivas Pandruvada 25263fb4f7cdSSrinivas Pandruvada static void parse_cmd_args(int argc, int start, char **argv) 25273fb4f7cdSSrinivas Pandruvada { 25283fb4f7cdSSrinivas Pandruvada int opt; 25293fb4f7cdSSrinivas Pandruvada int option_index; 25303fb4f7cdSSrinivas Pandruvada 25313fb4f7cdSSrinivas Pandruvada static struct option long_options[] = { 25323fb4f7cdSSrinivas Pandruvada { "bucket", required_argument, 0, 'b' }, 25333fb4f7cdSSrinivas Pandruvada { "level", required_argument, 0, 'l' }, 25343c64c81aSSrinivas Pandruvada { "online", required_argument, 0, 'o' }, 25353fb4f7cdSSrinivas Pandruvada { "trl-type", required_argument, 0, 'r' }, 25363fb4f7cdSSrinivas Pandruvada { "trl", required_argument, 0, 't' }, 25373fb4f7cdSSrinivas Pandruvada { "help", no_argument, 0, 'h' }, 25383fb4f7cdSSrinivas Pandruvada { "clos", required_argument, 0, 'c' }, 25393fb4f7cdSSrinivas Pandruvada { "desired", required_argument, 0, 'd' }, 25403fb4f7cdSSrinivas Pandruvada { "epp", required_argument, 0, 'e' }, 25413fb4f7cdSSrinivas Pandruvada { "min", required_argument, 0, 'n' }, 25423fb4f7cdSSrinivas Pandruvada { "max", required_argument, 0, 'm' }, 25433fb4f7cdSSrinivas Pandruvada { "priority", required_argument, 0, 'p' }, 25443fb4f7cdSSrinivas Pandruvada { "weight", required_argument, 0, 'w' }, 2545354bd06fSSrinivas Pandruvada { "auto", no_argument, 0, 'a' }, 25463fb4f7cdSSrinivas Pandruvada { 0, 0, 0, 0 } 25473fb4f7cdSSrinivas Pandruvada }; 25483fb4f7cdSSrinivas Pandruvada 25493fb4f7cdSSrinivas Pandruvada option_index = start; 25503fb4f7cdSSrinivas Pandruvada 25513fb4f7cdSSrinivas Pandruvada optind = start + 1; 2552b86639e1SSrinivas Pandruvada while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:r:hoa", 25533fb4f7cdSSrinivas Pandruvada long_options, &option_index)) != -1) { 25543fb4f7cdSSrinivas Pandruvada switch (opt) { 2555354bd06fSSrinivas Pandruvada case 'a': 2556354bd06fSSrinivas Pandruvada auto_mode = 1; 2557354bd06fSSrinivas Pandruvada break; 25583fb4f7cdSSrinivas Pandruvada case 'b': 25593fb4f7cdSSrinivas Pandruvada fact_bucket = atoi(optarg); 25603fb4f7cdSSrinivas Pandruvada break; 25613fb4f7cdSSrinivas Pandruvada case 'h': 25623fb4f7cdSSrinivas Pandruvada cmd_help = 1; 25633fb4f7cdSSrinivas Pandruvada break; 25643fb4f7cdSSrinivas Pandruvada case 'l': 25653fb4f7cdSSrinivas Pandruvada tdp_level = atoi(optarg); 25663fb4f7cdSSrinivas Pandruvada break; 25673c64c81aSSrinivas Pandruvada case 'o': 25683c64c81aSSrinivas Pandruvada force_online_offline = 1; 25693c64c81aSSrinivas Pandruvada break; 25703fb4f7cdSSrinivas Pandruvada case 't': 25713fb4f7cdSSrinivas Pandruvada sscanf(optarg, "0x%llx", &fact_trl); 25723fb4f7cdSSrinivas Pandruvada break; 25733fb4f7cdSSrinivas Pandruvada case 'r': 25743fb4f7cdSSrinivas Pandruvada if (!strncmp(optarg, "sse", 3)) { 25753fb4f7cdSSrinivas Pandruvada fact_avx = 0x01; 25763fb4f7cdSSrinivas Pandruvada } else if (!strncmp(optarg, "avx2", 4)) { 25773fb4f7cdSSrinivas Pandruvada fact_avx = 0x02; 2578b86639e1SSrinivas Pandruvada } else if (!strncmp(optarg, "avx512", 6)) { 25793fb4f7cdSSrinivas Pandruvada fact_avx = 0x04; 25803fb4f7cdSSrinivas Pandruvada } else { 25813fb4f7cdSSrinivas Pandruvada fprintf(outf, "Invalid sse,avx options\n"); 25823fb4f7cdSSrinivas Pandruvada exit(1); 25833fb4f7cdSSrinivas Pandruvada } 25843fb4f7cdSSrinivas Pandruvada break; 25853fb4f7cdSSrinivas Pandruvada /* CLOS related */ 25863fb4f7cdSSrinivas Pandruvada case 'c': 25873fb4f7cdSSrinivas Pandruvada current_clos = atoi(optarg); 25883fb4f7cdSSrinivas Pandruvada break; 25893fb4f7cdSSrinivas Pandruvada case 'd': 25903fb4f7cdSSrinivas Pandruvada clos_desired = atoi(optarg); 259113b868f8SZhang Rui clos_desired /= isst_get_disp_freq_multiplier(); 25923fb4f7cdSSrinivas Pandruvada break; 25933fb4f7cdSSrinivas Pandruvada case 'e': 25943fb4f7cdSSrinivas Pandruvada clos_epp = atoi(optarg); 2595fe6fb216SSrinivas Pandruvada if (is_skx_based_platform()) { 2596fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "epp can't be specified on this platform", 0, 0); 2597fe6fb216SSrinivas Pandruvada exit(0); 2598fe6fb216SSrinivas Pandruvada } 25993fb4f7cdSSrinivas Pandruvada break; 26003fb4f7cdSSrinivas Pandruvada case 'n': 26013fb4f7cdSSrinivas Pandruvada clos_min = atoi(optarg); 260213b868f8SZhang Rui clos_min /= isst_get_disp_freq_multiplier(); 26033fb4f7cdSSrinivas Pandruvada break; 26043fb4f7cdSSrinivas Pandruvada case 'm': 26053fb4f7cdSSrinivas Pandruvada clos_max = atoi(optarg); 260613b868f8SZhang Rui clos_max /= isst_get_disp_freq_multiplier(); 26073fb4f7cdSSrinivas Pandruvada break; 26083fb4f7cdSSrinivas Pandruvada case 'p': 26093fb4f7cdSSrinivas Pandruvada clos_priority_type = atoi(optarg); 2610fe6fb216SSrinivas Pandruvada if (is_skx_based_platform() && !clos_priority_type) { 2611fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid clos priority type: proportional for this platform", 0, 0); 2612fe6fb216SSrinivas Pandruvada exit(0); 2613fe6fb216SSrinivas Pandruvada } 26143fb4f7cdSSrinivas Pandruvada break; 26153fb4f7cdSSrinivas Pandruvada case 'w': 26163fb4f7cdSSrinivas Pandruvada clos_prop_prio = atoi(optarg); 2617fe6fb216SSrinivas Pandruvada if (is_skx_based_platform()) { 2618fe6fb216SSrinivas Pandruvada isst_display_error_info_message(1, "weight can't be specified on this platform", 0, 0); 2619fe6fb216SSrinivas Pandruvada exit(0); 2620fe6fb216SSrinivas Pandruvada } 26213fb4f7cdSSrinivas Pandruvada break; 26223fb4f7cdSSrinivas Pandruvada default: 26234a960353SSrinivas Pandruvada printf("Unknown option: ignore\n"); 26243fb4f7cdSSrinivas Pandruvada } 26253fb4f7cdSSrinivas Pandruvada } 26264a960353SSrinivas Pandruvada 26274a960353SSrinivas Pandruvada if (argv[optind]) 26284a960353SSrinivas Pandruvada printf("Garbage at the end of command: ignore\n"); 26293fb4f7cdSSrinivas Pandruvada } 26303fb4f7cdSSrinivas Pandruvada 26313fb4f7cdSSrinivas Pandruvada static void isst_help(void) 26323fb4f7cdSSrinivas Pandruvada { 26333fb4f7cdSSrinivas Pandruvada printf("perf-profile:\tAn architectural mechanism that allows multiple optimized \n\ 26343fb4f7cdSSrinivas Pandruvada performance profiles per system via static and/or dynamic\n\ 26353fb4f7cdSSrinivas Pandruvada adjustment of core count, workload, Tjmax, and\n\ 26363fb4f7cdSSrinivas Pandruvada TDP, etc.\n"); 26373fb4f7cdSSrinivas Pandruvada printf("\nCommands : For feature=perf-profile\n"); 26383fb4f7cdSSrinivas Pandruvada printf("\tinfo\n"); 2639c829f0efSPrarit Bhargava 2640c829f0efSPrarit Bhargava if (!is_clx_n_platform()) { 26413fb4f7cdSSrinivas Pandruvada printf("\tget-lock-status\n"); 26423fb4f7cdSSrinivas Pandruvada printf("\tget-config-levels\n"); 26433fb4f7cdSSrinivas Pandruvada printf("\tget-config-version\n"); 26443fb4f7cdSSrinivas Pandruvada printf("\tget-config-enabled\n"); 26453fb4f7cdSSrinivas Pandruvada printf("\tget-config-current-level\n"); 26463fb4f7cdSSrinivas Pandruvada printf("\tset-config-level\n"); 26473fb4f7cdSSrinivas Pandruvada } 2648c829f0efSPrarit Bhargava } 26493fb4f7cdSSrinivas Pandruvada 26503fb4f7cdSSrinivas Pandruvada static void pbf_help(void) 26513fb4f7cdSSrinivas Pandruvada { 26523fb4f7cdSSrinivas Pandruvada printf("base-freq:\tEnables users to increase guaranteed base frequency\n\ 26533fb4f7cdSSrinivas Pandruvada on certain cores (high priority cores) in exchange for lower\n\ 26543fb4f7cdSSrinivas Pandruvada base frequency on remaining cores (low priority cores).\n"); 26553fb4f7cdSSrinivas Pandruvada printf("\tcommand : info\n"); 26563fb4f7cdSSrinivas Pandruvada printf("\tcommand : enable\n"); 26573fb4f7cdSSrinivas Pandruvada printf("\tcommand : disable\n"); 26583fb4f7cdSSrinivas Pandruvada } 26593fb4f7cdSSrinivas Pandruvada 26603fb4f7cdSSrinivas Pandruvada static void fact_help(void) 26613fb4f7cdSSrinivas Pandruvada { 26623fb4f7cdSSrinivas Pandruvada printf("turbo-freq:\tEnables the ability to set different turbo ratio\n\ 26633fb4f7cdSSrinivas Pandruvada limits to cores based on priority.\n"); 26643fb4f7cdSSrinivas Pandruvada printf("\nCommand: For feature=turbo-freq\n"); 26653fb4f7cdSSrinivas Pandruvada printf("\tcommand : info\n"); 26663fb4f7cdSSrinivas Pandruvada printf("\tcommand : enable\n"); 26673fb4f7cdSSrinivas Pandruvada printf("\tcommand : disable\n"); 26683fb4f7cdSSrinivas Pandruvada } 26693fb4f7cdSSrinivas Pandruvada 2670006050a6SSrinivas Pandruvada static void turbo_mode_help(void) 2671006050a6SSrinivas Pandruvada { 26722c7dc57eSSrinivas Pandruvada printf("turbo-mode:\tEnables users to enable/disable turbo mode by adjusting frequency settings. Also allows to get and set turbo ratio limits (TRL).\n"); 2673006050a6SSrinivas Pandruvada printf("\tcommand : enable\n"); 2674006050a6SSrinivas Pandruvada printf("\tcommand : disable\n"); 26752c7dc57eSSrinivas Pandruvada printf("\tcommand : get-trl\n"); 26762c7dc57eSSrinivas Pandruvada printf("\tcommand : set-trl\n"); 2677006050a6SSrinivas Pandruvada } 2678006050a6SSrinivas Pandruvada 2679006050a6SSrinivas Pandruvada 26803fb4f7cdSSrinivas Pandruvada static void core_power_help(void) 26813fb4f7cdSSrinivas Pandruvada { 26823fb4f7cdSSrinivas Pandruvada printf("core-power:\tInterface that allows user to define per core/tile\n\ 26833fb4f7cdSSrinivas Pandruvada priority.\n"); 26843fb4f7cdSSrinivas Pandruvada printf("\nCommands : For feature=core-power\n"); 26853fb4f7cdSSrinivas Pandruvada printf("\tinfo\n"); 26863fb4f7cdSSrinivas Pandruvada printf("\tenable\n"); 26873fb4f7cdSSrinivas Pandruvada printf("\tdisable\n"); 26883fb4f7cdSSrinivas Pandruvada printf("\tconfig\n"); 2689188afed9SSrinivas Pandruvada printf("\tget-config\n"); 26903fb4f7cdSSrinivas Pandruvada printf("\tassoc\n"); 26913fb4f7cdSSrinivas Pandruvada printf("\tget-assoc\n"); 26923fb4f7cdSSrinivas Pandruvada } 26933fb4f7cdSSrinivas Pandruvada 26943fb4f7cdSSrinivas Pandruvada struct process_cmd_help_struct { 26953fb4f7cdSSrinivas Pandruvada char *feature; 26963fb4f7cdSSrinivas Pandruvada void (*process_fn)(void); 26973fb4f7cdSSrinivas Pandruvada }; 26983fb4f7cdSSrinivas Pandruvada 26993fb4f7cdSSrinivas Pandruvada static struct process_cmd_help_struct isst_help_cmds[] = { 27003fb4f7cdSSrinivas Pandruvada { "perf-profile", isst_help }, 27013fb4f7cdSSrinivas Pandruvada { "base-freq", pbf_help }, 27023fb4f7cdSSrinivas Pandruvada { "turbo-freq", fact_help }, 27033fb4f7cdSSrinivas Pandruvada { "core-power", core_power_help }, 2704006050a6SSrinivas Pandruvada { "turbo-mode", turbo_mode_help }, 27053fb4f7cdSSrinivas Pandruvada { NULL, NULL } 27063fb4f7cdSSrinivas Pandruvada }; 27073fb4f7cdSSrinivas Pandruvada 2708c829f0efSPrarit Bhargava static struct process_cmd_help_struct clx_n_help_cmds[] = { 2709c829f0efSPrarit Bhargava { "perf-profile", isst_help }, 2710c829f0efSPrarit Bhargava { "base-freq", pbf_help }, 2711c829f0efSPrarit Bhargava { NULL, NULL } 2712c829f0efSPrarit Bhargava }; 2713c829f0efSPrarit Bhargava 2714210369dcSPrarit Bhargava void process_command(int argc, char **argv, 2715210369dcSPrarit Bhargava struct process_cmd_help_struct *help_cmds, 2716210369dcSPrarit Bhargava struct process_cmd_struct *cmds) 27173fb4f7cdSSrinivas Pandruvada { 27183fb4f7cdSSrinivas Pandruvada int i = 0, matched = 0; 27193fb4f7cdSSrinivas Pandruvada char *feature = argv[optind]; 27203fb4f7cdSSrinivas Pandruvada char *cmd = argv[optind + 1]; 27213fb4f7cdSSrinivas Pandruvada 27223fb4f7cdSSrinivas Pandruvada if (!feature || !cmd) 27233fb4f7cdSSrinivas Pandruvada return; 27243fb4f7cdSSrinivas Pandruvada 27253fb4f7cdSSrinivas Pandruvada debug_printf("feature name [%s] command [%s]\n", feature, cmd); 27263fb4f7cdSSrinivas Pandruvada if (!strcmp(cmd, "-h") || !strcmp(cmd, "--help")) { 2727210369dcSPrarit Bhargava while (help_cmds[i].feature) { 2728210369dcSPrarit Bhargava if (!strcmp(help_cmds[i].feature, feature)) { 2729210369dcSPrarit Bhargava help_cmds[i].process_fn(); 27303fb4f7cdSSrinivas Pandruvada exit(0); 27313fb4f7cdSSrinivas Pandruvada } 27323fb4f7cdSSrinivas Pandruvada ++i; 27333fb4f7cdSSrinivas Pandruvada } 27343fb4f7cdSSrinivas Pandruvada } 27353fb4f7cdSSrinivas Pandruvada 27363fb4f7cdSSrinivas Pandruvada i = 0; 2737210369dcSPrarit Bhargava while (cmds[i].feature) { 2738210369dcSPrarit Bhargava if (!strcmp(cmds[i].feature, feature) && 2739210369dcSPrarit Bhargava !strcmp(cmds[i].command, cmd)) { 27403fb4f7cdSSrinivas Pandruvada parse_cmd_args(argc, optind + 1, argv); 2741210369dcSPrarit Bhargava cmds[i].process_fn(cmds[i].arg); 27423fb4f7cdSSrinivas Pandruvada matched = 1; 27433fb4f7cdSSrinivas Pandruvada break; 27443fb4f7cdSSrinivas Pandruvada } 27453fb4f7cdSSrinivas Pandruvada ++i; 27463fb4f7cdSSrinivas Pandruvada } 27473fb4f7cdSSrinivas Pandruvada 27483fb4f7cdSSrinivas Pandruvada if (!matched) 27493fb4f7cdSSrinivas Pandruvada fprintf(stderr, "Invalid command\n"); 27503fb4f7cdSSrinivas Pandruvada } 27513fb4f7cdSSrinivas Pandruvada 27523fb4f7cdSSrinivas Pandruvada static void usage(void) 27533fb4f7cdSSrinivas Pandruvada { 2754addd116dSSrinivas Pandruvada if (is_clx_n_platform()) { 2755addd116dSSrinivas Pandruvada fprintf(stderr, "\nThere is limited support of Intel Speed Select features on this platform.\n"); 2756addd116dSSrinivas Pandruvada fprintf(stderr, "Everything is pre-configured using BIOS options, this tool can't enable any feature in the hardware.\n\n"); 2757addd116dSSrinivas Pandruvada } 2758addd116dSSrinivas Pandruvada 27593fb4f7cdSSrinivas Pandruvada printf("\nUsage:\n"); 27603fb4f7cdSSrinivas Pandruvada printf("intel-speed-select [OPTIONS] FEATURE COMMAND COMMAND_ARGUMENTS\n"); 2761addd116dSSrinivas Pandruvada printf("\nUse this tool to enumerate and control the Intel Speed Select Technology features:\n"); 2762addd116dSSrinivas Pandruvada if (is_clx_n_platform()) 2763addd116dSSrinivas Pandruvada printf("\nFEATURE : [perf-profile|base-freq]\n"); 2764addd116dSSrinivas Pandruvada else 2765006050a6SSrinivas Pandruvada printf("\nFEATURE : [perf-profile|base-freq|turbo-freq|core-power|turbo-mode]\n"); 276643774c0dSPrarit Bhargava printf("\nFor help on each feature, use -h|--help\n"); 27673fb4f7cdSSrinivas Pandruvada printf("\tFor example: intel-speed-select perf-profile -h\n"); 27683fb4f7cdSSrinivas Pandruvada 27693fb4f7cdSSrinivas Pandruvada printf("\nFor additional help on each command for a feature, use --h|--help\n"); 27703fb4f7cdSSrinivas Pandruvada printf("\tFor example: intel-speed-select perf-profile get-lock-status -h\n"); 27713fb4f7cdSSrinivas Pandruvada printf("\t\t This will print help for the command \"get-lock-status\" for the feature \"perf-profile\"\n"); 27723fb4f7cdSSrinivas Pandruvada 27733fb4f7cdSSrinivas Pandruvada printf("\nOPTIONS\n"); 27743fb4f7cdSSrinivas Pandruvada printf("\t[-c|--cpu] : logical cpu number\n"); 27753fb4f7cdSSrinivas Pandruvada printf("\t\tDefault: Die scoped for all dies in the system with multiple dies/package\n"); 27763fb4f7cdSSrinivas Pandruvada printf("\t\t\t Or Package scoped for all Packages when each package contains one die\n"); 27773fb4f7cdSSrinivas Pandruvada printf("\t[-d|--debug] : Debug mode\n"); 2778addd116dSSrinivas Pandruvada printf("\t[-f|--format] : output format [json|text]. Default: text\n"); 27793fb4f7cdSSrinivas Pandruvada printf("\t[-h|--help] : Print help\n"); 27803fb4f7cdSSrinivas Pandruvada printf("\t[-i|--info] : Print platform information\n"); 27810d3dfd75SSrinivas Pandruvada printf("\t[-a|--all-cpus-online] : Force online every CPU in the system\n"); 27823fb4f7cdSSrinivas Pandruvada printf("\t[-o|--out] : Output file\n"); 27833fb4f7cdSSrinivas Pandruvada printf("\t\t\tDefault : stderr\n"); 2784a85a35fcSSrinivas Pandruvada printf("\t[-p|--pause] : Delay between two mail box commands in milliseconds\n"); 278532279be7SSrinivas Pandruvada printf("\t[-r|--retry] : Retry count for mail box commands on failure, default 3\n"); 27863fb4f7cdSSrinivas Pandruvada printf("\t[-v|--version] : Print version\n"); 27877fd786dfSSrinivas Pandruvada printf("\t[-b|--oob : Start a daemon to process HFI events for perf profile change from Out of Band agent.\n"); 27887fd786dfSSrinivas Pandruvada printf("\t[-n|--no-daemon : Don't run as daemon. By default --oob will turn on daemon mode\n"); 27897fd786dfSSrinivas Pandruvada printf("\t[-w|--delay : Delay for reading config level state change in OOB poll mode.\n"); 27903fb4f7cdSSrinivas Pandruvada printf("\nResult format\n"); 27913fb4f7cdSSrinivas Pandruvada printf("\tResult display uses a common format for each command:\n"); 27923fb4f7cdSSrinivas Pandruvada printf("\tResults are formatted in text/JSON with\n"); 27933fb4f7cdSSrinivas Pandruvada printf("\t\tPackage, Die, CPU, and command specific results.\n"); 2794addd116dSSrinivas Pandruvada 2795addd116dSSrinivas Pandruvada printf("\nExamples\n"); 2796addd116dSSrinivas Pandruvada printf("\tTo get platform information:\n"); 2797addd116dSSrinivas Pandruvada printf("\t\tintel-speed-select --info\n"); 2798addd116dSSrinivas Pandruvada printf("\tTo get full perf-profile information dump:\n"); 2799addd116dSSrinivas Pandruvada printf("\t\tintel-speed-select perf-profile info\n"); 2800addd116dSSrinivas Pandruvada printf("\tTo get full base-freq information dump:\n"); 2801addd116dSSrinivas Pandruvada printf("\t\tintel-speed-select base-freq info -l 0\n"); 2802addd116dSSrinivas Pandruvada if (!is_clx_n_platform()) { 2803addd116dSSrinivas Pandruvada printf("\tTo get full turbo-freq information dump:\n"); 2804addd116dSSrinivas Pandruvada printf("\t\tintel-speed-select turbo-freq info -l 0\n"); 2805addd116dSSrinivas Pandruvada } 28063fb4f7cdSSrinivas Pandruvada exit(1); 28073fb4f7cdSSrinivas Pandruvada } 28083fb4f7cdSSrinivas Pandruvada 28093fb4f7cdSSrinivas Pandruvada static void print_version(void) 28103fb4f7cdSSrinivas Pandruvada { 28113fb4f7cdSSrinivas Pandruvada fprintf(outf, "Version %s\n", version_str); 28123fb4f7cdSSrinivas Pandruvada exit(0); 28133fb4f7cdSSrinivas Pandruvada } 28143fb4f7cdSSrinivas Pandruvada 28153fb4f7cdSSrinivas Pandruvada static void cmdline(int argc, char **argv) 28163fb4f7cdSSrinivas Pandruvada { 2817f362cdccSSrinivas Pandruvada const char *pathname = "/dev/isst_interface"; 2818a85a35fcSSrinivas Pandruvada char *ptr; 2819f362cdccSSrinivas Pandruvada FILE *fp; 28200d3dfd75SSrinivas Pandruvada int opt, force_cpus_online = 0; 28213fb4f7cdSSrinivas Pandruvada int option_index = 0; 28223bc3d30cSPrarit Bhargava int ret; 28237fd786dfSSrinivas Pandruvada int oob_mode = 0; 28247fd786dfSSrinivas Pandruvada int poll_interval = -1; 28257fd786dfSSrinivas Pandruvada int no_daemon = 0; 28262042c0abSZhang Rui int mbox_delay = 0, mbox_retries = 3; 28273fb4f7cdSSrinivas Pandruvada 28283fb4f7cdSSrinivas Pandruvada static struct option long_options[] = { 28290d3dfd75SSrinivas Pandruvada { "all-cpus-online", no_argument, 0, 'a' }, 28303fb4f7cdSSrinivas Pandruvada { "cpu", required_argument, 0, 'c' }, 28313fb4f7cdSSrinivas Pandruvada { "debug", no_argument, 0, 'd' }, 28323fb4f7cdSSrinivas Pandruvada { "format", required_argument, 0, 'f' }, 28333fb4f7cdSSrinivas Pandruvada { "help", no_argument, 0, 'h' }, 28343fb4f7cdSSrinivas Pandruvada { "info", no_argument, 0, 'i' }, 2835a85a35fcSSrinivas Pandruvada { "pause", required_argument, 0, 'p' }, 28363fb4f7cdSSrinivas Pandruvada { "out", required_argument, 0, 'o' }, 283732279be7SSrinivas Pandruvada { "retry", required_argument, 0, 'r' }, 28383fb4f7cdSSrinivas Pandruvada { "version", no_argument, 0, 'v' }, 28397fd786dfSSrinivas Pandruvada { "oob", no_argument, 0, 'b' }, 28407fd786dfSSrinivas Pandruvada { "no-daemon", no_argument, 0, 'n' }, 28417fd786dfSSrinivas Pandruvada { "poll-interval", required_argument, 0, 'w' }, 28423fb4f7cdSSrinivas Pandruvada { 0, 0, 0, 0 } 28433fb4f7cdSSrinivas Pandruvada }; 28443fb4f7cdSSrinivas Pandruvada 2845f362cdccSSrinivas Pandruvada if (geteuid() != 0) { 2846f362cdccSSrinivas Pandruvada fprintf(stderr, "Must run as root\n"); 2847f362cdccSSrinivas Pandruvada exit(0); 2848f362cdccSSrinivas Pandruvada } 2849f362cdccSSrinivas Pandruvada 2850f362cdccSSrinivas Pandruvada ret = update_cpu_model(); 2851f362cdccSSrinivas Pandruvada if (ret) 2852f362cdccSSrinivas Pandruvada err(-1, "Invalid CPU model (%d)\n", cpu_model); 2853f362cdccSSrinivas Pandruvada printf("Intel(R) Speed Select Technology\n"); 2854f362cdccSSrinivas Pandruvada printf("Executing on CPU model:%d[0x%x]\n", cpu_model, cpu_model); 2855f362cdccSSrinivas Pandruvada 2856f362cdccSSrinivas Pandruvada if (!is_clx_n_platform()) { 2857f362cdccSSrinivas Pandruvada fp = fopen(pathname, "rb"); 2858f362cdccSSrinivas Pandruvada if (!fp) { 2859f362cdccSSrinivas Pandruvada fprintf(stderr, "Intel speed select drivers are not loaded on this system.\n"); 2860f362cdccSSrinivas Pandruvada fprintf(stderr, "Verify that kernel config includes CONFIG_INTEL_SPEED_SELECT_INTERFACE.\n"); 2861f362cdccSSrinivas Pandruvada fprintf(stderr, "If the config is included then this is not a supported platform.\n"); 2862f362cdccSSrinivas Pandruvada exit(0); 2863f362cdccSSrinivas Pandruvada } 2864f362cdccSSrinivas Pandruvada fclose(fp); 2865f362cdccSSrinivas Pandruvada } 2866f362cdccSSrinivas Pandruvada 2867e9f79348SZhang Rui ret = isst_fill_platform_info(); 2868e9f79348SZhang Rui if (ret) 2869e9f79348SZhang Rui goto out; 2870e9f79348SZhang Rui 28713fb4f7cdSSrinivas Pandruvada progname = argv[0]; 28727fd786dfSSrinivas Pandruvada while ((opt = getopt_long_only(argc, argv, "+c:df:hio:vabw:n", long_options, 28733fb4f7cdSSrinivas Pandruvada &option_index)) != -1) { 28743fb4f7cdSSrinivas Pandruvada switch (opt) { 28750d3dfd75SSrinivas Pandruvada case 'a': 28760d3dfd75SSrinivas Pandruvada force_cpus_online = 1; 28770d3dfd75SSrinivas Pandruvada break; 28783fb4f7cdSSrinivas Pandruvada case 'c': 28793fb4f7cdSSrinivas Pandruvada parse_cpu_command(optarg); 28803fb4f7cdSSrinivas Pandruvada break; 28813fb4f7cdSSrinivas Pandruvada case 'd': 28823fb4f7cdSSrinivas Pandruvada debug_flag = 1; 28833fb4f7cdSSrinivas Pandruvada printf("Debug Mode ON\n"); 28843fb4f7cdSSrinivas Pandruvada break; 28853fb4f7cdSSrinivas Pandruvada case 'f': 28863fb4f7cdSSrinivas Pandruvada if (!strncmp(optarg, "json", 4)) 28873fb4f7cdSSrinivas Pandruvada out_format_json = 1; 28883fb4f7cdSSrinivas Pandruvada break; 28893fb4f7cdSSrinivas Pandruvada case 'h': 28903fb4f7cdSSrinivas Pandruvada usage(); 28913fb4f7cdSSrinivas Pandruvada break; 28923fb4f7cdSSrinivas Pandruvada case 'i': 28933fb4f7cdSSrinivas Pandruvada isst_print_platform_information(); 28943fb4f7cdSSrinivas Pandruvada break; 28953fb4f7cdSSrinivas Pandruvada case 'o': 28963fb4f7cdSSrinivas Pandruvada if (outf) 28973fb4f7cdSSrinivas Pandruvada fclose(outf); 28983fb4f7cdSSrinivas Pandruvada outf = fopen_or_exit(optarg, "w"); 28993fb4f7cdSSrinivas Pandruvada break; 2900a85a35fcSSrinivas Pandruvada case 'p': 2901a85a35fcSSrinivas Pandruvada ret = strtol(optarg, &ptr, 10); 2902a85a35fcSSrinivas Pandruvada if (!ret) 2903a85a35fcSSrinivas Pandruvada fprintf(stderr, "Invalid pause interval, ignore\n"); 2904a85a35fcSSrinivas Pandruvada else 2905a85a35fcSSrinivas Pandruvada mbox_delay = ret; 2906a85a35fcSSrinivas Pandruvada break; 290732279be7SSrinivas Pandruvada case 'r': 290832279be7SSrinivas Pandruvada ret = strtol(optarg, &ptr, 10); 290932279be7SSrinivas Pandruvada if (!ret) 291032279be7SSrinivas Pandruvada fprintf(stderr, "Invalid retry count, ignore\n"); 291132279be7SSrinivas Pandruvada else 291232279be7SSrinivas Pandruvada mbox_retries = ret; 291332279be7SSrinivas Pandruvada break; 29143fb4f7cdSSrinivas Pandruvada case 'v': 29153fb4f7cdSSrinivas Pandruvada print_version(); 29163fb4f7cdSSrinivas Pandruvada break; 29177fd786dfSSrinivas Pandruvada case 'b': 29187fd786dfSSrinivas Pandruvada oob_mode = 1; 29197fd786dfSSrinivas Pandruvada break; 29207fd786dfSSrinivas Pandruvada case 'n': 29217fd786dfSSrinivas Pandruvada no_daemon = 1; 29227fd786dfSSrinivas Pandruvada break; 29237fd786dfSSrinivas Pandruvada case 'w': 29247fd786dfSSrinivas Pandruvada ret = strtol(optarg, &ptr, 10); 29257fd786dfSSrinivas Pandruvada if (!ret) { 29267fd786dfSSrinivas Pandruvada fprintf(stderr, "Invalid poll interval count\n"); 29277fd786dfSSrinivas Pandruvada exit(0); 29287fd786dfSSrinivas Pandruvada } 29297fd786dfSSrinivas Pandruvada poll_interval = ret; 29307fd786dfSSrinivas Pandruvada break; 29313fb4f7cdSSrinivas Pandruvada default: 29323fb4f7cdSSrinivas Pandruvada usage(); 29333fb4f7cdSSrinivas Pandruvada } 29343fb4f7cdSSrinivas Pandruvada } 29353fb4f7cdSSrinivas Pandruvada 29367fd786dfSSrinivas Pandruvada if (optind > (argc - 2) && !oob_mode) { 2937addd116dSSrinivas Pandruvada usage(); 29383fb4f7cdSSrinivas Pandruvada exit(0); 29393fb4f7cdSSrinivas Pandruvada } 29402042c0abSZhang Rui 29412042c0abSZhang Rui isst_update_platform_param(ISST_PARAM_MBOX_DELAY, mbox_delay); 29422042c0abSZhang Rui isst_update_platform_param(ISST_PARAM_MBOX_RETRIES, mbox_retries); 29432042c0abSZhang Rui 29443fb4f7cdSSrinivas Pandruvada set_max_cpu_num(); 29450d3dfd75SSrinivas Pandruvada if (force_cpus_online) 29460d3dfd75SSrinivas Pandruvada force_all_cpus_online(); 2947fb186158SSrinivas Pandruvada store_cpu_topology(); 2948ca56725dSZhang Rui create_cpu_map(); 2949c829f0efSPrarit Bhargava 29507fd786dfSSrinivas Pandruvada if (oob_mode) { 29517fd786dfSSrinivas Pandruvada if (debug_flag) 29527fd786dfSSrinivas Pandruvada fprintf(stderr, "OOB mode is enabled in debug mode\n"); 29537fd786dfSSrinivas Pandruvada 29547fd786dfSSrinivas Pandruvada ret = isst_daemon(debug_flag, poll_interval, no_daemon); 29557fd786dfSSrinivas Pandruvada if (ret) 29567fd786dfSSrinivas Pandruvada fprintf(stderr, "OOB mode enable failed\n"); 29577fd786dfSSrinivas Pandruvada goto out; 29587fd786dfSSrinivas Pandruvada } 29597fd786dfSSrinivas Pandruvada 2960c829f0efSPrarit Bhargava if (!is_clx_n_platform()) { 2961210369dcSPrarit Bhargava process_command(argc, argv, isst_help_cmds, isst_cmds); 2962c829f0efSPrarit Bhargava } else { 2963c829f0efSPrarit Bhargava process_command(argc, argv, clx_n_help_cmds, clx_n_cmds); 2964c829f0efSPrarit Bhargava } 29653bc3d30cSPrarit Bhargava out: 29663bc3d30cSPrarit Bhargava free_cpu_set(present_cpumask); 29673bc3d30cSPrarit Bhargava free_cpu_set(target_cpumask); 29683fb4f7cdSSrinivas Pandruvada } 29693fb4f7cdSSrinivas Pandruvada 29703fb4f7cdSSrinivas Pandruvada int main(int argc, char **argv) 29713fb4f7cdSSrinivas Pandruvada { 29723fb4f7cdSSrinivas Pandruvada outf = stderr; 29733fb4f7cdSSrinivas Pandruvada cmdline(argc, argv); 29743fb4f7cdSSrinivas Pandruvada return 0; 29753fb4f7cdSSrinivas Pandruvada } 2976