xref: /linux/tools/power/x86/intel-speed-select/isst-config.c (revision 57797f19d5a78b5a84b7452790f7da22865f6420)
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