irqchip: Fix dependencies for archs w/o HAS_IOMEM
[linux/fpc-iii.git] / tools / power / cpupower / utils / cpufreq-info.c
blob0e676433024109bef6d9a87e08709c40be37b2df
1 /*
2 * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de>
4 * Licensed under the terms of the GNU GPL License version 2.
5 */
8 #include <unistd.h>
9 #include <stdio.h>
10 #include <errno.h>
11 #include <stdlib.h>
12 #include <string.h>
14 #include <getopt.h>
16 #include "cpufreq.h"
17 #include "helpers/helpers.h"
18 #include "helpers/bitmask.h"
20 #define LINE_LEN 10
22 static unsigned int count_cpus(void)
24 FILE *fp;
25 char value[LINE_LEN];
26 unsigned int ret = 0;
27 unsigned int cpunr = 0;
29 fp = fopen("/proc/stat", "r");
30 if (!fp) {
31 printf(_("Couldn't count the number of CPUs (%s: %s), assuming 1\n"), "/proc/stat", strerror(errno));
32 return 1;
35 while (!feof(fp)) {
36 if (!fgets(value, LINE_LEN, fp))
37 continue;
38 value[LINE_LEN - 1] = '\0';
39 if (strlen(value) < (LINE_LEN - 2))
40 continue;
41 if (strstr(value, "cpu "))
42 continue;
43 if (sscanf(value, "cpu%d ", &cpunr) != 1)
44 continue;
45 if (cpunr > ret)
46 ret = cpunr;
48 fclose(fp);
50 /* cpu count starts from 0, on error return 1 (UP) */
51 return ret + 1;
55 static void proc_cpufreq_output(void)
57 unsigned int cpu, nr_cpus;
58 struct cpufreq_policy *policy;
59 unsigned int min_pctg = 0;
60 unsigned int max_pctg = 0;
61 unsigned long min, max;
63 printf(_(" minimum CPU frequency - maximum CPU frequency - governor\n"));
65 nr_cpus = count_cpus();
66 for (cpu = 0; cpu < nr_cpus; cpu++) {
67 policy = cpufreq_get_policy(cpu);
68 if (!policy)
69 continue;
71 if (cpufreq_get_hardware_limits(cpu, &min, &max)) {
72 max = 0;
73 } else {
74 min_pctg = (policy->min * 100) / max;
75 max_pctg = (policy->max * 100) / max;
77 printf("CPU%3d %9lu kHz (%3d %%) - %9lu kHz (%3d %%) - %s\n",
78 cpu , policy->min, max ? min_pctg : 0, policy->max,
79 max ? max_pctg : 0, policy->governor);
81 cpufreq_put_policy(policy);
85 static int no_rounding;
86 static void print_speed(unsigned long speed)
88 unsigned long tmp;
90 if (no_rounding) {
91 if (speed > 1000000)
92 printf("%u.%06u GHz", ((unsigned int) speed/1000000),
93 ((unsigned int) speed%1000000));
94 else if (speed > 100000)
95 printf("%u MHz", (unsigned int) speed);
96 else if (speed > 1000)
97 printf("%u.%03u MHz", ((unsigned int) speed/1000),
98 (unsigned int) (speed%1000));
99 else
100 printf("%lu kHz", speed);
101 } else {
102 if (speed > 1000000) {
103 tmp = speed%10000;
104 if (tmp >= 5000)
105 speed += 10000;
106 printf("%u.%02u GHz", ((unsigned int) speed/1000000),
107 ((unsigned int) (speed%1000000)/10000));
108 } else if (speed > 100000) {
109 tmp = speed%1000;
110 if (tmp >= 500)
111 speed += 1000;
112 printf("%u MHz", ((unsigned int) speed/1000));
113 } else if (speed > 1000) {
114 tmp = speed%100;
115 if (tmp >= 50)
116 speed += 100;
117 printf("%u.%01u MHz", ((unsigned int) speed/1000),
118 ((unsigned int) (speed%1000)/100));
122 return;
125 static void print_duration(unsigned long duration)
127 unsigned long tmp;
129 if (no_rounding) {
130 if (duration > 1000000)
131 printf("%u.%06u ms", ((unsigned int) duration/1000000),
132 ((unsigned int) duration%1000000));
133 else if (duration > 100000)
134 printf("%u us", ((unsigned int) duration/1000));
135 else if (duration > 1000)
136 printf("%u.%03u us", ((unsigned int) duration/1000),
137 ((unsigned int) duration%1000));
138 else
139 printf("%lu ns", duration);
140 } else {
141 if (duration > 1000000) {
142 tmp = duration%10000;
143 if (tmp >= 5000)
144 duration += 10000;
145 printf("%u.%02u ms", ((unsigned int) duration/1000000),
146 ((unsigned int) (duration%1000000)/10000));
147 } else if (duration > 100000) {
148 tmp = duration%1000;
149 if (tmp >= 500)
150 duration += 1000;
151 printf("%u us", ((unsigned int) duration / 1000));
152 } else if (duration > 1000) {
153 tmp = duration%100;
154 if (tmp >= 50)
155 duration += 100;
156 printf("%u.%01u us", ((unsigned int) duration/1000),
157 ((unsigned int) (duration%1000)/100));
158 } else
159 printf("%lu ns", duration);
161 return;
164 /* --boost / -b */
166 static int get_boost_mode(unsigned int cpu)
168 int support, active, b_states = 0, ret, pstate_no, i;
169 /* ToDo: Make this more global */
170 unsigned long pstates[MAX_HW_PSTATES] = {0,};
172 if (cpupower_cpu_info.vendor != X86_VENDOR_AMD &&
173 cpupower_cpu_info.vendor != X86_VENDOR_INTEL)
174 return 0;
176 ret = cpufreq_has_boost_support(cpu, &support, &active, &b_states);
177 if (ret) {
178 printf(_("Error while evaluating Boost Capabilities"
179 " on CPU %d -- are you root?\n"), cpu);
180 return ret;
182 /* P state changes via MSR are identified via cpuid 80000007
183 on Intel and AMD, but we assume boost capable machines can do that
184 if (cpuid_eax(0x80000000) >= 0x80000007
185 && (cpuid_edx(0x80000007) & (1 << 7)))
188 printf(_(" boost state support:\n"));
190 printf(_(" Supported: %s\n"), support ? _("yes") : _("no"));
191 printf(_(" Active: %s\n"), active ? _("yes") : _("no"));
193 if (cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
194 cpupower_cpu_info.family >= 0x10) {
195 ret = decode_pstates(cpu, cpupower_cpu_info.family, b_states,
196 pstates, &pstate_no);
197 if (ret)
198 return ret;
200 printf(_(" Boost States: %d\n"), b_states);
201 printf(_(" Total States: %d\n"), pstate_no);
202 for (i = 0; i < pstate_no; i++) {
203 if (i < b_states)
204 printf(_(" Pstate-Pb%d: %luMHz (boost state)"
205 "\n"), i, pstates[i]);
206 else
207 printf(_(" Pstate-P%d: %luMHz\n"),
208 i - b_states, pstates[i]);
210 } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO) {
211 double bclk;
212 unsigned long long intel_turbo_ratio = 0;
213 unsigned int ratio;
215 /* Any way to autodetect this ? */
216 if (cpupower_cpu_info.caps & CPUPOWER_CAP_IS_SNB)
217 bclk = 100.00;
218 else
219 bclk = 133.33;
220 intel_turbo_ratio = msr_intel_get_turbo_ratio(cpu);
221 dprint (" Ratio: 0x%llx - bclk: %f\n",
222 intel_turbo_ratio, bclk);
224 ratio = (intel_turbo_ratio >> 24) & 0xFF;
225 if (ratio)
226 printf(_(" %.0f MHz max turbo 4 active cores\n"),
227 ratio * bclk);
229 ratio = (intel_turbo_ratio >> 16) & 0xFF;
230 if (ratio)
231 printf(_(" %.0f MHz max turbo 3 active cores\n"),
232 ratio * bclk);
234 ratio = (intel_turbo_ratio >> 8) & 0xFF;
235 if (ratio)
236 printf(_(" %.0f MHz max turbo 2 active cores\n"),
237 ratio * bclk);
239 ratio = (intel_turbo_ratio >> 0) & 0xFF;
240 if (ratio)
241 printf(_(" %.0f MHz max turbo 1 active cores\n"),
242 ratio * bclk);
244 return 0;
247 static void debug_output_one(unsigned int cpu)
249 char *driver;
250 struct cpufreq_affected_cpus *cpus;
251 struct cpufreq_available_frequencies *freqs;
252 unsigned long min, max, freq_kernel, freq_hardware;
253 unsigned long total_trans, latency;
254 unsigned long long total_time;
255 struct cpufreq_policy *policy;
256 struct cpufreq_available_governors *governors;
257 struct cpufreq_stats *stats;
259 if (cpufreq_cpu_exists(cpu))
260 return;
262 freq_kernel = cpufreq_get_freq_kernel(cpu);
263 freq_hardware = cpufreq_get_freq_hardware(cpu);
265 driver = cpufreq_get_driver(cpu);
266 if (!driver) {
267 printf(_(" no or unknown cpufreq driver is active on this CPU\n"));
268 } else {
269 printf(_(" driver: %s\n"), driver);
270 cpufreq_put_driver(driver);
273 cpus = cpufreq_get_related_cpus(cpu);
274 if (cpus) {
275 printf(_(" CPUs which run at the same hardware frequency: "));
276 while (cpus->next) {
277 printf("%d ", cpus->cpu);
278 cpus = cpus->next;
280 printf("%d\n", cpus->cpu);
281 cpufreq_put_related_cpus(cpus);
284 cpus = cpufreq_get_affected_cpus(cpu);
285 if (cpus) {
286 printf(_(" CPUs which need to have their frequency coordinated by software: "));
287 while (cpus->next) {
288 printf("%d ", cpus->cpu);
289 cpus = cpus->next;
291 printf("%d\n", cpus->cpu);
292 cpufreq_put_affected_cpus(cpus);
295 latency = cpufreq_get_transition_latency(cpu);
296 if (latency) {
297 printf(_(" maximum transition latency: "));
298 print_duration(latency);
299 printf(".\n");
302 if (!(cpufreq_get_hardware_limits(cpu, &min, &max))) {
303 printf(_(" hardware limits: "));
304 print_speed(min);
305 printf(" - ");
306 print_speed(max);
307 printf("\n");
310 freqs = cpufreq_get_available_frequencies(cpu);
311 if (freqs) {
312 printf(_(" available frequency steps: "));
313 while (freqs->next) {
314 print_speed(freqs->frequency);
315 printf(", ");
316 freqs = freqs->next;
318 print_speed(freqs->frequency);
319 printf("\n");
320 cpufreq_put_available_frequencies(freqs);
323 governors = cpufreq_get_available_governors(cpu);
324 if (governors) {
325 printf(_(" available cpufreq governors: "));
326 while (governors->next) {
327 printf("%s, ", governors->governor);
328 governors = governors->next;
330 printf("%s\n", governors->governor);
331 cpufreq_put_available_governors(governors);
334 policy = cpufreq_get_policy(cpu);
335 if (policy) {
336 printf(_(" current policy: frequency should be within "));
337 print_speed(policy->min);
338 printf(_(" and "));
339 print_speed(policy->max);
341 printf(".\n ");
342 printf(_("The governor \"%s\" may"
343 " decide which speed to use\n within this range.\n"),
344 policy->governor);
345 cpufreq_put_policy(policy);
348 if (freq_kernel || freq_hardware) {
349 printf(_(" current CPU frequency is "));
350 if (freq_hardware) {
351 print_speed(freq_hardware);
352 printf(_(" (asserted by call to hardware)"));
353 } else
354 print_speed(freq_kernel);
355 printf(".\n");
357 stats = cpufreq_get_stats(cpu, &total_time);
358 if (stats) {
359 printf(_(" cpufreq stats: "));
360 while (stats) {
361 print_speed(stats->frequency);
362 printf(":%.2f%%", (100.0 * stats->time_in_state) / total_time);
363 stats = stats->next;
364 if (stats)
365 printf(", ");
367 cpufreq_put_stats(stats);
368 total_trans = cpufreq_get_transitions(cpu);
369 if (total_trans)
370 printf(" (%lu)\n", total_trans);
371 else
372 printf("\n");
374 get_boost_mode(cpu);
378 /* --freq / -f */
380 static int get_freq_kernel(unsigned int cpu, unsigned int human)
382 unsigned long freq = cpufreq_get_freq_kernel(cpu);
383 if (!freq)
384 return -EINVAL;
385 if (human) {
386 print_speed(freq);
387 printf("\n");
388 } else
389 printf("%lu\n", freq);
390 return 0;
394 /* --hwfreq / -w */
396 static int get_freq_hardware(unsigned int cpu, unsigned int human)
398 unsigned long freq = cpufreq_get_freq_hardware(cpu);
399 if (!freq)
400 return -EINVAL;
401 if (human) {
402 print_speed(freq);
403 printf("\n");
404 } else
405 printf("%lu\n", freq);
406 return 0;
409 /* --hwlimits / -l */
411 static int get_hardware_limits(unsigned int cpu)
413 unsigned long min, max;
414 if (cpufreq_get_hardware_limits(cpu, &min, &max))
415 return -EINVAL;
416 printf("%lu %lu\n", min, max);
417 return 0;
420 /* --driver / -d */
422 static int get_driver(unsigned int cpu)
424 char *driver = cpufreq_get_driver(cpu);
425 if (!driver)
426 return -EINVAL;
427 printf("%s\n", driver);
428 cpufreq_put_driver(driver);
429 return 0;
432 /* --policy / -p */
434 static int get_policy(unsigned int cpu)
436 struct cpufreq_policy *policy = cpufreq_get_policy(cpu);
437 if (!policy)
438 return -EINVAL;
439 printf("%lu %lu %s\n", policy->min, policy->max, policy->governor);
440 cpufreq_put_policy(policy);
441 return 0;
444 /* --governors / -g */
446 static int get_available_governors(unsigned int cpu)
448 struct cpufreq_available_governors *governors =
449 cpufreq_get_available_governors(cpu);
450 if (!governors)
451 return -EINVAL;
453 while (governors->next) {
454 printf("%s ", governors->governor);
455 governors = governors->next;
457 printf("%s\n", governors->governor);
458 cpufreq_put_available_governors(governors);
459 return 0;
463 /* --affected-cpus / -a */
465 static int get_affected_cpus(unsigned int cpu)
467 struct cpufreq_affected_cpus *cpus = cpufreq_get_affected_cpus(cpu);
468 if (!cpus)
469 return -EINVAL;
471 while (cpus->next) {
472 printf("%d ", cpus->cpu);
473 cpus = cpus->next;
475 printf("%d\n", cpus->cpu);
476 cpufreq_put_affected_cpus(cpus);
477 return 0;
480 /* --related-cpus / -r */
482 static int get_related_cpus(unsigned int cpu)
484 struct cpufreq_affected_cpus *cpus = cpufreq_get_related_cpus(cpu);
485 if (!cpus)
486 return -EINVAL;
488 while (cpus->next) {
489 printf("%d ", cpus->cpu);
490 cpus = cpus->next;
492 printf("%d\n", cpus->cpu);
493 cpufreq_put_related_cpus(cpus);
494 return 0;
497 /* --stats / -s */
499 static int get_freq_stats(unsigned int cpu, unsigned int human)
501 unsigned long total_trans = cpufreq_get_transitions(cpu);
502 unsigned long long total_time;
503 struct cpufreq_stats *stats = cpufreq_get_stats(cpu, &total_time);
504 while (stats) {
505 if (human) {
506 print_speed(stats->frequency);
507 printf(":%.2f%%",
508 (100.0 * stats->time_in_state) / total_time);
509 } else
510 printf("%lu:%llu",
511 stats->frequency, stats->time_in_state);
512 stats = stats->next;
513 if (stats)
514 printf(", ");
516 cpufreq_put_stats(stats);
517 if (total_trans)
518 printf(" (%lu)\n", total_trans);
519 return 0;
522 /* --latency / -y */
524 static int get_latency(unsigned int cpu, unsigned int human)
526 unsigned long latency = cpufreq_get_transition_latency(cpu);
527 if (!latency)
528 return -EINVAL;
530 if (human) {
531 print_duration(latency);
532 printf("\n");
533 } else
534 printf("%lu\n", latency);
535 return 0;
538 static struct option info_opts[] = {
539 {"debug", no_argument, NULL, 'e'},
540 {"boost", no_argument, NULL, 'b'},
541 {"freq", no_argument, NULL, 'f'},
542 {"hwfreq", no_argument, NULL, 'w'},
543 {"hwlimits", no_argument, NULL, 'l'},
544 {"driver", no_argument, NULL, 'd'},
545 {"policy", no_argument, NULL, 'p'},
546 {"governors", no_argument, NULL, 'g'},
547 {"related-cpus", no_argument, NULL, 'r'},
548 {"affected-cpus", no_argument, NULL, 'a'},
549 {"stats", no_argument, NULL, 's'},
550 {"latency", no_argument, NULL, 'y'},
551 {"proc", no_argument, NULL, 'o'},
552 {"human", no_argument, NULL, 'm'},
553 {"no-rounding", no_argument, NULL, 'n'},
554 { },
557 int cmd_freq_info(int argc, char **argv)
559 extern char *optarg;
560 extern int optind, opterr, optopt;
561 int ret = 0, cont = 1;
562 unsigned int cpu = 0;
563 unsigned int human = 0;
564 int output_param = 0;
566 do {
567 ret = getopt_long(argc, argv, "oefwldpgrasmybn", info_opts,
568 NULL);
569 switch (ret) {
570 case '?':
571 output_param = '?';
572 cont = 0;
573 break;
574 case -1:
575 cont = 0;
576 break;
577 case 'b':
578 case 'o':
579 case 'a':
580 case 'r':
581 case 'g':
582 case 'p':
583 case 'd':
584 case 'l':
585 case 'w':
586 case 'f':
587 case 'e':
588 case 's':
589 case 'y':
590 if (output_param) {
591 output_param = -1;
592 cont = 0;
593 break;
595 output_param = ret;
596 break;
597 case 'm':
598 if (human) {
599 output_param = -1;
600 cont = 0;
601 break;
603 human = 1;
604 break;
605 case 'n':
606 no_rounding = 1;
607 break;
608 default:
609 fprintf(stderr, "invalid or unknown argument\n");
610 return EXIT_FAILURE;
612 } while (cont);
614 switch (output_param) {
615 case 'o':
616 if (!bitmask_isallclear(cpus_chosen)) {
617 printf(_("The argument passed to this tool can't be "
618 "combined with passing a --cpu argument\n"));
619 return -EINVAL;
621 break;
622 case 0:
623 output_param = 'e';
626 ret = 0;
628 /* Default is: show output of CPU 0 only */
629 if (bitmask_isallclear(cpus_chosen))
630 bitmask_setbit(cpus_chosen, 0);
632 switch (output_param) {
633 case -1:
634 printf(_("You can't specify more than one --cpu parameter and/or\n"
635 "more than one output-specific argument\n"));
636 return -EINVAL;
637 case '?':
638 printf(_("invalid or unknown argument\n"));
639 return -EINVAL;
640 case 'o':
641 proc_cpufreq_output();
642 return EXIT_SUCCESS;
645 for (cpu = bitmask_first(cpus_chosen);
646 cpu <= bitmask_last(cpus_chosen); cpu++) {
648 if (!bitmask_isbitset(cpus_chosen, cpu))
649 continue;
650 if (cpufreq_cpu_exists(cpu)) {
651 printf(_("couldn't analyze CPU %d as it doesn't seem to be present\n"), cpu);
652 continue;
654 printf(_("analyzing CPU %d:\n"), cpu);
656 switch (output_param) {
657 case 'b':
658 get_boost_mode(cpu);
659 break;
660 case 'e':
661 debug_output_one(cpu);
662 break;
663 case 'a':
664 ret = get_affected_cpus(cpu);
665 break;
666 case 'r':
667 ret = get_related_cpus(cpu);
668 break;
669 case 'g':
670 ret = get_available_governors(cpu);
671 break;
672 case 'p':
673 ret = get_policy(cpu);
674 break;
675 case 'd':
676 ret = get_driver(cpu);
677 break;
678 case 'l':
679 ret = get_hardware_limits(cpu);
680 break;
681 case 'w':
682 ret = get_freq_hardware(cpu, human);
683 break;
684 case 'f':
685 ret = get_freq_kernel(cpu, human);
686 break;
687 case 's':
688 ret = get_freq_stats(cpu, human);
689 break;
690 case 'y':
691 ret = get_latency(cpu, human);
692 break;
694 if (ret)
695 return ret;
697 return ret;