From: Srinivas Pandruvada <srinivas.pandruv...@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.pandruv...@linux.intel.com> Signed-off-by: Yong, Jonathan <jonathan.y...@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 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto