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