diff options
Diffstat (limited to 'drivers/cpufreq/intel_pstate.c')
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index e90816105921..2cd36b9297f3 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -39,9 +39,10 @@ | |||
39 | #define BYT_TURBO_RATIOS 0x66c | 39 | #define BYT_TURBO_RATIOS 0x66c |
40 | 40 | ||
41 | 41 | ||
42 | #define FRAC_BITS 8 | 42 | #define FRAC_BITS 6 |
43 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) | 43 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) |
44 | #define fp_toint(X) ((X) >> FRAC_BITS) | 44 | #define fp_toint(X) ((X) >> FRAC_BITS) |
45 | #define FP_ROUNDUP(X) ((X) += 1 << FRAC_BITS) | ||
45 | 46 | ||
46 | static inline int32_t mul_fp(int32_t x, int32_t y) | 47 | static inline int32_t mul_fp(int32_t x, int32_t y) |
47 | { | 48 | { |
@@ -556,18 +557,20 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) | |||
556 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, | 557 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, |
557 | struct sample *sample) | 558 | struct sample *sample) |
558 | { | 559 | { |
559 | u64 core_pct; | 560 | int32_t core_pct; |
560 | u64 c0_pct; | 561 | int32_t c0_pct; |
561 | 562 | ||
562 | core_pct = div64_u64(sample->aperf * 100, sample->mperf); | 563 | core_pct = div_fp(int_tofp((sample->aperf)), |
564 | int_tofp((sample->mperf))); | ||
565 | core_pct = mul_fp(core_pct, int_tofp(100)); | ||
566 | FP_ROUNDUP(core_pct); | ||
567 | |||
568 | c0_pct = div_fp(int_tofp(sample->mperf), int_tofp(sample->tsc)); | ||
563 | 569 | ||
564 | c0_pct = div64_u64(sample->mperf * 100, sample->tsc); | ||
565 | sample->freq = fp_toint( | 570 | sample->freq = fp_toint( |
566 | mul_fp(int_tofp(cpu->pstate.max_pstate), | 571 | mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct)); |
567 | int_tofp(core_pct * 1000))); | ||
568 | 572 | ||
569 | sample->core_pct_busy = mul_fp(int_tofp(core_pct), | 573 | sample->core_pct_busy = mul_fp(core_pct, c0_pct); |
570 | div_fp(int_tofp(c0_pct + 1), int_tofp(100))); | ||
571 | } | 574 | } |
572 | 575 | ||
573 | static inline void intel_pstate_sample(struct cpudata *cpu) | 576 | static inline void intel_pstate_sample(struct cpudata *cpu) |
@@ -579,6 +582,10 @@ static inline void intel_pstate_sample(struct cpudata *cpu) | |||
579 | rdmsrl(MSR_IA32_MPERF, mperf); | 582 | rdmsrl(MSR_IA32_MPERF, mperf); |
580 | tsc = native_read_tsc(); | 583 | tsc = native_read_tsc(); |
581 | 584 | ||
585 | aperf = aperf >> FRAC_BITS; | ||
586 | mperf = mperf >> FRAC_BITS; | ||
587 | tsc = tsc >> FRAC_BITS; | ||
588 | |||
582 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; | 589 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; |
583 | cpu->samples[cpu->sample_ptr].aperf = aperf; | 590 | cpu->samples[cpu->sample_ptr].aperf = aperf; |
584 | cpu->samples[cpu->sample_ptr].mperf = mperf; | 591 | cpu->samples[cpu->sample_ptr].mperf = mperf; |
@@ -610,7 +617,8 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu) | |||
610 | core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy; | 617 | core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy; |
611 | max_pstate = int_tofp(cpu->pstate.max_pstate); | 618 | max_pstate = int_tofp(cpu->pstate.max_pstate); |
612 | current_pstate = int_tofp(cpu->pstate.current_pstate); | 619 | current_pstate = int_tofp(cpu->pstate.current_pstate); |
613 | return mul_fp(core_busy, div_fp(max_pstate, current_pstate)); | 620 | core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); |
621 | return FP_ROUNDUP(core_busy); | ||
614 | } | 622 | } |
615 | 623 | ||
616 | static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) | 624 | static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) |