[PATCH V6 2/2] drm/amd/pm: fix SMU v15 metrics fetch, scaling, and sensor mapping

Shubhankar Milind Sardeshpande <[email protected]> Wed, 29 Jul 2026 15:02:47 +0530
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
V6 fixes: Fix several issues in the SMU v15 metrics path
that were triggering CI warnings and causing
incorrect runtime metric values.

Key fixes:

-Always refresh the metrics table DRAM address during table init instead
 of skipping when addr is non-zero.
-Use memcpy_fromio() for copying the metrics table from MMIO/IO memory.
-Store metrics_time after a successful table read to make cache-age checks
 consistent.
-Use size_t for metrics table size to avoid type/size warnings.
-Correct accumulator fixed-point conversions in
 smu_v15_0_0_compute_all_metrics():
 Use div64_u64() for the 64-bit average and div_u64() for
 the final /1024 descaling so division stays in kernel helpers
 and avoids compiler-emitted divdi3 linkage/build errors
 clocks/activity: keep proper /1024 scaling
 power: convert to milliwatts
 temperature: convert to millidegree Celsius for hwmon/sysfs users
 voltage: convert fixed-point volts to millivolts
-Report GPU temperature via AMDGPU_PP_SENSOR_GPU_TEMP and map it to the
 correct metrics field (VRGFX temperature).
-This aligns computed metrics with hwmon/sysfs units and removes CI/lint
 issues from improper IO copy and integer handling.
-Bounds-check metrics member before array access.
 smu_v15_0_0_get_smu_metrics_data() indexes the fixed-size
 avg_metric[] array with a caller-supplied MetricsMember_t
 reject out-of-range members with -EINVAL to prevent a
 latent out-of-bounds access.

drm/amd/pm/smu15: switch SMU v15.0.0 to DRAM-based accumulator metrics

Replace the legacy SMU table-copy metrics path with a DRAM-mapped,
accumulator-based approach for SMU v15.0.0, using a ping-pong buffer
to compute averaged metrics from deltas between consecutive samples.

- Add GetMetricsTableVersion, GetMetricsTableLogSample and
  GetMetricsTableLogDramAddr messages and their MSG_MAP entries.
- Introduce SMU_15_0_0_MetricsInfo_t holding two MetricsTable_t
  buffers, the mapped DRAM address, table size and pre-computed
  avg_metric[] values.
- Resolve and ioremap_wc() the firmware log DRAM address once in
  init_smc_tables(); iounmap() it in fini_smc_tables().
- Fetch samples into the inactive buffer, compute averaged clocks,
  activity, power and temperature via wrapping_sub() accumulator
  deltas, then swap the active index.
- Rename the old get_metrics_table() to get_gpu_metrics_table() for
  the gpu_metrics v3.0 export path.
- Smartshift sensor reporting is dropped

Co-developed-by: Pratik Vishwakarma <[email protected]>
Signed-off-by: Pratik Vishwakarma <[email protected]>
Co-developed-by: Suresh Guttula <[email protected]>
Signed-off-by: Suresh Guttula <[email protected]>
Co-developed-by: Kanala Ramalingeswara Reddy <[email protected]>
Signed-off-by: Kanala Ramalingeswara Reddy <[email protected]>
Signed-off-by: Shubhankar Milind Sardeshpande <[email protected]>
---
 .../pm/swsmu/inc/pmfw_if/smu_v15_0_0_ppsmc.h  |   5 +-
 drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h  |   3 +
 .../drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c  | 312 +++++++++++-------
 .../drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h  |  13 +
 4 files changed, 218 insertions(+), 115 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v15_0_0_ppsmc.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v15_0_0_ppsmc.h
index bf216f83e689..9f627b5fef5b 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v15_0_0_ppsmc.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v15_0_0_ppsmc.h
@@ -100,7 +100,10 @@
 #define PPSMC_MSG_DisableLSdma                  0x1F ///< Disable LSDMA
 #define PPSMC_MSG_SetSoftMaxVpe                 0x20 ///<
 #define PPSMC_MSG_SetSoftMinVpe                 0x21 ///<
-#define PPSMC_Message_Count                     0x22 ///< Total number of PPSMC messages
+#define PPSMC_MSG_GetMetricsTableVersion        0x22
+#define PPSMC_MSG_GetMetricsTableLogSample      0x23
+#define PPSMC_MSG_GetMetricsTableLogDramAddr    0x24
+#define PPSMC_Message_Count                     0x25 ///< Total number of PPSMC messages
 /** @}*/
 
 /**
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
index acf03838d49d..d6675b4ee9be 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
@@ -297,6 +297,9 @@
 	__SMU_DUMMY_MAP(GetSmartShiftStatus), \
 	__SMU_DUMMY_MAP(EnableLSdma), \
 	__SMU_DUMMY_MAP(DisableLSdma), \
+	__SMU_DUMMY_MAP(GetMetricsTableVersion), \
+	__SMU_DUMMY_MAP(GetMetricsTableLogSample), \
+	__SMU_DUMMY_MAP(GetMetricsTableLogDramAddr), \
 	__SMU_DUMMY_MAP(InitializeGfx), \
 	__SMU_DUMMY_MAP(SetSoftMaxFclk), \
 	__SMU_DUMMY_MAP(SetSoftMaxGl2clk), \
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
index 0da1ffb3a567..12fe2bc0488e 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
@@ -33,6 +33,9 @@
 #include "smu_v15_0_0_pmfw.h"
 #include "smu_cmn.h"
 
+#include <linux/overflow.h>
+#include <linux/math64.h>
+
 /*
  * DO NOT use these for err/warn/info/debug messages.
  * Use dev_err, dev_warn, dev_info and dev_dbg instead.
@@ -119,6 +122,9 @@ static struct cmn2asic_msg_mapping smu_v15_0_0_message_map[SMU_MSG_MAX_COUNT] =
 	MSG_MAP(DisableLSdma,                   PPSMC_MSG_DisableLSdma,				1),
 	MSG_MAP(SetSoftMaxVpe,                  PPSMC_MSG_SetSoftMaxVpe,			1),
 	MSG_MAP(SetSoftMinVpe,                  PPSMC_MSG_SetSoftMinVpe,			1),
+	MSG_MAP(GetMetricsTableVersion,         PPSMC_MSG_GetMetricsTableVersion,		1),
+	MSG_MAP(GetMetricsTableLogSample,       PPSMC_MSG_GetMetricsTableLogSample,		1),
+	MSG_MAP(GetMetricsTableLogDramAddr,     PPSMC_MSG_GetMetricsTableLogDramAddr,	1),
 };
 
 static struct cmn2asic_mapping smu_v15_0_0_feature_mask_map[SMU_FEATURE_COUNT] = {
@@ -160,10 +166,37 @@ static struct cmn2asic_mapping smu_v15_0_0_table_map[SMU_TABLE_COUNT] = {
 	TAB_MAP_VALID(DPMCLOCKS),
 };
 
+static int smu_v15_0_0_get_metrics_table_dram_addr(struct smu_context *smu,
+					SMU_15_0_0_MetricsInfo_t *metrics_info)
+{
+	struct smu_msg_ctl *ctl = &smu->msg_ctl;
+	struct smu_msg_args args = {
+		.msg = SMU_MSG_GetMetricsTableLogDramAddr,
+		.num_args = 0,
+		.num_out_args = 3,
+	};
+	int ret;
+
+	ret = ctl->ops->send_msg(ctl, &args);
+	if (ret)
+		return ret;
+
+	metrics_info->addr = ((uint64_t)args.out_args[1] << 32) | args.out_args[0];
+	metrics_info->table_size = args.out_args[2];
+
+	metrics_info->cpu_addr = ioremap_wc(metrics_info->addr,
+					    metrics_info->table_size);
+	if (!metrics_info->cpu_addr)
+		return -ENOMEM;
+
+	return 0;
+}
+
 static int smu_v15_0_0_init_smc_tables(struct smu_context *smu)
 {
 	struct smu_table_context *smu_table = &smu->smu_table;
 	struct smu_table *tables = smu_table->tables;
+	SMU_15_0_0_MetricsInfo_t *metrics_info;
 	int ret;
 
 	SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
@@ -173,7 +206,7 @@ static int smu_v15_0_0_init_smc_tables(struct smu_context *smu)
 	SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
 		PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 
-	smu_table->metrics_table = kzalloc_obj(SmuMetrics_t);
+	smu_table->metrics_table = kzalloc_obj(SMU_15_0_0_MetricsInfo_t);
 	if (!smu_table->metrics_table)
 		goto err0_out;
 	smu_table->metrics_time = 0;
@@ -192,8 +225,16 @@ static int smu_v15_0_0_init_smc_tables(struct smu_context *smu)
 	if (ret)
 		goto err3_out;
 
+	metrics_info = (SMU_15_0_0_MetricsInfo_t *)smu_table->metrics_table;
+
+	ret = smu_v15_0_0_get_metrics_table_dram_addr(smu, metrics_info);
+	if (ret)
+		goto err4_out;
+
 	return 0;
 
+err4_out:
+	smu_driver_table_fini(smu, SMU_DRIVER_TABLE_GPU_METRICS);
 err3_out:
 	kfree(smu_table->watermarks_table);
 err2_out:
@@ -207,6 +248,14 @@ static int smu_v15_0_0_init_smc_tables(struct smu_context *smu)
 static int smu_v15_0_0_fini_smc_tables(struct smu_context *smu)
 {
 	struct smu_table_context *smu_table = &smu->smu_table;
+	SMU_15_0_0_MetricsInfo_t *metrics_info = smu_table->metrics_table;
+
+	if (metrics_info) {
+		if (metrics_info->cpu_addr) {
+			iounmap(metrics_info->cpu_addr);
+			metrics_info->cpu_addr = NULL;
+		}
+	}
 
 	kfree(smu_table->clocks_table);
 	smu_table->clocks_table = NULL;
@@ -299,7 +348,7 @@ static int smu_v15_0_0_set_default_dpm_tables(struct smu_context *smu)
 				    smu_table->clocks_table, false);
 }
 
-static int smu_v15_0_0_get_metrics_table(struct smu_context *smu,
+static int smu_v15_0_0_get_gpu_metrics_table(struct smu_context *smu,
 							void *metrics_table,
 							bool bypass_cache)
 {
@@ -329,114 +378,161 @@ static int smu_v15_0_0_get_metrics_table(struct smu_context *smu,
 	return 0;
 }
 
+/*
+ * Fetch a fresh metrics sample into the inactive buffer.
+ * Returns 0 if a new sample was copied, 1 if the cached sample is still
+ * fresh (nothing copied), or a negative errno on failure.
+ */
+static int smu_v15_0_0_get_metrics_table(struct smu_context *smu,
+					SMU_15_0_0_MetricsInfo_t *metrics_info)
+{
+	struct smu_table_context *smu_table = &smu->smu_table;
+	void __iomem *cpu_addr = metrics_info->cpu_addr;
+	struct smu_msg_ctl *ctl = &smu->msg_ctl;
+	struct smu_msg_args args = {0};
+	size_t table_size = metrics_info->table_size;
+	int ret;
+
+	if (smu_table->metrics_time &&
+	    !time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(1)))
+		return 1;
+
+	if (!cpu_addr)
+		return -ENOMEM;
+
+	args.msg = SMU_MSG_GetMetricsTableLogSample;
+	args.num_args = 0;
+	args.num_out_args = 0;
+
+	ret = ctl->ops->send_msg(ctl, &args);
+	if (ret)
+		return ret;
+
+	/* best to flush before copy */
+	amdgpu_hdp_invalidate(smu->adev, NULL);
+	if (table_size <= sizeof(MetricsTable_t))
+		memcpy_fromio(&metrics_info->metrics[!metrics_info->active_idx],
+			      cpu_addr, table_size);
+	else
+		memcpy_fromio(&metrics_info->metrics[!metrics_info->active_idx],
+			      cpu_addr, sizeof(MetricsTable_t));
+
+	metrics_info->active_idx = !metrics_info->active_idx;
+	smu_table->metrics_time = jiffies;
+
+	return 0;
+}
+
+/*
+ * Accumulators monotonically increase and roll over at their type width.
+ * Use the kernel wrapping_sub() API to compute the delta so the subtraction
+ * wraps modulo 2^n (correct across a single rollover) without tripping any
+ * wrap-around sanitizers.
+ */
+static void smu_v15_0_0_compute_all_metrics(
+		uint32_t *avg_metric,
+		MetricsTable_t *prev,
+		MetricsTable_t *curr)
+{
+	uint64_t counter, val;
+	uint32_t mw;
+	MetricsTable_IOD_t *p = &prev->IOD;
+	MetricsTable_IOD_t *c = &curr->IOD;
+
+	counter = wrapping_sub(u32, c->AccumulationCounter, p->AccumulationCounter);
+	if (!counter)
+		return;
+
+	/* Accumulator-based clock frequencies (fixed-point /1024) */
+	val = wrapping_sub(u64, c->GfxclkFreqEffAcc, p->GfxclkFreqEffAcc);
+	avg_metric[METRICS_AVERAGE_GFXCLK] = div_u64(div64_u64(val, counter), 1024);
+
+	val = wrapping_sub(u64, c->SocclkFreqEffAcc, p->SocclkFreqEffAcc);
+	avg_metric[METRICS_AVERAGE_SOCCLK] = div_u64(div64_u64(val, counter), 1024);
+
+	val = wrapping_sub(u64, c->VclkFreqEffAcc, p->VclkFreqEffAcc);
+	avg_metric[METRICS_AVERAGE_VCLK] = div_u64(div64_u64(val, counter), 1024);
+
+	val = wrapping_sub(u64, c->MemclkFreqEffAcc, p->MemclkFreqEffAcc);
+	avg_metric[METRICS_AVERAGE_UCLK] = div_u64(div64_u64(val, counter), 1024);
+
+	val = wrapping_sub(u64, c->FclkFreqEffAcc, p->FclkFreqEffAcc);
+	avg_metric[METRICS_AVERAGE_FCLK] = div_u64(div64_u64(val, counter), 1024);
+
+	val = wrapping_sub(u64, c->NpuhclkFreqEffAcc, p->NpuhclkFreqEffAcc);
+	avg_metric[METRICS_AVERAGE_NPUCLK] = div_u64(div64_u64(val, counter), 1024);
+
+	/* Activity (fixed-point /1024) */
+	val = wrapping_sub(u64, c->GfxBusyAcc, p->GfxBusyAcc);
+	avg_metric[METRICS_AVERAGE_GFXACTIVITY] = div_u64(div64_u64(val, counter), 1024);
+
+	val = wrapping_sub(u64, c->VcnBusyAcc, p->VcnBusyAcc);
+	avg_metric[METRICS_AVERAGE_VCNACTIVITY] = div_u64(div64_u64(val, counter), 1024);
+
+	/*
+	 * Power: accumulator holds a 1024x fixed-point value in Watts.
+	 * Average it into milliwatts, which is the unit expected by
+	 * power sensor consumers (hwmon/debugfs).
+	 */
+	val = wrapping_sub(u64, c->ApuPowerAcc, p->ApuPowerAcc);
+	mw = div_u64(div64_u64(val, counter) * 1000, 1024);
+	avg_metric[METRICS_AVERAGE_SOCKETPOWER] = mw;
+
+	val = wrapping_sub(u64, c->SystemPowerAcc, p->SystemPowerAcc);
+	mw = div_u64(div64_u64(val, counter) * 1000, 1024);
+	avg_metric[METRICS_CURR_SOCKETPOWER] = mw;
+
+	/*
+	 * Temperature: accumulator holds a 1024x fixed-point value in
+	 * Celsius. Descale by 1024 and convert to millidegrees C as the
+	 * hwmon/sysfs consumers expect (temp*_input is in millidegrees).
+	 */
+	val = wrapping_sub(u64, c->GFX_TempAcc, p->GFX_TempAcc);
+	avg_metric[METRICS_TEMPERATURE_VRGFX] =
+		div_u64(div64_u64(val, counter) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES, 1024);
+
+	val = wrapping_sub(u64, c->STT_APU_HotSpotTempAcc, p->STT_APU_HotSpotTempAcc);
+	avg_metric[METRICS_TEMPERATURE_HOTSPOT] =
+		div_u64(div64_u64(val, counter) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES, 1024);
+
+	/* Voltage: accumulator holds a 1024x fixed-point value in Volts;
+	 * convert to millivolts for the hwmon/sysfs consumers.
+	 */
+	val = wrapping_sub(u64, c->VDDCR_GFX_TelemetryVoltage, p->VDDCR_GFX_TelemetryVoltage);
+	avg_metric[METRICS_VOLTAGE_VDDGFX] = div_u64(div64_u64(val, counter) * 1000, 1024);
+
+	val = wrapping_sub(u64, c->VDDCR_SOC_TelemetryVoltage, p->VDDCR_SOC_TelemetryVoltage);
+	avg_metric[METRICS_VOLTAGE_VDDSOC] = div_u64(div64_u64(val, counter) * 1000, 1024);
+}
+
 static int smu_v15_0_0_get_smu_metrics_data(struct smu_context *smu,
 					    MetricsMember_t member,
 					    uint32_t *value)
 {
 	struct smu_table_context *smu_table = &smu->smu_table;
+	SMU_15_0_0_MetricsInfo_t *metrics_info =
+		(SMU_15_0_0_MetricsInfo_t *)smu_table->metrics_table;
+	int ret;
 
-	SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
-	int ret = 0;
+	if (member >= ARRAY_SIZE(metrics_info->avg_metric))
+		return -EINVAL;
 
-	ret = smu_v15_0_0_get_metrics_table(smu, NULL, false);
-	if (ret)
+	ret = smu_v15_0_0_get_metrics_table(smu, metrics_info);
+	if (ret < 0)
 		return ret;
 
-	switch (member) {
-	case METRICS_AVERAGE_GFXCLK:
-		*value = metrics->GfxclkFrequency;
-		break;
-	case METRICS_AVERAGE_SOCCLK:
-		*value = metrics->SocclkFrequency;
-		break;
-	case METRICS_AVERAGE_VCLK:
-		*value = metrics->VclkFrequency;
-		break;
-	case METRICS_AVERAGE_DCLK:
-		*value = 0;
-		break;
-	case METRICS_AVERAGE_UCLK:
-		*value = metrics->MemclkFrequency;
-		break;
-	case METRICS_AVERAGE_FCLK:
-		*value = metrics->FclkFrequency;
-		break;
-	case METRICS_AVERAGE_VPECLK:
-		*value = metrics->VpeclkFrequency;
-		break;
-	case METRICS_AVERAGE_NPUCLK:
-		*value = metrics->NpuclkFrequency;
-		break;
-	case METRICS_AVERAGE_GFXACTIVITY:
-		if ((smu->smc_fw_version > 0x5d4600))
-			*value = metrics->GfxActivity;
-		else
-			*value = metrics->GfxActivity / 100;
-		break;
-	case METRICS_AVERAGE_VCNACTIVITY:
-		*value = metrics->VcnActivity / 100;
-		break;
-	case METRICS_AVERAGE_SOCKETPOWER:
-	case METRICS_CURR_SOCKETPOWER:
-		*value = metrics->SocketPower;
-		break;
-	case METRICS_TEMPERATURE_EDGE:
-		*value = metrics->GfxTemperature / 100 *
-		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
-		break;
-	case METRICS_TEMPERATURE_HOTSPOT:
-		*value = metrics->SocTemperature / 100 *
-		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
-		break;
-	case METRICS_THROTTLER_RESIDENCY_PROCHOT:
-		*value = metrics->ThrottleResidency_PROCHOT;
-		break;
-	case METRICS_THROTTLER_RESIDENCY_SPL:
-		*value = metrics->ThrottleResidency_SPL;
-		break;
-	case METRICS_THROTTLER_RESIDENCY_FPPT:
-		*value = metrics->ThrottleResidency_FPPT;
-		break;
-	case METRICS_THROTTLER_RESIDENCY_SPPT:
-		*value = metrics->ThrottleResidency_SPPT;
-		break;
-	case METRICS_THROTTLER_RESIDENCY_THM_SOC:
-		*value = metrics->ThrottleResidency_THM_SOC;
-		break;
-	case METRICS_VOLTAGE_VDDGFX:
-		*value = 0;
-		break;
-	case METRICS_VOLTAGE_VDDSOC:
-		*value = 0;
-		break;
-	case METRICS_SS_APU_SHARE:
-		/* return the percentage of APU power with respect to APU's power limit.
-		 * percentage is reported, this isn't boost value. Smartshift power
-		 * boost/shift is only when the percentage is more than 100.
-		 */
-		if (metrics->StapmOpnLimit > 0)
-			*value = (metrics->ApuPower * 100) / metrics->StapmOpnLimit;
-		else
-			*value = 0;
-		break;
-	case METRICS_SS_DGPU_SHARE:
-		/* return the percentage of dGPU power with respect to dGPU's power limit.
-		 * percentage is reported, this isn't boost value. Smartshift power
-		 * boost/shift is only when the percentage is more than 100.
-		 */
-		if ((metrics->dGpuPower > 0) &&
-		    (metrics->StapmCurrentLimit > metrics->StapmOpnLimit))
-			*value = (metrics->dGpuPower * 100) /
-				 (metrics->StapmCurrentLimit - metrics->StapmOpnLimit);
-		else
-			*value = 0;
-		break;
-	default:
-		*value = UINT_MAX;
-		break;
+	if (ret == 0 &&
+	    metrics_info->metrics[metrics_info->active_idx].IOD.AccumulationCounter !=
+	    metrics_info->metrics[!metrics_info->active_idx].IOD.AccumulationCounter) {
+		/* New sample: active_idx already points to the latest sample. */
+		smu_v15_0_0_compute_all_metrics(metrics_info->avg_metric,
+						&metrics_info->metrics[!metrics_info->active_idx],
+						&metrics_info->metrics[metrics_info->active_idx]);
 	}
 
-	return ret;
+	*value = metrics_info->avg_metric[member];
+
+	return 0;
 }
 
 static int smu_v15_0_0_read_sensor(struct smu_context *smu,
@@ -473,9 +569,9 @@ static int smu_v15_0_0_read_sensor(struct smu_context *smu,
 						       (uint32_t *)data);
 		*size = 4;
 		break;
-	case AMDGPU_PP_SENSOR_EDGE_TEMP:
+	case AMDGPU_PP_SENSOR_GPU_TEMP:
 		ret = smu_v15_0_0_get_smu_metrics_data(smu,
-						       METRICS_TEMPERATURE_EDGE,
+						       METRICS_TEMPERATURE_VRGFX,
 						       (uint32_t *)data);
 		*size = 4;
 		break;
@@ -511,18 +607,6 @@ static int smu_v15_0_0_read_sensor(struct smu_context *smu,
 						       (uint32_t *)data);
 		*size = 4;
 		break;
-	case AMDGPU_PP_SENSOR_SS_APU_SHARE:
-		ret = smu_v15_0_0_get_smu_metrics_data(smu,
-						       METRICS_SS_APU_SHARE,
-						       (uint32_t *)data);
-		*size = 4;
-		break;
-	case AMDGPU_PP_SENSOR_SS_DGPU_SHARE:
-		ret = smu_v15_0_0_get_smu_metrics_data(smu,
-						       METRICS_SS_DGPU_SHARE,
-						       (uint32_t *)data);
-		*size = 4;
-		break;
 	default:
 		ret = -EOPNOTSUPP;
 		break;
@@ -633,7 +717,7 @@ static ssize_t smu_v15_0_0_get_gpu_metrics(struct smu_context *smu,
 	SmuMetrics_t metrics;
 	int ret = 0;
 
-	ret = smu_v15_0_0_get_metrics_table(smu, &metrics, false);
+	ret = smu_v15_0_0_get_gpu_metrics_table(smu, &metrics, false);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h
index 8365b9fea77e..8471ba1a353e 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.h
@@ -23,6 +23,19 @@
 #ifndef __SMU_V15_0_0_PPT_H__
 #define __SMU_V15_0_0_PPT_H__
 
+#include "amdgpu_smu.h"
+
+#include "pmfw_if/smu_v15_0_0_metrics.h"
+
+typedef struct {
+	MetricsTable_t metrics[2];
+	bool active_idx;
+	uint32_t table_size;
+	uint64_t addr;
+	void __iomem *cpu_addr;
+	uint32_t avg_metric[METRICS_AVERAGE_NPUCLK+1];
+} SMU_15_0_0_MetricsInfo_t;
+
 extern void smu_v15_0_0_set_ppt_funcs(struct smu_context *smu);
 
 #endif
\ No newline at end of file
-- 
2.43.0