diff options
Diffstat (limited to 'drivers/cpufreq/intel_pstate.c')
| -rw-r--r-- | drivers/cpufreq/intel_pstate.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 924bb2d42b1c..86631cb6f7de 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
| @@ -128,6 +128,7 @@ static struct pstate_funcs pstate_funcs; | |||
| 128 | 128 | ||
| 129 | struct perf_limits { | 129 | struct perf_limits { |
| 130 | int no_turbo; | 130 | int no_turbo; |
| 131 | int turbo_disabled; | ||
| 131 | int max_perf_pct; | 132 | int max_perf_pct; |
| 132 | int min_perf_pct; | 133 | int min_perf_pct; |
| 133 | int32_t max_perf; | 134 | int32_t max_perf; |
| @@ -287,7 +288,10 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b, | |||
| 287 | if (ret != 1) | 288 | if (ret != 1) |
| 288 | return -EINVAL; | 289 | return -EINVAL; |
| 289 | limits.no_turbo = clamp_t(int, input, 0 , 1); | 290 | limits.no_turbo = clamp_t(int, input, 0 , 1); |
| 290 | 291 | if (limits.turbo_disabled) { | |
| 292 | pr_warn("Turbo disabled by BIOS or unavailable on processor\n"); | ||
| 293 | limits.no_turbo = limits.turbo_disabled; | ||
| 294 | } | ||
| 291 | return count; | 295 | return count; |
| 292 | } | 296 | } |
| 293 | 297 | ||
| @@ -357,21 +361,21 @@ static int byt_get_min_pstate(void) | |||
| 357 | { | 361 | { |
| 358 | u64 value; | 362 | u64 value; |
| 359 | rdmsrl(BYT_RATIOS, value); | 363 | rdmsrl(BYT_RATIOS, value); |
| 360 | return (value >> 8) & 0x3F; | 364 | return (value >> 8) & 0x7F; |
| 361 | } | 365 | } |
| 362 | 366 | ||
| 363 | static int byt_get_max_pstate(void) | 367 | static int byt_get_max_pstate(void) |
| 364 | { | 368 | { |
| 365 | u64 value; | 369 | u64 value; |
| 366 | rdmsrl(BYT_RATIOS, value); | 370 | rdmsrl(BYT_RATIOS, value); |
| 367 | return (value >> 16) & 0x3F; | 371 | return (value >> 16) & 0x7F; |
| 368 | } | 372 | } |
| 369 | 373 | ||
| 370 | static int byt_get_turbo_pstate(void) | 374 | static int byt_get_turbo_pstate(void) |
| 371 | { | 375 | { |
| 372 | u64 value; | 376 | u64 value; |
| 373 | rdmsrl(BYT_TURBO_RATIOS, value); | 377 | rdmsrl(BYT_TURBO_RATIOS, value); |
| 374 | return value & 0x3F; | 378 | return value & 0x7F; |
| 375 | } | 379 | } |
| 376 | 380 | ||
| 377 | static void byt_set_pstate(struct cpudata *cpudata, int pstate) | 381 | static void byt_set_pstate(struct cpudata *cpudata, int pstate) |
| @@ -381,7 +385,7 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate) | |||
| 381 | u32 vid; | 385 | u32 vid; |
| 382 | 386 | ||
| 383 | val = pstate << 8; | 387 | val = pstate << 8; |
| 384 | if (limits.no_turbo) | 388 | if (limits.no_turbo && !limits.turbo_disabled) |
| 385 | val |= (u64)1 << 32; | 389 | val |= (u64)1 << 32; |
| 386 | 390 | ||
| 387 | vid_fp = cpudata->vid.min + mul_fp( | 391 | vid_fp = cpudata->vid.min + mul_fp( |
| @@ -405,8 +409,8 @@ static void byt_get_vid(struct cpudata *cpudata) | |||
| 405 | 409 | ||
| 406 | 410 | ||
| 407 | rdmsrl(BYT_VIDS, value); | 411 | rdmsrl(BYT_VIDS, value); |
| 408 | cpudata->vid.min = int_tofp((value >> 8) & 0x3f); | 412 | cpudata->vid.min = int_tofp((value >> 8) & 0x7f); |
| 409 | cpudata->vid.max = int_tofp((value >> 16) & 0x3f); | 413 | cpudata->vid.max = int_tofp((value >> 16) & 0x7f); |
| 410 | cpudata->vid.ratio = div_fp( | 414 | cpudata->vid.ratio = div_fp( |
| 411 | cpudata->vid.max - cpudata->vid.min, | 415 | cpudata->vid.max - cpudata->vid.min, |
| 412 | int_tofp(cpudata->pstate.max_pstate - | 416 | int_tofp(cpudata->pstate.max_pstate - |
| @@ -448,7 +452,7 @@ static void core_set_pstate(struct cpudata *cpudata, int pstate) | |||
| 448 | u64 val; | 452 | u64 val; |
| 449 | 453 | ||
| 450 | val = pstate << 8; | 454 | val = pstate << 8; |
| 451 | if (limits.no_turbo) | 455 | if (limits.no_turbo && !limits.turbo_disabled) |
| 452 | val |= (u64)1 << 32; | 456 | val |= (u64)1 << 32; |
| 453 | 457 | ||
| 454 | wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val); | 458 | wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val); |
| @@ -696,9 +700,8 @@ static int intel_pstate_init_cpu(unsigned int cpunum) | |||
| 696 | 700 | ||
| 697 | cpu = all_cpu_data[cpunum]; | 701 | cpu = all_cpu_data[cpunum]; |
| 698 | 702 | ||
| 699 | intel_pstate_get_cpu_pstates(cpu); | ||
| 700 | |||
| 701 | cpu->cpu = cpunum; | 703 | cpu->cpu = cpunum; |
| 704 | intel_pstate_get_cpu_pstates(cpu); | ||
| 702 | 705 | ||
| 703 | init_timer_deferrable(&cpu->timer); | 706 | init_timer_deferrable(&cpu->timer); |
| 704 | cpu->timer.function = intel_pstate_timer_func; | 707 | cpu->timer.function = intel_pstate_timer_func; |
| @@ -741,7 +744,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) | |||
| 741 | limits.min_perf = int_tofp(1); | 744 | limits.min_perf = int_tofp(1); |
| 742 | limits.max_perf_pct = 100; | 745 | limits.max_perf_pct = 100; |
| 743 | limits.max_perf = int_tofp(1); | 746 | limits.max_perf = int_tofp(1); |
| 744 | limits.no_turbo = 0; | 747 | limits.no_turbo = limits.turbo_disabled; |
| 745 | return 0; | 748 | return 0; |
| 746 | } | 749 | } |
| 747 | limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq; | 750 | limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq; |
| @@ -784,6 +787,7 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy) | |||
| 784 | { | 787 | { |
| 785 | struct cpudata *cpu; | 788 | struct cpudata *cpu; |
| 786 | int rc; | 789 | int rc; |
| 790 | u64 misc_en; | ||
| 787 | 791 | ||
| 788 | rc = intel_pstate_init_cpu(policy->cpu); | 792 | rc = intel_pstate_init_cpu(policy->cpu); |
| 789 | if (rc) | 793 | if (rc) |
| @@ -791,8 +795,13 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy) | |||
| 791 | 795 | ||
| 792 | cpu = all_cpu_data[policy->cpu]; | 796 | cpu = all_cpu_data[policy->cpu]; |
| 793 | 797 | ||
| 794 | if (!limits.no_turbo && | 798 | rdmsrl(MSR_IA32_MISC_ENABLE, misc_en); |
| 795 | limits.min_perf_pct == 100 && limits.max_perf_pct == 100) | 799 | if (misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE || |
| 800 | cpu->pstate.max_pstate == cpu->pstate.turbo_pstate) { | ||
| 801 | limits.turbo_disabled = 1; | ||
| 802 | limits.no_turbo = 1; | ||
| 803 | } | ||
| 804 | if (limits.min_perf_pct == 100 && limits.max_perf_pct == 100) | ||
| 796 | policy->policy = CPUFREQ_POLICY_PERFORMANCE; | 805 | policy->policy = CPUFREQ_POLICY_PERFORMANCE; |
| 797 | else | 806 | else |
| 798 | policy->policy = CPUFREQ_POLICY_POWERSAVE; | 807 | policy->policy = CPUFREQ_POLICY_POWERSAVE; |
