interconnect: Add a common standard aggregate function
[linux/fpc-iii.git] / tools / power / x86 / intel-speed-select / isst-core.c
blobd14c7bcd327af1c17ae947027c39684ac10bbb98
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Intel Speed Select -- Enumerate and control features
4 * Copyright (c) 2019 Intel Corporation.
5 */
7 #include "isst.h"
9 int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev)
11 unsigned int resp;
12 int ret;
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;
25 debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", cpu, resp);
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));
33 return 0;
36 int isst_get_ctdp_control(int cpu, int config_index,
37 struct isst_pkg_ctdp_level_info *ctdp_level)
39 unsigned int resp;
40 int ret;
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;
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));
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);
58 return 0;
61 int isst_get_tdp_info(int cpu, int config_index,
62 struct isst_pkg_ctdp_level_info *ctdp_level)
64 unsigned int resp;
65 int ret;
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;
72 ctdp_level->pkg_tdp = resp & GENMASK(14, 0);
73 ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16;
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;
82 int isst_get_pwr_info(int cpu, int config_index,
83 struct isst_pkg_ctdp_level_info *ctdp_level)
85 unsigned int resp;
86 int ret;
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;
93 ctdp_level->pkg_max_power = resp & GENMASK(14, 0);
94 ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16;
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);
101 return 0;
104 void isst_get_uncore_p0_p1_info(int cpu, int config_index,
105 struct isst_pkg_ctdp_level_info *ctdp_level)
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;
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);
126 void isst_get_p1_info(int cpu, int config_index,
127 struct isst_pkg_ctdp_level_info *ctdp_level)
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;
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);
149 void isst_get_uncore_mem_freq(int cpu, int config_index,
150 struct isst_pkg_ctdp_level_info *ctdp_level)
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;
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);
167 int isst_get_tjmax_info(int cpu, int config_index,
168 struct isst_pkg_ctdp_level_info *ctdp_level)
170 unsigned int resp;
171 int ret;
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;
178 ctdp_level->t_proc_hot = resp & GENMASK(7, 0);
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);
184 return 0;
187 int isst_get_coremask_info(int cpu, int config_index,
188 struct isst_pkg_ctdp_level_info *ctdp_level)
190 unsigned int resp;
191 int i, ret;
193 ctdp_level->cpu_count = 0;
194 for (i = 0; i < 2; ++i) {
195 unsigned long long mask;
196 int cpu_count = 0;
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;
204 debug_printf(
205 "cpu:%d ctdp:%d mask:%d CONFIG_TDP_GET_CORE_MASK resp:%x\n",
206 cpu, config_index, i, resp);
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);
218 return 0;
221 int isst_get_get_trl_from_msr(int cpu, int *trl)
223 unsigned long long msr_trl;
224 int ret;
226 ret = isst_send_msr_command(cpu, 0x1AD, 0, &msr_trl);
227 if (ret)
228 return ret;
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;
239 return 0;
242 int isst_get_get_trl(int cpu, int level, int avx_level, int *trl)
244 unsigned int req, resp;
245 int ret;
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;
254 debug_printf(
255 "cpu:%d CONFIG_TDP_GET_TURBO_LIMIT_RATIOS req:%x resp:%x\n",
256 cpu, req, resp);
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;
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;
270 debug_printf("cpu:%d CONFIG_TDP_GET_TURBO_LIMIT req:%x resp:%x\n", cpu,
271 req, resp);
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;
278 return 0;
281 int isst_get_trl_bucket_info(int cpu, unsigned long long *buckets_info)
283 int ret;
285 debug_printf("cpu:%d bucket info via MSR\n", cpu);
287 *buckets_info = 0;
289 ret = isst_send_msr_command(cpu, 0x1ae, 0, buckets_info);
290 if (ret)
291 return ret;
293 debug_printf("cpu:%d bucket info via MSR successful 0x%llx\n", cpu,
294 *buckets_info);
296 return 0;
299 int isst_set_tdp_level_msr(int cpu, int tdp_level)
301 unsigned long long level = tdp_level;
302 int ret;
304 debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level);
306 if (isst_get_config_tdp_lock_status(cpu)) {
307 debug_printf("cpu: tdp_locked %d\n", cpu);
308 return -1;
311 if (tdp_level > 2)
312 return -1; /* invalid value */
314 ret = isst_send_msr_command(cpu, 0x64b, 1, &level);
315 if (ret)
316 return ret;
318 debug_printf("cpu: tdp_level via MSR successful %d\n", cpu, tdp_level);
320 return 0;
323 int isst_set_tdp_level(int cpu, int tdp_level)
325 unsigned int resp;
326 int ret;
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);
333 return 0;
336 int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info)
338 int i, ret, core_cnt, max;
339 unsigned int req, resp;
341 pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask);
343 core_cnt = get_core_count(get_physical_package_id(cpu), get_physical_die_id(cpu));
344 max = core_cnt > 32 ? 2 : 1;
346 for (i = 0; i < max; ++i) {
347 unsigned long long mask;
348 int count;
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;
356 debug_printf(
357 "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n",
358 cpu, resp);
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);
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;
374 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO resp:%x\n", cpu,
375 resp);
377 pbf_info->p1_low = resp & 0xff;
378 pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8;
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;
386 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TDP_INFO resp:%x\n", cpu, resp);
388 pbf_info->tdp = resp & 0xffff;
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;
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;
401 return 0;
404 void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info)
406 free_cpu_set(pbf_info->core_cpumask);
409 int isst_set_pbf_fact_status(int cpu, int pbf, int enable)
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;
417 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
418 if (ret)
419 debug_printf("cpu:%d No support for dynamic ISST\n", cpu);
421 current_level = pkg_dev.current_level;
423 ret = isst_get_ctdp_control(cpu, current_level, &ctdp_level);
424 if (ret)
425 return ret;
427 if (pbf) {
428 if (ctdp_level.fact_enabled)
429 req = BIT(16);
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);
439 if (enable)
440 req |= BIT(16);
441 else
442 req &= ~BIT(16);
445 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
446 CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp);
447 if (ret)
448 return ret;
450 debug_printf("cpu:%d CONFIG_TDP_SET_TDP_CONTROL pbf/fact:%d req:%x\n",
451 cpu, pbf, req);
453 return 0;
456 int isst_get_fact_bucket_info(int cpu, int level,
457 struct isst_fact_bucket_info *bucket_info)
459 unsigned int resp;
460 int i, k, ret;
462 for (i = 0; i < 2; ++i) {
463 int j;
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;
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);
476 for (j = 0; j < 4; ++j) {
477 bucket_info[j + (i * 4)].high_priority_cores_count =
478 (resp >> (j * 8)) & 0xff;
482 for (k = 0; k < 3; ++k) {
483 for (i = 0; i < 2; ++i) {
484 int j;
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;
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);
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;
518 return 0;
521 int isst_get_fact_info(int cpu, int level, struct isst_fact_info *fact_info)
523 unsigned int resp;
524 int ret;
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;
532 debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n",
533 cpu, resp);
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;
539 ret = isst_get_fact_bucket_info(cpu, level, fact_info->bucket_info);
541 return ret;
544 int isst_set_trl(int cpu, unsigned long long trl)
546 int ret;
548 if (!trl)
549 trl = 0xFFFFFFFFFFFFFFFFULL;
551 ret = isst_send_msr_command(cpu, 0x1AD, 1, &trl);
552 if (ret)
553 return ret;
555 return 0;
558 int isst_set_trl_from_current_tdp(int cpu, unsigned long long trl)
560 unsigned long long msr_trl;
561 int ret;
563 if (trl) {
564 msr_trl = trl;
565 } else {
566 struct isst_pkg_ctdp pkg_dev;
567 int trl[8];
568 int i;
570 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
571 if (ret)
572 return ret;
574 ret = isst_get_get_trl(cpu, pkg_dev.current_level, 0, trl);
575 if (ret)
576 return ret;
578 msr_trl = 0;
579 for (i = 0; i < 8; ++i) {
580 unsigned long long _trl = trl[i];
582 msr_trl |= (_trl << (i * 8));
585 ret = isst_send_msr_command(cpu, 0x1AD, 1, &msr_trl);
586 if (ret)
587 return ret;
589 return 0;
592 /* Return 1 if locked */
593 int isst_get_config_tdp_lock_status(int cpu)
595 unsigned long long tdp_control = 0;
596 int ret;
598 ret = isst_send_msr_command(cpu, 0x64b, 0, &tdp_control);
599 if (ret)
600 return ret;
602 ret = !!(tdp_control & BIT(31));
604 return ret;
607 void isst_get_process_ctdp_complete(int cpu, struct isst_pkg_ctdp *pkg_dev)
609 int i;
611 if (!pkg_dev->processed)
612 return;
614 for (i = 0; i < pkg_dev->levels; ++i) {
615 struct isst_pkg_ctdp_level_info *ctdp_level;
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);
624 int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
626 int i, ret;
628 if (pkg_dev->processed)
629 return 0;
631 ret = isst_get_ctdp_levels(cpu, pkg_dev);
632 if (ret)
633 return ret;
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);
639 for (i = 0; i <= pkg_dev->levels; ++i) {
640 struct isst_pkg_ctdp_level_info *ctdp_level;
642 if (tdp_level != 0xff && i != tdp_level)
643 continue;
645 debug_printf("cpu:%d Get Information for TDP level:%d\n", cpu,
647 ctdp_level = &pkg_dev->ctdp_level[i];
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);
654 ret = isst_get_ctdp_control(cpu, i, ctdp_level);
655 if (ret)
656 continue;
658 pkg_dev->processed = 1;
659 ctdp_level->processed = 1;
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;
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;
674 if (!pkg_dev->enabled) {
675 int freq;
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;
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;
688 ret = isst_get_tdp_info(cpu, i, ctdp_level);
689 if (ret)
690 return ret;
692 ret = isst_get_pwr_info(cpu, i, ctdp_level);
693 if (ret)
694 return ret;
696 ret = isst_get_tjmax_info(cpu, i, ctdp_level);
697 if (ret)
698 return ret;
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;
706 ret = isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info);
707 if (ret)
708 return ret;
710 ret = isst_get_get_trl(cpu, i, 0,
711 ctdp_level->trl_sse_active_cores);
712 if (ret)
713 return ret;
715 ret = isst_get_get_trl(cpu, i, 1,
716 ctdp_level->trl_avx_active_cores);
717 if (ret)
718 return ret;
720 ret = isst_get_get_trl(cpu, i, 2,
721 ctdp_level->trl_avx_512_active_cores);
722 if (ret)
723 return ret;
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);
730 return 0;
733 int isst_clos_get_clos_information(int cpu, int *enable, int *type)
735 unsigned int resp;
736 int ret;
738 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
739 &resp);
740 if (ret)
741 return ret;
743 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp);
745 if (resp & BIT(1))
746 *enable = 1;
747 else
748 *enable = 0;
750 if (resp & BIT(2))
751 *type = 1;
752 else
753 *type = 0;
755 return 0;
758 int isst_pm_qos_config(int cpu, int enable_clos, int priority_type)
760 unsigned int req, resp;
761 int ret;
763 if (!enable_clos) {
764 struct isst_pkg_ctdp pkg_dev;
765 struct isst_pkg_ctdp_level_info ctdp_level;
767 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
768 if (ret) {
769 debug_printf("isst_get_ctdp_levels\n");
770 return ret;
773 ret = isst_get_ctdp_control(cpu, pkg_dev.current_level,
774 &ctdp_level);
775 if (ret)
776 return ret;
778 if (ctdp_level.fact_enabled) {
779 debug_printf("Turbo-freq feature must be disabled first\n");
780 return -EINVAL;
784 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
785 &resp);
786 if (ret)
787 return ret;
789 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp);
791 req = resp;
793 if (enable_clos)
794 req = req | BIT(1);
795 else
796 req = req & ~BIT(1);
798 if (priority_type)
799 req = req | BIT(2);
800 else
801 req = req & ~BIT(2);
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;
808 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", cpu,
809 priority_type, req);
811 return 0;
814 int isst_pm_get_clos(int cpu, int clos, struct isst_clos_config *clos_config)
816 unsigned int resp;
817 int ret;
819 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0,
820 &resp);
821 if (ret)
822 return ret;
824 clos_config->pkg_id = get_physical_package_id(cpu);
825 clos_config->die_id = get_physical_die_id(cpu);
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;
833 return 0;
836 int isst_set_clos(int cpu, int clos, struct isst_clos_config *clos_config)
838 unsigned int req, resp;
839 unsigned int param;
840 int ret;
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;
848 param = BIT(MBOX_CMD_WRITE_BIT) | clos;
850 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req,
851 &resp);
852 if (ret)
853 return ret;
855 debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", cpu, param, req);
857 return 0;
860 int isst_clos_get_assoc_status(int cpu, int *clos_id)
862 unsigned int resp;
863 unsigned int param;
864 int core_id, ret;
866 core_id = find_phy_core_num(cpu);
867 param = core_id;
869 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0,
870 &resp);
871 if (ret)
872 return ret;
874 debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", cpu, param,
875 resp);
876 *clos_id = (resp >> 16) & 0x03;
878 return 0;
881 int isst_clos_associate(int cpu, int clos_id)
883 unsigned int req, resp;
884 unsigned int param;
885 int core_id, ret;
887 req = (clos_id & 0x03) << 16;
888 core_id = find_phy_core_num(cpu);
889 param = BIT(MBOX_CMD_WRITE_BIT) | core_id;
891 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param,
892 req, &resp);
893 if (ret)
894 return ret;
896 debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", cpu, param,
897 req);
899 return 0;