diff options
Diffstat (limited to 'drivers/cpufreq/intel_pstate.c')
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 181 |
1 files changed, 133 insertions, 48 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index eb3fdc755000..89925513fea5 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -33,6 +33,8 @@ | |||
33 | 33 | ||
34 | #define SAMPLE_COUNT 3 | 34 | #define SAMPLE_COUNT 3 |
35 | 35 | ||
36 | #define BYT_RATIOS 0x66a | ||
37 | |||
36 | #define FRAC_BITS 8 | 38 | #define FRAC_BITS 8 |
37 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) | 39 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) |
38 | #define fp_toint(X) ((X) >> FRAC_BITS) | 40 | #define fp_toint(X) ((X) >> FRAC_BITS) |
@@ -78,7 +80,6 @@ struct cpudata { | |||
78 | 80 | ||
79 | struct timer_list timer; | 81 | struct timer_list timer; |
80 | 82 | ||
81 | struct pstate_adjust_policy *pstate_policy; | ||
82 | struct pstate_data pstate; | 83 | struct pstate_data pstate; |
83 | struct _pid pid; | 84 | struct _pid pid; |
84 | 85 | ||
@@ -100,15 +101,21 @@ struct pstate_adjust_policy { | |||
100 | int i_gain_pct; | 101 | int i_gain_pct; |
101 | }; | 102 | }; |
102 | 103 | ||
103 | static struct pstate_adjust_policy default_policy = { | 104 | struct pstate_funcs { |
104 | .sample_rate_ms = 10, | 105 | int (*get_max)(void); |
105 | .deadband = 0, | 106 | int (*get_min)(void); |
106 | .setpoint = 97, | 107 | int (*get_turbo)(void); |
107 | .p_gain_pct = 20, | 108 | void (*set)(int pstate); |
108 | .d_gain_pct = 0, | 109 | }; |
109 | .i_gain_pct = 0, | 110 | |
111 | struct cpu_defaults { | ||
112 | struct pstate_adjust_policy pid_policy; | ||
113 | struct pstate_funcs funcs; | ||
110 | }; | 114 | }; |
111 | 115 | ||
116 | static struct pstate_adjust_policy pid_params; | ||
117 | static struct pstate_funcs pstate_funcs; | ||
118 | |||
112 | struct perf_limits { | 119 | struct perf_limits { |
113 | int no_turbo; | 120 | int no_turbo; |
114 | int max_perf_pct; | 121 | int max_perf_pct; |
@@ -185,14 +192,14 @@ static signed int pid_calc(struct _pid *pid, int32_t busy) | |||
185 | 192 | ||
186 | static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu) | 193 | static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu) |
187 | { | 194 | { |
188 | pid_p_gain_set(&cpu->pid, cpu->pstate_policy->p_gain_pct); | 195 | pid_p_gain_set(&cpu->pid, pid_params.p_gain_pct); |
189 | pid_d_gain_set(&cpu->pid, cpu->pstate_policy->d_gain_pct); | 196 | pid_d_gain_set(&cpu->pid, pid_params.d_gain_pct); |
190 | pid_i_gain_set(&cpu->pid, cpu->pstate_policy->i_gain_pct); | 197 | pid_i_gain_set(&cpu->pid, pid_params.i_gain_pct); |
191 | 198 | ||
192 | pid_reset(&cpu->pid, | 199 | pid_reset(&cpu->pid, |
193 | cpu->pstate_policy->setpoint, | 200 | pid_params.setpoint, |
194 | 100, | 201 | 100, |
195 | cpu->pstate_policy->deadband, | 202 | pid_params.deadband, |
196 | 0); | 203 | 0); |
197 | } | 204 | } |
198 | 205 | ||
@@ -226,12 +233,12 @@ struct pid_param { | |||
226 | }; | 233 | }; |
227 | 234 | ||
228 | static struct pid_param pid_files[] = { | 235 | static struct pid_param pid_files[] = { |
229 | {"sample_rate_ms", &default_policy.sample_rate_ms}, | 236 | {"sample_rate_ms", &pid_params.sample_rate_ms}, |
230 | {"d_gain_pct", &default_policy.d_gain_pct}, | 237 | {"d_gain_pct", &pid_params.d_gain_pct}, |
231 | {"i_gain_pct", &default_policy.i_gain_pct}, | 238 | {"i_gain_pct", &pid_params.i_gain_pct}, |
232 | {"deadband", &default_policy.deadband}, | 239 | {"deadband", &pid_params.deadband}, |
233 | {"setpoint", &default_policy.setpoint}, | 240 | {"setpoint", &pid_params.setpoint}, |
234 | {"p_gain_pct", &default_policy.p_gain_pct}, | 241 | {"p_gain_pct", &pid_params.p_gain_pct}, |
235 | {NULL, NULL} | 242 | {NULL, NULL} |
236 | }; | 243 | }; |
237 | 244 | ||
@@ -336,33 +343,92 @@ static void intel_pstate_sysfs_expose_params(void) | |||
336 | } | 343 | } |
337 | 344 | ||
338 | /************************** sysfs end ************************/ | 345 | /************************** sysfs end ************************/ |
346 | static int byt_get_min_pstate(void) | ||
347 | { | ||
348 | u64 value; | ||
349 | rdmsrl(BYT_RATIOS, value); | ||
350 | return value & 0xFF; | ||
351 | } | ||
352 | |||
353 | static int byt_get_max_pstate(void) | ||
354 | { | ||
355 | u64 value; | ||
356 | rdmsrl(BYT_RATIOS, value); | ||
357 | return (value >> 16) & 0xFF; | ||
358 | } | ||
339 | 359 | ||
340 | static int intel_pstate_min_pstate(void) | 360 | static int core_get_min_pstate(void) |
341 | { | 361 | { |
342 | u64 value; | 362 | u64 value; |
343 | rdmsrl(MSR_PLATFORM_INFO, value); | 363 | rdmsrl(MSR_PLATFORM_INFO, value); |
344 | return (value >> 40) & 0xFF; | 364 | return (value >> 40) & 0xFF; |
345 | } | 365 | } |
346 | 366 | ||
347 | static int intel_pstate_max_pstate(void) | 367 | static int core_get_max_pstate(void) |
348 | { | 368 | { |
349 | u64 value; | 369 | u64 value; |
350 | rdmsrl(MSR_PLATFORM_INFO, value); | 370 | rdmsrl(MSR_PLATFORM_INFO, value); |
351 | return (value >> 8) & 0xFF; | 371 | return (value >> 8) & 0xFF; |
352 | } | 372 | } |
353 | 373 | ||
354 | static int intel_pstate_turbo_pstate(void) | 374 | static int core_get_turbo_pstate(void) |
355 | { | 375 | { |
356 | u64 value; | 376 | u64 value; |
357 | int nont, ret; | 377 | int nont, ret; |
358 | rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value); | 378 | rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value); |
359 | nont = intel_pstate_max_pstate(); | 379 | nont = core_get_max_pstate(); |
360 | ret = ((value) & 255); | 380 | ret = ((value) & 255); |
361 | if (ret <= nont) | 381 | if (ret <= nont) |
362 | ret = nont; | 382 | ret = nont; |
363 | return ret; | 383 | return ret; |
364 | } | 384 | } |
365 | 385 | ||
386 | static void core_set_pstate(int pstate) | ||
387 | { | ||
388 | u64 val; | ||
389 | |||
390 | val = pstate << 8; | ||
391 | if (limits.no_turbo) | ||
392 | val |= (u64)1 << 32; | ||
393 | |||
394 | wrmsrl(MSR_IA32_PERF_CTL, val); | ||
395 | } | ||
396 | |||
397 | static struct cpu_defaults core_params = { | ||
398 | .pid_policy = { | ||
399 | .sample_rate_ms = 10, | ||
400 | .deadband = 0, | ||
401 | .setpoint = 97, | ||
402 | .p_gain_pct = 20, | ||
403 | .d_gain_pct = 0, | ||
404 | .i_gain_pct = 0, | ||
405 | }, | ||
406 | .funcs = { | ||
407 | .get_max = core_get_max_pstate, | ||
408 | .get_min = core_get_min_pstate, | ||
409 | .get_turbo = core_get_turbo_pstate, | ||
410 | .set = core_set_pstate, | ||
411 | }, | ||
412 | }; | ||
413 | |||
414 | static struct cpu_defaults byt_params = { | ||
415 | .pid_policy = { | ||
416 | .sample_rate_ms = 10, | ||
417 | .deadband = 0, | ||
418 | .setpoint = 97, | ||
419 | .p_gain_pct = 14, | ||
420 | .d_gain_pct = 0, | ||
421 | .i_gain_pct = 4, | ||
422 | }, | ||
423 | .funcs = { | ||
424 | .get_max = byt_get_max_pstate, | ||
425 | .get_min = byt_get_min_pstate, | ||
426 | .get_turbo = byt_get_max_pstate, | ||
427 | .set = core_set_pstate, | ||
428 | }, | ||
429 | }; | ||
430 | |||
431 | |||
366 | static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) | 432 | static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) |
367 | { | 433 | { |
368 | int max_perf = cpu->pstate.turbo_pstate; | 434 | int max_perf = cpu->pstate.turbo_pstate; |
@@ -383,7 +449,6 @@ static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) | |||
383 | static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) | 449 | static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) |
384 | { | 450 | { |
385 | int max_perf, min_perf; | 451 | int max_perf, min_perf; |
386 | u64 val; | ||
387 | 452 | ||
388 | intel_pstate_get_min_max(cpu, &min_perf, &max_perf); | 453 | intel_pstate_get_min_max(cpu, &min_perf, &max_perf); |
389 | 454 | ||
@@ -395,11 +460,8 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) | |||
395 | trace_cpu_frequency(pstate * 100000, cpu->cpu); | 460 | trace_cpu_frequency(pstate * 100000, cpu->cpu); |
396 | 461 | ||
397 | cpu->pstate.current_pstate = pstate; | 462 | cpu->pstate.current_pstate = pstate; |
398 | val = pstate << 8; | ||
399 | if (limits.no_turbo) | ||
400 | val |= (u64)1 << 32; | ||
401 | 463 | ||
402 | wrmsrl(MSR_IA32_PERF_CTL, val); | 464 | pstate_funcs.set(pstate); |
403 | } | 465 | } |
404 | 466 | ||
405 | static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps) | 467 | static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps) |
@@ -421,9 +483,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) | |||
421 | { | 483 | { |
422 | sprintf(cpu->name, "Intel 2nd generation core"); | 484 | sprintf(cpu->name, "Intel 2nd generation core"); |
423 | 485 | ||
424 | cpu->pstate.min_pstate = intel_pstate_min_pstate(); | 486 | cpu->pstate.min_pstate = pstate_funcs.get_min(); |
425 | cpu->pstate.max_pstate = intel_pstate_max_pstate(); | 487 | cpu->pstate.max_pstate = pstate_funcs.get_max(); |
426 | cpu->pstate.turbo_pstate = intel_pstate_turbo_pstate(); | 488 | cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); |
427 | 489 | ||
428 | /* | 490 | /* |
429 | * goto max pstate so we don't slow up boot if we are built-in if we are | 491 | * goto max pstate so we don't slow up boot if we are built-in if we are |
@@ -465,7 +527,7 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu) | |||
465 | { | 527 | { |
466 | int sample_time, delay; | 528 | int sample_time, delay; |
467 | 529 | ||
468 | sample_time = cpu->pstate_policy->sample_rate_ms; | 530 | sample_time = pid_params.sample_rate_ms; |
469 | delay = msecs_to_jiffies(sample_time); | 531 | delay = msecs_to_jiffies(sample_time); |
470 | mod_timer_pinned(&cpu->timer, jiffies + delay); | 532 | mod_timer_pinned(&cpu->timer, jiffies + delay); |
471 | } | 533 | } |
@@ -521,14 +583,15 @@ static void intel_pstate_timer_func(unsigned long __data) | |||
521 | { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&policy } | 583 | { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&policy } |
522 | 584 | ||
523 | static const struct x86_cpu_id intel_pstate_cpu_ids[] = { | 585 | static const struct x86_cpu_id intel_pstate_cpu_ids[] = { |
524 | ICPU(0x2a, default_policy), | 586 | ICPU(0x2a, core_params), |
525 | ICPU(0x2d, default_policy), | 587 | ICPU(0x2d, core_params), |
526 | ICPU(0x3a, default_policy), | 588 | ICPU(0x37, byt_params), |
527 | ICPU(0x3c, default_policy), | 589 | ICPU(0x3a, core_params), |
528 | ICPU(0x3e, default_policy), | 590 | ICPU(0x3c, core_params), |
529 | ICPU(0x3f, default_policy), | 591 | ICPU(0x3e, core_params), |
530 | ICPU(0x45, default_policy), | 592 | ICPU(0x3f, core_params), |
531 | ICPU(0x46, default_policy), | 593 | ICPU(0x45, core_params), |
594 | ICPU(0x46, core_params), | ||
532 | {} | 595 | {} |
533 | }; | 596 | }; |
534 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); | 597 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); |
@@ -552,8 +615,7 @@ static int intel_pstate_init_cpu(unsigned int cpunum) | |||
552 | intel_pstate_get_cpu_pstates(cpu); | 615 | intel_pstate_get_cpu_pstates(cpu); |
553 | 616 | ||
554 | cpu->cpu = cpunum; | 617 | cpu->cpu = cpunum; |
555 | cpu->pstate_policy = | 618 | |
556 | (struct pstate_adjust_policy *)id->driver_data; | ||
557 | init_timer_deferrable(&cpu->timer); | 619 | init_timer_deferrable(&cpu->timer); |
558 | cpu->timer.function = intel_pstate_timer_func; | 620 | cpu->timer.function = intel_pstate_timer_func; |
559 | cpu->timer.data = | 621 | cpu->timer.data = |
@@ -613,9 +675,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) | |||
613 | 675 | ||
614 | static int intel_pstate_verify_policy(struct cpufreq_policy *policy) | 676 | static int intel_pstate_verify_policy(struct cpufreq_policy *policy) |
615 | { | 677 | { |
616 | cpufreq_verify_within_limits(policy, | 678 | cpufreq_verify_within_cpu_limits(policy); |
617 | policy->cpuinfo.min_freq, | ||
618 | policy->cpuinfo.max_freq); | ||
619 | 679 | ||
620 | if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) && | 680 | if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) && |
621 | (policy->policy != CPUFREQ_POLICY_PERFORMANCE)) | 681 | (policy->policy != CPUFREQ_POLICY_PERFORMANCE)) |
@@ -683,9 +743,9 @@ static int intel_pstate_msrs_not_valid(void) | |||
683 | rdmsrl(MSR_IA32_APERF, aperf); | 743 | rdmsrl(MSR_IA32_APERF, aperf); |
684 | rdmsrl(MSR_IA32_MPERF, mperf); | 744 | rdmsrl(MSR_IA32_MPERF, mperf); |
685 | 745 | ||
686 | if (!intel_pstate_min_pstate() || | 746 | if (!pstate_funcs.get_max() || |
687 | !intel_pstate_max_pstate() || | 747 | !pstate_funcs.get_min() || |
688 | !intel_pstate_turbo_pstate()) | 748 | !pstate_funcs.get_turbo()) |
689 | return -ENODEV; | 749 | return -ENODEV; |
690 | 750 | ||
691 | rdmsrl(MSR_IA32_APERF, tmp); | 751 | rdmsrl(MSR_IA32_APERF, tmp); |
@@ -698,10 +758,30 @@ static int intel_pstate_msrs_not_valid(void) | |||
698 | 758 | ||
699 | return 0; | 759 | return 0; |
700 | } | 760 | } |
761 | |||
762 | void copy_pid_params(struct pstate_adjust_policy *policy) | ||
763 | { | ||
764 | pid_params.sample_rate_ms = policy->sample_rate_ms; | ||
765 | pid_params.p_gain_pct = policy->p_gain_pct; | ||
766 | pid_params.i_gain_pct = policy->i_gain_pct; | ||
767 | pid_params.d_gain_pct = policy->d_gain_pct; | ||
768 | pid_params.deadband = policy->deadband; | ||
769 | pid_params.setpoint = policy->setpoint; | ||
770 | } | ||
771 | |||
772 | void copy_cpu_funcs(struct pstate_funcs *funcs) | ||
773 | { | ||
774 | pstate_funcs.get_max = funcs->get_max; | ||
775 | pstate_funcs.get_min = funcs->get_min; | ||
776 | pstate_funcs.get_turbo = funcs->get_turbo; | ||
777 | pstate_funcs.set = funcs->set; | ||
778 | } | ||
779 | |||
701 | static int __init intel_pstate_init(void) | 780 | static int __init intel_pstate_init(void) |
702 | { | 781 | { |
703 | int cpu, rc = 0; | 782 | int cpu, rc = 0; |
704 | const struct x86_cpu_id *id; | 783 | const struct x86_cpu_id *id; |
784 | struct cpu_defaults *cpu_info; | ||
705 | 785 | ||
706 | if (no_load) | 786 | if (no_load) |
707 | return -ENODEV; | 787 | return -ENODEV; |
@@ -710,6 +790,11 @@ static int __init intel_pstate_init(void) | |||
710 | if (!id) | 790 | if (!id) |
711 | return -ENODEV; | 791 | return -ENODEV; |
712 | 792 | ||
793 | cpu_info = (struct cpu_defaults *)id->driver_data; | ||
794 | |||
795 | copy_pid_params(&cpu_info->pid_policy); | ||
796 | copy_cpu_funcs(&cpu_info->funcs); | ||
797 | |||
713 | if (intel_pstate_msrs_not_valid()) | 798 | if (intel_pstate_msrs_not_valid()) |
714 | return -ENODEV; | 799 | return -ENODEV; |
715 | 800 | ||