[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