Linux 6.7-rc7
[linux-modified.git] / tools / power / x86 / intel-speed-select / isst-core-tpmi.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Intel Speed Select -- Enumerate and control features for TPMI Interface
4  * Copyright (c) 2022 Intel Corporation.
5  */
6
7 #include <linux/isst_if.h>
8 #include "isst.h"
9
10 int tpmi_process_ioctl(int ioctl_no, void *info)
11 {
12         const char *pathname = "/dev/isst_interface";
13         int fd;
14
15         if (is_debug_enabled()) {
16                 debug_printf("Issue IOCTL: ");
17                 switch (ioctl_no) {
18                 case ISST_IF_CORE_POWER_STATE:
19                         debug_printf("ISST_IF_CORE_POWER_STATE\n");
20                         break;
21                 case ISST_IF_CLOS_PARAM:
22                         debug_printf("ISST_IF_CLOS_PARAM\n");
23                         break;
24                 case ISST_IF_CLOS_ASSOC:
25                         debug_printf("ISST_IF_CLOS_ASSOC\n");
26                         break;
27                 case ISST_IF_PERF_LEVELS:
28                         debug_printf("ISST_IF_PERF_LEVELS\n");
29                         break;
30                 case ISST_IF_PERF_SET_LEVEL:
31                         debug_printf("ISST_IF_PERF_SET_LEVEL\n");
32                         break;
33                 case ISST_IF_PERF_SET_FEATURE:
34                         debug_printf("ISST_IF_PERF_SET_FEATURE\n");
35                         break;
36                 case ISST_IF_GET_PERF_LEVEL_INFO:
37                         debug_printf("ISST_IF_GET_PERF_LEVEL_INFO\n");
38                         break;
39                 case ISST_IF_GET_PERF_LEVEL_CPU_MASK:
40                         debug_printf("ISST_IF_GET_PERF_LEVEL_CPU_MASK\n");
41                         break;
42                 case ISST_IF_GET_BASE_FREQ_INFO:
43                         debug_printf("ISST_IF_GET_BASE_FREQ_INFO\n");
44                         break;
45                 case ISST_IF_GET_BASE_FREQ_CPU_MASK:
46                         debug_printf("ISST_IF_GET_BASE_FREQ_CPU_MASK\n");
47                         break;
48                 case ISST_IF_GET_TURBO_FREQ_INFO:
49                         debug_printf("ISST_IF_GET_TURBO_FREQ_INFO\n");
50                         break;
51                 case ISST_IF_COUNT_TPMI_INSTANCES:
52                         debug_printf("ISST_IF_COUNT_TPMI_INSTANCES\n");
53                         break;
54                 default:
55                         debug_printf("%d\n", ioctl_no);
56                         break;
57                 }
58         }
59
60         fd = open(pathname, O_RDWR);
61         if (fd < 0)
62                 return -1;
63
64         if (ioctl(fd, ioctl_no, info) == -1) {
65                 debug_printf("IOCTL %d Failed\n", ioctl_no);
66                 close(fd);
67                 return -1;
68         }
69
70         close(fd);
71
72         return 0;
73 }
74
75 static int tpmi_get_disp_freq_multiplier(void)
76 {
77         return 1;
78 }
79
80 static int tpmi_get_trl_max_levels(void)
81 {
82         return TRL_MAX_LEVELS;
83 }
84
85 static char *tpmi_get_trl_level_name(int level)
86 {
87         switch (level) {
88         case 0:
89                 return "level-0";
90         case 1:
91                 return "level-1";
92         case 2:
93                 return "level-2";
94         case 3:
95                 return "level-3";
96         case 4:
97                 return "level-4";
98         case 5:
99                 return "level-5";
100         case 6:
101                 return "level-6";
102         case 7:
103                 return "level-7";
104         default:
105                 return NULL;
106         }
107 }
108
109
110 static void tpmi_update_platform_param(enum isst_platform_param param, int value)
111 {
112         /* No params need to be updated for now */
113 }
114
115 static int tpmi_is_punit_valid(struct isst_id *id)
116 {
117         struct isst_tpmi_instance_count info;
118         int ret;
119
120         if (id->punit < 0)
121                 return 0;
122
123         info.socket_id = id->pkg;
124         ret = tpmi_process_ioctl(ISST_IF_COUNT_TPMI_INSTANCES, &info);
125         if (ret == -1)
126                 return 0;
127
128         if (info.valid_mask & BIT(id->punit))
129                 return 1;
130
131         return 0;
132 }
133
134 static int tpmi_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap)
135 {
136         struct isst_core_power info;
137         int ret;
138
139         info.get_set = 0;
140         info.socket_id = id->pkg;
141         info.power_domain_id = id->punit;
142         ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info);
143         if (ret == -1)
144                 return ret;
145
146         *cp_state = info.enable;
147         *cp_cap = info.supported;
148
149         return 0;
150 }
151
152 int tpmi_get_config_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev)
153 {
154         struct isst_perf_level_info info;
155         int ret;
156
157         info.socket_id = id->pkg;
158         info.power_domain_id = id->punit;
159
160         ret = tpmi_process_ioctl(ISST_IF_PERF_LEVELS, &info);
161         if (ret == -1)
162                 return ret;
163
164         pkg_dev->version = info.feature_rev;
165         pkg_dev->levels = info.max_level;
166         pkg_dev->locked = info.locked;
167         pkg_dev->current_level = info.current_level;
168         pkg_dev->locked = info.locked;
169         pkg_dev->enabled = info.enabled;
170
171         return 0;
172 }
173
174 static int tpmi_get_ctdp_control(struct isst_id *id, int config_index,
175                                  struct isst_pkg_ctdp_level_info *ctdp_level)
176 {
177         struct isst_core_power core_power_info;
178         struct isst_perf_level_info info;
179         int level_mask;
180         int ret;
181
182         info.socket_id = id->pkg;
183         info.power_domain_id = id->punit;
184
185         ret = tpmi_process_ioctl(ISST_IF_PERF_LEVELS, &info);
186         if (ret == -1)
187                 return -1;
188
189         if (config_index != 0xff)
190                 level_mask = 1 << config_index;
191         else
192                 level_mask = config_index;
193
194         if (!(info.level_mask & level_mask))
195                 return -1;
196
197         ctdp_level->fact_support = info.sst_tf_support;
198         ctdp_level->pbf_support = info.sst_bf_support;
199         ctdp_level->fact_enabled = !!(info.feature_state & BIT(1));
200         ctdp_level->pbf_enabled = !!(info.feature_state & BIT(0));
201
202         core_power_info.get_set = 0;
203         core_power_info.socket_id = id->pkg;
204         core_power_info.power_domain_id = id->punit;
205
206         ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &core_power_info);
207         if (ret == -1)
208                 return ret;
209
210         ctdp_level->sst_cp_support = core_power_info.supported;
211         ctdp_level->sst_cp_enabled = core_power_info.enable;
212
213         debug_printf
214             ("cpu:%d CONFIG_TDP_GET_TDP_CONTROL fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n",
215              id->cpu, ctdp_level->fact_support, ctdp_level->pbf_support,
216              ctdp_level->fact_enabled, ctdp_level->pbf_enabled);
217
218         return 0;
219 }
220
221 static int tpmi_get_tdp_info(struct isst_id *id, int config_index,
222                              struct isst_pkg_ctdp_level_info *ctdp_level)
223 {
224         struct isst_perf_level_data_info info;
225         int ret;
226
227         info.socket_id = id->pkg;
228         info.power_domain_id = id->punit;
229         info.level = config_index;
230
231         ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info);
232         if (ret == -1)
233                 return ret;
234
235         ctdp_level->pkg_tdp = info.thermal_design_power_w;
236         ctdp_level->tdp_ratio = info.tdp_ratio;
237         ctdp_level->sse_p1 = info.base_freq_mhz;
238         ctdp_level->avx2_p1 = info.base_freq_avx2_mhz;
239         ctdp_level->avx512_p1 = info.base_freq_avx512_mhz;
240         ctdp_level->amx_p1 = info.base_freq_amx_mhz;
241
242         ctdp_level->t_proc_hot = info.tjunction_max_c;
243         ctdp_level->mem_freq = info.max_memory_freq_mhz;
244         ctdp_level->cooling_type = info.cooling_type;
245
246         ctdp_level->uncore_p0 = info.p0_fabric_freq_mhz;
247         ctdp_level->uncore_p1 = info.p1_fabric_freq_mhz;
248         ctdp_level->uncore_pm = info.pm_fabric_freq_mhz;
249
250         debug_printf
251             ("cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO tdp_ratio:%d pkg_tdp:%d ctdp_level->t_proc_hot:%d\n",
252              id->cpu, config_index, ctdp_level->tdp_ratio, ctdp_level->pkg_tdp,
253              ctdp_level->t_proc_hot);
254
255         return 0;
256 }
257
258 static int tpmi_get_pwr_info(struct isst_id *id, int config_index,
259                              struct isst_pkg_ctdp_level_info *ctdp_level)
260 {
261         /* TBD */
262         ctdp_level->pkg_max_power = 0;
263         ctdp_level->pkg_min_power = 0;
264
265         debug_printf
266             ("cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO pkg_max_power:%d pkg_min_power:%d\n",
267              id->cpu, config_index, ctdp_level->pkg_max_power,
268              ctdp_level->pkg_min_power);
269
270         return 0;
271 }
272
273 int tpmi_get_coremask_info(struct isst_id *id, int config_index,
274                            struct isst_pkg_ctdp_level_info *ctdp_level)
275 {
276         struct isst_perf_level_cpu_mask info;
277         int ret, cpu_count;
278
279         info.socket_id = id->pkg;
280         info.power_domain_id = id->punit;
281         info.level = config_index;
282         info.punit_cpu_map = 1;
283
284         ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_CPU_MASK, &info);
285         if (ret == -1)
286                 return ret;
287
288         set_cpu_mask_from_punit_coremask(id, info.mask,
289                                          ctdp_level->core_cpumask_size,
290                                          ctdp_level->core_cpumask, &cpu_count);
291         ctdp_level->cpu_count = cpu_count;
292
293         debug_printf("cpu:%d ctdp:%d core_mask ino cpu count:%d\n",
294                      id->cpu, config_index, ctdp_level->cpu_count);
295
296         return 0;
297 }
298
299 static int tpmi_get_get_trls(struct isst_id *id, int config_index,
300                              struct isst_pkg_ctdp_level_info *ctdp_level)
301 {
302         struct isst_perf_level_data_info info;
303         int ret, i, j;
304
305         info.socket_id = id->pkg;
306         info.power_domain_id = id->punit;
307         info.level = config_index;
308
309         ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info);
310         if (ret == -1)
311                 return ret;
312
313         if (info.max_buckets > TRL_MAX_BUCKETS)
314                 info.max_buckets = TRL_MAX_BUCKETS;
315
316         if (info.max_trl_levels > TRL_MAX_LEVELS)
317                 info.max_trl_levels = TRL_MAX_LEVELS;
318
319         for (i = 0; i < info.max_trl_levels; ++i)
320                 for (j = 0; j < info.max_buckets; ++j)
321                         ctdp_level->trl_ratios[i][j] = info.trl_freq_mhz[i][j];
322
323         return 0;
324 }
325
326 static int tpmi_get_get_trl(struct isst_id *id, int level, int config_index,
327                             int *trl)
328 {
329         struct isst_pkg_ctdp_level_info ctdp_level;
330         int ret, i;
331
332         ret = tpmi_get_get_trls(id, config_index, &ctdp_level);
333         if (ret)
334                 return ret;
335
336         /* FIX ME: Just return for level 0 */
337         for (i = 0; i < 8; ++i)
338                 trl[i] = ctdp_level.trl_ratios[0][i];
339
340         return 0;
341 }
342
343 static int tpmi_get_trl_bucket_info(struct isst_id *id, int config_index,
344                                     unsigned long long *buckets_info)
345 {
346         struct isst_perf_level_data_info info;
347         unsigned char *mask = (unsigned char *)buckets_info;
348         int ret, i;
349
350         info.socket_id = id->pkg;
351         info.power_domain_id = id->punit;
352         info.level = config_index;
353
354         ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info);
355         if (ret == -1)
356                 return ret;
357
358         if (info.max_buckets > TRL_MAX_BUCKETS)
359                 info.max_buckets = TRL_MAX_BUCKETS;
360
361         for (i = 0; i < info.max_buckets; ++i)
362                 mask[i] = info.bucket_core_counts[i];
363
364         debug_printf("cpu:%d TRL bucket info: 0x%llx\n", id->cpu,
365                      *buckets_info);
366
367         return 0;
368 }
369
370 static int tpmi_set_tdp_level(struct isst_id *id, int tdp_level)
371 {
372         struct isst_perf_level_control info;
373         int ret;
374
375         info.socket_id = id->pkg;
376         info.power_domain_id = id->punit;
377         info.level = tdp_level;
378
379         ret = tpmi_process_ioctl(ISST_IF_PERF_SET_LEVEL, &info);
380         if (ret == -1)
381                 return ret;
382
383         return 0;
384 }
385
386 static int _pbf_get_coremask_info(struct isst_id *id, int config_index,
387                                   struct isst_pbf_info *pbf_info)
388 {
389         struct isst_perf_level_cpu_mask info;
390         int ret, cpu_count;
391
392         info.socket_id = id->pkg;
393         info.power_domain_id = id->punit;
394         info.level = config_index;
395         info.punit_cpu_map = 1;
396
397         ret = tpmi_process_ioctl(ISST_IF_GET_BASE_FREQ_CPU_MASK, &info);
398         if (ret == -1)
399                 return ret;
400
401         set_cpu_mask_from_punit_coremask(id, info.mask,
402                                          pbf_info->core_cpumask_size,
403                                          pbf_info->core_cpumask, &cpu_count);
404
405         debug_printf("cpu:%d ctdp:%d pbf core_mask info cpu count:%d\n",
406                      id->cpu, config_index, cpu_count);
407
408         return 0;
409 }
410
411 static int tpmi_get_pbf_info(struct isst_id *id, int level,
412                              struct isst_pbf_info *pbf_info)
413 {
414         struct isst_base_freq_info info;
415         int ret;
416
417         info.socket_id = id->pkg;
418         info.power_domain_id = id->punit;
419         info.level = level;
420
421         ret = tpmi_process_ioctl(ISST_IF_GET_BASE_FREQ_INFO, &info);
422         if (ret == -1)
423                 return ret;
424
425         pbf_info->p1_low = info.low_base_freq_mhz;
426         pbf_info->p1_high = info.high_base_freq_mhz;
427         pbf_info->tdp = info.thermal_design_power_w;
428         pbf_info->t_prochot = info.tjunction_max_c;
429
430         debug_printf("cpu:%d ctdp:%d pbf info:%d:%d:%d:%d\n",
431                      id->cpu, level, pbf_info->p1_low, pbf_info->p1_high,
432                      pbf_info->tdp, pbf_info->t_prochot);
433
434         return _pbf_get_coremask_info(id, level, pbf_info);
435 }
436
437 static int tpmi_set_pbf_fact_status(struct isst_id *id, int pbf, int enable)
438 {
439         struct isst_pkg_ctdp pkg_dev;
440         struct isst_pkg_ctdp_level_info ctdp_level;
441         int current_level;
442         struct isst_perf_feature_control info;
443         int ret;
444
445         ret = isst_get_ctdp_levels(id, &pkg_dev);
446         if (ret)
447                 debug_printf("cpu:%d No support for dynamic ISST\n", id->cpu);
448
449         current_level = pkg_dev.current_level;
450
451         ret = isst_get_ctdp_control(id, current_level, &ctdp_level);
452         if (ret)
453                 return ret;
454
455         info.socket_id = id->pkg;
456         info.power_domain_id = id->punit;
457
458         info.feature = 0;
459
460         if (pbf) {
461                 if (ctdp_level.fact_enabled)
462                         info.feature |= BIT(1);
463
464                 if (enable)
465                         info.feature |= BIT(0);
466                 else
467                         info.feature &= ~BIT(0);
468         } else {
469
470                 if (enable && !ctdp_level.sst_cp_enabled)
471                         isst_display_error_info_message(0,
472                                                         "Make sure to execute before: core-power enable",
473                                                         0, 0);
474
475                 if (ctdp_level.pbf_enabled)
476                         info.feature |= BIT(0);
477
478                 if (enable)
479                         info.feature |= BIT(1);
480                 else
481                         info.feature &= ~BIT(1);
482         }
483
484         ret = tpmi_process_ioctl(ISST_IF_PERF_SET_FEATURE, &info);
485         if (ret == -1)
486                 return ret;
487
488         return 0;
489 }
490
491 static int tpmi_get_fact_info(struct isst_id *id, int level, int fact_bucket,
492                               struct isst_fact_info *fact_info)
493 {
494         struct isst_turbo_freq_info info;
495         int i, j;
496         int ret;
497
498         info.socket_id = id->pkg;
499         info.power_domain_id = id->punit;
500         info.level = level;
501
502         ret = tpmi_process_ioctl(ISST_IF_GET_TURBO_FREQ_INFO, &info);
503         if (ret == -1)
504                 return ret;
505
506         for (i = 0; i < info.max_clip_freqs; ++i)
507                 fact_info->lp_ratios[i] = info.lp_clip_freq_mhz[i];
508
509         if (info.max_buckets > TRL_MAX_BUCKETS)
510                 info.max_buckets = TRL_MAX_BUCKETS;
511
512         if (info.max_trl_levels > TRL_MAX_LEVELS)
513                 info.max_trl_levels = TRL_MAX_LEVELS;
514
515         for (i = 0; i < info.max_trl_levels; ++i) {
516                 for (j = 0; j < info.max_buckets; ++j)
517                         fact_info->bucket_info[j].hp_ratios[i] =
518                             info.trl_freq_mhz[i][j];
519         }
520
521         for (i = 0; i < info.max_buckets; ++i)
522                 fact_info->bucket_info[i].hp_cores = info.bucket_core_counts[i];
523
524         return 0;
525 }
526
527 static void _set_uncore_min_max(struct isst_id *id, int max, int freq)
528 {
529         DIR *dir;
530         FILE *filep;
531         struct dirent *entry;
532         char buffer[512];
533         unsigned int tmp_id;
534         int ret;
535
536         dir = opendir("/sys/devices/system/cpu/intel_uncore_frequency/");
537         if (!dir)
538                 return;
539
540         while ((entry = readdir(dir)) != NULL ) {
541                 /* Check domain_id */
542                 snprintf(buffer, sizeof(buffer),
543                          "/sys/devices/system/cpu/intel_uncore_frequency/%s/domain_id", entry->d_name);
544
545                 filep = fopen(buffer, "r");
546                 if (!filep)
547                         goto end;
548
549                 ret = fscanf(filep, "%u", &tmp_id);
550                 fclose(filep);
551                 if (ret != 1)
552                         goto end;
553
554                 if (tmp_id != id->punit)
555                         continue;
556
557                 /* Check package_id */
558                 snprintf(buffer, sizeof(buffer),
559                          "/sys/devices/system/cpu/intel_uncore_frequency/%s/package_id", entry->d_name);
560
561                 filep = fopen(buffer, "r");
562                 if (!filep)
563                         goto end;
564
565                 ret = fscanf(filep, "%u", &tmp_id);
566                 fclose(filep);
567
568                 if (ret != 1)
569                         goto end;
570
571                 if (tmp_id != id->pkg)
572                         continue;
573
574                 /* Found the right sysfs path, adjust and quit */
575                 if (max)
576                         snprintf(buffer, sizeof(buffer),
577                                  "/sys/devices/system/cpu/intel_uncore_frequency/%s/max_freq_khz", entry->d_name);
578                  else
579                         snprintf(buffer, sizeof(buffer),
580                                  "/sys/devices/system/cpu/intel_uncore_frequency/%s/min_freq_khz", entry->d_name);
581
582                 filep = fopen(buffer, "w");
583                 if (!filep)
584                         goto end;
585
586                 fprintf(filep, "%d\n", freq);
587                 fclose(filep);
588                 break;
589         }
590
591 end:
592         closedir(dir);
593 }
594
595 static void tpmi_adjust_uncore_freq(struct isst_id *id, int config_index,
596                                 struct isst_pkg_ctdp_level_info *ctdp_level)
597 {
598         struct isst_perf_level_data_info info;
599         int ret;
600
601         info.socket_id = id->pkg;
602         info.power_domain_id = id->punit;
603         info.level = config_index;
604
605         ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info);
606         if (ret == -1)
607                 return;
608
609         ctdp_level->uncore_p0 = info.p0_fabric_freq_mhz;
610         ctdp_level->uncore_p1 = info.p1_fabric_freq_mhz;
611         ctdp_level->uncore_pm = info.pm_fabric_freq_mhz;
612
613         if (ctdp_level->uncore_pm)
614                 _set_uncore_min_max(id, 0, ctdp_level->uncore_pm * 100000);
615
616         if (ctdp_level->uncore_p0)
617                 _set_uncore_min_max(id, 1, ctdp_level->uncore_p0 * 100000);
618
619         return;
620 }
621
622 static int tpmi_get_clos_information(struct isst_id *id, int *enable, int *type)
623 {
624         struct isst_core_power info;
625         int ret;
626
627         info.get_set = 0;
628         info.socket_id = id->pkg;
629         info.power_domain_id = id->punit;
630         ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info);
631         if (ret == -1)
632                 return ret;
633
634         *enable = info.enable;
635         *type = info.priority_type;
636
637         return 0;
638 }
639
640 static int tpmi_pm_qos_config(struct isst_id *id, int enable_clos,
641                               int priority_type)
642 {
643         struct isst_core_power info;
644         int i, ret, saved_punit;
645
646         info.get_set = 1;
647         info.socket_id = id->pkg;
648         info.power_domain_id = id->punit;
649         info.enable = enable_clos;
650         info.priority_type = priority_type;
651
652         saved_punit = id->punit;
653
654         /* Set for all other dies also. This is per package setting */
655         for (i = 0; i < MAX_PUNIT_PER_DIE; i++) {
656                 id->punit = i;
657                 if (isst_is_punit_valid(id)) {
658                         info.power_domain_id = i;
659                         ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info);
660                         if (ret == -1) {
661                                 id->punit = saved_punit;
662                                 return ret;
663                         }
664                 }
665         }
666
667         id->punit = saved_punit;
668
669         return 0;
670 }
671
672 int tpmi_pm_get_clos(struct isst_id *id, int clos,
673                      struct isst_clos_config *clos_config)
674 {
675         struct isst_clos_param info;
676         int ret;
677
678         info.get_set = 0;
679         info.socket_id = id->pkg;
680         info.power_domain_id = id->punit;
681         info.clos = clos;
682
683         ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info);
684         if (ret == -1)
685                 return ret;
686
687         clos_config->epp = 0;
688         clos_config->clos_prop_prio = info.prop_prio;
689         clos_config->clos_min = info.min_freq_mhz;
690         clos_config->clos_max = info.max_freq_mhz;
691         clos_config->clos_desired = 0;
692
693         debug_printf("cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos,
694                      clos_config->clos_min, clos_config->clos_max);
695
696         return 0;
697 }
698
699 int tpmi_set_clos(struct isst_id *id, int clos,
700                   struct isst_clos_config *clos_config)
701 {
702         struct isst_clos_param info;
703         int i, ret, saved_punit;
704
705         info.get_set = 1;
706         info.socket_id = id->pkg;
707         info.power_domain_id = id->punit;
708         info.clos = clos;
709         info.prop_prio = clos_config->clos_prop_prio;
710
711         info.min_freq_mhz = clos_config->clos_min;
712         info.max_freq_mhz = clos_config->clos_max;
713
714         if (info.min_freq_mhz <= 0xff)
715                 info.min_freq_mhz *= 100;
716         if (info.max_freq_mhz <= 0xff)
717                 info.max_freq_mhz *= 100;
718
719         saved_punit = id->punit;
720
721         /* Set for all other dies also. This is per package setting */
722         for (i = 0; i < MAX_PUNIT_PER_DIE; i++) {
723                 id->punit = i;
724                 if (isst_is_punit_valid(id)) {
725                         info.power_domain_id = i;
726                         ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info);
727                         if (ret == -1) {
728                                 id->punit = saved_punit;
729                                 return ret;
730                         }
731                 }
732         }
733
734         id->punit = saved_punit;
735
736         debug_printf("set cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos,
737                      clos_config->clos_min, clos_config->clos_max);
738
739         return 0;
740 }
741
742 static int tpmi_clos_get_assoc_status(struct isst_id *id, int *clos_id)
743 {
744         struct isst_if_clos_assoc_cmds assoc_cmds;
745         int ret;
746
747         assoc_cmds.cmd_count = 1;
748         assoc_cmds.get_set = 0;
749         assoc_cmds.punit_cpu_map = 1;
750         assoc_cmds.assoc_info[0].logical_cpu = find_phy_core_num(id->cpu);
751         assoc_cmds.assoc_info[0].socket_id = id->pkg;
752         assoc_cmds.assoc_info[0].power_domain_id = id->punit;
753
754         ret = tpmi_process_ioctl(ISST_IF_CLOS_ASSOC, &assoc_cmds);
755         if (ret == -1)
756                 return ret;
757
758         *clos_id = assoc_cmds.assoc_info[0].clos;
759
760         return 0;
761 }
762
763 static int tpmi_clos_associate(struct isst_id *id, int clos_id)
764 {
765         struct isst_if_clos_assoc_cmds assoc_cmds;
766         int ret;
767
768         assoc_cmds.cmd_count = 1;
769         assoc_cmds.get_set = 1;
770         assoc_cmds.punit_cpu_map = 1;
771         assoc_cmds.assoc_info[0].logical_cpu = find_phy_core_num(id->cpu);
772         assoc_cmds.assoc_info[0].clos = clos_id;
773         assoc_cmds.assoc_info[0].socket_id = id->pkg;
774         assoc_cmds.assoc_info[0].power_domain_id = id->punit;
775
776         ret = tpmi_process_ioctl(ISST_IF_CLOS_ASSOC, &assoc_cmds);
777         if (ret == -1)
778                 return ret;
779
780         return 0;
781 }
782
783 static struct isst_platform_ops tpmi_ops = {
784         .get_disp_freq_multiplier = tpmi_get_disp_freq_multiplier,
785         .get_trl_max_levels = tpmi_get_trl_max_levels,
786         .get_trl_level_name = tpmi_get_trl_level_name,
787         .update_platform_param = tpmi_update_platform_param,
788         .is_punit_valid = tpmi_is_punit_valid,
789         .read_pm_config = tpmi_read_pm_config,
790         .get_config_levels = tpmi_get_config_levels,
791         .get_ctdp_control = tpmi_get_ctdp_control,
792         .get_tdp_info = tpmi_get_tdp_info,
793         .get_pwr_info = tpmi_get_pwr_info,
794         .get_coremask_info = tpmi_get_coremask_info,
795         .get_get_trl = tpmi_get_get_trl,
796         .get_get_trls = tpmi_get_get_trls,
797         .get_trl_bucket_info = tpmi_get_trl_bucket_info,
798         .set_tdp_level = tpmi_set_tdp_level,
799         .get_pbf_info = tpmi_get_pbf_info,
800         .set_pbf_fact_status = tpmi_set_pbf_fact_status,
801         .get_fact_info = tpmi_get_fact_info,
802         .adjust_uncore_freq = tpmi_adjust_uncore_freq,
803         .get_clos_information = tpmi_get_clos_information,
804         .pm_qos_config = tpmi_pm_qos_config,
805         .pm_get_clos = tpmi_pm_get_clos,
806         .set_clos = tpmi_set_clos,
807         .clos_get_assoc_status = tpmi_clos_get_assoc_status,
808         .clos_associate = tpmi_clos_associate,
809 };
810
811 struct isst_platform_ops *tpmi_get_platform_ops(void)
812 {
813         return &tpmi_ops;
814 }