Skip to content

Commit 857a61c

Browse files
nsolanki22superm1
authored andcommitted
cpufreq/amd-pstate: Refactor max frequency calculation
The previous approach introduced roundoff errors during division when calculating the boost ratio. This, in turn, affected the maximum frequency calculation, often resulting in reporting lower frequency values. For example, on the Glinda SoC based board with the following parameters: max_perf = 208 nominal_perf = 100 nominal_freq = 2600 MHz The Linux kernel previously calculated the frequency as: freq = ((max_perf * 1024 / nominal_perf) * nominal_freq) / 1024 freq = 5405 MHz // Integer arithmetic. With the updated formula: freq = (max_perf * nominal_freq) / nominal_perf freq = 5408 MHz This change ensures more accurate frequency calculations by eliminating unnecessary shifts and divisions, thereby improving precision. Signed-off-by: Naresh Solanki <naresh.solanki@9elements.com> [ML: trim the changelog from commit message] Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> Link: https://lore.kernel.org/r/20241219201833.2750998-1-naresh.solanki@9elements.com Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
1 parent fd604ae commit 857a61c

File tree

1 file changed

+4
-9
lines changed

1 file changed

+4
-9
lines changed

drivers/cpufreq/amd-pstate.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -908,9 +908,8 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
908908
{
909909
int ret;
910910
u32 min_freq, max_freq;
911-
u32 nominal_perf, nominal_freq;
911+
u32 highest_perf, nominal_perf, nominal_freq;
912912
u32 lowest_nonlinear_perf, lowest_nonlinear_freq;
913-
u32 boost_ratio, lowest_nonlinear_ratio;
914913
struct cppc_perf_caps cppc_perf;
915914

916915
ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
@@ -927,16 +926,12 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
927926
else
928927
nominal_freq = cppc_perf.nominal_freq;
929928

929+
highest_perf = READ_ONCE(cpudata->highest_perf);
930930
nominal_perf = READ_ONCE(cpudata->nominal_perf);
931-
932-
boost_ratio = div_u64(cpudata->highest_perf << SCHED_CAPACITY_SHIFT, nominal_perf);
933-
max_freq = (nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT);
931+
max_freq = div_u64((u64)highest_perf * nominal_freq, nominal_perf);
934932

935933
lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
936-
lowest_nonlinear_ratio = div_u64(lowest_nonlinear_perf << SCHED_CAPACITY_SHIFT,
937-
nominal_perf);
938-
lowest_nonlinear_freq = (nominal_freq * lowest_nonlinear_ratio >> SCHED_CAPACITY_SHIFT);
939-
934+
lowest_nonlinear_freq = div_u64((u64)nominal_freq * lowest_nonlinear_perf, nominal_perf);
940935
WRITE_ONCE(cpudata->min_freq, min_freq * 1000);
941936
WRITE_ONCE(cpudata->lowest_nonlinear_freq, lowest_nonlinear_freq * 1000);
942937
WRITE_ONCE(cpudata->nominal_freq, nominal_freq * 1000);

0 commit comments

Comments
 (0)