diff options
Diffstat (limited to 'drivers/cpufreq/intel_pstate.c')
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index f6dd1e761129..ad72922919ed 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -358,14 +358,14 @@ static void intel_pstate_sysfs_expose_params(void) | |||
358 | static int intel_pstate_min_pstate(void) | 358 | static int intel_pstate_min_pstate(void) |
359 | { | 359 | { |
360 | u64 value; | 360 | u64 value; |
361 | rdmsrl(0xCE, value); | 361 | rdmsrl(MSR_PLATFORM_INFO, value); |
362 | return (value >> 40) & 0xFF; | 362 | return (value >> 40) & 0xFF; |
363 | } | 363 | } |
364 | 364 | ||
365 | static int intel_pstate_max_pstate(void) | 365 | static int intel_pstate_max_pstate(void) |
366 | { | 366 | { |
367 | u64 value; | 367 | u64 value; |
368 | rdmsrl(0xCE, value); | 368 | rdmsrl(MSR_PLATFORM_INFO, value); |
369 | return (value >> 8) & 0xFF; | 369 | return (value >> 8) & 0xFF; |
370 | } | 370 | } |
371 | 371 | ||
@@ -373,7 +373,7 @@ static int intel_pstate_turbo_pstate(void) | |||
373 | { | 373 | { |
374 | u64 value; | 374 | u64 value; |
375 | int nont, ret; | 375 | int nont, ret; |
376 | rdmsrl(0x1AD, value); | 376 | rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value); |
377 | nont = intel_pstate_max_pstate(); | 377 | nont = intel_pstate_max_pstate(); |
378 | ret = ((value) & 255); | 378 | ret = ((value) & 255); |
379 | if (ret <= nont) | 379 | if (ret <= nont) |
@@ -454,7 +454,7 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu, | |||
454 | sample->idletime_us * 100, | 454 | sample->idletime_us * 100, |
455 | sample->duration_us); | 455 | sample->duration_us); |
456 | core_pct = div64_u64(sample->aperf * 100, sample->mperf); | 456 | core_pct = div64_u64(sample->aperf * 100, sample->mperf); |
457 | sample->freq = cpu->pstate.turbo_pstate * core_pct * 1000; | 457 | sample->freq = cpu->pstate.max_pstate * core_pct * 1000; |
458 | 458 | ||
459 | sample->core_pct_busy = div_s64((sample->pstate_pct_busy * core_pct), | 459 | sample->core_pct_busy = div_s64((sample->pstate_pct_busy * core_pct), |
460 | 100); | 460 | 100); |
@@ -752,6 +752,29 @@ static struct cpufreq_driver intel_pstate_driver = { | |||
752 | 752 | ||
753 | static int __initdata no_load; | 753 | static int __initdata no_load; |
754 | 754 | ||
755 | static int intel_pstate_msrs_not_valid(void) | ||
756 | { | ||
757 | /* Check that all the msr's we are using are valid. */ | ||
758 | u64 aperf, mperf, tmp; | ||
759 | |||
760 | rdmsrl(MSR_IA32_APERF, aperf); | ||
761 | rdmsrl(MSR_IA32_MPERF, mperf); | ||
762 | |||
763 | if (!intel_pstate_min_pstate() || | ||
764 | !intel_pstate_max_pstate() || | ||
765 | !intel_pstate_turbo_pstate()) | ||
766 | return -ENODEV; | ||
767 | |||
768 | rdmsrl(MSR_IA32_APERF, tmp); | ||
769 | if (!(tmp - aperf)) | ||
770 | return -ENODEV; | ||
771 | |||
772 | rdmsrl(MSR_IA32_MPERF, tmp); | ||
773 | if (!(tmp - mperf)) | ||
774 | return -ENODEV; | ||
775 | |||
776 | return 0; | ||
777 | } | ||
755 | static int __init intel_pstate_init(void) | 778 | static int __init intel_pstate_init(void) |
756 | { | 779 | { |
757 | int cpu, rc = 0; | 780 | int cpu, rc = 0; |
@@ -764,6 +787,9 @@ static int __init intel_pstate_init(void) | |||
764 | if (!id) | 787 | if (!id) |
765 | return -ENODEV; | 788 | return -ENODEV; |
766 | 789 | ||
790 | if (intel_pstate_msrs_not_valid()) | ||
791 | return -ENODEV; | ||
792 | |||
767 | pr_info("Intel P-state driver initializing.\n"); | 793 | pr_info("Intel P-state driver initializing.\n"); |
768 | 794 | ||
769 | all_cpu_data = vmalloc(sizeof(void *) * num_possible_cpus()); | 795 | all_cpu_data = vmalloc(sizeof(void *) * num_possible_cpus()); |