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.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index cddc61939a86..3af9dd7332e6 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -260,24 +260,31 @@ static inline void update_turbo_state(void)
260 cpu->pstate.max_pstate == cpu->pstate.turbo_pstate); 260 cpu->pstate.max_pstate == cpu->pstate.turbo_pstate);
261} 261}
262 262
263#define PCT_TO_HWP(x) (x * 255 / 100)
264static void intel_pstate_hwp_set(void) 263static void intel_pstate_hwp_set(void)
265{ 264{
266 int min, max, cpu; 265 int min, hw_min, max, hw_max, cpu, range, adj_range;
267 u64 value, freq; 266 u64 value, cap;
267
268 rdmsrl(MSR_HWP_CAPABILITIES, cap);
269 hw_min = HWP_LOWEST_PERF(cap);
270 hw_max = HWP_HIGHEST_PERF(cap);
271 range = hw_max - hw_min;
268 272
269 get_online_cpus(); 273 get_online_cpus();
270 274
271 for_each_online_cpu(cpu) { 275 for_each_online_cpu(cpu) {
272 rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value); 276 rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value);
273 min = PCT_TO_HWP(limits.min_perf_pct); 277 adj_range = limits.min_perf_pct * range / 100;
278 min = hw_min + adj_range;
274 value &= ~HWP_MIN_PERF(~0L); 279 value &= ~HWP_MIN_PERF(~0L);
275 value |= HWP_MIN_PERF(min); 280 value |= HWP_MIN_PERF(min);
276 281
277 max = PCT_TO_HWP(limits.max_perf_pct); 282 adj_range = limits.max_perf_pct * range / 100;
283 max = hw_min + adj_range;
278 if (limits.no_turbo) { 284 if (limits.no_turbo) {
279 rdmsrl( MSR_HWP_CAPABILITIES, freq); 285 hw_max = HWP_GUARANTEED_PERF(cap);
280 max = HWP_GUARANTEED_PERF(freq); 286 if (hw_max < max)
287 max = hw_max;
281 } 288 }
282 289
283 value &= ~HWP_MAX_PERF(~0L); 290 value &= ~HWP_MAX_PERF(~0L);
@@ -423,6 +430,8 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
423 430
424 limits.max_sysfs_pct = clamp_t(int, input, 0 , 100); 431 limits.max_sysfs_pct = clamp_t(int, input, 0 , 100);
425 limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); 432 limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct);
433 limits.max_perf_pct = max(limits.min_policy_pct, limits.max_perf_pct);
434 limits.max_perf_pct = max(limits.min_perf_pct, limits.max_perf_pct);
426 limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); 435 limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
427 436
428 if (hwp_active) 437 if (hwp_active)
@@ -442,6 +451,8 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b,
442 451
443 limits.min_sysfs_pct = clamp_t(int, input, 0 , 100); 452 limits.min_sysfs_pct = clamp_t(int, input, 0 , 100);
444 limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct); 453 limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct);
454 limits.min_perf_pct = min(limits.max_policy_pct, limits.min_perf_pct);
455 limits.min_perf_pct = min(limits.max_perf_pct, limits.min_perf_pct);
445 limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); 456 limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
446 457
447 if (hwp_active) 458 if (hwp_active)
@@ -989,12 +1000,19 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
989 1000
990 limits.min_policy_pct = (policy->min * 100) / policy->cpuinfo.max_freq; 1001 limits.min_policy_pct = (policy->min * 100) / policy->cpuinfo.max_freq;
991 limits.min_policy_pct = clamp_t(int, limits.min_policy_pct, 0 , 100); 1002 limits.min_policy_pct = clamp_t(int, limits.min_policy_pct, 0 , 100);
992 limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct);
993 limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
994
995 limits.max_policy_pct = (policy->max * 100) / policy->cpuinfo.max_freq; 1003 limits.max_policy_pct = (policy->max * 100) / policy->cpuinfo.max_freq;
996 limits.max_policy_pct = clamp_t(int, limits.max_policy_pct, 0 , 100); 1004 limits.max_policy_pct = clamp_t(int, limits.max_policy_pct, 0 , 100);
1005
1006 /* Normalize user input to [min_policy_pct, max_policy_pct] */
1007 limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct);
1008 limits.min_perf_pct = min(limits.max_policy_pct, limits.min_perf_pct);
997 limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); 1009 limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct);
1010 limits.max_perf_pct = max(limits.min_policy_pct, limits.max_perf_pct);
1011
1012 /* Make sure min_perf_pct <= max_perf_pct */
1013 limits.min_perf_pct = min(limits.max_perf_pct, limits.min_perf_pct);
1014
1015 limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
998 limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); 1016 limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
999 1017
1000 if (hwp_active) 1018 if (hwp_active)