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.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 7e257b233602..c788abf1c457 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -51,12 +51,11 @@ static inline int32_t div_fp(int32_t x, int32_t y)
51 return div_s64((int64_t)x << FRAC_BITS, (int64_t)y); 51 return div_s64((int64_t)x << FRAC_BITS, (int64_t)y);
52} 52}
53 53
54static u64 energy_divisor;
55
56struct sample { 54struct sample {
57 int32_t core_pct_busy; 55 int32_t core_pct_busy;
58 u64 aperf; 56 u64 aperf;
59 u64 mperf; 57 u64 mperf;
58 unsigned long long tsc;
60 int freq; 59 int freq;
61}; 60};
62 61
@@ -96,6 +95,7 @@ struct cpudata {
96 95
97 u64 prev_aperf; 96 u64 prev_aperf;
98 u64 prev_mperf; 97 u64 prev_mperf;
98 unsigned long long prev_tsc;
99 int sample_ptr; 99 int sample_ptr;
100 struct sample samples[SAMPLE_COUNT]; 100 struct sample samples[SAMPLE_COUNT];
101}; 101};
@@ -548,30 +548,41 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu,
548 struct sample *sample) 548 struct sample *sample)
549{ 549{
550 u64 core_pct; 550 u64 core_pct;
551 core_pct = div64_u64(int_tofp(sample->aperf * 100), 551 u64 c0_pct;
552 sample->mperf); 552
553 sample->freq = fp_toint(cpu->pstate.max_pstate * core_pct * 1000); 553 core_pct = div64_u64(sample->aperf * 100, sample->mperf);
554 554
555 sample->core_pct_busy = core_pct; 555 c0_pct = div64_u64(sample->mperf * 100, sample->tsc);
556 sample->freq = fp_toint(
557 mul_fp(int_tofp(cpu->pstate.max_pstate),
558 int_tofp(core_pct * 1000)));
559
560 sample->core_pct_busy = mul_fp(int_tofp(core_pct),
561 div_fp(int_tofp(c0_pct + 1), int_tofp(100)));
556} 562}
557 563
558static inline void intel_pstate_sample(struct cpudata *cpu) 564static inline void intel_pstate_sample(struct cpudata *cpu)
559{ 565{
560 u64 aperf, mperf; 566 u64 aperf, mperf;
567 unsigned long long tsc;
561 568
562 rdmsrl(MSR_IA32_APERF, aperf); 569 rdmsrl(MSR_IA32_APERF, aperf);
563 rdmsrl(MSR_IA32_MPERF, mperf); 570 rdmsrl(MSR_IA32_MPERF, mperf);
571 tsc = native_read_tsc();
564 572
565 cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; 573 cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT;
566 cpu->samples[cpu->sample_ptr].aperf = aperf; 574 cpu->samples[cpu->sample_ptr].aperf = aperf;
567 cpu->samples[cpu->sample_ptr].mperf = mperf; 575 cpu->samples[cpu->sample_ptr].mperf = mperf;
576 cpu->samples[cpu->sample_ptr].tsc = tsc;
568 cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; 577 cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf;
569 cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; 578 cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf;
579 cpu->samples[cpu->sample_ptr].tsc -= cpu->prev_tsc;
570 580
571 intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); 581 intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]);
572 582
573 cpu->prev_aperf = aperf; 583 cpu->prev_aperf = aperf;
574 cpu->prev_mperf = mperf; 584 cpu->prev_mperf = mperf;
585 cpu->prev_tsc = tsc;
575} 586}
576 587
577static inline void intel_pstate_set_sample_time(struct cpudata *cpu) 588static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
@@ -617,12 +628,10 @@ static void intel_pstate_timer_func(unsigned long __data)
617{ 628{
618 struct cpudata *cpu = (struct cpudata *) __data; 629 struct cpudata *cpu = (struct cpudata *) __data;
619 struct sample *sample; 630 struct sample *sample;
620 u64 energy;
621 631
622 intel_pstate_sample(cpu); 632 intel_pstate_sample(cpu);
623 633
624 sample = &cpu->samples[cpu->sample_ptr]; 634 sample = &cpu->samples[cpu->sample_ptr];
625 rdmsrl(MSR_PKG_ENERGY_STATUS, energy);
626 635
627 intel_pstate_adjust_busy_pstate(cpu); 636 intel_pstate_adjust_busy_pstate(cpu);
628 637
@@ -631,7 +640,6 @@ static void intel_pstate_timer_func(unsigned long __data)
631 cpu->pstate.current_pstate, 640 cpu->pstate.current_pstate,
632 sample->mperf, 641 sample->mperf,
633 sample->aperf, 642 sample->aperf,
634 div64_u64(energy, energy_divisor),
635 sample->freq); 643 sample->freq);
636 644
637 intel_pstate_set_sample_time(cpu); 645 intel_pstate_set_sample_time(cpu);
@@ -913,7 +921,6 @@ static int __init intel_pstate_init(void)
913 int cpu, rc = 0; 921 int cpu, rc = 0;
914 const struct x86_cpu_id *id; 922 const struct x86_cpu_id *id;
915 struct cpu_defaults *cpu_info; 923 struct cpu_defaults *cpu_info;
916 u64 units;
917 924
918 if (no_load) 925 if (no_load)
919 return -ENODEV; 926 return -ENODEV;
@@ -947,9 +954,6 @@ static int __init intel_pstate_init(void)
947 if (rc) 954 if (rc)
948 goto out; 955 goto out;
949 956
950 rdmsrl(MSR_RAPL_POWER_UNIT, units);
951 energy_divisor = 1 << ((units >> 8) & 0x1f); /* bits{12:8} */
952
953 intel_pstate_debug_expose_params(); 957 intel_pstate_debug_expose_params();
954 intel_pstate_sysfs_expose_params(); 958 intel_pstate_sysfs_expose_params();
955 959