Replace the simple exact-match loop in emit_clk_levels with a call to smu_v14_0_0_find_clk_level() introduced in patch 1. The helper already handles both exact and closest-match semantics.
Build a stack-local frequency table from the DPM levels (using reverse index for SMU_MCLK since MemPstateTable stores levels high-to-low), then call the helper once to find the active level. The SMU reports time-filtered average frequencies that often do not match any DPM table entry exactly. Without closest-match fallback, MCLK, FCLK and other clocks show DPM levels but never display the * marker, breaking userspace tools that rely on it to identify the active frequency. Signed-off-by: Priya Hosur <[email protected]> Reviewed-by: Lijo Lazar <[email protected]> --- .../drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) 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 f273b95928c9..9efeaedbe317 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 @@ -1243,14 +1243,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; + + 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); - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, - cur_value == 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: -- 2.43.0
