[linux-yocto] [PATCH 2/4] cpufreq: intel_p_state: Fix P1 and below as guaranteed performance
Yong, Jonathan
jonathan.yong at intel.com
Mon Jun 20 22:33:04 PDT 2016
From: Srinivas Pandruvada <srinivas.pandruvada at linux.intel.com>
Request for performance states P1 and below should be honored unless
limited by some platform thermals, but shouldn't get more than what
OS requested. On several platforms when we restrict P state to P1 or
below, we see jump to turbo range. We get the max non turbo P state
from read only MSR 0xCE (PLATFORM_INFO). But the turbo activation ratio
doesn't follow the value read from this MSR. This uses
MSR TURBO_ACTIVATION_RATIO(0x64C). BIOS is supposed to set the
TURBO_ACTIVATION_RATIO. The value currently set on these platform is very
low. For example on Surface 3 pro, the max non turbo P state is 0x17,
but turbo activation ratio is set to 0x10. So any P state above 0x10
will force P state to turbo range, where it will execute in any state
between P1 and P0. This change programs TURBO_ACTIVATION_RATIO to max non
turbo P state from PLATFORM_INFO.
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada at linux.intel.com>
Signed-off-by: Yong, Jonathan <jonathan.yong at intel.com>
---
arch/x86/include/uapi/asm/msr-index.h | 1 +
drivers/cpufreq/intel_pstate.c | 26 ++++++++++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h
index a63a302..899effc 100644
--- a/arch/x86/include/uapi/asm/msr-index.h
+++ b/arch/x86/include/uapi/asm/msr-index.h
@@ -64,6 +64,7 @@
#define MSR_TURBO_RATIO_LIMIT 0x000001ad
#define MSR_TURBO_RATIO_LIMIT1 0x000001ae
#define MSR_TURBO_RATIO_LIMIT2 0x000001af
+#define MSR_TURBO_ACTIVATION_RATIO 0x0000064c
#define MSR_LBR_SELECT 0x000001c8
#define MSR_LBR_TOS 0x000001c9
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 7d02796..389e55b 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -129,6 +129,7 @@ struct pstate_funcs {
int (*get_max)(void);
int (*get_min)(void);
int (*get_turbo)(void);
+ void (*adjust_states)(struct cpudata *);
int (*get_scaling)(void);
void (*set)(struct cpudata*, int pstate);
void (*get_vid)(struct cpudata *);
@@ -601,6 +602,26 @@ static int core_get_turbo_pstate(void)
return ret;
}
+static void core_adjust_states(struct cpudata *cpudata)
+{
+ u64 value;
+
+ if (rdmsrl_safe(MSR_TURBO_ACTIVATION_RATIO, &value))
+ return;
+
+ if (value & BIT(31))
+ return; /* locked */
+
+ if (cpudata->pstate.max_pstate > value) {
+ int err;
+
+ value = cpudata->pstate.max_pstate & 0xff;
+ err = wrmsrl_safe(MSR_TURBO_ACTIVATION_RATIO, value);
+ if (err)
+ pr_err("Adjust MSR_TURBO_ACTIVATION_RATIO failed\n");
+ }
+}
+
static inline int core_get_scaling(void)
{
return 100000;
@@ -645,6 +666,7 @@ static struct cpu_defaults core_params = {
.get_turbo = core_get_turbo_pstate,
.get_scaling = core_get_scaling,
.set = core_set_pstate,
+ .adjust_states = core_adjust_states,
},
};
@@ -738,6 +760,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
if (pstate_funcs.get_vid)
pstate_funcs.get_vid(cpu);
intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate, false);
+
+ if (pstate_funcs.adjust_states)
+ pstate_funcs.adjust_states(cpu);
}
static inline void intel_pstate_calc_busy(struct cpudata *cpu)
@@ -1106,6 +1131,7 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs)
pstate_funcs.get_scaling = funcs->get_scaling;
pstate_funcs.set = funcs->set;
pstate_funcs.get_vid = funcs->get_vid;
+ pstate_funcs.adjust_states = funcs->adjust_states;
}
#if IS_ENABLED(CONFIG_ACPI)
--
2.7.3
More information about the linux-yocto
mailing list