aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/intel_pstate.c
diff options
context:
space:
mode:
authorDirk Brandewie <dirk.j.brandewie@intel.com>2014-05-29 12:32:23 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-06-02 06:44:59 -0400
commitf0fe3cd7e12d8290c82284b5c8aee723cbd0371a (patch)
tree8cb72c5039750da308ff05dab076a0c455e9bf15 /drivers/cpufreq/intel_pstate.c
parentadacdf3f2b8e65aa441613cf61c4f598e9042690 (diff)
intel_pstate: Correct rounding in busy calculation
Changing to fixed point math throughout the busy calculation in commit e66c1768 (Change busy calculation to use fixed point math.) Introduced some inaccuracies by rounding the busy value at two points in the calculation. This change removes roundings and moves the rounding to the output of the PID where the calculations are complete and the value returned as an integer. Fixes: e66c17683746 (intel_pstate: Change busy calculation to use fixed point math.) Reported-by: Doug Smythies <dsmythies@telus.net> Cc: 3.14+ <stable@vger.kernel.org> # 3.14+ Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/intel_pstate.c')
-rw-r--r--drivers/cpufreq/intel_pstate.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index e5735446c7ed..3d57e53212d6 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -40,10 +40,10 @@
40#define BYT_TURBO_VIDS 0x66d 40#define BYT_TURBO_VIDS 0x66d
41 41
42 42
43#define FRAC_BITS 6 43#define FRAC_BITS 8
44#define int_tofp(X) ((int64_t)(X) << FRAC_BITS) 44#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
45#define fp_toint(X) ((X) >> FRAC_BITS) 45#define fp_toint(X) ((X) >> FRAC_BITS)
46#define FP_ROUNDUP(X) ((X) += 1 << FRAC_BITS) 46
47 47
48static inline int32_t mul_fp(int32_t x, int32_t y) 48static inline int32_t mul_fp(int32_t x, int32_t y)
49{ 49{
@@ -198,7 +198,10 @@ static signed int pid_calc(struct _pid *pid, int32_t busy)
198 pid->last_err = fp_error; 198 pid->last_err = fp_error;
199 199
200 result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm; 200 result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm;
201 201 if (result >= 0)
202 result = result + (1 << (FRAC_BITS-1));
203 else
204 result = result - (1 << (FRAC_BITS-1));
202 return (signed int)fp_toint(result); 205 return (signed int)fp_toint(result);
203} 206}
204 207
@@ -563,7 +566,6 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu,
563 core_pct = div_fp(int_tofp((sample->aperf)), 566 core_pct = div_fp(int_tofp((sample->aperf)),
564 int_tofp((sample->mperf))); 567 int_tofp((sample->mperf)));
565 core_pct = mul_fp(core_pct, int_tofp(100)); 568 core_pct = mul_fp(core_pct, int_tofp(100));
566 FP_ROUNDUP(core_pct);
567 569
568 sample->freq = fp_toint( 570 sample->freq = fp_toint(
569 mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct)); 571 mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct));
@@ -609,7 +611,7 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
609 max_pstate = int_tofp(cpu->pstate.max_pstate); 611 max_pstate = int_tofp(cpu->pstate.max_pstate);
610 current_pstate = int_tofp(cpu->pstate.current_pstate); 612 current_pstate = int_tofp(cpu->pstate.current_pstate);
611 core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); 613 core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate));
612 return FP_ROUNDUP(core_busy); 614 return core_busy;
613} 615}
614 616
615static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) 617static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)