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