aboutsummaryrefslogtreecommitdiff
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorDirk Brandewie2014-05-29 09:32:23 -0700
committerRafael J. Wysocki2014-06-02 12:44:59 +0200
commitf0fe3cd7e12d8290c82284b5c8aee723cbd0371a (patch)
tree8cb72c5039750da308ff05dab076a0c455e9bf15 /drivers/cpufreq
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')
-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 @@
#define BYT_TURBO_VIDS 0x66d
-#define FRAC_BITS 6
+#define FRAC_BITS 8
#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
#define fp_toint(X) ((X) >> FRAC_BITS)
-#define FP_ROUNDUP(X) ((X) += 1 << FRAC_BITS)
+
static inline int32_t mul_fp(int32_t x, int32_t y)
{
@@ -198,7 +198,10 @@ static signed int pid_calc(struct _pid *pid, int32_t busy)
pid->last_err = fp_error;
result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm;
-
+ if (result >= 0)
+ result = result + (1 << (FRAC_BITS-1));
+ else
+ result = result - (1 << (FRAC_BITS-1));
return (signed int)fp_toint(result);
}
@@ -563,7 +566,6 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu,
core_pct = div_fp(int_tofp((sample->aperf)),
int_tofp((sample->mperf)));
core_pct = mul_fp(core_pct, int_tofp(100));
- FP_ROUNDUP(core_pct);
sample->freq = fp_toint(
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)
max_pstate = int_tofp(cpu->pstate.max_pstate);
current_pstate = int_tofp(cpu->pstate.current_pstate);
core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate));
- return FP_ROUNDUP(core_busy);
+ return core_busy;
}
static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)