aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/intel_pstate.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/intel_pstate.c')
-rw-r--r--drivers/cpufreq/intel_pstate.c40
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
129struct perf_limits { 129struct 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
366static int byt_get_max_pstate(void) 367static 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
373static int byt_get_turbo_pstate(void) 374static 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
380static void byt_set_pstate(struct cpudata *cpudata, int pstate) 381static 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;