drm/panel: panel-himax-hx83102: support for csot-pna957qt1-1 MIPI-DSI panel
[drm/drm-misc.git] / tools / power / cpupower / utils / cpufreq-info.c
blobfc750e127404c25f31f6f5238193848a6d227980
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de>
4 */
7 #include <unistd.h>
8 #include <stdio.h>
9 #include <errno.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <limits.h>
14 #include <getopt.h>
16 #include "cpufreq.h"
17 #include "helpers/sysfs.h"
18 #include "helpers/helpers.h"
19 #include "helpers/bitmask.h"
21 #define LINE_LEN 10
23 static unsigned int count_cpus(void)
25 FILE *fp;
26 char value[LINE_LEN];
27 unsigned int ret = 0;
28 unsigned int cpunr = 0;
30 fp = fopen("/proc/stat", "r");
31 if (!fp) {
32 printf(_("Couldn't count the number of CPUs (%s: %s), assuming 1\n"), "/proc/stat", strerror(errno));
33 return 1;
36 while (!feof(fp)) {
37 if (!fgets(value, LINE_LEN, fp))
38 continue;
39 value[LINE_LEN - 1] = '\0';
40 if (strlen(value) < (LINE_LEN - 2))
41 continue;
42 if (strstr(value, "cpu "))
43 continue;
44 if (sscanf(value, "cpu%d ", &cpunr) != 1)
45 continue;
46 if (cpunr > ret)
47 ret = cpunr;
49 fclose(fp);
51 /* cpu count starts from 0, on error return 1 (UP) */
52 return ret + 1;
56 static void proc_cpufreq_output(void)
58 unsigned int cpu, nr_cpus;
59 struct cpufreq_policy *policy;
60 unsigned int min_pctg = 0;
61 unsigned int max_pctg = 0;
62 unsigned long min, max;
64 printf(_(" minimum CPU frequency - maximum CPU frequency - governor\n"));
66 nr_cpus = count_cpus();
67 for (cpu = 0; cpu < nr_cpus; cpu++) {
68 policy = cpufreq_get_policy(cpu);
69 if (!policy)
70 continue;
72 if (cpufreq_get_hardware_limits(cpu, &min, &max)) {
73 max = 0;
74 } else {
75 min_pctg = (policy->min * 100) / max;
76 max_pctg = (policy->max * 100) / max;
78 printf("CPU%3d %9lu kHz (%3d %%) - %9lu kHz (%3d %%) - %s\n",
79 cpu , policy->min, max ? min_pctg : 0, policy->max,
80 max ? max_pctg : 0, policy->governor);
82 cpufreq_put_policy(policy);
86 static int no_rounding;
87 static void print_duration(unsigned long duration)
89 unsigned long tmp;
91 if (no_rounding) {
92 if (duration > 1000000)
93 printf("%u.%06u ms", ((unsigned int) duration/1000000),
94 ((unsigned int) duration%1000000));
95 else if (duration > 100000)
96 printf("%u us", ((unsigned int) duration/1000));
97 else if (duration > 1000)
98 printf("%u.%03u us", ((unsigned int) duration/1000),
99 ((unsigned int) duration%1000));
100 else
101 printf("%lu ns", duration);
102 } else {
103 if (duration > 1000000) {
104 tmp = duration%10000;
105 if (tmp >= 5000)
106 duration += 10000;
107 printf("%u.%02u ms", ((unsigned int) duration/1000000),
108 ((unsigned int) (duration%1000000)/10000));
109 } else if (duration > 100000) {
110 tmp = duration%1000;
111 if (tmp >= 500)
112 duration += 1000;
113 printf("%u us", ((unsigned int) duration / 1000));
114 } else if (duration > 1000) {
115 tmp = duration%100;
116 if (tmp >= 50)
117 duration += 100;
118 printf("%u.%01u us", ((unsigned int) duration/1000),
119 ((unsigned int) (duration%1000)/100));
120 } else
121 printf("%lu ns", duration);
125 static int get_boost_mode_x86(unsigned int cpu)
127 int support, active, b_states = 0, ret, pstate_no, i;
128 /* ToDo: Make this more global */
129 unsigned long pstates[MAX_HW_PSTATES] = {0,};
131 ret = cpufreq_has_boost_support(cpu, &support, &active, &b_states);
132 if (ret) {
133 printf(_("Error while evaluating Boost Capabilities"
134 " on CPU %d -- are you root?\n"), cpu);
135 return ret;
137 /* P state changes via MSR are identified via cpuid 80000007
138 on Intel and AMD, but we assume boost capable machines can do that
139 if (cpuid_eax(0x80000000) >= 0x80000007
140 && (cpuid_edx(0x80000007) & (1 << 7)))
143 printf(_(" boost state support:\n"));
145 printf(_(" Supported: %s\n"), support ? _("yes") : _("no"));
146 printf(_(" Active: %s\n"), active ? _("yes") : _("no"));
148 if (cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
149 cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) {
150 return 0;
151 } else if ((cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
152 cpupower_cpu_info.family >= 0x10) ||
153 cpupower_cpu_info.vendor == X86_VENDOR_HYGON) {
154 ret = decode_pstates(cpu, b_states, pstates, &pstate_no);
155 if (ret)
156 return ret;
158 printf(_(" Boost States: %d\n"), b_states);
159 printf(_(" Total States: %d\n"), pstate_no);
160 for (i = 0; i < pstate_no; i++) {
161 if (!pstates[i])
162 continue;
163 if (i < b_states)
164 printf(_(" Pstate-Pb%d: %luMHz (boost state)"
165 "\n"), i, pstates[i]);
166 else
167 printf(_(" Pstate-P%d: %luMHz\n"),
168 i - b_states, pstates[i]);
170 } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO) {
171 double bclk;
172 unsigned long long intel_turbo_ratio = 0;
173 unsigned int ratio;
175 /* Any way to autodetect this ? */
176 if (cpupower_cpu_info.caps & CPUPOWER_CAP_IS_SNB)
177 bclk = 100.00;
178 else
179 bclk = 133.33;
180 intel_turbo_ratio = msr_intel_get_turbo_ratio(cpu);
181 dprint (" Ratio: 0x%llx - bclk: %f\n",
182 intel_turbo_ratio, bclk);
184 ratio = (intel_turbo_ratio >> 24) & 0xFF;
185 if (ratio)
186 printf(_(" %.0f MHz max turbo 4 active cores\n"),
187 ratio * bclk);
189 ratio = (intel_turbo_ratio >> 16) & 0xFF;
190 if (ratio)
191 printf(_(" %.0f MHz max turbo 3 active cores\n"),
192 ratio * bclk);
194 ratio = (intel_turbo_ratio >> 8) & 0xFF;
195 if (ratio)
196 printf(_(" %.0f MHz max turbo 2 active cores\n"),
197 ratio * bclk);
199 ratio = (intel_turbo_ratio >> 0) & 0xFF;
200 if (ratio)
201 printf(_(" %.0f MHz max turbo 1 active cores\n"),
202 ratio * bclk);
204 return 0;
207 /* --boost / -b */
209 static int get_boost_mode(unsigned int cpu)
211 struct cpufreq_available_frequencies *freqs;
213 if (cpupower_cpu_info.vendor == X86_VENDOR_AMD ||
214 cpupower_cpu_info.vendor == X86_VENDOR_HYGON ||
215 cpupower_cpu_info.vendor == X86_VENDOR_INTEL)
216 return get_boost_mode_x86(cpu);
218 freqs = cpufreq_get_boost_frequencies(cpu);
219 if (freqs) {
220 printf(_(" boost frequency steps: "));
221 while (freqs->next) {
222 print_speed(freqs->frequency, no_rounding);
223 printf(", ");
224 freqs = freqs->next;
226 print_speed(freqs->frequency, no_rounding);
227 printf("\n");
228 cpufreq_put_available_frequencies(freqs);
231 return 0;
234 /* --freq / -f */
236 static int get_freq_kernel(unsigned int cpu, unsigned int human)
238 unsigned long freq = cpufreq_get_freq_kernel(cpu);
239 printf(_(" current CPU frequency: "));
240 if (!freq) {
241 printf(_(" Unable to call to kernel\n"));
242 return -EINVAL;
244 if (human) {
245 print_speed(freq, no_rounding);
246 } else
247 printf("%lu", freq);
248 printf(_(" (asserted by call to kernel)\n"));
249 return 0;
253 /* --hwfreq / -w */
255 static int get_freq_hardware(unsigned int cpu, unsigned int human)
257 unsigned long freq;
259 if (cpupower_cpu_info.caps & CPUPOWER_CAP_APERF)
260 return -EINVAL;
262 freq = cpufreq_get_freq_hardware(cpu);
263 printf(_(" current CPU frequency: "));
264 if (!freq) {
265 printf("Unable to call hardware\n");
266 return -EINVAL;
268 if (human) {
269 print_speed(freq, no_rounding);
270 } else
271 printf("%lu", freq);
272 printf(_(" (asserted by call to hardware)\n"));
273 return 0;
276 /* --hwlimits / -l */
278 static int get_hardware_limits(unsigned int cpu, unsigned int human)
280 unsigned long min, max;
282 if (cpufreq_get_hardware_limits(cpu, &min, &max)) {
283 printf(_("Not Available\n"));
284 return -EINVAL;
287 if (human) {
288 printf(_(" hardware limits: "));
289 print_speed(min, no_rounding);
290 printf(" - ");
291 print_speed(max, no_rounding);
292 printf("\n");
293 } else {
294 printf("%lu %lu\n", min, max);
296 return 0;
299 /* --driver / -d */
301 static int get_driver(unsigned int cpu)
303 char *driver = cpufreq_get_driver(cpu);
304 if (!driver) {
305 printf(_(" no or unknown cpufreq driver is active on this CPU\n"));
306 return -EINVAL;
308 printf(" driver: %s\n", driver);
309 cpufreq_put_driver(driver);
310 return 0;
313 /* --policy / -p */
315 static int get_policy(unsigned int cpu)
317 struct cpufreq_policy *policy = cpufreq_get_policy(cpu);
318 if (!policy) {
319 printf(_(" Unable to determine current policy\n"));
320 return -EINVAL;
322 printf(_(" current policy: frequency should be within "));
323 print_speed(policy->min, no_rounding);
324 printf(_(" and "));
325 print_speed(policy->max, no_rounding);
327 printf(".\n ");
328 printf(_("The governor \"%s\" may decide which speed to use\n"
329 " within this range.\n"),
330 policy->governor);
331 cpufreq_put_policy(policy);
332 return 0;
335 /* --governors / -g */
337 static int get_available_governors(unsigned int cpu)
339 struct cpufreq_available_governors *governors =
340 cpufreq_get_available_governors(cpu);
342 printf(_(" available cpufreq governors: "));
343 if (!governors) {
344 printf(_("Not Available\n"));
345 return -EINVAL;
348 while (governors->next) {
349 printf("%s ", governors->governor);
350 governors = governors->next;
352 printf("%s\n", governors->governor);
353 cpufreq_put_available_governors(governors);
354 return 0;
358 /* --affected-cpus / -a */
360 static int get_affected_cpus(unsigned int cpu)
362 struct cpufreq_affected_cpus *cpus = cpufreq_get_affected_cpus(cpu);
364 printf(_(" CPUs which need to have their frequency coordinated by software: "));
365 if (!cpus) {
366 printf(_("Not Available\n"));
367 return -EINVAL;
370 while (cpus->next) {
371 printf("%d ", cpus->cpu);
372 cpus = cpus->next;
374 printf("%d\n", cpus->cpu);
375 cpufreq_put_affected_cpus(cpus);
376 return 0;
379 /* --related-cpus / -r */
381 static int get_related_cpus(unsigned int cpu)
383 struct cpufreq_affected_cpus *cpus = cpufreq_get_related_cpus(cpu);
385 printf(_(" CPUs which run at the same hardware frequency: "));
386 if (!cpus) {
387 printf(_("Not Available\n"));
388 return -EINVAL;
391 while (cpus->next) {
392 printf("%d ", cpus->cpu);
393 cpus = cpus->next;
395 printf("%d\n", cpus->cpu);
396 cpufreq_put_related_cpus(cpus);
397 return 0;
400 /* --stats / -s */
402 static int get_freq_stats(unsigned int cpu, unsigned int human)
404 unsigned long total_trans = cpufreq_get_transitions(cpu);
405 unsigned long long total_time;
406 struct cpufreq_stats *stats = cpufreq_get_stats(cpu, &total_time);
407 while (stats) {
408 if (human) {
409 print_speed(stats->frequency, no_rounding);
410 printf(":%.2f%%",
411 (100.0 * stats->time_in_state) / total_time);
412 } else
413 printf("%lu:%llu",
414 stats->frequency, stats->time_in_state);
415 stats = stats->next;
416 if (stats)
417 printf(", ");
419 cpufreq_put_stats(stats);
420 if (total_trans)
421 printf(" (%lu)\n", total_trans);
422 return 0;
425 /* --epp / -z */
427 static int get_epp(unsigned int cpu, bool interactive)
429 char *epp;
431 epp = cpufreq_get_energy_performance_preference(cpu);
432 if (!epp)
433 return -EINVAL;
434 if (interactive)
435 printf(_(" energy performance preference: %s\n"), epp);
437 cpufreq_put_energy_performance_preference(epp);
439 return 0;
442 /* --latency / -y */
444 static int get_latency(unsigned int cpu, unsigned int human)
446 unsigned long latency = cpufreq_get_transition_latency(cpu);
448 if (!get_epp(cpu, false))
449 return -EINVAL;
451 printf(_(" maximum transition latency: "));
452 if (!latency || latency == UINT_MAX) {
453 printf(_(" Cannot determine or is not supported.\n"));
454 return -EINVAL;
457 if (human) {
458 print_duration(latency);
459 printf("\n");
460 } else
461 printf("%lu\n", latency);
462 return 0;
465 /* --performance / -c */
467 static int get_perf_cap(unsigned int cpu)
469 if (cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
470 cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE)
471 amd_pstate_show_perf_and_freq(cpu, no_rounding);
473 return 0;
476 static void debug_output_one(unsigned int cpu)
478 struct cpufreq_available_frequencies *freqs;
480 get_driver(cpu);
481 get_related_cpus(cpu);
482 get_affected_cpus(cpu);
483 get_latency(cpu, 1);
484 get_epp(cpu, true);
485 get_hardware_limits(cpu, 1);
487 freqs = cpufreq_get_available_frequencies(cpu);
488 if (freqs) {
489 printf(_(" available frequency steps: "));
490 while (freqs->next) {
491 print_speed(freqs->frequency, no_rounding);
492 printf(", ");
493 freqs = freqs->next;
495 print_speed(freqs->frequency, no_rounding);
496 printf("\n");
497 cpufreq_put_available_frequencies(freqs);
500 get_available_governors(cpu);
501 get_policy(cpu);
502 if (get_freq_hardware(cpu, 1) < 0)
503 get_freq_kernel(cpu, 1);
504 get_boost_mode(cpu);
505 get_perf_cap(cpu);
508 static struct option info_opts[] = {
509 {"debug", no_argument, NULL, 'e'},
510 {"boost", no_argument, NULL, 'b'},
511 {"freq", no_argument, NULL, 'f'},
512 {"hwfreq", no_argument, NULL, 'w'},
513 {"hwlimits", no_argument, NULL, 'l'},
514 {"driver", no_argument, NULL, 'd'},
515 {"policy", no_argument, NULL, 'p'},
516 {"governors", no_argument, NULL, 'g'},
517 {"related-cpus", no_argument, NULL, 'r'},
518 {"affected-cpus", no_argument, NULL, 'a'},
519 {"stats", no_argument, NULL, 's'},
520 {"latency", no_argument, NULL, 'y'},
521 {"proc", no_argument, NULL, 'o'},
522 {"human", no_argument, NULL, 'm'},
523 {"no-rounding", no_argument, NULL, 'n'},
524 {"performance", no_argument, NULL, 'c'},
525 {"epp", no_argument, NULL, 'z'},
526 { },
529 int cmd_freq_info(int argc, char **argv)
531 extern char *optarg;
532 extern int optind, opterr, optopt;
533 int ret = 0, cont = 1;
534 unsigned int cpu = 0;
535 unsigned int human = 0;
536 int output_param = 0;
538 do {
539 ret = getopt_long(argc, argv, "oefwldpgrasmybncz", info_opts,
540 NULL);
541 switch (ret) {
542 case '?':
543 output_param = '?';
544 cont = 0;
545 break;
546 case -1:
547 cont = 0;
548 break;
549 case 'b':
550 case 'o':
551 case 'a':
552 case 'r':
553 case 'g':
554 case 'p':
555 case 'd':
556 case 'l':
557 case 'w':
558 case 'f':
559 case 'e':
560 case 's':
561 case 'y':
562 case 'c':
563 case 'z':
564 if (output_param) {
565 output_param = -1;
566 cont = 0;
567 break;
569 output_param = ret;
570 break;
571 case 'm':
572 if (human) {
573 output_param = -1;
574 cont = 0;
575 break;
577 human = 1;
578 break;
579 case 'n':
580 no_rounding = 1;
581 break;
582 default:
583 fprintf(stderr, "invalid or unknown argument\n");
584 return EXIT_FAILURE;
586 } while (cont);
588 switch (output_param) {
589 case 'o':
590 if (!bitmask_isallclear(cpus_chosen)) {
591 printf(_("The argument passed to this tool can't be "
592 "combined with passing a --cpu argument\n"));
593 return -EINVAL;
595 break;
596 case 0:
597 output_param = 'e';
600 ret = 0;
602 /* Default is: show output of base_cpu only */
603 if (bitmask_isallclear(cpus_chosen))
604 bitmask_setbit(cpus_chosen, base_cpu);
606 switch (output_param) {
607 case -1:
608 printf(_("You can't specify more than one --cpu parameter and/or\n"
609 "more than one output-specific argument\n"));
610 return -EINVAL;
611 case '?':
612 printf(_("invalid or unknown argument\n"));
613 return -EINVAL;
614 case 'o':
615 proc_cpufreq_output();
616 return EXIT_SUCCESS;
619 for (cpu = bitmask_first(cpus_chosen);
620 cpu <= bitmask_last(cpus_chosen); cpu++) {
622 if (!bitmask_isbitset(cpus_chosen, cpu))
623 continue;
625 printf(_("analyzing CPU %d:\n"), cpu);
627 if (sysfs_is_cpu_online(cpu) != 1) {
628 printf(_(" *is offline\n"));
629 printf("\n");
630 continue;
633 switch (output_param) {
634 case 'b':
635 get_boost_mode(cpu);
636 break;
637 case 'e':
638 debug_output_one(cpu);
639 break;
640 case 'a':
641 ret = get_affected_cpus(cpu);
642 break;
643 case 'r':
644 ret = get_related_cpus(cpu);
645 break;
646 case 'g':
647 ret = get_available_governors(cpu);
648 break;
649 case 'p':
650 ret = get_policy(cpu);
651 break;
652 case 'd':
653 ret = get_driver(cpu);
654 break;
655 case 'l':
656 ret = get_hardware_limits(cpu, human);
657 break;
658 case 'w':
659 ret = get_freq_hardware(cpu, human);
660 break;
661 case 'f':
662 ret = get_freq_kernel(cpu, human);
663 break;
664 case 's':
665 ret = get_freq_stats(cpu, human);
666 break;
667 case 'y':
668 ret = get_latency(cpu, human);
669 break;
670 case 'c':
671 ret = get_perf_cap(cpu);
672 break;
673 case 'z':
674 ret = get_epp(cpu, true);
675 break;
677 if (ret)
678 return ret;
680 return ret;