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