[PATCH 2/3] drm/amd/ras: add get_die_id for uniras umc v12

Tao Zhou <[email protected]> Mon, 3 Aug 2026 11:38:05 +0800
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
For legacy ras eeprom format, die id (node instance) is not stored,
we get it from mca address and physical address (pa) here, and now
we can calculate pa in any nps mode for legacy ras eeprom data as well.

Also refactor eeprom_rec2nps_addr to simplify code.

Signed-off-by: Tao Zhou <[email protected]>
---
 drivers/gpu/drm/amd/ras/rascore/ras_umc.c     | 38 ++++++++++++++++---
 drivers/gpu/drm/amd/ras/rascore/ras_umc.h     |  1 +
 .../gpu/drm/amd/ras/rascore/ras_umc_v12_0.c   | 25 ++++++++++++
 3 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
index b8e3a92ab174..becbf8d2d09e 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
+++ b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
@@ -323,8 +323,9 @@ int ras_umc_ma2pa(struct ras_core_context *ras_core,
 	return ret;
 }
 
-static int ras_umc_eeprom_rec2nps_addr(struct ras_core_context *ras_core,
-	struct eeprom_umc_record *record, uint64_t *pa, uint32_t nps)
+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)
 {
 	struct device_system_info dev_info = {0};
 	struct umc_mca_addr addr_in;
@@ -339,7 +340,7 @@ static int ras_umc_eeprom_rec2nps_addr(struct ras_core_context *ras_core,
 	addr_in.err_addr = record->address;
 	addr_in.ch_inst = record->mem_channel;
 	addr_in.umc_inst = record->mcumc_id;
-	addr_in.node_inst = UMC_INV_AID_NODE;
+	addr_in.node_inst = die_id;
 	addr_in.socket_id = dev_info.socket_id;
 
 	ret = ras_umc_ma2pa(ras_core, &addr_in, &addr_out, nps);
@@ -351,6 +352,33 @@ static int ras_umc_eeprom_rec2nps_addr(struct ras_core_context *ras_core,
 	return 0;
 }
 
+static int ras_umc_eeprom_rec2nps_addr(struct ras_core_context *ras_core,
+	struct eeprom_umc_record *record, uint64_t *pa, uint32_t nps)
+{
+	return __eeprom_rec2nps_addr(ras_core, record, pa, nps, UMC_INV_AID_NODE);
+}
+
+/* For legacy eeprom data format, the scope of channel index is
+ * limited to umc instance, and die id is not stored, have to
+ * get it from PA
+ */
+static int ras_umc_eeprom_rec2nps_addr_legacy(struct ras_core_context *ras_core,
+	struct eeprom_umc_record *record, uint64_t *pa, uint32_t nps)
+{
+	uint32_t die_id;
+
+	/* although die id is gotten from PA in nps1 mode, the id is
+	 * fitable for any nps mode
+	 */
+	if (ras_core->ras_umc.ip_func && ras_core->ras_umc.ip_func->get_die_id)
+		die_id = ras_core->ras_umc.ip_func->get_die_id(record->address,
+				RAS_PFN_TO_ADDR(record->retired_row_pfn));
+	else
+		return -EINVAL;
+
+	return __eeprom_rec2nps_addr(ras_core, record, pa, nps, die_id);
+}
+
 static int ras_umc_eeprom_rec2nps_rec(struct ras_core_context *ras_core,
 	struct eeprom_umc_record *record, uint32_t nps)
 {
@@ -375,8 +403,8 @@ static int ras_umc_eeprom_rec2nps_rec(struct ras_core_context *ras_core,
 		/* old eeprom data format, the scope of channel index is
 		 * limited to umc instance
 		 */
-		/* TODO */
-		ret = -EOPNOTSUPP;
+		if (ras_umc_eeprom_rec2nps_addr_legacy(ras_core, record, &pa, nps))
+			return -EOPNOTSUPP;
 	}
 
 	record->cur_nps = nps;
diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_umc.h b/drivers/gpu/drm/amd/ras/rascore/ras_umc.h
index 9d32ac344316..44f1b01d217b 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras_umc.h
+++ b/drivers/gpu/drm/amd/ras/rascore/ras_umc.h
@@ -133,6 +133,7 @@ struct ras_umc_ip_func {
 		uint32_t nps);
 	uint64_t (*nps_pa_to_row_pa)(struct ras_core_context *ras_core,
 		uint64_t pa, enum umc_memory_partition_mode nps, bool zero_pfn_ok);
+	uint32_t (*get_die_id)(uint64_t mca_addr, uint64_t pa);
 };
 
 struct eeprom_store_record {
diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_umc_v12_0.c b/drivers/gpu/drm/amd/ras/rascore/ras_umc_v12_0.c
index 73eb1dba16ec..1ab397e45d3c 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras_umc_v12_0.c
+++ b/drivers/gpu/drm/amd/ras/rascore/ras_umc_v12_0.c
@@ -489,6 +489,30 @@ static void umc_v12_0_mca_ipid_parse(struct ras_core_context *ras_core, uint64_t
 		*sid = ACA_IPID_2_SOCKET_ID(ipid);
 }
 
+static uint32_t umc_v12_0_get_die_id(uint64_t mca_addr, uint64_t pa)
+{
+	uint32_t die = 0;
+
+	/* we only calculate die id for nps1 mode right now */
+	die += ((((pa >> 12) & 0x1ULL)^
+			((pa >> 20) & 0x1ULL) ^
+			((pa >> 27) & 0x1ULL) ^
+			((pa >> 34) & 0x1ULL) ^
+			((pa >> 41) & 0x1ULL)) << 0);
+
+	/* the original PA_C4 and PA_R13 may be cleared in retired_page, so
+	 * get them from mca_addr.
+	 */
+	die += ((((pa >> 13) & 0x1ULL) ^
+			((mca_addr >> 5) & 0x1ULL) ^
+			((pa >> 28) & 0x1ULL) ^
+			((mca_addr >> 23) & 0x1ULL) ^
+			((pa >> 42) & 0x1ULL)) << 1);
+	die &= 3;
+
+	return die;
+}
+
 const struct ras_umc_ip_func ras_umc_func_v12_0 = {
 	.bank_to_eeprom_record = umc_v12_0_bank_to_eeprom_record,
 	.eeprom_record_to_nps_pages = umc_v12_0_eeprom_record_to_nps_pages,
@@ -497,5 +521,6 @@ const struct ras_umc_ip_func ras_umc_func_v12_0 = {
 	.mca_ipid_parse = umc_v12_0_mca_ipid_parse,
 	.ma2pa = umc_v12_ma2pa,
 	.nps_pa_to_row_pa = umc_v12_0_nps_pa_to_row_pa,
+	.get_die_id = umc_v12_0_get_die_id,
 };
 
-- 
2.34.1