diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c index 7cf522609583..c83c58d5a2e2 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c @@ -1242,14 +1242,29 @@ static int smu_v14_0_0_emit_clk_levels(struct smu_context *smu, if (ret) return ret; - for (i = 0; i < count; i++) { - idx = (clk_type == SMU_MCLK) ? (count - i - 1) : i; - ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, idx, &value); - if (ret) - return ret; + /* + * Build a frequency table and use find_clk_level() to + * locate the closest DPM level. The SMU often reports + * time-averaged frequencies that do not match any DPM + * entry exactly. + */ + { + uint32_t freqs[NUM_SOCCLK_DPM_LEVELS]; + int active; - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, - cur_value == value ? "*" : ""); + for (i = 0; i < count; i++) { + idx = (clk_type == SMU_MCLK) ? (count - i - 1) : i; + ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, idx, &freqs[i]); + if (ret) + return ret; + } + + active = smu_v14_0_0_find_clk_level(freqs, count, cur_value); + + for (i = 0; i < count; i++) + size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", + i, freqs[i], + i == active ? "*" : ""); } break; case SMU_DCEFCLK: