diff options
author | Thomas Renninger <trenn@suse.de> | 2011-07-21 11:54:53 +0200 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2011-07-29 19:37:25 +0200 |
commit | 8fb2e440b223b966f74a04a48f6f71f288fa671b (patch) | |
tree | 3a9f2c19c039072d0b2641385bf0e6897bed2361 /tools/power | |
parent | 76b659a31df5174d71832b7882ef31b32e1f8d59 (diff) |
cpupower: Show Intel turbo ratio support via ./cpupower frequency-info
This adds the last piece missing from turbostat (if called with -v).
It shows on Intel machines supporting Turbo Boost how many cores
have to be active/idle to enter which boost mode (frequency).
Whether the HW really enters these boost modes can be verified via
./cpupower monitor.
Signed-off-by: Thomas Renninger <trenn@suse.de>
CC: lenb@kernel.org
CC: linux@dominikbrodowski.net
CC: cpufreq@vger.kernel.org
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'tools/power')
-rw-r--r-- | tools/power/cpupower/utils/cpufreq-info.c | 54 | ||||
-rw-r--r-- | tools/power/cpupower/utils/helpers/cpuid.c | 29 | ||||
-rw-r--r-- | tools/power/cpupower/utils/helpers/helpers.h | 13 | ||||
-rw-r--r-- | tools/power/cpupower/utils/helpers/msr.c | 16 |
4 files changed, 95 insertions, 17 deletions
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c index 8628644188cf..5a1d25f056b3 100644 --- a/tools/power/cpupower/utils/cpufreq-info.c +++ b/tools/power/cpupower/utils/cpufreq-info.c @@ -165,26 +165,56 @@ static int get_boost_mode(unsigned int cpu) printf(_(" Supported: %s\n"), support ? _("yes") : _("no")); printf(_(" Active: %s\n"), active ? _("yes") : _("no")); - /* ToDo: Only works for AMD for now... */ - if (cpupower_cpu_info.vendor == X86_VENDOR_AMD && cpupower_cpu_info.family >= 0x10) { ret = decode_pstates(cpu, cpupower_cpu_info.family, b_states, pstates, &pstate_no); if (ret) return ret; - } else - return 0; - printf(_(" Boost States: %d\n"), b_states); - printf(_(" Total States: %d\n"), pstate_no); - for (i = 0; i < pstate_no; i++) { - if (i < b_states) - printf(_(" Pstate-Pb%d: %luMHz (boost state)\n"), - i, pstates[i]); + printf(_(" Boost States: %d\n"), b_states); + printf(_(" Total States: %d\n"), pstate_no); + for (i = 0; i < pstate_no; i++) { + if (i < b_states) + printf(_(" Pstate-Pb%d: %luMHz (boost state)" + "\n"), i, pstates[i]); + else + printf(_(" Pstate-P%d: %luMHz\n"), + i - b_states, pstates[i]); + } + } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO) { + double bclk; + unsigned long long intel_turbo_ratio = 0; + unsigned int ratio; + + /* Any way to autodetect this ? */ + if (cpupower_cpu_info.caps & CPUPOWER_CAP_IS_SNB) + bclk = 100.00; else - printf(_(" Pstate-P%d: %luMHz\n"), - i - b_states, pstates[i]); + bclk = 133.33; + intel_turbo_ratio = msr_intel_get_turbo_ratio(cpu); + dprint (" Ratio: 0x%llx - bclk: %f\n", + intel_turbo_ratio, bclk); + + ratio = (intel_turbo_ratio >> 24) & 0xFF; + if (ratio) + printf(_(" %.0f MHz max turbo 4 active cores\n"), + ratio * bclk); + + ratio = (intel_turbo_ratio >> 16) & 0xFF; + if (ratio) + printf(_(" %.0f MHz max turbo 3 active cores\n"), + ratio * bclk); + + ratio = (intel_turbo_ratio >> 8) & 0xFF; + if (ratio) + printf(_(" %.0f MHz max turbo 2 active cores\n"), + ratio * bclk); + + ratio = (intel_turbo_ratio >> 0) & 0xFF; + if (ratio) + printf(_(" %.0f MHz max turbo 1 active cores\n"), + ratio * bclk); } return 0; } diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c index 944b2c1659d8..a97f091fcf2b 100644 --- a/tools/power/cpupower/utils/helpers/cpuid.c +++ b/tools/power/cpupower/utils/helpers/cpuid.c @@ -130,10 +130,37 @@ out: cpu_info->caps |= CPUPOWER_CAP_AMD_CBP; } - /* Intel's perf-bias MSR support */ if (cpu_info->vendor == X86_VENDOR_INTEL) { + /* Intel's perf-bias MSR support */ if (cpuid_level >= 6 && (cpuid_ecx(6) & (1 << 3))) cpu_info->caps |= CPUPOWER_CAP_PERF_BIAS; + + /* Intel's Turbo Ratio Limit support */ + if (cpu_info->family == 6) { + switch (cpu_info->model) { + case 0x1A: /* Core i7, Xeon 5500 series + * Bloomfield, Gainstown NHM-EP + */ + case 0x1E: /* Core i7 and i5 Processor + * Clarksfield, Lynnfield, Jasper Forest + */ + case 0x1F: /* Core i7 and i5 Processor - Nehalem */ + case 0x25: /* Westmere Client + * Clarkdale, Arrandale + */ + case 0x2C: /* Westmere EP - Gulftown */ + cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO; + case 0x2A: /* SNB */ + case 0x2D: /* SNB Xeon */ + cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO; + cpu_info->caps |= CPUPOWER_CAP_IS_SNB; + break; + case 0x2E: /* Nehalem-EX Xeon - Beckton */ + case 0x2F: /* Westmere-EX Xeon - Eagleton */ + default: + break; + } + } } /* printf("ID: %u - Extid: 0x%x - Caps: 0x%llx\n", diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index 048f065925c9..9125a551ac1d 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -52,10 +52,12 @@ extern int be_verbose; enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, X86_VENDOR_AMD, X86_VENDOR_MAX}; -#define CPUPOWER_CAP_INV_TSC 0x00000001 -#define CPUPOWER_CAP_APERF 0x00000002 -#define CPUPOWER_CAP_AMD_CBP 0x00000004 -#define CPUPOWER_CAP_PERF_BIAS 0x00000008 +#define CPUPOWER_CAP_INV_TSC 0x00000001 +#define CPUPOWER_CAP_APERF 0x00000002 +#define CPUPOWER_CAP_AMD_CBP 0x00000004 +#define CPUPOWER_CAP_PERF_BIAS 0x00000008 +#define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010 +#define CPUPOWER_CAP_IS_SNB 0x00000011 #define MAX_HW_PSTATES 10 @@ -111,6 +113,7 @@ extern int write_msr(int cpu, unsigned int idx, unsigned long long val); extern int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val); extern int msr_intel_get_perf_bias(unsigned int cpu); +extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu); extern int msr_intel_has_boost_support(unsigned int cpu); extern int msr_intel_boost_is_active(unsigned int cpu); @@ -157,6 +160,8 @@ static inline int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val) { return -1; }; static inline int msr_intel_get_perf_bias(unsigned int cpu) { return -1; }; +static inline unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu) +{ return 0; }; static inline int msr_intel_has_boost_support(unsigned int cpu) { return -1; }; diff --git a/tools/power/cpupower/utils/helpers/msr.c b/tools/power/cpupower/utils/helpers/msr.c index 93d48bd56e57..7869ca64dfd3 100644 --- a/tools/power/cpupower/utils/helpers/msr.c +++ b/tools/power/cpupower/utils/helpers/msr.c @@ -11,6 +11,7 @@ #define MSR_IA32_PERF_STATUS 0x198 #define MSR_IA32_MISC_ENABLES 0x1a0 #define MSR_IA32_ENERGY_PERF_BIAS 0x1b0 +#define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1ad /* * read_msr @@ -79,6 +80,7 @@ int msr_intel_has_boost_support(unsigned int cpu) ret = read_msr(cpu, MSR_IA32_MISC_ENABLES, &misc_enables); if (ret) return ret; + return (misc_enables >> 38) & 0x1; } @@ -119,4 +121,18 @@ int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val) return ret; return 0; } + +unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu) +{ + unsigned long long val; + int ret; + + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO)) + return -1; + + ret = read_msr(cpu, MSR_NEHALEM_TURBO_RATIO_LIMIT, &val); + if (ret) + return ret; + return val; +} #endif |