SmuMetrics_t has no DclkFrequency field but DCLK and VCLK have
separate DPM clock tables with different frequencies at each level.

For METRICS_AVERAGE_DCLK, find the DPM level whose VCLK frequency
matches the reported VclkFrequency and return the DCLK frequency at
that same level index, since both clocks share the same level count
(VcnClkLevelsEnabled / Vcn0ClkLevelsEnabled).

The original code returned 0 for METRICS_AVERAGE_DCLK, which broke
the active-level marker in pp_dpm_dclk entirely.

Signed-off-by: Priya Hosur <[email protected]>
---
 .../drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c  | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

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 2fe006de927a..c4c45c8dff69 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
@@ -284,7 +284,34 @@ static int smu_v14_0_0_get_smu_metrics_data(struct 
smu_context *smu,
                *value = metrics->VclkFrequency;
                break;
        case METRICS_AVERAGE_DCLK:
+               /*
+                * SmuMetrics_t has no DclkFrequency field.  DCLK and VCLK
+                * share the same DPM level count, so find the DPM level
+                * whose VCLK matches the reported VclkFrequency and return
+                * the DCLK frequency at that level.
+                */
                *value = 0;
+               if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 
0, 1)) {
+                       DpmClocks_t_v14_0_1 *clk_table = 
smu->smu_table.clocks_table;
+                       uint8_t i, levels = clk_table->Vcn0ClkLevelsEnabled;
+
+                       for (i = 0; i < levels; i++) {
+                               if (clk_table->VClocks0[i] == 
metrics->VclkFrequency) {
+                                       *value = clk_table->DClocks0[i];
+                                       break;
+                               }
+                       }
+               } else {
+                       DpmClocks_t *clk_table = smu->smu_table.clocks_table;
+                       uint8_t i, levels = clk_table->VcnClkLevelsEnabled;
+
+                       for (i = 0; i < levels; i++) {
+                               if (clk_table->VClocks[i] == 
metrics->VclkFrequency) {
+                                       *value = clk_table->DClocks[i];
+                                       break;
+                               }
+                       }
+               }
                break;
        case METRICS_AVERAGE_UCLK:
                *value = metrics->MemclkFrequency;
-- 
2.43.0

Reply via email to