]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/pm: Add partition metrics support
authorAsad Kamal <asad.kamal@amd.com>
Fri, 26 Dec 2025 09:58:03 +0000 (17:58 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 17 Apr 2026 19:41:14 +0000 (15:41 -0400)
Add partition metrics support for smu_v15_0_8

Signed-off-by: Asad Kamal <asad.kamal@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.h

index 912a1e1e0cd6aca048f031cfbb52a8c6be5ae4ab..288fab5ee5e534d97fa07875d49b3528be62b56f 100644 (file)
@@ -63,6 +63,8 @@
        for ((stack_idx) = 0; (umc_mask); \
             (umc_mask) >>= 4, (stack_idx)++) \
 
+#define NUM_JPEG_RINGS_FW      10
+
 #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
 
 #define SMU_15_0_8_FEA_MAP(smu_feature, smu_15_0_8_feature)                    \
@@ -1593,6 +1595,81 @@ static ssize_t smu_v15_0_8_get_temp_metrics(struct smu_context *smu,
        }
 }
 
+static ssize_t smu_v15_0_8_get_xcp_metrics(struct smu_context *smu, int xcp_id,
+                                          void *table)
+{
+       struct smu_table_context *smu_table = &smu->smu_table;
+       const u8 num_jpeg_rings = NUM_JPEG_RINGS_FW;
+       struct smu_v15_0_8_partition_metrics *xcp_metrics;
+       MetricsTable_t *metrics;
+       struct amdgpu_device *adev = smu->adev;
+       int ret, inst, i, j, k, idx;
+       struct amdgpu_xcp *xcp;
+       u32 inst_mask;
+
+       if (!table)
+               return sizeof(*xcp_metrics);
+
+       for_each_xcp(adev->xcp_mgr, xcp, i) {
+               if (xcp->id == xcp_id)
+                       break;
+       }
+       if (i == adev->xcp_mgr->num_xcps)
+               return -EINVAL;
+
+       xcp_metrics = (struct smu_v15_0_8_partition_metrics *)table;
+       smu_v15_0_8_partition_metrics_init(xcp_metrics, 1, 1);
+
+       ret = smu_v15_0_8_get_metrics_table_internal(smu, 1, NULL);
+       if (ret)
+               return ret;
+
+       metrics = (MetricsTable_t *)smu_table->metrics_table;
+
+       amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_VCN, &inst_mask);
+       idx = 0;
+       for_each_inst(k, inst_mask) {
+               /* Both JPEG and VCN has same instances */
+               inst = GET_INST(VCN, k);
+               for (j = 0; j < num_jpeg_rings; ++j) {
+                       xcp_metrics->jpeg_busy[(idx * num_jpeg_rings) + j] =
+                               SMUQ10_ROUND(metrics->JpegBusy[(inst * num_jpeg_rings) + j]);
+               }
+               xcp_metrics->vcn_busy[idx] =
+                       SMUQ10_ROUND(metrics->VcnBusy[inst]);
+
+               xcp_metrics->current_vclk[idx] = SMUQ10_ROUND(metrics->VclkFrequency[inst]);
+               xcp_metrics->current_dclk[idx] = SMUQ10_ROUND(metrics->DclkFrequency[inst]);
+
+               idx++;
+       }
+
+       amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_GFX, &inst_mask);
+       idx = 0;
+       for_each_inst(k, inst_mask) {
+               inst = GET_INST(GC, k);
+               xcp_metrics->current_gfxclk[idx] =
+                       SMUQ10_ROUND(metrics->GfxclkFrequency[inst]);
+
+               xcp_metrics->gfx_busy_inst[idx] = SMUQ10_ROUND(metrics->GfxBusy[inst]);
+               xcp_metrics->gfx_busy_acc[idx] = SMUQ10_ROUND(metrics->GfxBusyAcc[inst]);
+               xcp_metrics->gfx_below_host_limit_ppt_acc[idx] =
+                       SMUQ10_ROUND(metrics->GfxclkBelowHostLimitPptAcc[inst]);
+               xcp_metrics->gfx_below_host_limit_thm_acc[idx] =
+                       SMUQ10_ROUND(metrics->GfxclkBelowHostLimitThmAcc[inst]);
+               xcp_metrics->gfx_low_utilization_acc[idx] =
+                       SMUQ10_ROUND(metrics->GfxclkLowUtilizationAcc[inst]);
+               xcp_metrics->gfx_below_host_limit_total_acc[idx] =
+                       SMUQ10_ROUND(metrics->GfxclkBelowHostLimitTotalAcc[inst]);
+               idx++;
+       }
+
+       xcp_metrics->accumulation_counter = metrics->AccumulationCounter;
+       xcp_metrics->firmware_timestamp = metrics->Timestamp;
+
+       return sizeof(*xcp_metrics);
+}
+
 static ssize_t smu_v15_0_8_get_gpu_metrics(struct smu_context *smu, void **table)
 {
        struct smu_table_context *smu_table = &smu->smu_table;
@@ -2222,6 +2299,7 @@ static const struct pptable_funcs smu_v15_0_8_ppt_funcs = {
        .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
        .wait_for_event = smu_v15_0_wait_for_event,
        .get_pm_metrics = smu_v15_0_8_get_pm_metrics,
+       .get_xcp_metrics = smu_v15_0_8_get_xcp_metrics,
        .mode2_reset = smu_v15_0_8_mode2_reset,
        .get_dpm_ultimate_freq = smu_v15_0_8_get_dpm_ultimate_freq,
        .get_gpu_metrics = smu_v15_0_8_get_gpu_metrics,
index 398ce44821741defebc08303555f5321d3d5db88..4dfc40aaffcb4e8a9d5c4d48c74511231f44bccc 100644 (file)
@@ -309,5 +309,39 @@ DECLARE_SMU_METRICS_CLASS(smu_v15_0_8_gpuboard_temp_metrics,
 
 DECLARE_SMU_METRICS_CLASS(smu_v15_0_8_baseboard_temp_metrics,
                          SMU_15_0_8_BASEBOARD_TEMP_METRICS_FIELDS);
+#define SMU_15_0_8_PARTITION_METRICS_FIELDS(SMU_SCALAR, SMU_ARRAY)             \
+       SMU_ARRAY(SMU_MATTR(CURRENT_GFXCLK), SMU_MUNIT(CLOCK_1),               \
+                 SMU_MTYPE(U16), current_gfxclk, SMU_15_0_8_MAX_XCC);         \
+       SMU_ARRAY(SMU_MATTR(CURRENT_VCLK0), SMU_MUNIT(CLOCK_1),                \
+                 SMU_MTYPE(U16), current_vclk, SMU_15_0_8_MAX_VCN);          \
+       SMU_ARRAY(SMU_MATTR(CURRENT_DCLK0), SMU_MUNIT(CLOCK_1),                \
+                 SMU_MTYPE(U16), current_dclk, SMU_15_0_8_MAX_VCN);          \
+       SMU_ARRAY(SMU_MATTR(GFX_BUSY_INST), SMU_MUNIT(PERCENT),                \
+                 SMU_MTYPE(U8), gfx_busy_inst, SMU_15_0_8_MAX_XCC);          \
+       SMU_ARRAY(SMU_MATTR(JPEG_BUSY), SMU_MUNIT(PERCENT), SMU_MTYPE(U8),    \
+                 jpeg_busy, SMU_15_0_8_MAX_JPEG);                             \
+       SMU_ARRAY(SMU_MATTR(VCN_BUSY), SMU_MUNIT(PERCENT), SMU_MTYPE(U8),     \
+                 vcn_busy, SMU_15_0_8_MAX_VCN);                               \
+       SMU_ARRAY(SMU_MATTR(GFX_BUSY_ACC), SMU_MUNIT(NONE), SMU_MTYPE(U64),    \
+                 gfx_busy_acc, SMU_15_0_8_MAX_XCC);                           \
+       SMU_ARRAY(SMU_MATTR(GFX_BELOW_HOST_LIMIT_PPT_ACC), SMU_MUNIT(NONE),    \
+                 SMU_MTYPE(U64), gfx_below_host_limit_ppt_acc,                \
+                 SMU_15_0_8_MAX_XCC);                                         \
+       SMU_ARRAY(SMU_MATTR(GFX_BELOW_HOST_LIMIT_THM_ACC), SMU_MUNIT(NONE),    \
+                 SMU_MTYPE(U64), gfx_below_host_limit_thm_acc,                \
+                 SMU_15_0_8_MAX_XCC);                                         \
+       SMU_ARRAY(SMU_MATTR(GFX_LOW_UTILIZATION_ACC), SMU_MUNIT(NONE),         \
+                 SMU_MTYPE(U64), gfx_low_utilization_acc,                     \
+                 SMU_15_0_8_MAX_XCC);                                         \
+       SMU_ARRAY(SMU_MATTR(GFX_BELOW_HOST_LIMIT_TOTAL_ACC), SMU_MUNIT(NONE),  \
+                 SMU_MTYPE(U64), gfx_below_host_limit_total_acc,              \
+                 SMU_15_0_8_MAX_XCC);                                         \
+       SMU_SCALAR(SMU_MATTR(ACCUMULATION_COUNTER), SMU_MUNIT(NONE),           \
+                  SMU_MTYPE(U64), accumulation_counter);                      \
+       SMU_SCALAR(SMU_MATTR(FIRMWARE_TIMESTAMP), SMU_MUNIT(TIME_2),           \
+                  SMU_MTYPE(U64), firmware_timestamp);
+
+DECLARE_SMU_METRICS_CLASS(smu_v15_0_8_partition_metrics,
+                         SMU_15_0_8_PARTITION_METRICS_FIELDS);
 #endif
 #endif