~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/power/x86/intel-speed-select/isst-core-tpmi.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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         if (api_version() > 2) {
198                 ctdp_level->fact_support = info.sst_tf_support & BIT(config_index);
199                 ctdp_level->pbf_support = info.sst_bf_support & BIT(config_index);
200         } else {
201                 ctdp_level->fact_support = info.sst_tf_support;
202                 ctdp_level->pbf_support = info.sst_bf_support;
203         }
204 
205         ctdp_level->fact_enabled = !!(info.feature_state & BIT(1));
206         ctdp_level->pbf_enabled = !!(info.feature_state & BIT(0));
207 
208         core_power_info.get_set = 0;
209         core_power_info.socket_id = id->pkg;
210         core_power_info.power_domain_id = id->punit;
211 
212         ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &core_power_info);
213         if (ret == -1)
214                 return ret;
215 
216         ctdp_level->sst_cp_support = core_power_info.supported;
217         ctdp_level->sst_cp_enabled = core_power_info.enable;
218 
219         debug_printf
220             ("cpu:%d CONFIG_TDP_GET_TDP_CONTROL fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n",
221              id->cpu, ctdp_level->fact_support, ctdp_level->pbf_support,
222              ctdp_level->fact_enabled, ctdp_level->pbf_enabled);
223 
224         return 0;
225 }
226 
227 static int tpmi_get_tdp_info(struct isst_id *id, int config_index,
228                              struct isst_pkg_ctdp_level_info *ctdp_level)
229 {
230         struct isst_perf_level_data_info info;
231         int ret;
232 
233         info.socket_id = id->pkg;
234         info.power_domain_id = id->punit;
235         info.level = config_index;
236 
237         ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info);
238         if (ret == -1)
239                 return ret;
240 
241         ctdp_level->pkg_tdp = info.thermal_design_power_w;
242         ctdp_level->tdp_ratio = info.tdp_ratio;
243         ctdp_level->sse_p1 = info.base_freq_mhz;
244         ctdp_level->avx2_p1 = info.base_freq_avx2_mhz;
245         ctdp_level->avx512_p1 = info.base_freq_avx512_mhz;
246         ctdp_level->amx_p1 = info.base_freq_amx_mhz;
247 
248         ctdp_level->t_proc_hot = info.tjunction_max_c;
249         ctdp_level->mem_freq = info.max_memory_freq_mhz;
250         ctdp_level->cooling_type = info.cooling_type;
251 
252         ctdp_level->uncore_p0 = info.p0_fabric_freq_mhz;
253         ctdp_level->uncore_p1 = info.p1_fabric_freq_mhz;
254         ctdp_level->uncore_pm = info.pm_fabric_freq_mhz;
255 
256         debug_printf
257             ("cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO tdp_ratio:%d pkg_tdp:%d ctdp_level->t_proc_hot:%d\n",
258              id->cpu, config_index, ctdp_level->tdp_ratio, ctdp_level->pkg_tdp,
259              ctdp_level->t_proc_hot);
260 
261         return 0;
262 }
263 
264 static int tpmi_get_pwr_info(struct isst_id *id, int config_index,
265                              struct isst_pkg_ctdp_level_info *ctdp_level)
266 {
267         /* TBD */
268         ctdp_level->pkg_max_power = 0;
269         ctdp_level->pkg_min_power = 0;
270 
271         debug_printf
272             ("cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO pkg_max_power:%d pkg_min_power:%d\n",
273              id->cpu, config_index, ctdp_level->pkg_max_power,
274              ctdp_level->pkg_min_power);
275 
276         return 0;
277 }
278 
279 int tpmi_get_coremask_info(struct isst_id *id, int config_index,
280                            struct isst_pkg_ctdp_level_info *ctdp_level)
281 {
282         struct isst_perf_level_cpu_mask info;
283         int ret, cpu_count;
284 
285         info.socket_id = id->pkg;
286         info.power_domain_id = id->punit;
287         info.level = config_index;
288         info.punit_cpu_map = 1;
289 
290         ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_CPU_MASK, &info);
291         if (ret == -1)
292                 return ret;
293 
294         set_cpu_mask_from_punit_coremask(id, info.mask,
295                                          ctdp_level->core_cpumask_size,
296                                          ctdp_level->core_cpumask, &cpu_count);
297         ctdp_level->cpu_count = cpu_count;
298 
299         debug_printf("cpu:%d ctdp:%d core_mask ino cpu count:%d\n",
300                      id->cpu, config_index, ctdp_level->cpu_count);
301 
302         return 0;
303 }
304 
305 static int tpmi_get_get_trls(struct isst_id *id, int config_index,
306                              struct isst_pkg_ctdp_level_info *ctdp_level)
307 {
308         struct isst_perf_level_data_info info;
309         int ret, i, j;
310 
311         info.socket_id = id->pkg;
312         info.power_domain_id = id->punit;
313         info.level = config_index;
314 
315         ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info);
316         if (ret == -1)
317                 return ret;
318 
319         if (info.max_buckets > TRL_MAX_BUCKETS)
320                 info.max_buckets = TRL_MAX_BUCKETS;
321 
322         if (info.max_trl_levels > TRL_MAX_LEVELS)
323                 info.max_trl_levels = TRL_MAX_LEVELS;
324 
325         for (i = 0; i < info.max_trl_levels; ++i)
326                 for (j = 0; j < info.max_buckets; ++j)
327                         ctdp_level->trl_ratios[i][j] = info.trl_freq_mhz[i][j];
328 
329         return 0;
330 }
331 
332 static int tpmi_get_get_trl(struct isst_id *id, int level, int config_index,
333                             int *trl)
334 {
335         struct isst_pkg_ctdp_level_info ctdp_level;
336         int ret, i;
337 
338         ret = tpmi_get_get_trls(id, config_index, &ctdp_level);
339         if (ret)
340                 return ret;
341 
342         /* FIX ME: Just return for level 0 */
343         for (i = 0; i < 8; ++i)
344                 trl[i] = ctdp_level.trl_ratios[0][i];
345 
346         return 0;
347 }
348 
349 static int tpmi_get_trl_bucket_info(struct isst_id *id, int config_index,
350                                     unsigned long long *buckets_info)
351 {
352         struct isst_perf_level_data_info info;
353         unsigned char *mask = (unsigned char *)buckets_info;
354         int ret, i;
355 
356         info.socket_id = id->pkg;
357         info.power_domain_id = id->punit;
358         info.level = config_index;
359 
360         ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info);
361         if (ret == -1)
362                 return ret;
363 
364         if (info.max_buckets > TRL_MAX_BUCKETS)
365                 info.max_buckets = TRL_MAX_BUCKETS;
366 
367         for (i = 0; i < info.max_buckets; ++i)
368                 mask[i] = info.bucket_core_counts[i];
369 
370         debug_printf("cpu:%d TRL bucket info: 0x%llx\n", id->cpu,
371                      *buckets_info);
372 
373         return 0;
374 }
375 
376 static int tpmi_set_tdp_level(struct isst_id *id, int tdp_level)
377 {
378         struct isst_perf_level_control info;
379         int ret;
380 
381         info.socket_id = id->pkg;
382         info.power_domain_id = id->punit;
383         info.level = tdp_level;
384 
385         ret = tpmi_process_ioctl(ISST_IF_PERF_SET_LEVEL, &info);
386         if (ret == -1)
387                 return ret;
388 
389         return 0;
390 }
391 
392 static int _pbf_get_coremask_info(struct isst_id *id, int config_index,
393                                   struct isst_pbf_info *pbf_info)
394 {
395         struct isst_perf_level_cpu_mask info;
396         int ret, cpu_count;
397 
398         info.socket_id = id->pkg;
399         info.power_domain_id = id->punit;
400         info.level = config_index;
401         info.punit_cpu_map = 1;
402 
403         ret = tpmi_process_ioctl(ISST_IF_GET_BASE_FREQ_CPU_MASK, &info);
404         if (ret == -1)
405                 return ret;
406 
407         set_cpu_mask_from_punit_coremask(id, info.mask,
408                                          pbf_info->core_cpumask_size,
409                                          pbf_info->core_cpumask, &cpu_count);
410 
411         debug_printf("cpu:%d ctdp:%d pbf core_mask info cpu count:%d\n",
412                      id->cpu, config_index, cpu_count);
413 
414         return 0;
415 }
416 
417 static int tpmi_get_pbf_info(struct isst_id *id, int level,
418                              struct isst_pbf_info *pbf_info)
419 {
420         struct isst_base_freq_info info;
421         int ret;
422 
423         info.socket_id = id->pkg;
424         info.power_domain_id = id->punit;
425         info.level = level;
426 
427         ret = tpmi_process_ioctl(ISST_IF_GET_BASE_FREQ_INFO, &info);
428         if (ret == -1)
429                 return ret;
430 
431         pbf_info->p1_low = info.low_base_freq_mhz;
432         pbf_info->p1_high = info.high_base_freq_mhz;
433         pbf_info->tdp = info.thermal_design_power_w;
434         pbf_info->t_prochot = info.tjunction_max_c;
435 
436         debug_printf("cpu:%d ctdp:%d pbf info:%d:%d:%d:%d\n",
437                      id->cpu, level, pbf_info->p1_low, pbf_info->p1_high,
438                      pbf_info->tdp, pbf_info->t_prochot);
439 
440         return _pbf_get_coremask_info(id, level, pbf_info);
441 }
442 
443 static int tpmi_set_pbf_fact_status(struct isst_id *id, int pbf, int enable)
444 {
445         struct isst_pkg_ctdp pkg_dev;
446         struct isst_pkg_ctdp_level_info ctdp_level;
447         int current_level;
448         struct isst_perf_feature_control info;
449         int ret;
450 
451         ret = isst_get_ctdp_levels(id, &pkg_dev);
452         if (ret)
453                 debug_printf("cpu:%d No support for dynamic ISST\n", id->cpu);
454 
455         current_level = pkg_dev.current_level;
456 
457         ret = isst_get_ctdp_control(id, current_level, &ctdp_level);
458         if (ret)
459                 return ret;
460 
461         info.socket_id = id->pkg;
462         info.power_domain_id = id->punit;
463 
464         info.feature = 0;
465 
466         if (pbf) {
467                 if (ctdp_level.fact_enabled)
468                         info.feature |= BIT(1);
469 
470                 if (enable)
471                         info.feature |= BIT(0);
472                 else
473                         info.feature &= ~BIT(0);
474         } else {
475 
476                 if (enable && !ctdp_level.sst_cp_enabled)
477                         isst_display_error_info_message(0,
478                                                         "Make sure to execute before: core-power enable",
479                                                         0, 0);
480 
481                 if (ctdp_level.pbf_enabled)
482                         info.feature |= BIT(0);
483 
484                 if (enable)
485                         info.feature |= BIT(1);
486                 else
487                         info.feature &= ~BIT(1);
488         }
489 
490         ret = tpmi_process_ioctl(ISST_IF_PERF_SET_FEATURE, &info);
491         if (ret == -1)
492                 return ret;
493 
494         return 0;
495 }
496 
497 static int tpmi_get_fact_info(struct isst_id *id, int level, int fact_bucket,
498                               struct isst_fact_info *fact_info)
499 {
500         struct isst_turbo_freq_info info;
501         int i, j;
502         int ret;
503 
504         info.socket_id = id->pkg;
505         info.power_domain_id = id->punit;
506         info.level = level;
507 
508         ret = tpmi_process_ioctl(ISST_IF_GET_TURBO_FREQ_INFO, &info);
509         if (ret == -1)
510                 return ret;
511 
512         for (i = 0; i < info.max_clip_freqs; ++i)
513                 fact_info->lp_ratios[i] = info.lp_clip_freq_mhz[i];
514 
515         if (info.max_buckets > TRL_MAX_BUCKETS)
516                 info.max_buckets = TRL_MAX_BUCKETS;
517 
518         if (info.max_trl_levels > TRL_MAX_LEVELS)
519                 info.max_trl_levels = TRL_MAX_LEVELS;
520 
521         for (i = 0; i < info.max_trl_levels; ++i) {
522                 for (j = 0; j < info.max_buckets; ++j)
523                         fact_info->bucket_info[j].hp_ratios[i] =
524                             info.trl_freq_mhz[i][j];
525         }
526 
527         for (i = 0; i < info.max_buckets; ++i)
528                 fact_info->bucket_info[i].hp_cores = info.bucket_core_counts[i];
529 
530         return 0;
531 }
532 
533 static void _set_uncore_min_max(struct isst_id *id, int max, int freq)
534 {
535         DIR *dir;
536         FILE *filep;
537         struct dirent *entry;
538         char buffer[512];
539         unsigned int tmp_id;
540         int ret;
541 
542         dir = opendir("/sys/devices/system/cpu/intel_uncore_frequency/");
543         if (!dir)
544                 return;
545 
546         while ((entry = readdir(dir)) != NULL ) {
547                 /* Check domain_id */
548                 snprintf(buffer, sizeof(buffer),
549                          "/sys/devices/system/cpu/intel_uncore_frequency/%s/domain_id", entry->d_name);
550 
551                 filep = fopen(buffer, "r");
552                 if (!filep)
553                         goto end;
554 
555                 ret = fscanf(filep, "%u", &tmp_id);
556                 fclose(filep);
557                 if (ret != 1)
558                         goto end;
559 
560                 if (tmp_id != id->punit)
561                         continue;
562 
563                 /* Check package_id */
564                 snprintf(buffer, sizeof(buffer),
565                          "/sys/devices/system/cpu/intel_uncore_frequency/%s/package_id", entry->d_name);
566 
567                 filep = fopen(buffer, "r");
568                 if (!filep)
569                         goto end;
570 
571                 ret = fscanf(filep, "%u", &tmp_id);
572                 fclose(filep);
573 
574                 if (ret != 1)
575                         goto end;
576 
577                 if (tmp_id != id->pkg)
578                         continue;
579 
580                 /* Found the right sysfs path, adjust and quit */
581                 if (max)
582                         snprintf(buffer, sizeof(buffer),
583                                  "/sys/devices/system/cpu/intel_uncore_frequency/%s/max_freq_khz", entry->d_name);
584                  else
585                         snprintf(buffer, sizeof(buffer),
586                                  "/sys/devices/system/cpu/intel_uncore_frequency/%s/min_freq_khz", entry->d_name);
587 
588                 filep = fopen(buffer, "w");
589                 if (!filep)
590                         goto end;
591 
592                 fprintf(filep, "%d\n", freq);
593                 fclose(filep);
594                 break;
595         }
596 
597 end:
598         closedir(dir);
599 }
600 
601 static void tpmi_adjust_uncore_freq(struct isst_id *id, int config_index,
602                                 struct isst_pkg_ctdp_level_info *ctdp_level)
603 {
604         struct isst_perf_level_data_info info;
605         int ret;
606 
607         info.socket_id = id->pkg;
608         info.power_domain_id = id->punit;
609         info.level = config_index;
610 
611         ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info);
612         if (ret == -1)
613                 return;
614 
615         ctdp_level->uncore_p0 = info.p0_fabric_freq_mhz;
616         ctdp_level->uncore_p1 = info.p1_fabric_freq_mhz;
617         ctdp_level->uncore_pm = info.pm_fabric_freq_mhz;
618 
619         if (ctdp_level->uncore_pm)
620                 _set_uncore_min_max(id, 0, ctdp_level->uncore_pm * 100000);
621 
622         if (ctdp_level->uncore_p0)
623                 _set_uncore_min_max(id, 1, ctdp_level->uncore_p0 * 100000);
624 
625         return;
626 }
627 
628 static int tpmi_get_clos_information(struct isst_id *id, int *enable, int *type)
629 {
630         struct isst_core_power info;
631         int ret;
632 
633         info.get_set = 0;
634         info.socket_id = id->pkg;
635         info.power_domain_id = id->punit;
636         ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info);
637         if (ret == -1)
638                 return ret;
639 
640         *enable = info.enable;
641         *type = info.priority_type;
642 
643         return 0;
644 }
645 
646 static int tpmi_pm_qos_config(struct isst_id *id, int enable_clos,
647                               int priority_type)
648 {
649         struct isst_core_power info;
650         int i, ret, saved_punit;
651 
652         info.get_set = 1;
653         info.socket_id = id->pkg;
654         info.power_domain_id = id->punit;
655         info.enable = enable_clos;
656         info.priority_type = priority_type;
657 
658         saved_punit = id->punit;
659 
660         /* Set for all other dies also. This is per package setting */
661         for (i = 0; i < MAX_PUNIT_PER_DIE; i++) {
662                 id->punit = i;
663                 if (isst_is_punit_valid(id)) {
664                         info.power_domain_id = i;
665                         ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info);
666                         if (ret == -1) {
667                                 id->punit = saved_punit;
668                                 return ret;
669                         }
670                 }
671         }
672 
673         id->punit = saved_punit;
674 
675         return 0;
676 }
677 
678 int tpmi_pm_get_clos(struct isst_id *id, int clos,
679                      struct isst_clos_config *clos_config)
680 {
681         struct isst_clos_param info;
682         int ret;
683 
684         info.get_set = 0;
685         info.socket_id = id->pkg;
686         info.power_domain_id = id->punit;
687         info.clos = clos;
688 
689         ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info);
690         if (ret == -1)
691                 return ret;
692 
693         clos_config->epp = 0;
694         clos_config->clos_prop_prio = info.prop_prio;
695         clos_config->clos_min = info.min_freq_mhz;
696         clos_config->clos_max = info.max_freq_mhz;
697         clos_config->clos_desired = 0;
698 
699         debug_printf("cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos,
700                      clos_config->clos_min, clos_config->clos_max);
701 
702         return 0;
703 }
704 
705 int tpmi_set_clos(struct isst_id *id, int clos,
706                   struct isst_clos_config *clos_config)
707 {
708         struct isst_clos_param info;
709         int i, ret, saved_punit;
710 
711         info.get_set = 1;
712         info.socket_id = id->pkg;
713         info.power_domain_id = id->punit;
714         info.clos = clos;
715         info.prop_prio = clos_config->clos_prop_prio;
716 
717         info.min_freq_mhz = clos_config->clos_min;
718         info.max_freq_mhz = clos_config->clos_max;
719 
720         if (info.min_freq_mhz <= 0xff)
721                 info.min_freq_mhz *= 100;
722         if (info.max_freq_mhz <= 0xff)
723                 info.max_freq_mhz *= 100;
724 
725         saved_punit = id->punit;
726 
727         /* Set for all other dies also. This is per package setting */
728         for (i = 0; i < MAX_PUNIT_PER_DIE; i++) {
729                 id->punit = i;
730                 if (isst_is_punit_valid(id)) {
731                         info.power_domain_id = i;
732                         ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info);
733                         if (ret == -1) {
734                                 id->punit = saved_punit;
735                                 return ret;
736                         }
737                 }
738         }
739 
740         id->punit = saved_punit;
741 
742         debug_printf("set cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos,
743                      clos_config->clos_min, clos_config->clos_max);
744 
745         return 0;
746 }
747 
748 static int tpmi_clos_get_assoc_status(struct isst_id *id, int *clos_id)
749 {
750         struct isst_if_clos_assoc_cmds assoc_cmds;
751         int ret;
752 
753         assoc_cmds.cmd_count = 1;
754         assoc_cmds.get_set = 0;
755         assoc_cmds.punit_cpu_map = 1;
756         assoc_cmds.assoc_info[0].logical_cpu = find_phy_core_num(id->cpu);
757         assoc_cmds.assoc_info[0].socket_id = id->pkg;
758         assoc_cmds.assoc_info[0].power_domain_id = id->punit;
759 
760         ret = tpmi_process_ioctl(ISST_IF_CLOS_ASSOC, &assoc_cmds);
761         if (ret == -1)
762                 return ret;
763 
764         *clos_id = assoc_cmds.assoc_info[0].clos;
765 
766         return 0;
767 }
768 
769 static int tpmi_clos_associate(struct isst_id *id, int clos_id)
770 {
771         struct isst_if_clos_assoc_cmds assoc_cmds;
772         int ret;
773 
774         assoc_cmds.cmd_count = 1;
775         assoc_cmds.get_set = 1;
776         assoc_cmds.punit_cpu_map = 1;
777         assoc_cmds.assoc_info[0].logical_cpu = find_phy_core_num(id->cpu);
778         assoc_cmds.assoc_info[0].clos = clos_id;
779         assoc_cmds.assoc_info[0].socket_id = id->pkg;
780         assoc_cmds.assoc_info[0].power_domain_id = id->punit;
781 
782         ret = tpmi_process_ioctl(ISST_IF_CLOS_ASSOC, &assoc_cmds);
783         if (ret == -1)
784                 return ret;
785 
786         return 0;
787 }
788 
789 static struct isst_platform_ops tpmi_ops = {
790         .get_disp_freq_multiplier = tpmi_get_disp_freq_multiplier,
791         .get_trl_max_levels = tpmi_get_trl_max_levels,
792         .get_trl_level_name = tpmi_get_trl_level_name,
793         .update_platform_param = tpmi_update_platform_param,
794         .is_punit_valid = tpmi_is_punit_valid,
795         .read_pm_config = tpmi_read_pm_config,
796         .get_config_levels = tpmi_get_config_levels,
797         .get_ctdp_control = tpmi_get_ctdp_control,
798         .get_tdp_info = tpmi_get_tdp_info,
799         .get_pwr_info = tpmi_get_pwr_info,
800         .get_coremask_info = tpmi_get_coremask_info,
801         .get_get_trl = tpmi_get_get_trl,
802         .get_get_trls = tpmi_get_get_trls,
803         .get_trl_bucket_info = tpmi_get_trl_bucket_info,
804         .set_tdp_level = tpmi_set_tdp_level,
805         .get_pbf_info = tpmi_get_pbf_info,
806         .set_pbf_fact_status = tpmi_set_pbf_fact_status,
807         .get_fact_info = tpmi_get_fact_info,
808         .adjust_uncore_freq = tpmi_adjust_uncore_freq,
809         .get_clos_information = tpmi_get_clos_information,
810         .pm_qos_config = tpmi_pm_qos_config,
811         .pm_get_clos = tpmi_pm_get_clos,
812         .set_clos = tpmi_set_clos,
813         .clos_get_assoc_status = tpmi_clos_get_assoc_status,
814         .clos_associate = tpmi_clos_associate,
815 };
816 
817 struct isst_platform_ops *tpmi_get_platform_ops(void)
818 {
819         return &tpmi_ops;
820 }
821 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php