2f3921cd87f32802feb7996f88a6a3fb5121d8b7
[linux-2.6-microblaze.git] / tools / power / x86 / intel-speed-select / isst-core.c
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         int i, ret, core_cnt, max;
398         unsigned int req, resp;
399
400         pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask);
401
402         core_cnt = get_core_count(get_physical_package_id(cpu), get_physical_die_id(cpu));
403         max = core_cnt > 32 ? 2 : 1;
404
405         for (i = 0; i < max; ++i) {
406                 unsigned long long mask;
407                 int count;
408
409                 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
410                                              CONFIG_TDP_PBF_GET_CORE_MASK_INFO,
411                                              0, (i << 8) | level, &resp);
412                 if (ret)
413                         break;
414
415                 debug_printf(
416                         "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n",
417                         cpu, resp);
418
419                 mask = (unsigned long long)resp << (32 * i);
420                 set_cpu_mask_from_punit_coremask(cpu, mask,
421                                                  pbf_info->core_cpumask_size,
422                                                  pbf_info->core_cpumask,
423                                                  &count);
424         }
425
426         req = level;
427         ret = isst_send_mbox_command(cpu, CONFIG_TDP,
428                                      CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req,
429                                      &resp);
430         if (ret)
431                 return ret;
432
433         debug_printf("cpu:%d CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO resp:%x\n", cpu,
434                      resp);
435
436         pbf_info->p1_low = resp & 0xff;
437         pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8;
438
439         req = level;
440         ret = isst_send_mbox_command(
441                 cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp);
442         if (ret)
443                 return ret;
444
445         debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TDP_INFO resp:%x\n", cpu, resp);
446
447         pbf_info->tdp = resp & 0xffff;
448
449         req = level;
450         ret = isst_send_mbox_command(
451                 cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp);
452         if (ret)
453                 return ret;
454
455         debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TJ_MAX_INFO resp:%x\n", cpu,
456                      resp);
457         pbf_info->t_control = (resp >> 8) & 0xff;
458         pbf_info->t_prochot = resp & 0xff;
459
460         return 0;
461 }
462
463 void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info)
464 {
465         free_cpu_set(pbf_info->core_cpumask);
466 }
467
468 int isst_set_pbf_fact_status(int cpu, int pbf, int enable)
469 {
470         struct isst_pkg_ctdp pkg_dev;
471         struct isst_pkg_ctdp_level_info ctdp_level;
472         int current_level;
473         unsigned int req = 0, resp;
474         int ret;
475
476         ret = isst_get_ctdp_levels(cpu, &pkg_dev);
477         if (ret)
478                 debug_printf("cpu:%d No support for dynamic ISST\n", cpu);
479
480         current_level = pkg_dev.current_level;
481
482         ret = isst_get_ctdp_control(cpu, current_level, &ctdp_level);
483         if (ret)
484                 return ret;
485
486         if (pbf) {
487                 if (ctdp_level.fact_enabled)
488                         req = BIT(16);
489
490                 if (enable)
491                         req |= BIT(17);
492                 else
493                         req &= ~BIT(17);
494         } else {
495                 if (ctdp_level.pbf_enabled)
496                         req = BIT(17);
497
498                 if (enable)
499                         req |= BIT(16);
500                 else
501                         req &= ~BIT(16);
502         }
503
504         ret = isst_send_mbox_command(cpu, CONFIG_TDP,
505                                      CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp);
506         if (ret)
507                 return ret;
508
509         debug_printf("cpu:%d CONFIG_TDP_SET_TDP_CONTROL pbf/fact:%d req:%x\n",
510                      cpu, pbf, req);
511
512         return 0;
513 }
514
515 int isst_get_fact_bucket_info(int cpu, int level,
516                               struct isst_fact_bucket_info *bucket_info)
517 {
518         unsigned int resp;
519         int i, k, ret;
520
521         for (i = 0; i < 2; ++i) {
522                 int j;
523
524                 ret = isst_send_mbox_command(
525                         cpu, CONFIG_TDP,
526                         CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0,
527                         (i << 8) | level, &resp);
528                 if (ret)
529                         return ret;
530
531                 debug_printf(
532                         "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES index:%d level:%d resp:%x\n",
533                         cpu, i, level, resp);
534
535                 for (j = 0; j < 4; ++j) {
536                         bucket_info[j + (i * 4)].high_priority_cores_count =
537                                 (resp >> (j * 8)) & 0xff;
538                 }
539         }
540
541         for (k = 0; k < 3; ++k) {
542                 for (i = 0; i < 2; ++i) {
543                         int j;
544
545                         ret = isst_send_mbox_command(
546                                 cpu, CONFIG_TDP,
547                                 CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0,
548                                 (k << 16) | (i << 8) | level, &resp);
549                         if (ret)
550                                 return ret;
551
552                         debug_printf(
553                                 "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS index:%d level:%d avx:%d resp:%x\n",
554                                 cpu, i, level, k, resp);
555
556                         for (j = 0; j < 4; ++j) {
557                                 switch (k) {
558                                 case 0:
559                                         bucket_info[j + (i * 4)].sse_trl =
560                                                 (resp >> (j * 8)) & 0xff;
561                                         break;
562                                 case 1:
563                                         bucket_info[j + (i * 4)].avx_trl =
564                                                 (resp >> (j * 8)) & 0xff;
565                                         break;
566                                 case 2:
567                                         bucket_info[j + (i * 4)].avx512_trl =
568                                                 (resp >> (j * 8)) & 0xff;
569                                         break;
570                                 default:
571                                         break;
572                                 }
573                         }
574                 }
575         }
576
577         return 0;
578 }
579
580 int isst_get_fact_info(int cpu, int level, struct isst_fact_info *fact_info)
581 {
582         unsigned int resp;
583         int ret;
584
585         ret = isst_send_mbox_command(cpu, CONFIG_TDP,
586                                      CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0,
587                                      level, &resp);
588         if (ret)
589                 return ret;
590
591         debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n",
592                      cpu, resp);
593
594         fact_info->lp_clipping_ratio_license_sse = resp & 0xff;
595         fact_info->lp_clipping_ratio_license_avx2 = (resp >> 8) & 0xff;
596         fact_info->lp_clipping_ratio_license_avx512 = (resp >> 16) & 0xff;
597
598         ret = isst_get_fact_bucket_info(cpu, level, fact_info->bucket_info);
599
600         return ret;
601 }
602
603 int isst_set_trl(int cpu, unsigned long long trl)
604 {
605         int ret;
606
607         if (!trl)
608                 trl = 0xFFFFFFFFFFFFFFFFULL;
609
610         ret = isst_send_msr_command(cpu, 0x1AD, 1, &trl);
611         if (ret)
612                 return ret;
613
614         return 0;
615 }
616
617 int isst_set_trl_from_current_tdp(int cpu, unsigned long long trl)
618 {
619         unsigned long long msr_trl;
620         int ret;
621
622         if (trl) {
623                 msr_trl = trl;
624         } else {
625                 struct isst_pkg_ctdp pkg_dev;
626                 int trl[8];
627                 int i;
628
629                 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
630                 if (ret)
631                         return ret;
632
633                 ret = isst_get_get_trl(cpu, pkg_dev.current_level, 0, trl);
634                 if (ret)
635                         return ret;
636
637                 msr_trl = 0;
638                 for (i = 0; i < 8; ++i) {
639                         unsigned long long _trl = trl[i];
640
641                         msr_trl |= (_trl << (i * 8));
642                 }
643         }
644         ret = isst_send_msr_command(cpu, 0x1AD, 1, &msr_trl);
645         if (ret)
646                 return ret;
647
648         return 0;
649 }
650
651 /* Return 1 if locked */
652 int isst_get_config_tdp_lock_status(int cpu)
653 {
654         unsigned long long tdp_control = 0;
655         int ret;
656
657         ret = isst_send_msr_command(cpu, 0x64b, 0, &tdp_control);
658         if (ret)
659                 return ret;
660
661         ret = !!(tdp_control & BIT(31));
662
663         return ret;
664 }
665
666 void isst_get_process_ctdp_complete(int cpu, struct isst_pkg_ctdp *pkg_dev)
667 {
668         int i;
669
670         if (!pkg_dev->processed)
671                 return;
672
673         for (i = 0; i < pkg_dev->levels; ++i) {
674                 struct isst_pkg_ctdp_level_info *ctdp_level;
675
676                 ctdp_level = &pkg_dev->ctdp_level[i];
677                 if (ctdp_level->pbf_support)
678                         free_cpu_set(ctdp_level->pbf_info.core_cpumask);
679                 free_cpu_set(ctdp_level->core_cpumask);
680         }
681 }
682
683 int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
684 {
685         int i, ret, valid = 0;
686
687         if (pkg_dev->processed)
688                 return 0;
689
690         ret = isst_get_ctdp_levels(cpu, pkg_dev);
691         if (ret)
692                 return ret;
693
694         debug_printf("cpu: %d ctdp enable:%d current level: %d levels:%d\n",
695                      cpu, pkg_dev->enabled, pkg_dev->current_level,
696                      pkg_dev->levels);
697
698         if (tdp_level != 0xff && tdp_level > pkg_dev->levels) {
699                 isst_display_error_info_message(1, "Invalid level", 0, 0);
700                 return -1;
701         }
702
703         if (!pkg_dev->enabled)
704                 isst_display_error_info_message(0, "perf-profile feature is not supported, just base-config level 0 is valid", 0, 0);
705
706         for (i = 0; i <= pkg_dev->levels; ++i) {
707                 struct isst_pkg_ctdp_level_info *ctdp_level;
708
709                 if (tdp_level != 0xff && i != tdp_level)
710                         continue;
711
712                 debug_printf("cpu:%d Get Information for TDP level:%d\n", cpu,
713                              i);
714                 ctdp_level = &pkg_dev->ctdp_level[i];
715
716                 ctdp_level->level = i;
717                 ctdp_level->control_cpu = cpu;
718                 ctdp_level->pkg_id = get_physical_package_id(cpu);
719                 ctdp_level->die_id = get_physical_die_id(cpu);
720
721                 ret = isst_get_ctdp_control(cpu, i, ctdp_level);
722                 if (ret)
723                         continue;
724
725                 valid = 1;
726                 pkg_dev->processed = 1;
727                 ctdp_level->processed = 1;
728
729                 if (ctdp_level->pbf_support) {
730                         ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info);
731                         if (!ret)
732                                 ctdp_level->pbf_found = 1;
733                 }
734
735                 if (ctdp_level->fact_support) {
736                         ret = isst_get_fact_info(cpu, i,
737                                                  &ctdp_level->fact_info);
738                         if (ret)
739                                 return ret;
740                 }
741
742                 if (!pkg_dev->enabled) {
743                         int freq;
744
745                         freq = get_cpufreq_base_freq(cpu);
746                         if (freq > 0) {
747                                 ctdp_level->sse_p1 = freq / 100000;
748                                 ctdp_level->tdp_ratio = ctdp_level->sse_p1;
749                         }
750
751                         isst_get_get_trl_from_msr(cpu, ctdp_level->trl_sse_active_cores);
752                         isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info);
753                         continue;
754                 }
755
756                 ret = isst_get_tdp_info(cpu, i, ctdp_level);
757                 if (ret)
758                         return ret;
759
760                 ret = isst_get_pwr_info(cpu, i, ctdp_level);
761                 if (ret)
762                         return ret;
763
764                 ret = isst_get_tjmax_info(cpu, i, ctdp_level);
765                 if (ret)
766                         return ret;
767
768                 ctdp_level->core_cpumask_size =
769                         alloc_cpu_set(&ctdp_level->core_cpumask);
770                 ret = isst_get_coremask_info(cpu, i, ctdp_level);
771                 if (ret)
772                         return ret;
773
774                 ret = isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info);
775                 if (ret)
776                         return ret;
777
778                 ret = isst_get_get_trl(cpu, i, 0,
779                                        ctdp_level->trl_sse_active_cores);
780                 if (ret)
781                         return ret;
782
783                 ret = isst_get_get_trl(cpu, i, 1,
784                                        ctdp_level->trl_avx_active_cores);
785                 if (ret)
786                         return ret;
787
788                 ret = isst_get_get_trl(cpu, i, 2,
789                                        ctdp_level->trl_avx_512_active_cores);
790                 if (ret)
791                         return ret;
792
793                 isst_get_uncore_p0_p1_info(cpu, i, ctdp_level);
794                 isst_get_p1_info(cpu, i, ctdp_level);
795                 isst_get_uncore_mem_freq(cpu, i, ctdp_level);
796         }
797
798         if (!valid)
799                 isst_display_error_info_message(0, "Invalid level, Can't get TDP control information at specified levels on cpu", 1, cpu);
800
801         return 0;
802 }
803
804 int isst_clos_get_clos_information(int cpu, int *enable, int *type)
805 {
806         unsigned int resp;
807         int ret;
808
809         ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
810                                      &resp);
811         if (ret)
812                 return ret;
813
814         debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp);
815
816         if (resp & BIT(1))
817                 *enable = 1;
818         else
819                 *enable = 0;
820
821         if (resp & BIT(2))
822                 *type = 1;
823         else
824                 *type = 0;
825
826         return 0;
827 }
828
829 int isst_pm_qos_config(int cpu, int enable_clos, int priority_type)
830 {
831         unsigned int req, resp;
832         int ret;
833
834         if (!enable_clos) {
835                 struct isst_pkg_ctdp pkg_dev;
836                 struct isst_pkg_ctdp_level_info ctdp_level;
837
838                 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
839                 if (ret) {
840                         debug_printf("isst_get_ctdp_levels\n");
841                         return ret;
842                 }
843
844                 ret = isst_get_ctdp_control(cpu, pkg_dev.current_level,
845                                             &ctdp_level);
846                 if (ret)
847                         return ret;
848
849                 if (ctdp_level.fact_enabled) {
850                         debug_printf("Turbo-freq feature must be disabled first\n");
851                         return -EINVAL;
852                 }
853                 ret = isst_write_pm_config(cpu, 0);
854                 if (ret)
855                         perror("isst_write_pm_config\n");
856         } else {
857                 ret = isst_write_pm_config(cpu, 1);
858                 if (ret)
859                         perror("isst_write_pm_config\n");
860         }
861
862         ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
863                                      &resp);
864         if (ret)
865                 return ret;
866
867         debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp);
868
869         req = resp;
870
871         if (enable_clos)
872                 req = req | BIT(1);
873         else
874                 req = req & ~BIT(1);
875
876         if (priority_type)
877                 req = req | BIT(2);
878         else
879                 req = req & ~BIT(2);
880
881         ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG,
882                                      BIT(MBOX_CMD_WRITE_BIT), req, &resp);
883         if (ret)
884                 return ret;
885
886         debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", cpu,
887                      priority_type, req);
888
889         return 0;
890 }
891
892 int isst_pm_get_clos(int cpu, int clos, struct isst_clos_config *clos_config)
893 {
894         unsigned int resp;
895         int ret;
896
897         ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0,
898                                      &resp);
899         if (ret)
900                 return ret;
901
902         clos_config->pkg_id = get_physical_package_id(cpu);
903         clos_config->die_id = get_physical_die_id(cpu);
904
905         clos_config->epp = resp & 0x0f;
906         clos_config->clos_prop_prio = (resp >> 4) & 0x0f;
907         clos_config->clos_min = (resp >> 8) & 0xff;
908         clos_config->clos_max = (resp >> 16) & 0xff;
909         clos_config->clos_desired = (resp >> 24) & 0xff;
910
911         return 0;
912 }
913
914 int isst_set_clos(int cpu, int clos, struct isst_clos_config *clos_config)
915 {
916         unsigned int req, resp;
917         unsigned int param;
918         int ret;
919
920         req = clos_config->epp & 0x0f;
921         req |= (clos_config->clos_prop_prio & 0x0f) << 4;
922         req |= (clos_config->clos_min & 0xff) << 8;
923         req |= (clos_config->clos_max & 0xff) << 16;
924         req |= (clos_config->clos_desired & 0xff) << 24;
925
926         param = BIT(MBOX_CMD_WRITE_BIT) | clos;
927
928         ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req,
929                                      &resp);
930         if (ret)
931                 return ret;
932
933         debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", cpu, param, req);
934
935         return 0;
936 }
937
938 int isst_clos_get_assoc_status(int cpu, int *clos_id)
939 {
940         unsigned int resp;
941         unsigned int param;
942         int core_id, ret;
943
944         core_id = find_phy_core_num(cpu);
945         param = core_id;
946
947         ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0,
948                                      &resp);
949         if (ret)
950                 return ret;
951
952         debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", cpu, param,
953                      resp);
954         *clos_id = (resp >> 16) & 0x03;
955
956         return 0;
957 }
958
959 int isst_clos_associate(int cpu, int clos_id)
960 {
961         unsigned int req, resp;
962         unsigned int param;
963         int core_id, ret;
964
965         req = (clos_id & 0x03) << 16;
966         core_id = find_phy_core_num(cpu);
967         param = BIT(MBOX_CMD_WRITE_BIT) | core_id;
968
969         ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param,
970                                      req, &resp);
971         if (ret)
972                 return ret;
973
974         debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", cpu, param,
975                      req);
976
977         return 0;
978 }