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
