diff options
Diffstat (limited to 'drivers/cpufreq/intel_pstate.c')
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 4e7f492ad583..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; |
@@ -196,10 +197,7 @@ static signed int pid_calc(struct _pid *pid, int32_t busy) | |||
196 | pid->last_err = fp_error; | 197 | pid->last_err = fp_error; |
197 | 198 | ||
198 | result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm; | 199 | result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm; |
199 | if (result >= 0) | 200 | result = result + (1 << (FRAC_BITS-1)); |
200 | result = result + (1 << (FRAC_BITS-1)); | ||
201 | else | ||
202 | result = result - (1 << (FRAC_BITS-1)); | ||
203 | return (signed int)fp_toint(result); | 201 | return (signed int)fp_toint(result); |
204 | } | 202 | } |
205 | 203 | ||
@@ -290,7 +288,10 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b, | |||
290 | if (ret != 1) | 288 | if (ret != 1) |
291 | return -EINVAL; | 289 | return -EINVAL; |
292 | limits.no_turbo = clamp_t(int, input, 0 , 1); | 290 | limits.no_turbo = clamp_t(int, input, 0 , 1); |
293 | 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 | } | ||
294 | return count; | 295 | return count; |
295 | } | 296 | } |
296 | 297 | ||
@@ -360,21 +361,21 @@ static int byt_get_min_pstate(void) | |||
360 | { | 361 | { |
361 | u64 value; | 362 | u64 value; |
362 | rdmsrl(BYT_RATIOS, value); | 363 | rdmsrl(BYT_RATIOS, value); |
363 | return (value >> 8) & 0x3F; | 364 | return (value >> 8) & 0x7F; |
364 | } | 365 | } |
365 | 366 | ||
366 | static int byt_get_max_pstate(void) | 367 | static int byt_get_max_pstate(void) |
367 | { | 368 | { |
368 | u64 value; | 369 | u64 value; |
369 | rdmsrl(BYT_RATIOS, value); | 370 | rdmsrl(BYT_RATIOS, value); |
370 | return (value >> 16) & 0x3F; | 371 | return (value >> 16) & 0x7F; |
371 | } | 372 | } |
372 | 373 | ||
373 | static int byt_get_turbo_pstate(void) | 374 | static int byt_get_turbo_pstate(void) |
374 | { | 375 | { |
375 | u64 value; | 376 | u64 value; |
376 | rdmsrl(BYT_TURBO_RATIOS, value); | 377 | rdmsrl(BYT_TURBO_RATIOS, value); |
377 | return value & 0x3F; | 378 | return value & 0x7F; |
378 | } | 379 | } |
379 | 380 | ||
380 | static void byt_set_pstate(struct cpudata *cpudata, int pstate) | 381 | static void byt_set_pstate(struct cpudata *cpudata, int pstate) |
@@ -384,7 +385,7 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate) | |||
384 | u32 vid; | 385 | u32 vid; |
385 | 386 | ||
386 | val = pstate << 8; | 387 | val = pstate << 8; |
387 | if (limits.no_turbo) | 388 | if (limits.no_turbo && !limits.turbo_disabled) |
388 | val |= (u64)1 << 32; | 389 | val |= (u64)1 << 32; |
389 | 390 | ||
390 | vid_fp = cpudata->vid.min + mul_fp( | 391 | vid_fp = cpudata->vid.min + mul_fp( |
@@ -408,8 +409,8 @@ static void byt_get_vid(struct cpudata *cpudata) | |||
408 | 409 | ||
409 | 410 | ||
410 | rdmsrl(BYT_VIDS, value); | 411 | rdmsrl(BYT_VIDS, value); |
411 | cpudata->vid.min = int_tofp((value >> 8) & 0x3f); | 412 | cpudata->vid.min = int_tofp((value >> 8) & 0x7f); |
412 | cpudata->vid.max = int_tofp((value >> 16) & 0x3f); | 413 | cpudata->vid.max = int_tofp((value >> 16) & 0x7f); |
413 | cpudata->vid.ratio = div_fp( | 414 | cpudata->vid.ratio = div_fp( |
414 | cpudata->vid.max - cpudata->vid.min, | 415 | cpudata->vid.max - cpudata->vid.min, |
415 | int_tofp(cpudata->pstate.max_pstate - | 416 | int_tofp(cpudata->pstate.max_pstate - |
@@ -451,7 +452,7 @@ static void core_set_pstate(struct cpudata *cpudata, int pstate) | |||
451 | u64 val; | 452 | u64 val; |
452 | 453 | ||
453 | val = pstate << 8; | 454 | val = pstate << 8; |
454 | if (limits.no_turbo) | 455 | if (limits.no_turbo && !limits.turbo_disabled) |
455 | val |= (u64)1 << 32; | 456 | val |= (u64)1 << 32; |
456 | 457 | ||
457 | wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val); | 458 | wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val); |
@@ -699,9 +700,8 @@ static int intel_pstate_init_cpu(unsigned int cpunum) | |||
699 | 700 | ||
700 | cpu = all_cpu_data[cpunum]; | 701 | cpu = all_cpu_data[cpunum]; |
701 | 702 | ||
702 | intel_pstate_get_cpu_pstates(cpu); | ||
703 | |||
704 | cpu->cpu = cpunum; | 703 | cpu->cpu = cpunum; |
704 | intel_pstate_get_cpu_pstates(cpu); | ||
705 | 705 | ||
706 | init_timer_deferrable(&cpu->timer); | 706 | init_timer_deferrable(&cpu->timer); |
707 | cpu->timer.function = intel_pstate_timer_func; | 707 | cpu->timer.function = intel_pstate_timer_func; |
@@ -744,7 +744,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) | |||
744 | limits.min_perf = int_tofp(1); | 744 | limits.min_perf = int_tofp(1); |
745 | limits.max_perf_pct = 100; | 745 | limits.max_perf_pct = 100; |
746 | limits.max_perf = int_tofp(1); | 746 | limits.max_perf = int_tofp(1); |
747 | limits.no_turbo = 0; | 747 | limits.no_turbo = limits.turbo_disabled; |
748 | return 0; | 748 | return 0; |
749 | } | 749 | } |
750 | limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq; | 750 | limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq; |
@@ -787,6 +787,7 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy) | |||
787 | { | 787 | { |
788 | struct cpudata *cpu; | 788 | struct cpudata *cpu; |
789 | int rc; | 789 | int rc; |
790 | u64 misc_en; | ||
790 | 791 | ||
791 | rc = intel_pstate_init_cpu(policy->cpu); | 792 | rc = intel_pstate_init_cpu(policy->cpu); |
792 | if (rc) | 793 | if (rc) |
@@ -794,8 +795,13 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy) | |||
794 | 795 | ||
795 | cpu = all_cpu_data[policy->cpu]; | 796 | cpu = all_cpu_data[policy->cpu]; |
796 | 797 | ||
797 | if (!limits.no_turbo && | 798 | rdmsrl(MSR_IA32_MISC_ENABLE, misc_en); |
798 | 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) | ||
799 | policy->policy = CPUFREQ_POLICY_PERFORMANCE; | 805 | policy->policy = CPUFREQ_POLICY_PERFORMANCE; |
800 | else | 806 | else |
801 | policy->policy = CPUFREQ_POLICY_POWERSAVE; | 807 | policy->policy = CPUFREQ_POLICY_POWERSAVE; |