1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Intel Speed Select -- Enumerate and control features
4  * Copyright (c) 2019 Intel Corporation.
5  */
6 
7 #include "isst.h"
8 
9 int isst_write_pm_config(int cpu, int cp_state)
10 {
11 	unsigned int req, resp;
12 	int ret;
13 
14 	if (cp_state)
15 		req = BIT(16);
16 	else
17 		req = 0;
18 
19 	ret = isst_send_mbox_command(cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req,
20 				     &resp);
21 	if (ret)
22 		return ret;
23 
24 	debug_printf("cpu:%d WRITE_PM_CONFIG resp:%x\n", cpu, resp);
25 
26 	return 0;
27 }
28 
29 int isst_read_pm_config(int cpu, int *cp_state, int *cp_cap)
30 {
31 	unsigned int resp;
32 	int ret;
33 
34 	ret = isst_send_mbox_command(cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0,
35 				     &resp);
36 	if (ret)
37 		return ret;
38 
39 	debug_printf("cpu:%d READ_PM_CONFIG resp:%x\n", cpu, resp);
40 
41 	*cp_state = resp & BIT(16);
42 	*cp_cap = resp & BIT(0) ? 1 : 0;
43 
44 	return 0;
45 }
46 
47 int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev)
48 {
49 	unsigned int resp;
50 	int ret;
51 
52 	ret = isst_send_mbox_command(cpu, CONFIG_TDP,
53 				     CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp);
54 	if (ret) {
55 		pkg_dev->levels = 0;
56 		pkg_dev->locked = 1;
57 		pkg_dev->current_level = 0;
58 		pkg_dev->version = 0;
59 		pkg_dev->enabled = 0;
60 		return 0;
61 	}
62 
63 	debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", cpu, resp);
64 
65 	pkg_dev->version = resp & 0xff;
66 	pkg_dev->levels = (resp >> 8) & 0xff;
67 	pkg_dev->current_level = (resp >> 16) & 0xff;
68 	pkg_dev->locked = !!(resp & BIT(24));
69 	pkg_dev->enabled = !!(resp & BIT(31));
70 
71 	return 0;
72 }
73 
74 int isst_get_ctdp_control(int cpu, int config_index,
75 			  struct isst_pkg_ctdp_level_info *ctdp_level)
76 {
77 	int cp_state, cp_cap;
78 	unsigned int resp;
79 	int ret;
80 
81 	ret = isst_send_mbox_command(cpu, CONFIG_TDP,
82 				     CONFIG_TDP_GET_TDP_CONTROL, 0,
83 				     config_index, &resp);
84 	if (ret)
85 		return ret;
86 
87 	ctdp_level->fact_support = resp & BIT(0);
88 	ctdp_level->pbf_support = !!(resp & BIT(1));
89 	ctdp_level->fact_enabled = !!(resp & BIT(16));
90 	ctdp_level->pbf_enabled = !!(resp & BIT(17));
91 
92 	ret = isst_read_pm_config(cpu, &cp_state, &cp_cap);
93 	if (ret) {
94 		debug_printf("cpu:%d pm_config is not supported \n", cpu);
95 	} else {
96 		debug_printf("cpu:%d pm_config SST-CP state:%d cap:%d \n", cpu, cp_state, cp_cap);
97 		ctdp_level->sst_cp_support = cp_cap;
98 		ctdp_level->sst_cp_enabled = cp_state;
99 	}
100 
101 	debug_printf(
102 		"cpu:%d CONFIG_TDP_GET_TDP_CONTROL resp:%x fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n",
103 		cpu, resp, ctdp_level->fact_support, ctdp_level->pbf_support,
104 		ctdp_level->fact_enabled, ctdp_level->pbf_enabled);
105 
106 	return 0;
107 }
108 
109 int isst_get_tdp_info(int cpu, int config_index,
110 		      struct isst_pkg_ctdp_level_info *ctdp_level)
111 {
112 	unsigned int resp;
113 	int ret;
114 
115 	ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO,
116 				     0, config_index, &resp);
117 	if (ret) {
118 		isst_display_error_info_message(1, "Invalid level, Can't get TDP information at level", 1, config_index);
119 		return ret;
120 	}
121 
122 	ctdp_level->pkg_tdp = resp & GENMASK(14, 0);
123 	ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16;
124 
125 	debug_printf(
126 		"cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO resp:%x tdp_ratio:%d pkg_tdp:%d\n",
127 		cpu, config_index, resp, ctdp_level->tdp_ratio,
128 		ctdp_level->pkg_tdp);
129 	return 0;
130 }
131 
132 int isst_get_pwr_info(int cpu, int config_index,
133 		      struct isst_pkg_ctdp_level_info *ctdp_level)
134 {
135 	unsigned int resp;
136 	int ret;
137 
138 	ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO,
139 				     0, config_index, &resp);
140 	if (ret)
141 		return ret;
142 
143 	ctdp_level->pkg_max_power = resp & GENMASK(14, 0);
144 	ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16;
145 
146 	debug_printf(
147 		"cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO resp:%x pkg_max_power:%d pkg_min_power:%d\n",
148 		cpu, config_index, resp, ctdp_level->pkg_max_power,
149 		ctdp_level->pkg_min_power);
150 
151 	return 0;
152 }
153 
154 void isst_get_uncore_p0_p1_info(int cpu, int config_index,
155 				struct isst_pkg_ctdp_level_info *ctdp_level)
156 {
157 	unsigned int resp;
158 	int ret;
159 	ret = isst_send_mbox_command(cpu, CONFIG_TDP,
160 				     CONFIG_TDP_GET_UNCORE_P0_P1_INFO, 0,
161 				     config_index, &resp);
162 	if (ret) {
163 		ctdp_level->uncore_p0 = 0;
164 		ctdp_level->uncore_p1 = 0;
165 		return;
166 	}
167 
168 	ctdp_level->uncore_p0 = resp & GENMASK(7, 0);
169 	ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8;
170 	debug_printf(
171 		"cpu:%d ctdp:%d CONFIG_TDP_GET_UNCORE_P0_P1_INFO resp:%x uncore p0:%d uncore p1:%d\n",
172 		cpu, config_index, resp, ctdp_level->uncore_p0,
173 		ctdp_level->uncore_p1);
174 }
175 
176 void isst_get_p1_info(int cpu, int config_index,
177 		      struct isst_pkg_ctdp_level_info *ctdp_level)
178 {
179 	unsigned int resp;
180 	int ret;
181 	ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0,
182 				     config_index, &resp);
183 	if (ret) {
184 		ctdp_level->sse_p1 = 0;
185 		ctdp_level->avx2_p1 = 0;
186 		ctdp_level->avx512_p1 = 0;
187 		return;
188 	}
189 
190 	ctdp_level->sse_p1 = resp & GENMASK(7, 0);
191 	ctdp_level->avx2_p1 = (resp & GENMASK(15, 8)) >> 8;
192 	ctdp_level->avx512_p1 = (resp & GENMASK(23, 16)) >> 16;
193 	debug_printf(
194 		"cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d\n",
195 		cpu, config_index, resp, ctdp_level->sse_p1,
196 		ctdp_level->avx2_p1, ctdp_level->avx512_p1);
197 }
198 
199 void isst_get_uncore_mem_freq(int cpu, int config_index,
200 			      struct isst_pkg_ctdp_level_info *ctdp_level)
201 {
202 	unsigned int resp;
203 	int ret;
204 	ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ,
205 				     0, config_index, &resp);
206 	if (ret) {
207 		ctdp_level->mem_freq = 0;
208 		return;
209 	}
210 
211 	ctdp_level->mem_freq = resp & GENMASK(7, 0);
212 	debug_printf(
213 		"cpu:%d ctdp:%d CONFIG_TDP_GET_MEM_FREQ resp:%x uncore mem_freq:%d\n",
214 		cpu, config_index, resp, ctdp_level->mem_freq);
215 }
216 
217 int isst_get_tjmax_info(int cpu, int config_index,
218 			struct isst_pkg_ctdp_level_info *ctdp_level)
219 {
220 	unsigned int resp;
221 	int ret;
222 
223 	ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO,
224 				     0, config_index, &resp);
225 	if (ret)
226 		return ret;
227 
228 	ctdp_level->t_proc_hot = resp & GENMASK(7, 0);
229 
230 	debug_printf(
231 		"cpu:%d ctdp:%d CONFIG_TDP_GET_TJMAX_INFO resp:%x t_proc_hot:%d\n",
232 		cpu, config_index, resp, ctdp_level->t_proc_hot);
233 
234 	return 0;
235 }
236 
237 int isst_get_coremask_info(int cpu, int config_index,
238 			   struct isst_pkg_ctdp_level_info *ctdp_level)
239 {
240 	unsigned int resp;
241 	int i, ret;
242 
243 	ctdp_level->cpu_count = 0;
244 	for (i = 0; i < 2; ++i) {
245 		unsigned long long mask;
246 		int cpu_count = 0;
247 
248 		ret = isst_send_mbox_command(cpu, CONFIG_TDP,
249 					     CONFIG_TDP_GET_CORE_MASK, 0,
250 					     (i << 8) | config_index, &resp);
251 		if (ret)
252 			return ret;
253 
254 		debug_printf(
255 			"cpu:%d ctdp:%d mask:%d CONFIG_TDP_GET_CORE_MASK resp:%x\n",
256 			cpu, config_index, i, resp);
257 
258 		mask = (unsigned long long)resp << (32 * i);
259 		set_cpu_mask_from_punit_coremask(cpu, mask,
260 						 ctdp_level->core_cpumask_size,
261 						 ctdp_level->core_cpumask,
262 						 &cpu_count);
263 		ctdp_level->cpu_count += cpu_count;
264 		debug_printf("cpu:%d ctdp:%d mask:%d cpu count:%d\n", cpu,
265 			     config_index, i, ctdp_level->cpu_count);
266 	}
267 
268 	return 0;
269 }
270 
271 int isst_get_get_trl_from_msr(int cpu, int *trl)
272 {
273 	unsigned long long msr_trl;
274 	int ret;
275 
276 	ret = isst_send_msr_command(cpu, 0x1AD, 0, &msr_trl);
277 	if (ret)
278 		return ret;
279 
280 	trl[0] = msr_trl & GENMASK(7, 0);
281 	trl[1] = (msr_trl & GENMASK(15, 8)) >> 8;
282 	trl[2] = (msr_trl & GENMASK(23, 16)) >> 16;
283 	trl[3] = (msr_trl & GENMASK(31, 24)) >> 24;
284 	trl[4] = (msr_trl & GENMASK(39, 32)) >> 32;
285 	trl[5] = (msr_trl & GENMASK(47, 40)) >> 40;
286 	trl[6] = (msr_trl & GENMASK(55, 48)) >> 48;
287 	trl[7] = (msr_trl & GENMASK(63, 56)) >> 56;
288 
289 	return 0;
290 }
291 
292 int isst_get_get_trl(int cpu, int level, int avx_level, int *trl)
293 {
294 	unsigned int req, resp;
295 	int ret;
296 
297 	req = level | (avx_level << 16);
298 	ret = isst_send_mbox_command(cpu, CONFIG_TDP,
299 				     CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req,
300 				     &resp);
301 	if (ret)
302 		return ret;
303 
304 	debug_printf(
305 		"cpu:%d CONFIG_TDP_GET_TURBO_LIMIT_RATIOS req:%x resp:%x\n",
306 		cpu, req, resp);
307 
308 	trl[0] = resp & GENMASK(7, 0);
309 	trl[1] = (resp & GENMASK(15, 8)) >> 8;
310 	trl[2] = (resp & GENMASK(23, 16)) >> 16;
311 	trl[3] = (resp & GENMASK(31, 24)) >> 24;
312 
313 	req = level | BIT(8) | (avx_level << 16);
314 	ret = isst_send_mbox_command(cpu, CONFIG_TDP,
315 				     CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req,
316 				     &resp);
317 	if (ret)
318 		return ret;
319 
320 	debug_printf("cpu:%d CONFIG_TDP_GET_TURBO_LIMIT req:%x resp:%x\n", cpu,
321 		     req, resp);
322 
323 	trl[4] = resp & GENMASK(7, 0);
324 	trl[5] = (resp & GENMASK(15, 8)) >> 8;
325 	trl[6] = (resp & GENMASK(23, 16)) >> 16;
326 	trl[7] = (resp & GENMASK(31, 24)) >> 24;
327 
328 	return 0;
329 }
330 
331 int isst_get_trl_bucket_info(int cpu, unsigned long long *buckets_info)
332 {
333 	int ret;
334 
335 	debug_printf("cpu:%d bucket info via MSR\n", cpu);
336 
337 	*buckets_info = 0;
338 
339 	ret = isst_send_msr_command(cpu, 0x1ae, 0, buckets_info);
340 	if (ret)
341 		return ret;
342 
343 	debug_printf("cpu:%d bucket info via MSR successful 0x%llx\n", cpu,
344 		     *buckets_info);
345 
346 	return 0;
347 }
348 
349 int isst_set_tdp_level_msr(int cpu, int tdp_level)
350 {
351 	unsigned long long level = tdp_level;
352 	int ret;
353 
354 	debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level);
355 
356 	if (isst_get_config_tdp_lock_status(cpu)) {
357 		isst_display_error_info_message(1, "tdp_locked", 0, 0);
358 		return -1;
359 	}
360 
361 	if (tdp_level > 2)
362 		return -1; /* invalid value */
363 
364 	ret = isst_send_msr_command(cpu, 0x64b, 1, &level);
365 	if (ret)
366 		return ret;
367 
368 	debug_printf("cpu: tdp_level via MSR successful %d\n", cpu, tdp_level);
369 
370 	return 0;
371 }
372 
373 int isst_set_tdp_level(int cpu, int tdp_level)
374 {
375 	unsigned int resp;
376 	int ret;
377 
378 
379 	if (isst_get_config_tdp_lock_status(cpu)) {
380 		isst_display_error_info_message(1, "TDP is locked", 0, 0);
381 		return -1;
382 
383 	}
384 
385 	ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0,
386 				     tdp_level, &resp);
387 	if (ret) {
388 		isst_display_error_info_message(1, "Set TDP level failed for level", 1, tdp_level);
389 		return ret;
390 	}
391 
392 	return 0;
393 }
394 
395 int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info)
396 {
397 	struct isst_pkg_ctdp_level_info ctdp_level;
398 	struct isst_pkg_ctdp pkg_dev;
399 	int i, ret, max_punit_core, max_mask_index;
400 	unsigned int req, resp;
401 
402 	ret = isst_get_ctdp_levels(cpu, &pkg_dev);
403 	if (ret) {
404 		isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
405 		return ret;
406 	}
407 
408 	if (level > pkg_dev.levels) {
409 		isst_display_error_info_message(1, "Invalid level", 1, level);
410 		return -1;
411 	}
412 
413 	ret = isst_get_ctdp_control(cpu, level, &ctdp_level);
414 	if (ret)
415 		return ret;
416 
417 	if (!ctdp_level.pbf_support) {
418 		isst_display_error_info_message(1, "base-freq feature is not present at this level", 1, level);
419 		return -1;
420 	}
421 
422 	pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask);
423 
424 	max_punit_core = get_max_punit_core_id(get_physical_package_id(cpu), get_physical_die_id(cpu));
425 	max_mask_index = max_punit_core > 32 ? 2 : 1;
426 
427 	for (i = 0; i < max_mask_index; ++i) {
428 		unsigned long long mask;
429 		int count;
430 
431 		ret = isst_send_mbox_command(cpu, CONFIG_TDP,
432 					     CONFIG_TDP_PBF_GET_CORE_MASK_INFO,
433 					     0, (i << 8) | level, &resp);
434 		if (ret)
435 			break;
436 
437 		debug_printf(
438 			"cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n",
439 			cpu, resp);
440 
441 		mask = (unsigned long long)resp << (32 * i);
442 		set_cpu_mask_from_punit_coremask(cpu, mask,
443 						 pbf_info->core_cpumask_size,
444 						 pbf_info->core_cpumask,
445 						 &count);
446 	}
447 
448 	req = level;
449 	ret = isst_send_mbox_command(cpu, CONFIG_TDP,
450 				     CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req,
451 				     &resp);
452 	if (ret)
453 		return ret;
454 
455 	debug_printf("cpu:%d CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO resp:%x\n", cpu,
456 		     resp);
457 
458 	pbf_info->p1_low = resp & 0xff;
459 	pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8;
460 
461 	req = level;
462 	ret = isst_send_mbox_command(
463 		cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp);
464 	if (ret)
465 		return ret;
466 
467 	debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TDP_INFO resp:%x\n", cpu, resp);
468 
469 	pbf_info->tdp = resp & 0xffff;
470 
471 	req = level;
472 	ret = isst_send_mbox_command(
473 		cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp);
474 	if (ret)
475 		return ret;
476 
477 	debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TJ_MAX_INFO resp:%x\n", cpu,
478 		     resp);
479 	pbf_info->t_control = (resp >> 8) & 0xff;
480 	pbf_info->t_prochot = resp & 0xff;
481 
482 	return 0;
483 }
484 
485 void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info)
486 {
487 	free_cpu_set(pbf_info->core_cpumask);
488 }
489 
490 int isst_set_pbf_fact_status(int cpu, int pbf, int enable)
491 {
492 	struct isst_pkg_ctdp pkg_dev;
493 	struct isst_pkg_ctdp_level_info ctdp_level;
494 	int current_level;
495 	unsigned int req = 0, resp;
496 	int ret;
497 
498 	ret = isst_get_ctdp_levels(cpu, &pkg_dev);
499 	if (ret)
500 		debug_printf("cpu:%d No support for dynamic ISST\n", cpu);
501 
502 	current_level = pkg_dev.current_level;
503 
504 	ret = isst_get_ctdp_control(cpu, current_level, &ctdp_level);
505 	if (ret)
506 		return ret;
507 
508 	if (pbf) {
509 		if (ctdp_level.fact_enabled)
510 			req = BIT(16);
511 
512 		if (enable)
513 			req |= BIT(17);
514 		else
515 			req &= ~BIT(17);
516 	} else {
517 
518 		if (enable && !ctdp_level.sst_cp_enabled)
519 			isst_display_error_info_message(0, "Make sure to execute before: core-power enable", 0, 0);
520 
521 		if (ctdp_level.pbf_enabled)
522 			req = BIT(17);
523 
524 		if (enable)
525 			req |= BIT(16);
526 		else
527 			req &= ~BIT(16);
528 	}
529 
530 	ret = isst_send_mbox_command(cpu, CONFIG_TDP,
531 				     CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp);
532 	if (ret)
533 		return ret;
534 
535 	debug_printf("cpu:%d CONFIG_TDP_SET_TDP_CONTROL pbf/fact:%d req:%x\n",
536 		     cpu, pbf, req);
537 
538 	return 0;
539 }
540 
541 int isst_get_fact_bucket_info(int cpu, int level,
542 			      struct isst_fact_bucket_info *bucket_info)
543 {
544 	unsigned int resp;
545 	int i, k, ret;
546 
547 	for (i = 0; i < 2; ++i) {
548 		int j;
549 
550 		ret = isst_send_mbox_command(
551 			cpu, CONFIG_TDP,
552 			CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0,
553 			(i << 8) | level, &resp);
554 		if (ret)
555 			return ret;
556 
557 		debug_printf(
558 			"cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES index:%d level:%d resp:%x\n",
559 			cpu, i, level, resp);
560 
561 		for (j = 0; j < 4; ++j) {
562 			bucket_info[j + (i * 4)].high_priority_cores_count =
563 				(resp >> (j * 8)) & 0xff;
564 		}
565 	}
566 
567 	for (k = 0; k < 3; ++k) {
568 		for (i = 0; i < 2; ++i) {
569 			int j;
570 
571 			ret = isst_send_mbox_command(
572 				cpu, CONFIG_TDP,
573 				CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0,
574 				(k << 16) | (i << 8) | level, &resp);
575 			if (ret)
576 				return ret;
577 
578 			debug_printf(
579 				"cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS index:%d level:%d avx:%d resp:%x\n",
580 				cpu, i, level, k, resp);
581 
582 			for (j = 0; j < 4; ++j) {
583 				switch (k) {
584 				case 0:
585 					bucket_info[j + (i * 4)].sse_trl =
586 						(resp >> (j * 8)) & 0xff;
587 					break;
588 				case 1:
589 					bucket_info[j + (i * 4)].avx_trl =
590 						(resp >> (j * 8)) & 0xff;
591 					break;
592 				case 2:
593 					bucket_info[j + (i * 4)].avx512_trl =
594 						(resp >> (j * 8)) & 0xff;
595 					break;
596 				default:
597 					break;
598 				}
599 			}
600 		}
601 	}
602 
603 	return 0;
604 }
605 
606 int isst_get_fact_info(int cpu, int level, int fact_bucket, struct isst_fact_info *fact_info)
607 {
608 	struct isst_pkg_ctdp_level_info ctdp_level;
609 	struct isst_pkg_ctdp pkg_dev;
610 	unsigned int resp;
611 	int j, ret, print;
612 
613 	ret = isst_get_ctdp_levels(cpu, &pkg_dev);
614 	if (ret) {
615 		isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
616 		return ret;
617 	}
618 
619 	if (level > pkg_dev.levels) {
620 		isst_display_error_info_message(1, "Invalid level", 1, level);
621 		return -1;
622 	}
623 
624 	ret = isst_get_ctdp_control(cpu, level, &ctdp_level);
625 	if (ret)
626 		return ret;
627 
628 	if (!ctdp_level.fact_support) {
629 		isst_display_error_info_message(1, "turbo-freq feature is not present at this level", 1, level);
630 		return -1;
631 	}
632 
633 	ret = isst_send_mbox_command(cpu, CONFIG_TDP,
634 				     CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0,
635 				     level, &resp);
636 	if (ret)
637 		return ret;
638 
639 	debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n",
640 		     cpu, resp);
641 
642 	fact_info->lp_clipping_ratio_license_sse = resp & 0xff;
643 	fact_info->lp_clipping_ratio_license_avx2 = (resp >> 8) & 0xff;
644 	fact_info->lp_clipping_ratio_license_avx512 = (resp >> 16) & 0xff;
645 
646 	ret = isst_get_fact_bucket_info(cpu, level, fact_info->bucket_info);
647 	if (ret)
648 		return ret;
649 
650 	print = 0;
651 	for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
652 		if (fact_bucket != 0xff && fact_bucket != j)
653 			continue;
654 
655 		if (!fact_info->bucket_info[j].high_priority_cores_count)
656 			break;
657 
658 		print = 1;
659 	}
660 	if (!print) {
661 		isst_display_error_info_message(1, "Invalid bucket", 0, 0);
662 		return -1;
663 	}
664 
665 	return 0;
666 }
667 
668 int isst_get_trl(int cpu, unsigned long long *trl)
669 {
670 	int ret;
671 
672 	ret = isst_send_msr_command(cpu, 0x1AD, 0, trl);
673 	if (ret)
674 		return ret;
675 
676 	return 0;
677 }
678 
679 int isst_set_trl(int cpu, unsigned long long trl)
680 {
681 	int ret;
682 
683 	if (!trl)
684 		trl = 0xFFFFFFFFFFFFFFFFULL;
685 
686 	ret = isst_send_msr_command(cpu, 0x1AD, 1, &trl);
687 	if (ret)
688 		return ret;
689 
690 	return 0;
691 }
692 
693 int isst_set_trl_from_current_tdp(int cpu, unsigned long long trl)
694 {
695 	unsigned long long msr_trl;
696 	int ret;
697 
698 	if (trl) {
699 		msr_trl = trl;
700 	} else {
701 		struct isst_pkg_ctdp pkg_dev;
702 		int trl[8];
703 		int i;
704 
705 		ret = isst_get_ctdp_levels(cpu, &pkg_dev);
706 		if (ret)
707 			return ret;
708 
709 		ret = isst_get_get_trl(cpu, pkg_dev.current_level, 0, trl);
710 		if (ret)
711 			return ret;
712 
713 		msr_trl = 0;
714 		for (i = 0; i < 8; ++i) {
715 			unsigned long long _trl = trl[i];
716 
717 			msr_trl |= (_trl << (i * 8));
718 		}
719 	}
720 	ret = isst_send_msr_command(cpu, 0x1AD, 1, &msr_trl);
721 	if (ret)
722 		return ret;
723 
724 	return 0;
725 }
726 
727 /* Return 1 if locked */
728 int isst_get_config_tdp_lock_status(int cpu)
729 {
730 	unsigned long long tdp_control = 0;
731 	int ret;
732 
733 	ret = isst_send_msr_command(cpu, 0x64b, 0, &tdp_control);
734 	if (ret)
735 		return ret;
736 
737 	ret = !!(tdp_control & BIT(31));
738 
739 	return ret;
740 }
741 
742 void isst_get_process_ctdp_complete(int cpu, struct isst_pkg_ctdp *pkg_dev)
743 {
744 	int i;
745 
746 	if (!pkg_dev->processed)
747 		return;
748 
749 	for (i = 0; i < pkg_dev->levels; ++i) {
750 		struct isst_pkg_ctdp_level_info *ctdp_level;
751 
752 		ctdp_level = &pkg_dev->ctdp_level[i];
753 		if (ctdp_level->pbf_support)
754 			free_cpu_set(ctdp_level->pbf_info.core_cpumask);
755 		free_cpu_set(ctdp_level->core_cpumask);
756 	}
757 }
758 
759 int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
760 {
761 	int i, ret, valid = 0;
762 
763 	if (pkg_dev->processed)
764 		return 0;
765 
766 	ret = isst_get_ctdp_levels(cpu, pkg_dev);
767 	if (ret)
768 		return ret;
769 
770 	debug_printf("cpu: %d ctdp enable:%d current level: %d levels:%d\n",
771 		     cpu, pkg_dev->enabled, pkg_dev->current_level,
772 		     pkg_dev->levels);
773 
774 	if (tdp_level != 0xff && tdp_level > pkg_dev->levels) {
775 		isst_display_error_info_message(1, "Invalid level", 0, 0);
776 		return -1;
777 	}
778 
779 	if (!pkg_dev->enabled)
780 		isst_display_error_info_message(0, "perf-profile feature is not supported, just base-config level 0 is valid", 0, 0);
781 
782 	for (i = 0; i <= pkg_dev->levels; ++i) {
783 		struct isst_pkg_ctdp_level_info *ctdp_level;
784 
785 		if (tdp_level != 0xff && i != tdp_level)
786 			continue;
787 
788 		debug_printf("cpu:%d Get Information for TDP level:%d\n", cpu,
789 			     i);
790 		ctdp_level = &pkg_dev->ctdp_level[i];
791 
792 		ctdp_level->level = i;
793 		ctdp_level->control_cpu = cpu;
794 		ctdp_level->pkg_id = get_physical_package_id(cpu);
795 		ctdp_level->die_id = get_physical_die_id(cpu);
796 
797 		ret = isst_get_ctdp_control(cpu, i, ctdp_level);
798 		if (ret)
799 			continue;
800 
801 		valid = 1;
802 		pkg_dev->processed = 1;
803 		ctdp_level->processed = 1;
804 
805 		if (ctdp_level->pbf_support) {
806 			ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info);
807 			if (!ret)
808 				ctdp_level->pbf_found = 1;
809 		}
810 
811 		if (ctdp_level->fact_support) {
812 			ret = isst_get_fact_info(cpu, i, 0xff,
813 						 &ctdp_level->fact_info);
814 			if (ret)
815 				return ret;
816 		}
817 
818 		if (!pkg_dev->enabled && is_skx_based_platform()) {
819 			int freq;
820 
821 			freq = get_cpufreq_base_freq(cpu);
822 			if (freq > 0) {
823 				ctdp_level->sse_p1 = freq / 100000;
824 				ctdp_level->tdp_ratio = ctdp_level->sse_p1;
825 			}
826 
827 			isst_get_get_trl_from_msr(cpu, ctdp_level->trl_sse_active_cores);
828 			isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info);
829 			continue;
830 		}
831 
832 		ret = isst_get_tdp_info(cpu, i, ctdp_level);
833 		if (ret)
834 			return ret;
835 
836 		ret = isst_get_pwr_info(cpu, i, ctdp_level);
837 		if (ret)
838 			return ret;
839 
840 		ret = isst_get_tjmax_info(cpu, i, ctdp_level);
841 		if (ret)
842 			return ret;
843 
844 		ctdp_level->core_cpumask_size =
845 			alloc_cpu_set(&ctdp_level->core_cpumask);
846 		ret = isst_get_coremask_info(cpu, i, ctdp_level);
847 		if (ret)
848 			return ret;
849 
850 		ret = isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info);
851 		if (ret)
852 			return ret;
853 
854 		ret = isst_get_get_trl(cpu, i, 0,
855 				       ctdp_level->trl_sse_active_cores);
856 		if (ret)
857 			return ret;
858 
859 		ret = isst_get_get_trl(cpu, i, 1,
860 				       ctdp_level->trl_avx_active_cores);
861 		if (ret)
862 			return ret;
863 
864 		ret = isst_get_get_trl(cpu, i, 2,
865 				       ctdp_level->trl_avx_512_active_cores);
866 		if (ret)
867 			return ret;
868 
869 		isst_get_uncore_p0_p1_info(cpu, i, ctdp_level);
870 		isst_get_p1_info(cpu, i, ctdp_level);
871 		isst_get_uncore_mem_freq(cpu, i, ctdp_level);
872 	}
873 
874 	if (!valid)
875 		isst_display_error_info_message(0, "Invalid level, Can't get TDP control information at specified levels on cpu", 1, cpu);
876 
877 	return 0;
878 }
879 
880 int isst_clos_get_clos_information(int cpu, int *enable, int *type)
881 {
882 	unsigned int resp;
883 	int ret;
884 
885 	ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
886 				     &resp);
887 	if (ret)
888 		return ret;
889 
890 	debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp);
891 
892 	if (resp & BIT(1))
893 		*enable = 1;
894 	else
895 		*enable = 0;
896 
897 	if (resp & BIT(2))
898 		*type = 1;
899 	else
900 		*type = 0;
901 
902 	return 0;
903 }
904 
905 int isst_pm_qos_config(int cpu, int enable_clos, int priority_type)
906 {
907 	unsigned int req, resp;
908 	int ret;
909 
910 	if (!enable_clos) {
911 		struct isst_pkg_ctdp pkg_dev;
912 		struct isst_pkg_ctdp_level_info ctdp_level;
913 
914 		ret = isst_get_ctdp_levels(cpu, &pkg_dev);
915 		if (ret) {
916 			debug_printf("isst_get_ctdp_levels\n");
917 			return ret;
918 		}
919 
920 		ret = isst_get_ctdp_control(cpu, pkg_dev.current_level,
921 					    &ctdp_level);
922 		if (ret)
923 			return ret;
924 
925 		if (ctdp_level.fact_enabled) {
926 			isst_display_error_info_message(1, "Ignoring request, turbo-freq feature is still enabled", 0, 0);
927 			return -EINVAL;
928 		}
929 		ret = isst_write_pm_config(cpu, 0);
930 		if (ret)
931 			isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0);
932 	} else {
933 		ret = isst_write_pm_config(cpu, 1);
934 		if (ret)
935 			isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0);
936 	}
937 
938 	ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
939 				     &resp);
940 	if (ret) {
941 		isst_display_error_info_message(1, "CLOS_PM_QOS_CONFIG command failed", 0, 0);
942 		return ret;
943 	}
944 
945 	debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp);
946 
947 	req = resp;
948 
949 	if (enable_clos)
950 		req = req | BIT(1);
951 	else
952 		req = req & ~BIT(1);
953 
954 	if (priority_type > 1)
955 		isst_display_error_info_message(1, "Invalid priority type: Changing type to ordered", 0, 0);
956 
957 	if (priority_type)
958 		req = req | BIT(2);
959 	else
960 		req = req & ~BIT(2);
961 
962 	ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG,
963 				     BIT(MBOX_CMD_WRITE_BIT), req, &resp);
964 	if (ret)
965 		return ret;
966 
967 	debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", cpu,
968 		     priority_type, req);
969 
970 	return 0;
971 }
972 
973 int isst_pm_get_clos(int cpu, int clos, struct isst_clos_config *clos_config)
974 {
975 	unsigned int resp;
976 	int ret;
977 
978 	ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0,
979 				     &resp);
980 	if (ret)
981 		return ret;
982 
983 	clos_config->pkg_id = get_physical_package_id(cpu);
984 	clos_config->die_id = get_physical_die_id(cpu);
985 
986 	clos_config->epp = resp & 0x0f;
987 	clos_config->clos_prop_prio = (resp >> 4) & 0x0f;
988 	clos_config->clos_min = (resp >> 8) & 0xff;
989 	clos_config->clos_max = (resp >> 16) & 0xff;
990 	clos_config->clos_desired = (resp >> 24) & 0xff;
991 
992 	return 0;
993 }
994 
995 int isst_set_clos(int cpu, int clos, struct isst_clos_config *clos_config)
996 {
997 	unsigned int req, resp;
998 	unsigned int param;
999 	int ret;
1000 
1001 	req = clos_config->epp & 0x0f;
1002 	req |= (clos_config->clos_prop_prio & 0x0f) << 4;
1003 	req |= (clos_config->clos_min & 0xff) << 8;
1004 	req |= (clos_config->clos_max & 0xff) << 16;
1005 	req |= (clos_config->clos_desired & 0xff) << 24;
1006 
1007 	param = BIT(MBOX_CMD_WRITE_BIT) | clos;
1008 
1009 	ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req,
1010 				     &resp);
1011 	if (ret)
1012 		return ret;
1013 
1014 	debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", cpu, param, req);
1015 
1016 	return 0;
1017 }
1018 
1019 int isst_clos_get_assoc_status(int cpu, int *clos_id)
1020 {
1021 	unsigned int resp;
1022 	unsigned int param;
1023 	int core_id, ret;
1024 
1025 	core_id = find_phy_core_num(cpu);
1026 	param = core_id;
1027 
1028 	ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0,
1029 				     &resp);
1030 	if (ret)
1031 		return ret;
1032 
1033 	debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", cpu, param,
1034 		     resp);
1035 	*clos_id = (resp >> 16) & 0x03;
1036 
1037 	return 0;
1038 }
1039 
1040 int isst_clos_associate(int cpu, int clos_id)
1041 {
1042 	unsigned int req, resp;
1043 	unsigned int param;
1044 	int core_id, ret;
1045 
1046 	req = (clos_id & 0x03) << 16;
1047 	core_id = find_phy_core_num(cpu);
1048 	param = BIT(MBOX_CMD_WRITE_BIT) | core_id;
1049 
1050 	ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param,
1051 				     req, &resp);
1052 	if (ret)
1053 		return ret;
1054 
1055 	debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", cpu, param,
1056 		     req);
1057 
1058 	return 0;
1059 }
1060