cpufreq: intel-pstate: Use separate max pstate for scaling
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Wed, 14 Oct 2015 23:12:00 +0000 (16:12 -0700)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 14 Oct 2015 23:53:18 +0000 (01:53 +0200)
Systems with configurable TDP have multiple max non turbo p state. Intel
P state uses max non turbo P state for scaling. But using the real max
non turbo p state causes underestimation of next P state. So using
the physical max non turbo P state as before for scaling.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Acked-by: Kristen Carlson Accardi <kristen@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpufreq/intel_pstate.c

index da92d02..1369afd 100644 (file)
@@ -77,6 +77,7 @@ struct pstate_data {
        int     current_pstate;
        int     min_pstate;
        int     max_pstate;
+       int     max_pstate_physical;
        int     scaling;
        int     turbo_pstate;
 };
@@ -126,6 +127,7 @@ struct pstate_adjust_policy {
 
 struct pstate_funcs {
        int (*get_max)(void);
+       int (*get_max_physical)(void);
        int (*get_min)(void);
        int (*get_turbo)(void);
        int (*get_scaling)(void);
@@ -590,6 +592,14 @@ static int core_get_min_pstate(void)
        return (value >> 40) & 0xFF;
 }
 
+static int core_get_max_pstate_physical(void)
+{
+       u64 value;
+
+       rdmsrl(MSR_PLATFORM_INFO, value);
+       return (value >> 8) & 0xFF;
+}
+
 static int core_get_max_pstate(void)
 {
        u64 tar;
@@ -683,6 +693,7 @@ static struct cpu_defaults core_params = {
        },
        .funcs = {
                .get_max = core_get_max_pstate,
+               .get_max_physical = core_get_max_pstate_physical,
                .get_min = core_get_min_pstate,
                .get_turbo = core_get_turbo_pstate,
                .get_scaling = core_get_scaling,
@@ -701,6 +712,7 @@ static struct cpu_defaults byt_params = {
        },
        .funcs = {
                .get_max = byt_get_max_pstate,
+               .get_max_physical = byt_get_max_pstate,
                .get_min = byt_get_min_pstate,
                .get_turbo = byt_get_turbo_pstate,
                .set = byt_set_pstate,
@@ -720,6 +732,7 @@ static struct cpu_defaults knl_params = {
        },
        .funcs = {
                .get_max = core_get_max_pstate,
+               .get_max_physical = core_get_max_pstate_physical,
                .get_min = core_get_min_pstate,
                .get_turbo = knl_get_turbo_pstate,
                .get_scaling = core_get_scaling,
@@ -774,6 +787,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
 {
        cpu->pstate.min_pstate = pstate_funcs.get_min();
        cpu->pstate.max_pstate = pstate_funcs.get_max();
+       cpu->pstate.max_pstate_physical = pstate_funcs.get_max_physical();
        cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
        cpu->pstate.scaling = pstate_funcs.get_scaling();
 
@@ -792,7 +806,8 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu)
 
        sample->freq = fp_toint(
                mul_fp(int_tofp(
-                       cpu->pstate.max_pstate * cpu->pstate.scaling / 100),
+                       cpu->pstate.max_pstate_physical *
+                       cpu->pstate.scaling / 100),
                        core_pct));
 
        sample->core_pct_busy = (int32_t)core_pct;
@@ -860,7 +875,7 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
         * specified pstate.
         */
        core_busy = cpu->sample.core_pct_busy;
-       max_pstate = int_tofp(cpu->pstate.max_pstate);
+       max_pstate = int_tofp(cpu->pstate.max_pstate_physical);
        current_pstate = int_tofp(cpu->pstate.current_pstate);
        core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate));
 
@@ -1144,6 +1159,7 @@ static void copy_pid_params(struct pstate_adjust_policy *policy)
 static void copy_cpu_funcs(struct pstate_funcs *funcs)
 {
        pstate_funcs.get_max   = funcs->get_max;
+       pstate_funcs.get_max_physical = funcs->get_max_physical;
        pstate_funcs.get_min   = funcs->get_min;
        pstate_funcs.get_turbo = funcs->get_turbo;
        pstate_funcs.get_scaling = funcs->get_scaling;