drm/amd/pm: Add partition metrics support

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>
This commit is contained in:
Asad Kamal 2025-12-26 17:58:03 +08:00 committed by Alex Deucher
parent b0220373ce
commit 910e8a5f3e
2 changed files with 112 additions and 0 deletions

View 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,

View 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