8309810e7425622d2aefa2212fb886d6befa389d
[sfrench/cifs-2.6.git] / tools / power / x86 / intel-speed-select / isst-display.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Intel dynamic_speed_select -- Enumerate and control features
4  * Copyright (c) 2019 Intel Corporation.
5  */
6
7 #include "isst.h"
8
9 static void printcpulist(int str_len, char *str, int mask_size,
10                          cpu_set_t *cpu_mask)
11 {
12         int i, first, curr_index, index;
13
14         if (!CPU_COUNT_S(mask_size, cpu_mask)) {
15                 snprintf(str, str_len, "none");
16                 return;
17         }
18
19         curr_index = 0;
20         first = 1;
21         for (i = 0; i < get_topo_max_cpus(); ++i) {
22                 if (!CPU_ISSET_S(i, mask_size, cpu_mask))
23                         continue;
24                 if (!first) {
25                         index = snprintf(&str[curr_index],
26                                          str_len - curr_index, ",");
27                         curr_index += index;
28                 }
29                 index = snprintf(&str[curr_index], str_len - curr_index, "%d",
30                                  i);
31                 curr_index += index;
32                 first = 0;
33         }
34 }
35
36 static void printcpumask(int str_len, char *str, int mask_size,
37                          cpu_set_t *cpu_mask)
38 {
39         int i, max_cpus = get_topo_max_cpus();
40         unsigned int *mask;
41         int size, index, curr_index;
42
43         size = max_cpus / (sizeof(unsigned int) * 8);
44         if (max_cpus % (sizeof(unsigned int) * 8))
45                 size++;
46
47         mask = calloc(size, sizeof(unsigned int));
48         if (!mask)
49                 return;
50
51         for (i = 0; i < max_cpus; ++i) {
52                 int mask_index, bit_index;
53
54                 if (!CPU_ISSET_S(i, mask_size, cpu_mask))
55                         continue;
56
57                 mask_index = i / (sizeof(unsigned int) * 8);
58                 bit_index = i % (sizeof(unsigned int) * 8);
59                 mask[mask_index] |= BIT(bit_index);
60         }
61
62         curr_index = 0;
63         for (i = size - 1; i >= 0; --i) {
64                 index = snprintf(&str[curr_index], str_len - curr_index, "%08x",
65                                  mask[i]);
66                 curr_index += index;
67                 if (i) {
68                         strncat(&str[curr_index], ",", str_len - curr_index);
69                         curr_index++;
70                 }
71         }
72
73         free(mask);
74 }
75
76 static void format_and_print_txt(FILE *outf, int level, char *header,
77                                  char *value)
78 {
79         char *spaces = "  ";
80         static char delimiters[256];
81         int i, j = 0;
82
83         if (!level)
84                 return;
85
86         if (level == 1) {
87                 strcpy(delimiters, " ");
88         } else {
89                 for (i = 0; i < level - 1; ++i)
90                         j += snprintf(&delimiters[j], sizeof(delimiters) - j,
91                                       "%s", spaces);
92         }
93
94         if (header && value) {
95                 fprintf(outf, "%s", delimiters);
96                 fprintf(outf, "%s:%s\n", header, value);
97         } else if (header) {
98                 fprintf(outf, "%s", delimiters);
99                 fprintf(outf, "%s\n", header);
100         }
101 }
102
103 static int last_level;
104 static void format_and_print(FILE *outf, int level, char *header, char *value)
105 {
106         char *spaces = "  ";
107         static char delimiters[256];
108         int i;
109
110         if (!out_format_is_json()) {
111                 format_and_print_txt(outf, level, header, value);
112                 return;
113         }
114
115         if (level == 0) {
116                 if (header)
117                         fprintf(outf, "{");
118                 else
119                         fprintf(outf, "\n}\n");
120
121         } else {
122                 int j = 0;
123
124                 for (i = 0; i < level; ++i)
125                         j += snprintf(&delimiters[j], sizeof(delimiters) - j,
126                                       "%s", spaces);
127
128                 if (last_level == level)
129                         fprintf(outf, ",\n");
130
131                 if (value) {
132                         if (last_level != level)
133                                 fprintf(outf, "\n");
134
135                         fprintf(outf, "%s\"%s\": ", delimiters, header);
136                         fprintf(outf, "\"%s\"", value);
137                 } else {
138                         for (i = last_level - 1; i >= level; --i) {
139                                 int k = 0;
140
141                                 for (j = i; j > 0; --j)
142                                         k += snprintf(&delimiters[k],
143                                                       sizeof(delimiters) - k,
144                                                       "%s", spaces);
145                                 if (i == level && header)
146                                         fprintf(outf, "\n%s},", delimiters);
147                                 else
148                                         fprintf(outf, "\n%s}", delimiters);
149                         }
150                         if (abs(last_level - level) < 3)
151                                 fprintf(outf, "\n");
152                         if (header)
153                                 fprintf(outf, "%s\"%s\": {", delimiters,
154                                         header);
155                 }
156         }
157
158         last_level = level;
159 }
160
161 static void print_package_info(int cpu, FILE *outf)
162 {
163         char header[256];
164
165         snprintf(header, sizeof(header), "package-%d",
166                  get_physical_package_id(cpu));
167         format_and_print(outf, 1, header, NULL);
168         snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
169         format_and_print(outf, 2, header, NULL);
170         snprintf(header, sizeof(header), "cpu-%d", cpu);
171         format_and_print(outf, 3, header, NULL);
172 }
173
174 static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
175                                           struct isst_pbf_info *pbf_info,
176                                           int disp_level)
177 {
178         char header[256];
179         char value[256];
180
181         snprintf(header, sizeof(header), "speed-select-base-freq");
182         format_and_print(outf, disp_level, header, NULL);
183
184         snprintf(header, sizeof(header), "high-priority-base-frequency(MHz)");
185         snprintf(value, sizeof(value), "%d",
186                  pbf_info->p1_high * DISP_FREQ_MULTIPLIER);
187         format_and_print(outf, disp_level + 1, header, value);
188
189         snprintf(header, sizeof(header), "high-priority-cpu-mask");
190         printcpumask(sizeof(value), value, pbf_info->core_cpumask_size,
191                      pbf_info->core_cpumask);
192         format_and_print(outf, disp_level + 1, header, value);
193
194         snprintf(header, sizeof(header), "high-priority-cpu-list");
195         printcpulist(sizeof(value), value,
196                      pbf_info->core_cpumask_size,
197                      pbf_info->core_cpumask);
198         format_and_print(outf, disp_level + 1, header, value);
199
200         snprintf(header, sizeof(header), "low-priority-base-frequency(MHz)");
201         snprintf(value, sizeof(value), "%d",
202                  pbf_info->p1_low * DISP_FREQ_MULTIPLIER);
203         format_and_print(outf, disp_level + 1, header, value);
204
205         if (is_clx_n_platform())
206                 return;
207
208         snprintf(header, sizeof(header), "tjunction-temperature(C)");
209         snprintf(value, sizeof(value), "%d", pbf_info->t_prochot);
210         format_and_print(outf, disp_level + 1, header, value);
211
212         snprintf(header, sizeof(header), "thermal-design-power(W)");
213         snprintf(value, sizeof(value), "%d", pbf_info->tdp);
214         format_and_print(outf, disp_level + 1, header, value);
215 }
216
217 static void _isst_fact_display_information(int cpu, FILE *outf, int level,
218                                            int fact_bucket, int fact_avx,
219                                            struct isst_fact_info *fact_info,
220                                            int base_level)
221 {
222         struct isst_fact_bucket_info *bucket_info = fact_info->bucket_info;
223         char header[256];
224         char value[256];
225         int j;
226
227         snprintf(header, sizeof(header), "speed-select-turbo-freq");
228         format_and_print(outf, base_level, header, NULL);
229         for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
230                 if (fact_bucket != 0xff && fact_bucket != j)
231                         continue;
232
233                 if (!bucket_info[j].high_priority_cores_count)
234                         break;
235
236                 snprintf(header, sizeof(header), "bucket-%d", j);
237                 format_and_print(outf, base_level + 1, header, NULL);
238
239                 snprintf(header, sizeof(header), "high-priority-cores-count");
240                 snprintf(value, sizeof(value), "%d",
241                          bucket_info[j].high_priority_cores_count);
242                 format_and_print(outf, base_level + 2, header, value);
243
244                 if (fact_avx & 0x01) {
245                         snprintf(header, sizeof(header),
246                                  "high-priority-max-frequency(MHz)");
247                         snprintf(value, sizeof(value), "%d",
248                                  bucket_info[j].sse_trl * DISP_FREQ_MULTIPLIER);
249                         format_and_print(outf, base_level + 2, header, value);
250                 }
251
252                 if (fact_avx & 0x02) {
253                         snprintf(header, sizeof(header),
254                                  "high-priority-max-avx2-frequency(MHz)");
255                         snprintf(value, sizeof(value), "%d",
256                                  bucket_info[j].avx_trl * DISP_FREQ_MULTIPLIER);
257                         format_and_print(outf, base_level + 2, header, value);
258                 }
259
260                 if (fact_avx & 0x04) {
261                         snprintf(header, sizeof(header),
262                                  "high-priority-max-avx512-frequency(MHz)");
263                         snprintf(value, sizeof(value), "%d",
264                                  bucket_info[j].avx512_trl *
265                                          DISP_FREQ_MULTIPLIER);
266                         format_and_print(outf, base_level + 2, header, value);
267                 }
268         }
269         snprintf(header, sizeof(header),
270                  "speed-select-turbo-freq-clip-frequencies");
271         format_and_print(outf, base_level + 1, header, NULL);
272         snprintf(header, sizeof(header), "low-priority-max-frequency(MHz)");
273         snprintf(value, sizeof(value), "%d",
274                  fact_info->lp_clipping_ratio_license_sse *
275                          DISP_FREQ_MULTIPLIER);
276         format_and_print(outf, base_level + 2, header, value);
277         snprintf(header, sizeof(header),
278                  "low-priority-max-avx2-frequency(MHz)");
279         snprintf(value, sizeof(value), "%d",
280                  fact_info->lp_clipping_ratio_license_avx2 *
281                          DISP_FREQ_MULTIPLIER);
282         format_and_print(outf, base_level + 2, header, value);
283         snprintf(header, sizeof(header),
284                  "low-priority-max-avx512-frequency(MHz)");
285         snprintf(value, sizeof(value), "%d",
286                  fact_info->lp_clipping_ratio_license_avx512 *
287                          DISP_FREQ_MULTIPLIER);
288         format_and_print(outf, base_level + 2, header, value);
289 }
290
291 void isst_ctdp_display_core_info(int cpu, FILE *outf, char *prefix,
292                                  unsigned int val)
293 {
294         char header[256];
295         char value[256];
296
297         snprintf(header, sizeof(header), "package-%d",
298                  get_physical_package_id(cpu));
299         format_and_print(outf, 1, header, NULL);
300         snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
301         format_and_print(outf, 2, header, NULL);
302         snprintf(header, sizeof(header), "cpu-%d", cpu);
303         format_and_print(outf, 3, header, NULL);
304
305         snprintf(value, sizeof(value), "%u", val);
306         format_and_print(outf, 4, prefix, value);
307
308         format_and_print(outf, 1, NULL, NULL);
309 }
310
311 void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
312                                    struct isst_pkg_ctdp *pkg_dev)
313 {
314         char header[256];
315         char value[256];
316         int i, base_level = 1;
317
318         print_package_info(cpu, outf);
319
320         for (i = 0; i <= pkg_dev->levels; ++i) {
321                 struct isst_pkg_ctdp_level_info *ctdp_level;
322                 int j;
323
324                 ctdp_level = &pkg_dev->ctdp_level[i];
325                 if (!ctdp_level->processed)
326                         continue;
327
328                 snprintf(header, sizeof(header), "perf-profile-level-%d",
329                          ctdp_level->level);
330                 format_and_print(outf, base_level + 3, header, NULL);
331
332                 snprintf(header, sizeof(header), "cpu-count");
333                 j = get_cpu_count(get_physical_die_id(cpu),
334                                   get_physical_die_id(cpu));
335                 snprintf(value, sizeof(value), "%d", j);
336                 format_and_print(outf, base_level + 4, header, value);
337
338                 snprintf(header, sizeof(header), "enable-cpu-mask");
339                 printcpumask(sizeof(value), value,
340                              ctdp_level->core_cpumask_size,
341                              ctdp_level->core_cpumask);
342                 format_and_print(outf, base_level + 4, header, value);
343
344                 snprintf(header, sizeof(header), "enable-cpu-list");
345                 printcpulist(sizeof(value), value,
346                              ctdp_level->core_cpumask_size,
347                              ctdp_level->core_cpumask);
348                 format_and_print(outf, base_level + 4, header, value);
349
350                 snprintf(header, sizeof(header), "thermal-design-power-ratio");
351                 snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio);
352                 format_and_print(outf, base_level + 4, header, value);
353
354                 snprintf(header, sizeof(header), "base-frequency(MHz)");
355                 snprintf(value, sizeof(value), "%d",
356                          ctdp_level->tdp_ratio * DISP_FREQ_MULTIPLIER);
357                 format_and_print(outf, base_level + 4, header, value);
358
359                 snprintf(header, sizeof(header),
360                          "speed-select-turbo-freq");
361                 if (ctdp_level->fact_support) {
362                         if (ctdp_level->fact_enabled)
363                                 snprintf(value, sizeof(value), "enabled");
364                         else
365                                 snprintf(value, sizeof(value), "disabled");
366                 } else
367                         snprintf(value, sizeof(value), "unsupported");
368                 format_and_print(outf, base_level + 4, header, value);
369
370                 snprintf(header, sizeof(header),
371                          "speed-select-base-freq");
372                 if (ctdp_level->pbf_support) {
373                         if (ctdp_level->pbf_enabled)
374                                 snprintf(value, sizeof(value), "enabled");
375                         else
376                                 snprintf(value, sizeof(value), "disabled");
377                 } else
378                         snprintf(value, sizeof(value), "unsupported");
379                 format_and_print(outf, base_level + 4, header, value);
380
381                 if (is_clx_n_platform()) {
382                         if (ctdp_level->pbf_support)
383                                 _isst_pbf_display_information(cpu, outf,
384                                                               tdp_level,
385                                                           &ctdp_level->pbf_info,
386                                                               base_level + 4);
387                         continue;
388                 }
389
390                 snprintf(header, sizeof(header), "thermal-design-power(W)");
391                 snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp);
392                 format_and_print(outf, base_level + 4, header, value);
393
394                 snprintf(header, sizeof(header), "tjunction-max(C)");
395                 snprintf(value, sizeof(value), "%d", ctdp_level->t_proc_hot);
396                 format_and_print(outf, base_level + 4, header, value);
397
398                 snprintf(header, sizeof(header), "turbo-ratio-limits-sse");
399                 format_and_print(outf, base_level + 4, header, NULL);
400                 for (j = 0; j < 8; ++j) {
401                         snprintf(header, sizeof(header), "bucket-%d", j);
402                         format_and_print(outf, base_level + 5, header, NULL);
403
404                         snprintf(header, sizeof(header), "core-count");
405                         snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
406                         format_and_print(outf, base_level + 6, header, value);
407
408                         snprintf(header, sizeof(header),
409                                 "max-turbo-frequency(MHz)");
410                         snprintf(value, sizeof(value), "%d",
411                                  ctdp_level->trl_sse_active_cores[j] *
412                                   DISP_FREQ_MULTIPLIER);
413                         format_and_print(outf, base_level + 6, header, value);
414                 }
415                 snprintf(header, sizeof(header), "turbo-ratio-limits-avx");
416                 format_and_print(outf, base_level + 4, header, NULL);
417                 for (j = 0; j < 8; ++j) {
418                         snprintf(header, sizeof(header), "bucket-%d", j);
419                         format_and_print(outf, base_level + 5, header, NULL);
420
421                         snprintf(header, sizeof(header), "core-count");
422                         snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
423                         format_and_print(outf, base_level + 6, header, value);
424
425                         snprintf(header, sizeof(header),
426                                 "max-turbo-frequency(MHz)");
427                         snprintf(value, sizeof(value), "%d",
428                                  ctdp_level->trl_avx_active_cores[j] *
429                                   DISP_FREQ_MULTIPLIER);
430                         format_and_print(outf, base_level + 6, header, value);
431                 }
432
433                 snprintf(header, sizeof(header), "turbo-ratio-limits-avx512");
434                 format_and_print(outf, base_level + 4, header, NULL);
435                 for (j = 0; j < 8; ++j) {
436                         snprintf(header, sizeof(header), "bucket-%d", j);
437                         format_and_print(outf, base_level + 5, header, NULL);
438
439                         snprintf(header, sizeof(header), "core-count");
440                         snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
441                         format_and_print(outf, base_level + 6, header, value);
442
443                         snprintf(header, sizeof(header),
444                                 "max-turbo-frequency(MHz)");
445                         snprintf(value, sizeof(value), "%d",
446                                  ctdp_level->trl_avx_512_active_cores[j] *
447                                   DISP_FREQ_MULTIPLIER);
448                         format_and_print(outf, base_level + 6, header, value);
449                 }
450                 if (ctdp_level->pbf_support)
451                         _isst_pbf_display_information(cpu, outf, i,
452                                                       &ctdp_level->pbf_info,
453                                                       base_level + 4);
454                 if (ctdp_level->fact_support)
455                         _isst_fact_display_information(cpu, outf, i, 0xff, 0xff,
456                                                        &ctdp_level->fact_info,
457                                                        base_level + 4);
458         }
459
460         format_and_print(outf, 1, NULL, NULL);
461 }
462
463 void isst_ctdp_display_information_start(FILE *outf)
464 {
465         last_level = 0;
466         format_and_print(outf, 0, "start", NULL);
467 }
468
469 void isst_ctdp_display_information_end(FILE *outf)
470 {
471         format_and_print(outf, 0, NULL, NULL);
472 }
473
474 void isst_pbf_display_information(int cpu, FILE *outf, int level,
475                                   struct isst_pbf_info *pbf_info)
476 {
477         print_package_info(cpu, outf);
478         _isst_pbf_display_information(cpu, outf, level, pbf_info, 4);
479         format_and_print(outf, 1, NULL, NULL);
480 }
481
482 void isst_fact_display_information(int cpu, FILE *outf, int level,
483                                    int fact_bucket, int fact_avx,
484                                    struct isst_fact_info *fact_info)
485 {
486         print_package_info(cpu, outf);
487         _isst_fact_display_information(cpu, outf, level, fact_bucket, fact_avx,
488                                        fact_info, 4);
489         format_and_print(outf, 1, NULL, NULL);
490 }
491
492 void isst_clos_display_information(int cpu, FILE *outf, int clos,
493                                    struct isst_clos_config *clos_config)
494 {
495         char header[256];
496         char value[256];
497
498         snprintf(header, sizeof(header), "package-%d",
499                  get_physical_package_id(cpu));
500         format_and_print(outf, 1, header, NULL);
501         snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
502         format_and_print(outf, 2, header, NULL);
503         snprintf(header, sizeof(header), "cpu-%d", cpu);
504         format_and_print(outf, 3, header, NULL);
505
506         snprintf(header, sizeof(header), "core-power");
507         format_and_print(outf, 4, header, NULL);
508
509         snprintf(header, sizeof(header), "clos");
510         snprintf(value, sizeof(value), "%d", clos);
511         format_and_print(outf, 5, header, value);
512
513         snprintf(header, sizeof(header), "epp");
514         snprintf(value, sizeof(value), "%d", clos_config->epp);
515         format_and_print(outf, 5, header, value);
516
517         snprintf(header, sizeof(header), "clos-proportional-priority");
518         snprintf(value, sizeof(value), "%d", clos_config->clos_prop_prio);
519         format_and_print(outf, 5, header, value);
520
521         snprintf(header, sizeof(header), "clos-min");
522         snprintf(value, sizeof(value), "%d", clos_config->clos_min);
523         format_and_print(outf, 5, header, value);
524
525         snprintf(header, sizeof(header), "clos-max");
526         snprintf(value, sizeof(value), "%d", clos_config->clos_max);
527         format_and_print(outf, 5, header, value);
528
529         snprintf(header, sizeof(header), "clos-desired");
530         snprintf(value, sizeof(value), "%d", clos_config->clos_desired);
531         format_and_print(outf, 5, header, value);
532
533         format_and_print(outf, 1, NULL, NULL);
534 }
535
536 void isst_clos_display_clos_information(int cpu, FILE *outf,
537                                         int clos_enable, int type)
538 {
539         char header[256];
540         char value[256];
541
542         snprintf(header, sizeof(header), "package-%d",
543                  get_physical_package_id(cpu));
544         format_and_print(outf, 1, header, NULL);
545         snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
546         format_and_print(outf, 2, header, NULL);
547         snprintf(header, sizeof(header), "cpu-%d", cpu);
548         format_and_print(outf, 3, header, NULL);
549
550         snprintf(header, sizeof(header), "core-power");
551         format_and_print(outf, 4, header, NULL);
552
553         snprintf(header, sizeof(header), "enable-status");
554         snprintf(value, sizeof(value), "%d", clos_enable);
555         format_and_print(outf, 5, header, value);
556
557         snprintf(header, sizeof(header), "priority-type");
558         snprintf(value, sizeof(value), "%d", type);
559         format_and_print(outf, 5, header, value);
560
561         format_and_print(outf, 1, NULL, NULL);
562 }
563
564 void isst_clos_display_assoc_information(int cpu, FILE *outf, int clos)
565 {
566         char header[256];
567         char value[256];
568
569         snprintf(header, sizeof(header), "package-%d",
570                  get_physical_package_id(cpu));
571         format_and_print(outf, 1, header, NULL);
572         snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
573         format_and_print(outf, 2, header, NULL);
574         snprintf(header, sizeof(header), "cpu-%d", cpu);
575         format_and_print(outf, 3, header, NULL);
576
577         snprintf(header, sizeof(header), "get-assoc");
578         format_and_print(outf, 4, header, NULL);
579
580         snprintf(header, sizeof(header), "clos");
581         snprintf(value, sizeof(value), "%d", clos);
582         format_and_print(outf, 5, header, value);
583
584         format_and_print(outf, 1, NULL, NULL);
585 }
586
587 void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd,
588                          int result)
589 {
590         char header[256];
591         char value[256];
592
593         snprintf(header, sizeof(header), "package-%d",
594                  get_physical_package_id(cpu));
595         format_and_print(outf, 1, header, NULL);
596         snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
597         format_and_print(outf, 2, header, NULL);
598         snprintf(header, sizeof(header), "cpu-%d", cpu);
599         format_and_print(outf, 3, header, NULL);
600         snprintf(header, sizeof(header), "%s", feature);
601         format_and_print(outf, 4, header, NULL);
602         snprintf(header, sizeof(header), "%s", cmd);
603         if (!result)
604                 snprintf(value, sizeof(value), "success");
605         else
606                 snprintf(value, sizeof(value), "failed(error %d)", result);
607         format_and_print(outf, 5, header, value);
608
609         format_and_print(outf, 1, NULL, NULL);
610 }