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