1 // SPDX-License-Identifier: GPL-2.0
3 * Intel dynamic_speed_select -- Enumerate and control features
4 * Copyright (c) 2019 Intel Corporation.
9 static void printcpulist(int str_len, char *str, int mask_size,
12 int i, first, curr_index, index;
14 if (!CPU_COUNT_S(mask_size, cpu_mask)) {
15 snprintf(str, str_len, "none");
21 for (i = 0; i < get_topo_max_cpus(); ++i) {
22 if (!CPU_ISSET_S(i, mask_size, cpu_mask))
25 index = snprintf(&str[curr_index],
26 str_len - curr_index, ",");
29 index = snprintf(&str[curr_index], str_len - curr_index, "%d",
36 static void printcpumask(int str_len, char *str, int mask_size,
39 int i, max_cpus = get_topo_max_cpus();
41 int size, index, curr_index;
43 size = max_cpus / (sizeof(unsigned int) * 8);
44 if (max_cpus % (sizeof(unsigned int) * 8))
47 mask = calloc(size, sizeof(unsigned int));
51 for (i = 0; i < max_cpus; ++i) {
52 int mask_index, bit_index;
54 if (!CPU_ISSET_S(i, mask_size, cpu_mask))
57 mask_index = i / (sizeof(unsigned int) * 8);
58 bit_index = i % (sizeof(unsigned int) * 8);
59 mask[mask_index] |= BIT(bit_index);
63 for (i = size - 1; i >= 0; --i) {
64 index = snprintf(&str[curr_index], str_len - curr_index, "%08x",
68 strncat(&str[curr_index], ",", str_len - curr_index);
76 static void format_and_print_txt(FILE *outf, int level, char *header,
80 static char delimiters[256];
87 strcpy(delimiters, " ");
89 for (i = 0; i < level - 1; ++i)
90 j += snprintf(&delimiters[j], sizeof(delimiters) - j,
94 if (header && value) {
95 fprintf(outf, "%s", delimiters);
96 fprintf(outf, "%s:%s\n", header, value);
98 fprintf(outf, "%s", delimiters);
99 fprintf(outf, "%s\n", header);
103 static int last_level;
104 static void format_and_print(FILE *outf, int level, char *header, char *value)
107 static char delimiters[256];
110 if (!out_format_is_json()) {
111 format_and_print_txt(outf, level, header, value);
119 fprintf(outf, "\n}\n");
124 for (i = 0; i < level; ++i)
125 j += snprintf(&delimiters[j], sizeof(delimiters) - j,
128 if (last_level == level)
129 fprintf(outf, ",\n");
132 if (last_level != level)
135 fprintf(outf, "%s\"%s\": ", delimiters, header);
136 fprintf(outf, "\"%s\"", value);
138 for (i = last_level - 1; i >= level; --i) {
141 for (j = i; j > 0; --j)
142 k += snprintf(&delimiters[k],
143 sizeof(delimiters) - k,
145 if (i == level && header)
146 fprintf(outf, "\n%s},", delimiters);
148 fprintf(outf, "\n%s}", delimiters);
150 if (abs(last_level - level) < 3)
153 fprintf(outf, "%s\"%s\": {", delimiters,
161 static void print_package_info(int cpu, FILE *outf)
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);
174 static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
175 struct isst_pbf_info *pbf_info,
181 snprintf(header, sizeof(header), "speed-select-base-freq");
182 format_and_print(outf, disp_level, header, NULL);
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);
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);
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);
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);
205 if (is_clx_n_platform())
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);
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);
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,
222 struct isst_fact_bucket_info *bucket_info = fact_info->bucket_info;
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)
233 if (!bucket_info[j].high_priority_cores_count)
236 snprintf(header, sizeof(header), "bucket-%d", j);
237 format_and_print(outf, base_level + 1, header, NULL);
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);
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);
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);
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);
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);
291 void isst_ctdp_display_core_info(int cpu, FILE *outf, char *prefix,
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);
305 snprintf(value, sizeof(value), "%u", val);
306 format_and_print(outf, 4, prefix, value);
308 format_and_print(outf, 1, NULL, NULL);
311 void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
312 struct isst_pkg_ctdp *pkg_dev)
316 int i, base_level = 1;
318 print_package_info(cpu, outf);
320 for (i = 0; i <= pkg_dev->levels; ++i) {
321 struct isst_pkg_ctdp_level_info *ctdp_level;
324 ctdp_level = &pkg_dev->ctdp_level[i];
325 if (!ctdp_level->processed)
328 snprintf(header, sizeof(header), "perf-profile-level-%d",
330 format_and_print(outf, base_level + 3, header, NULL);
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);
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);
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);
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);
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);
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");
365 snprintf(value, sizeof(value), "disabled");
367 snprintf(value, sizeof(value), "unsupported");
368 format_and_print(outf, base_level + 4, header, value);
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");
376 snprintf(value, sizeof(value), "disabled");
378 snprintf(value, sizeof(value), "unsupported");
379 format_and_print(outf, base_level + 4, header, value);
381 if (is_clx_n_platform()) {
382 if (ctdp_level->pbf_support)
383 _isst_pbf_display_information(cpu, outf,
385 &ctdp_level->pbf_info,
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
450 if (ctdp_level->pbf_support)
451 _isst_pbf_display_information(cpu, outf, i,
452 &ctdp_level->pbf_info,
454 if (ctdp_level->fact_support)
455 _isst_fact_display_information(cpu, outf, i, 0xff, 0xff,
456 &ctdp_level->fact_info,
460 format_and_print(outf, 1, NULL, NULL);
463 void isst_ctdp_display_information_start(FILE *outf)
466 format_and_print(outf, 0, "start", NULL);
469 void isst_ctdp_display_information_end(FILE *outf)
471 format_and_print(outf, 0, NULL, NULL);
474 void isst_pbf_display_information(int cpu, FILE *outf, int level,
475 struct isst_pbf_info *pbf_info)
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);
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)
486 print_package_info(cpu, outf);
487 _isst_fact_display_information(cpu, outf, level, fact_bucket, fact_avx,
489 format_and_print(outf, 1, NULL, NULL);
492 void isst_clos_display_information(int cpu, FILE *outf, int clos,
493 struct isst_clos_config *clos_config)
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);
506 snprintf(header, sizeof(header), "core-power");
507 format_and_print(outf, 4, header, NULL);
509 snprintf(header, sizeof(header), "clos");
510 snprintf(value, sizeof(value), "%d", clos);
511 format_and_print(outf, 5, header, value);
513 snprintf(header, sizeof(header), "epp");
514 snprintf(value, sizeof(value), "%d", clos_config->epp);
515 format_and_print(outf, 5, header, value);
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);
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);
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);
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);
533 format_and_print(outf, 1, NULL, NULL);
536 void isst_clos_display_clos_information(int cpu, FILE *outf,
537 int clos_enable, int type)
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);
550 snprintf(header, sizeof(header), "core-power");
551 format_and_print(outf, 4, header, NULL);
553 snprintf(header, sizeof(header), "enable-status");
554 snprintf(value, sizeof(value), "%d", clos_enable);
555 format_and_print(outf, 5, header, value);
557 snprintf(header, sizeof(header), "priority-type");
558 snprintf(value, sizeof(value), "%d", type);
559 format_and_print(outf, 5, header, value);
561 format_and_print(outf, 1, NULL, NULL);
564 void isst_clos_display_assoc_information(int cpu, FILE *outf, int clos)
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);
577 snprintf(header, sizeof(header), "get-assoc");
578 format_and_print(outf, 4, header, NULL);
580 snprintf(header, sizeof(header), "clos");
581 snprintf(value, sizeof(value), "%d", clos);
582 format_and_print(outf, 5, header, value);
584 format_and_print(outf, 1, NULL, NULL);
587 void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd,
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);
604 snprintf(value, sizeof(value), "success");
606 snprintf(value, sizeof(value), "failed(error %d)", result);
607 format_and_print(outf, 5, header, value);
609 format_and_print(outf, 1, NULL, NULL);