Merge branches 'fixes' and 'misc' into for-next
[linux-2.6-microblaze.git] / drivers / cpufreq / intel_pstate.c
index 79606f4..2cd36b9 100644 (file)
 
 #define SAMPLE_COUNT           3
 
-#define BYT_RATIOS     0x66a
-#define BYT_VIDS        0x66b
+#define BYT_RATIOS             0x66a
+#define BYT_VIDS               0x66b
+#define BYT_TURBO_RATIOS       0x66c
 
-#define FRAC_BITS 8
+
+#define FRAC_BITS 6
 #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)
 {
@@ -51,8 +54,6 @@ static inline int32_t div_fp(int32_t x, int32_t y)
        return div_s64((int64_t)x << FRAC_BITS, (int64_t)y);
 }
 
-static u64 energy_divisor;
-
 struct sample {
        int32_t core_pct_busy;
        u64 aperf;
@@ -359,7 +360,7 @@ static int byt_get_min_pstate(void)
 {
        u64 value;
        rdmsrl(BYT_RATIOS, value);
-       return value & 0xFF;
+       return (value >> 8) & 0xFF;
 }
 
 static int byt_get_max_pstate(void)
@@ -369,6 +370,13 @@ static int byt_get_max_pstate(void)
        return (value >> 16) & 0xFF;
 }
 
+static int byt_get_turbo_pstate(void)
+{
+       u64 value;
+       rdmsrl(BYT_TURBO_RATIOS, value);
+       return value & 0x3F;
+}
+
 static void byt_set_pstate(struct cpudata *cpudata, int pstate)
 {
        u64 val;
@@ -471,7 +479,7 @@ static struct cpu_defaults byt_params = {
        .funcs = {
                .get_max = byt_get_max_pstate,
                .get_min = byt_get_min_pstate,
-               .get_turbo = byt_get_max_pstate,
+               .get_turbo = byt_get_turbo_pstate,
                .set = byt_set_pstate,
                .get_vid = byt_get_vid,
        },
@@ -549,18 +557,20 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
 static inline void intel_pstate_calc_busy(struct cpudata *cpu,
                                        struct sample *sample)
 {
-       u64 core_pct;
-       u64 c0_pct;
+       int32_t core_pct;
+       int32_t c0_pct;
+
+       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);
 
-       core_pct = div64_u64(sample->aperf * 100, sample->mperf);
+       c0_pct = div_fp(int_tofp(sample->mperf), int_tofp(sample->tsc));
 
-       c0_pct = div64_u64(sample->mperf * 100, sample->tsc);
        sample->freq = fp_toint(
-               mul_fp(int_tofp(cpu->pstate.max_pstate),
-                       int_tofp(core_pct * 1000)));
+               mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct));
 
-       sample->core_pct_busy = mul_fp(int_tofp(core_pct),
-                               div_fp(int_tofp(c0_pct + 1), int_tofp(100)));
+       sample->core_pct_busy = mul_fp(core_pct, c0_pct);
 }
 
 static inline void intel_pstate_sample(struct cpudata *cpu)
@@ -572,6 +582,10 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
        rdmsrl(MSR_IA32_MPERF, mperf);
        tsc = native_read_tsc();
 
+       aperf = aperf >> FRAC_BITS;
+       mperf = mperf >> FRAC_BITS;
+       tsc = tsc >> FRAC_BITS;
+
        cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT;
        cpu->samples[cpu->sample_ptr].aperf = aperf;
        cpu->samples[cpu->sample_ptr].mperf = mperf;
@@ -603,7 +617,8 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
        core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy;
        max_pstate = int_tofp(cpu->pstate.max_pstate);
        current_pstate = int_tofp(cpu->pstate.current_pstate);
-       return mul_fp(core_busy, div_fp(max_pstate, current_pstate));
+       core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate));
+       return FP_ROUNDUP(core_busy);
 }
 
 static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
@@ -630,12 +645,10 @@ static void intel_pstate_timer_func(unsigned long __data)
 {
        struct cpudata *cpu = (struct cpudata *) __data;
        struct sample *sample;
-       u64 energy;
 
        intel_pstate_sample(cpu);
 
        sample = &cpu->samples[cpu->sample_ptr];
-       rdmsrl(MSR_PKG_ENERGY_STATUS, energy);
 
        intel_pstate_adjust_busy_pstate(cpu);
 
@@ -644,7 +657,6 @@ static void intel_pstate_timer_func(unsigned long __data)
                        cpu->pstate.current_pstate,
                        sample->mperf,
                        sample->aperf,
-                       div64_u64(energy, energy_divisor),
                        sample->freq);
 
        intel_pstate_set_sample_time(cpu);
@@ -926,7 +938,6 @@ static int __init intel_pstate_init(void)
        int cpu, rc = 0;
        const struct x86_cpu_id *id;
        struct cpu_defaults *cpu_info;
-       u64 units;
 
        if (no_load)
                return -ENODEV;
@@ -960,9 +971,6 @@ static int __init intel_pstate_init(void)
        if (rc)
                goto out;
 
-       rdmsrl(MSR_RAPL_POWER_UNIT, units);
-       energy_divisor = 1 << ((units >> 8) & 0x1f); /* bits{12:8} */
-
        intel_pstate_debug_expose_params();
        intel_pstate_sysfs_expose_params();