Replace the simple exact-match loop in emit_clk_levels with a two-pass approach: the first pass checks whether the current frequency matches any DPM level exactly and also tracks the closest level by absolute frequency difference. The second pass emits the levels, marking the exact match if found, otherwise the closest level.
The SMU reports time-filtered average frequencies that often do not match any DPM table entry exactly. Without this 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. Also uses reverse DPM index for SMU_MCLK since MemPstateTable stores levels high-to-low. Signed-off-by: Priya Hosur <[email protected]> --- .../drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c | 46 ++++++++++++++++--- 1 file changed, 39 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 c203e828cce4..b113cf2b26fa 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 @@ -1195,14 +1195,46 @@ 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; + /* + * Try exact match first. If the SMU reports a time-averaged + * frequency that doesn't match any DPM level exactly, fall + * back to marking the closest DPM level. + */ + { + int closest_idx = 0; + uint32_t closest_diff = U32_MAX; + bool exact_match = false; + + 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; + + if (cur_value == value) + exact_match = true; + + if (abs((int)cur_value - (int)value) < closest_diff) { + closest_diff = abs((int)cur_value - (int)value); + closest_idx = i; + } + } - 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, &value); + if (ret) + return ret; + + if (exact_match) + size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", + i, value, + cur_value == value ? "*" : ""); + else + size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", + i, value, + i == closest_idx ? "*" : ""); + } } break; case SMU_DCEFCLK: -- 2.43.0
