summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPriya Hosur <Priya.Hosur@amd.com>2026-06-15 10:33:12 +0530
committerAlex Deucher <alexander.deucher@amd.com>2026-08-06 09:27:17 -0400
commit39dfe8a7d7092c23e480f35e2cb2760d3e93f7a6 (patch)
tree961e03545ea7a8160c3864aa14ff1410dc3ac10f
parentae60a2b05f813d434591c2d897222ba9cdff173f (diff)
downloadlinux-39dfe8a7d7092c23e480f35e2cb2760d3e93f7a6.tar.gz
linux-39dfe8a7d7092c23e480f35e2cb2760d3e93f7a6.zip
drm/amd/pm: smu_v14_0_0: use find_clk_level() for DPM level marking
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 <Priya.Hosur@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c29
1 files 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 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;
+
+ 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: