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.c90
1 files changed, 54 insertions, 36 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index c788abf1c457..099967302bf2 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -34,12 +34,15 @@
34 34
35#define SAMPLE_COUNT 3 35#define SAMPLE_COUNT 3
36 36
37#define BYT_RATIOS 0x66a 37#define BYT_RATIOS 0x66a
38#define BYT_VIDS 0x66b 38#define BYT_VIDS 0x66b
39#define BYT_TURBO_RATIOS 0x66c
39 40
40#define FRAC_BITS 8 41
42#define FRAC_BITS 6
41#define int_tofp(X) ((int64_t)(X) << FRAC_BITS) 43#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
42#define fp_toint(X) ((X) >> FRAC_BITS) 44#define fp_toint(X) ((X) >> FRAC_BITS)
45#define FP_ROUNDUP(X) ((X) += 1 << FRAC_BITS)
43 46
44static inline int32_t mul_fp(int32_t x, int32_t y) 47static inline int32_t mul_fp(int32_t x, int32_t y)
45{ 48{
@@ -96,8 +99,7 @@ struct cpudata {
96 u64 prev_aperf; 99 u64 prev_aperf;
97 u64 prev_mperf; 100 u64 prev_mperf;
98 unsigned long long prev_tsc; 101 unsigned long long prev_tsc;
99 int sample_ptr; 102 struct sample sample;
100 struct sample samples[SAMPLE_COUNT];
101}; 103};
102 104
103static struct cpudata **all_cpu_data; 105static struct cpudata **all_cpu_data;
@@ -151,7 +153,7 @@ static inline void pid_reset(struct _pid *pid, int setpoint, int busy,
151 pid->setpoint = setpoint; 153 pid->setpoint = setpoint;
152 pid->deadband = deadband; 154 pid->deadband = deadband;
153 pid->integral = int_tofp(integral); 155 pid->integral = int_tofp(integral);
154 pid->last_err = setpoint - busy; 156 pid->last_err = int_tofp(setpoint) - int_tofp(busy);
155} 157}
156 158
157static inline void pid_p_gain_set(struct _pid *pid, int percent) 159static inline void pid_p_gain_set(struct _pid *pid, int percent)
@@ -357,7 +359,7 @@ static int byt_get_min_pstate(void)
357{ 359{
358 u64 value; 360 u64 value;
359 rdmsrl(BYT_RATIOS, value); 361 rdmsrl(BYT_RATIOS, value);
360 return value & 0xFF; 362 return (value >> 8) & 0xFF;
361} 363}
362 364
363static int byt_get_max_pstate(void) 365static int byt_get_max_pstate(void)
@@ -367,6 +369,13 @@ static int byt_get_max_pstate(void)
367 return (value >> 16) & 0xFF; 369 return (value >> 16) & 0xFF;
368} 370}
369 371
372static int byt_get_turbo_pstate(void)
373{
374 u64 value;
375 rdmsrl(BYT_TURBO_RATIOS, value);
376 return value & 0x3F;
377}
378
370static void byt_set_pstate(struct cpudata *cpudata, int pstate) 379static void byt_set_pstate(struct cpudata *cpudata, int pstate)
371{ 380{
372 u64 val; 381 u64 val;
@@ -437,7 +446,7 @@ static void core_set_pstate(struct cpudata *cpudata, int pstate)
437 if (limits.no_turbo) 446 if (limits.no_turbo)
438 val |= (u64)1 << 32; 447 val |= (u64)1 << 32;
439 448
440 wrmsrl(MSR_IA32_PERF_CTL, val); 449 wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val);
441} 450}
442 451
443static struct cpu_defaults core_params = { 452static struct cpu_defaults core_params = {
@@ -469,7 +478,7 @@ static struct cpu_defaults byt_params = {
469 .funcs = { 478 .funcs = {
470 .get_max = byt_get_max_pstate, 479 .get_max = byt_get_max_pstate,
471 .get_min = byt_get_min_pstate, 480 .get_min = byt_get_min_pstate,
472 .get_turbo = byt_get_max_pstate, 481 .get_turbo = byt_get_turbo_pstate,
473 .set = byt_set_pstate, 482 .set = byt_set_pstate,
474 .get_vid = byt_get_vid, 483 .get_vid = byt_get_vid,
475 }, 484 },
@@ -547,18 +556,20 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
547static inline void intel_pstate_calc_busy(struct cpudata *cpu, 556static inline void intel_pstate_calc_busy(struct cpudata *cpu,
548 struct sample *sample) 557 struct sample *sample)
549{ 558{
550 u64 core_pct; 559 int32_t core_pct;
551 u64 c0_pct; 560 int32_t c0_pct;
561
562 core_pct = div_fp(int_tofp((sample->aperf)),
563 int_tofp((sample->mperf)));
564 core_pct = mul_fp(core_pct, int_tofp(100));
565 FP_ROUNDUP(core_pct);
552 566
553 core_pct = div64_u64(sample->aperf * 100, sample->mperf); 567 c0_pct = div_fp(int_tofp(sample->mperf), int_tofp(sample->tsc));
554 568
555 c0_pct = div64_u64(sample->mperf * 100, sample->tsc);
556 sample->freq = fp_toint( 569 sample->freq = fp_toint(
557 mul_fp(int_tofp(cpu->pstate.max_pstate), 570 mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct));
558 int_tofp(core_pct * 1000)));
559 571
560 sample->core_pct_busy = mul_fp(int_tofp(core_pct), 572 sample->core_pct_busy = mul_fp(core_pct, c0_pct);
561 div_fp(int_tofp(c0_pct + 1), int_tofp(100)));
562} 573}
563 574
564static inline void intel_pstate_sample(struct cpudata *cpu) 575static inline void intel_pstate_sample(struct cpudata *cpu)
@@ -570,15 +581,18 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
570 rdmsrl(MSR_IA32_MPERF, mperf); 581 rdmsrl(MSR_IA32_MPERF, mperf);
571 tsc = native_read_tsc(); 582 tsc = native_read_tsc();
572 583
573 cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; 584 aperf = aperf >> FRAC_BITS;
574 cpu->samples[cpu->sample_ptr].aperf = aperf; 585 mperf = mperf >> FRAC_BITS;
575 cpu->samples[cpu->sample_ptr].mperf = mperf; 586 tsc = tsc >> FRAC_BITS;
576 cpu->samples[cpu->sample_ptr].tsc = tsc; 587
577 cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; 588 cpu->sample.aperf = aperf;
578 cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; 589 cpu->sample.mperf = mperf;
579 cpu->samples[cpu->sample_ptr].tsc -= cpu->prev_tsc; 590 cpu->sample.tsc = tsc;
591 cpu->sample.aperf -= cpu->prev_aperf;
592 cpu->sample.mperf -= cpu->prev_mperf;
593 cpu->sample.tsc -= cpu->prev_tsc;
580 594
581 intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); 595 intel_pstate_calc_busy(cpu, &cpu->sample);
582 596
583 cpu->prev_aperf = aperf; 597 cpu->prev_aperf = aperf;
584 cpu->prev_mperf = mperf; 598 cpu->prev_mperf = mperf;
@@ -598,10 +612,11 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
598{ 612{
599 int32_t core_busy, max_pstate, current_pstate; 613 int32_t core_busy, max_pstate, current_pstate;
600 614
601 core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy; 615 core_busy = cpu->sample.core_pct_busy;
602 max_pstate = int_tofp(cpu->pstate.max_pstate); 616 max_pstate = int_tofp(cpu->pstate.max_pstate);
603 current_pstate = int_tofp(cpu->pstate.current_pstate); 617 current_pstate = int_tofp(cpu->pstate.current_pstate);
604 return mul_fp(core_busy, div_fp(max_pstate, current_pstate)); 618 core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate));
619 return FP_ROUNDUP(core_busy);
605} 620}
606 621
607static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) 622static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
@@ -631,7 +646,7 @@ static void intel_pstate_timer_func(unsigned long __data)
631 646
632 intel_pstate_sample(cpu); 647 intel_pstate_sample(cpu);
633 648
634 sample = &cpu->samples[cpu->sample_ptr]; 649 sample = &cpu->sample;
635 650
636 intel_pstate_adjust_busy_pstate(cpu); 651 intel_pstate_adjust_busy_pstate(cpu);
637 652
@@ -712,7 +727,7 @@ static unsigned int intel_pstate_get(unsigned int cpu_num)
712 cpu = all_cpu_data[cpu_num]; 727 cpu = all_cpu_data[cpu_num];
713 if (!cpu) 728 if (!cpu)
714 return 0; 729 return 0;
715 sample = &cpu->samples[cpu->sample_ptr]; 730 sample = &cpu->sample;
716 return sample->freq; 731 return sample->freq;
717} 732}
718 733
@@ -756,14 +771,17 @@ static int intel_pstate_verify_policy(struct cpufreq_policy *policy)
756 return 0; 771 return 0;
757} 772}
758 773
759static int intel_pstate_cpu_exit(struct cpufreq_policy *policy) 774static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
760{ 775{
761 int cpu = policy->cpu; 776 int cpu_num = policy->cpu;
777 struct cpudata *cpu = all_cpu_data[cpu_num];
762 778
763 del_timer(&all_cpu_data[cpu]->timer); 779 pr_info("intel_pstate CPU %d exiting\n", cpu_num);
764 kfree(all_cpu_data[cpu]); 780
765 all_cpu_data[cpu] = NULL; 781 del_timer_sync(&all_cpu_data[cpu_num]->timer);
766 return 0; 782 intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
783 kfree(all_cpu_data[cpu_num]);
784 all_cpu_data[cpu_num] = NULL;
767} 785}
768 786
769static int intel_pstate_cpu_init(struct cpufreq_policy *policy) 787static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
@@ -801,7 +819,7 @@ static struct cpufreq_driver intel_pstate_driver = {
801 .setpolicy = intel_pstate_set_policy, 819 .setpolicy = intel_pstate_set_policy,
802 .get = intel_pstate_get, 820 .get = intel_pstate_get,
803 .init = intel_pstate_cpu_init, 821 .init = intel_pstate_cpu_init,
804 .exit = intel_pstate_cpu_exit, 822 .stop_cpu = intel_pstate_stop_cpu,
805 .name = "intel_pstate", 823 .name = "intel_pstate",
806}; 824};
807 825