[PATCH 3/3] drm/amd/ras: Handle the lack of mca address case for uniras

Tao Zhou <[email protected]> Mon, 3 Aug 2026 11:38:06 +0800
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
For specific old eeprom data, mca address is not stored, get mca
address from physical address(pa) and then convert it into pa in
current nps mode.

Signed-off-by: Tao Zhou <[email protected]>
---
 drivers/gpu/drm/amd/ras/rascore/ras_umc.c | 38 +++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
index becbf8d2d09e..c3cd1e84468b 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
+++ b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
@@ -323,6 +323,31 @@ int ras_umc_ma2pa(struct ras_core_context *ras_core,
 	return ret;
 }
 
+static int ras_umc_pa2ma(struct ras_core_context *ras_core, uint64_t pa,
+		uint64_t *mca, uint32_t nps)
+{
+	struct ras_ta_query_address_input addr_in;
+	struct ras_ta_query_address_output addr_out;
+	int ret;
+
+	if (!ras_psp_check_supported_cmd(ras_core, RAS_TA_CMD_ID__QUERY_ADDRESS))
+		return -EOPNOTSUPP;
+
+	/* nps: the pa belongs to */
+	addr_in.pa.pa = pa | ((uint64_t)nps << 58);
+	addr_in.addr_type = RAS_TA_PA_TO_MCA;
+	ret = ras_psp_query_address(ras_core, &addr_in, &addr_out);
+	if (ret) {
+		RAS_DEV_ERR(ras_core->dev,
+			"Failed to query RAS MCA address for 0x%llx", pa);
+
+		return ret;
+	}
+
+	*mca = addr_out.ma.err_addr;
+	return 0;
+}
+
 static int __eeprom_rec2nps_addr(struct ras_core_context *ras_core,
 	struct eeprom_umc_record *record, uint64_t *pa,
 	uint32_t nps, uint32_t die_id)
@@ -389,6 +414,7 @@ static int ras_umc_eeprom_rec2nps_rec(struct ras_core_context *ras_core,
 	save_nps = EEPROM_RECORD_UMC_NPS_MODE(record);
 	/* eeprom v2 has no stored nps, always convert if the flag is set */
 	ch_idx_v2 = record->retired_row_pfn & UMC_CHANNEL_IDX_V2;
+	record->cur_nps = nps;
 
 	if (save_nps || ch_idx_v2) {
 		if ((nps == save_nps) && !ras_fw_eeprom_supported(ras_core)) {
@@ -400,6 +426,16 @@ static int ras_umc_eeprom_rec2nps_rec(struct ras_core_context *ras_core,
 				record->cur_nps_retired_row_pfn = RAS_ADDR_TO_PFN(pa);
 		}
 	} else {
+		/* for specific old eeprom data, mca address is not stored,
+		 * calc it from pa
+		 */
+		if (record->address == 0) {
+			ret = ras_umc_pa2ma(ras_core, record->retired_row_pfn,
+					&(record->address), UMC_MEMORY_PARTITION_MODE_NPS1);
+			if (ret)
+				return ret;
+		}
+
 		/* old eeprom data format, the scope of channel index is
 		 * limited to umc instance
 		 */
@@ -407,8 +443,6 @@ static int ras_umc_eeprom_rec2nps_rec(struct ras_core_context *ras_core,
 			return -EOPNOTSUPP;
 	}
 
-	record->cur_nps = nps;
-
 	return ret;
 }
 
-- 
2.34.1