cpufreq/amd-pstate-ut: Fix amd_pstate_ut_check_freq failure with 'Requested CPU Min frequency' BIOS option

Since commit 608a76b652 ("cpufreq/amd-pstate: Add support for the
"Requested CPU Min frequency" BIOS option"), amd-pstate driver sets
policy->min to frequency corresponding to bios_min_perf if a valid BIOS
programmed min frequency value is detected.

amd_pstate_ut_check_freq expects policy->min to always match
lowest_nonlinear_freq which does not hold true on platforms with user
configured BIOS min freq.

Update the test case to compare policy->min to bios_min_freq on
platforms that set it. Final comparison is adjusted to account for
insane values by clamping the result within the supported frequency
range.

While at it, move freq_to_perf() and perf_to_freq() helpers to internal
header to allow their use from amd-pstate-ut.

Reviewed-by: Mario Limonciello <superm1@kernel.org>
Fixes: 608a76b652 ("cpufreq/amd-pstate: Add support for the "Requested CPU Min frequency" BIOS option")
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
Link: https://lore.kernel.org/r/20260909102650.4582-1-kprateek.nayak@amd.com
Signed-off-by: Mario Limonciello <superm1@kernel.org>
This commit is contained in:
K Prateek Nayak 2026-09-09 10:26:50 +00:00 committed by Mario Limonciello
parent df2908090c
commit a23fca4ae1
3 changed files with 36 additions and 14 deletions

View File

@ -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;

View File

@ -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)
{
/**

View File

@ -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);