diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c index e23773680e05..c2c1a166b3a9 100644 --- a/drivers/cpufreq/amd-pstate-ut.c +++ b/drivers/cpufreq/amd-pstate-ut.c @@ -226,11 +226,14 @@ static int amd_pstate_ut_check_freq(u32 index) for_each_online_cpu(cpu) { struct cpufreq_policy *policy __free(put_cpufreq_policy) = NULL; struct amd_cpudata *cpudata; + union perf_cached perf; policy = cpufreq_cpu_get(cpu); if (!policy) continue; + cpudata = policy->driver_data; + perf = READ_ONCE(cpudata->perf); if (!((policy->cpuinfo.max_freq >= cpudata->nominal_freq) && (cpudata->nominal_freq > cpudata->lowest_nonlinear_freq) && @@ -242,7 +245,25 @@ static int amd_pstate_ut_check_freq(u32 index) return -EINVAL; } - if (cpudata->lowest_nonlinear_freq != policy->min) { + if (perf.bios_min_perf) { + u32 bios_min_freq = perf_to_freq(perf, cpudata->nominal_freq, + perf.bios_min_perf); + + /* + * User set bios_min_freq cannot be trusted to + * be within the driver limits. Clamp it similar + * to cpufreq_verify_within_cpu_limits(). + */ + bios_min_freq = clamp_t(u32, bios_min_freq, + policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + + if (bios_min_freq != policy->min) { + pr_err("%s cpu%d bios_min_freq=%d policy_min=%d, they should be equal!\n", + __func__, cpu, bios_min_freq, policy->min); + return -EINVAL; + } + } else if (cpudata->lowest_nonlinear_freq != policy->min) { pr_err("%s cpu%d cpudata_lowest_nonlinear_freq=%d policy_min=%d, they should be equal!\n", __func__, cpu, cpudata->lowest_nonlinear_freq, policy->min); return -EINVAL; diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 8bfd46d60843..ae1673b36ac4 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -145,19 +145,6 @@ static struct quirk_entry quirk_amd_7k62 = { .lowest_freq = 550, }; -static inline u8 freq_to_perf(union perf_cached perf, u32 nominal_freq, unsigned int freq_val) -{ - u32 perf_val = DIV_ROUND_UP_ULL((u64)freq_val * perf.nominal_perf, nominal_freq); - - return (u8)clamp(perf_val, perf.lowest_perf, perf.highest_perf); -} - -static inline u32 perf_to_freq(union perf_cached perf, u32 nominal_freq, u8 perf_val) -{ - return DIV_ROUND_UP_ULL((u64)nominal_freq * perf_val, - perf.nominal_perf); -} - static int __init dmi_matched_7k62_bios_bug(const struct dmi_system_id *dmi) { /** diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h index 9f5a81976eae..578465187b7a 100644 --- a/drivers/cpufreq/amd-pstate.h +++ b/drivers/cpufreq/amd-pstate.h @@ -159,6 +159,20 @@ enum amd_pstate_mode { AMD_PSTATE_GUIDED, AMD_PSTATE_MAX, }; + +static inline u8 freq_to_perf(union perf_cached perf, u32 nominal_freq, unsigned int freq_val) +{ + u32 perf_val = DIV_ROUND_UP_ULL((u64)freq_val * perf.nominal_perf, nominal_freq); + + return (u8)clamp(perf_val, perf.lowest_perf, perf.highest_perf); +} + +static inline u32 perf_to_freq(union perf_cached perf, u32 nominal_freq, u8 perf_val) +{ + return DIV_ROUND_UP_ULL((u64)nominal_freq * perf_val, + perf.nominal_perf); +} + const char *amd_pstate_get_mode_string(enum amd_pstate_mode mode); int amd_pstate_get_status(void); int amd_pstate_update_status(const char *buf, size_t size);