diff options
-rw-r--r-- | arch/x86/kernel/smpboot.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index ba9d3bdc191c..8cb3113377a9 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1841,6 +1841,48 @@ static const struct x86_cpu_id has_glm_turbo_ratio_limits[] = { {} }; +static bool knl_set_max_freq_ratio(u64 *base_freq, u64 *turbo_freq, + int num_delta_fratio) +{ + int fratio, delta_fratio, found; + int err, i; + u64 msr; + + if (!x86_match_cpu(has_knl_turbo_ratio_limits)) + return false; + + err = rdmsrl_safe(MSR_PLATFORM_INFO, base_freq); + if (err) + return false; + + *base_freq = (*base_freq >> 8) & 0xFF; /* max P state */ + + err = rdmsrl_safe(MSR_TURBO_RATIO_LIMIT, &msr); + if (err) + return false; + + fratio = (msr >> 8) & 0xFF; + i = 16; + found = 0; + do { + if (found >= num_delta_fratio) { + *turbo_freq = fratio; + return true; + } + + delta_fratio = (msr >> (i + 5)) & 0x7; + + if (delta_fratio) { + found += 1; + fratio -= delta_fratio; + } + + i += 8; + } while (i < 64); + + return true; +} + static bool skx_set_max_freq_ratio(u64 *base_freq, u64 *turbo_freq, int size) { u64 ratios, counts; @@ -1895,20 +1937,21 @@ static bool intel_set_max_freq_ratio(void) /* * TODO: add support for: * - * - Xeon Phi (KNM, KNL) * - Atom Goldmont * - Atom Silvermont */ u64 base_freq = 1, turbo_freq = 1; - if (x86_match_cpu(has_knl_turbo_ratio_limits) || - x86_match_cpu(has_glm_turbo_ratio_limits)) + if (x86_match_cpu(has_glm_turbo_ratio_limits)) return false; if (turbo_disabled()) goto out; + if (knl_set_max_freq_ratio(&base_freq, &turbo_freq, 1)) + goto out; + if (x86_match_cpu(has_skx_turbo_ratio_limits) && skx_set_max_freq_ratio(&base_freq, &turbo_freq, 4)) goto out; |