Skip to content

Commit bedadcf

Browse files
Perry Yuanrafaeljw
authored andcommitted
cpufreq: amd-pstate: Fix initial highest_perf value
To avoid some new AMD processors use wrong highest perf when amd pstate driver loaded, this fix will query the highest perf from MSR register MSR_AMD_CPPC_CAP1 and cppc_acpi interface firstly, then compare with the highest perf value got by calling amd_get_highest_perf() function. The lower value will be the correct highest perf we need to use. Otherwise the CPU max MHz will be incorrect if the amd_get_highest_perf() did not cover the new process family and model ID. Like this lscpu info, the max frequency is incorrect. Vendor ID: AuthenticAMD Socket(s): 1 Stepping: 2 CPU max MHz: 5410.0000 CPU min MHz: 400.0000 BogoMIPS: 5600.54 Fixes: 3743d55 (x86, sched: Fix the AMD CPPC maximum performance value on certain AMD Ryzen generations) Acked-by: Huang Rui <[email protected]> Signed-off-by: Perry Yuan <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent ca08e46 commit bedadcf

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

drivers/cpufreq/amd-pstate.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ static inline int amd_pstate_enable(bool enable)
152152
static int pstate_init_perf(struct amd_cpudata *cpudata)
153153
{
154154
u64 cap1;
155+
u32 highest_perf;
155156

156157
int ret = rdmsrl_safe_on_cpu(cpudata->cpu, MSR_AMD_CPPC_CAP1,
157158
&cap1);
@@ -163,7 +164,11 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
163164
*
164165
* CPPC entry doesn't indicate the highest performance in some ASICs.
165166
*/
166-
WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf());
167+
highest_perf = amd_get_highest_perf();
168+
if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1))
169+
highest_perf = AMD_CPPC_HIGHEST_PERF(cap1);
170+
171+
WRITE_ONCE(cpudata->highest_perf, highest_perf);
167172

168173
WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1));
169174
WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1));
@@ -175,12 +180,17 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
175180
static int cppc_init_perf(struct amd_cpudata *cpudata)
176181
{
177182
struct cppc_perf_caps cppc_perf;
183+
u32 highest_perf;
178184

179185
int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
180186
if (ret)
181187
return ret;
182188

183-
WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf());
189+
highest_perf = amd_get_highest_perf();
190+
if (highest_perf > cppc_perf.highest_perf)
191+
highest_perf = cppc_perf.highest_perf;
192+
193+
WRITE_ONCE(cpudata->highest_perf, highest_perf);
184194

185195
WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf);
186196
WRITE_ONCE(cpudata->lowest_nonlinear_perf,

0 commit comments

Comments
 (0)