[PATCH 1/3] drm/amd/ras: move some umc v12 specific functions to ras_umc.c

Tao Zhou <[email protected]> Mon, 3 Aug 2026 11:38:04 +0800
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
So we can reuse these functions across different ASICs.

Signed-off-by: Tao Zhou <[email protected]>
---
 drivers/gpu/drm/amd/ras/rascore/ras_umc.c     | 101 +++++++++++++--
 drivers/gpu/drm/amd/ras/rascore/ras_umc.h     |  13 +-
 .../gpu/drm/amd/ras/rascore/ras_umc_v12_0.c   | 118 +++---------------
 3 files changed, 119 insertions(+), 113 deletions(-)

diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
index f59f0b6cad06..b8e3a92ab174 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
+++ b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
@@ -82,7 +82,7 @@ static const struct ras_umc_ip_func *ras_umc_get_ip_func(
 	return NULL;
 }
 
-int ras_umc_psp_convert_ma_to_pa(struct ras_core_context *ras_core,
+int ras_umc_psp_ma2pa(struct ras_core_context *ras_core,
 		struct umc_mca_addr *in, struct umc_phy_addr *out,
 		uint32_t nps)
 {
@@ -307,6 +307,83 @@ int ras_umc_log_bad_bank(struct ras_core_context *ras_core, struct ras_bank_ecc
 	return ret;
 }
 
+int ras_umc_ma2pa(struct ras_core_context *ras_core,
+	struct umc_mca_addr *addr_in, struct umc_phy_addr *addr_out,
+	uint32_t nps)
+{
+	struct ras_umc *ras_umc = &ras_core->ras_umc;
+	int ret;
+
+	if (ras_psp_check_supported_cmd(ras_core, RAS_TA_CMD_ID__QUERY_ADDRESS))
+		ret = ras_umc_psp_ma2pa(ras_core, addr_in, addr_out, nps);
+	else
+		ret = ras_umc->ip_func->ma2pa(ras_core, addr_in,
+				addr_out, nps);
+
+	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)
+{
+	struct device_system_info dev_info = {0};
+	struct umc_mca_addr addr_in;
+	struct umc_phy_addr addr_out;
+	int ret;
+
+	memset(&addr_in, 0, sizeof(addr_in));
+	memset(&addr_out, 0, sizeof(addr_out));
+
+	ras_core_get_device_system_info(ras_core, &dev_info);
+
+	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.socket_id = dev_info.socket_id;
+
+	ret = ras_umc_ma2pa(ras_core, &addr_in, &addr_out, nps);
+	if (ret)
+		return ret;
+
+	*pa = ras_core->ras_umc.ip_func->nps_pa_to_row_pa(ras_core, addr_out.pa, nps, false);
+
+	return 0;
+}
+
+static int ras_umc_eeprom_rec2nps_rec(struct ras_core_context *ras_core,
+	struct eeprom_umc_record *record, uint32_t nps)
+{
+	uint64_t ch_idx_v2, pa = 0;
+	uint32_t save_nps;
+	int ret = 0;
+
+	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;
+
+	if (save_nps || ch_idx_v2) {
+		if ((nps == save_nps) && !ras_fw_eeprom_supported(ras_core)) {
+			record->cur_nps_retired_row_pfn =
+				EEPROM_RECORD_UMC_ADDR_PFN(record);
+		} else {
+			ret = ras_umc_eeprom_rec2nps_addr(ras_core, record, &pa, nps);
+			if (!ret)
+				record->cur_nps_retired_row_pfn = RAS_ADDR_TO_PFN(pa);
+		}
+	} else {
+		/* old eeprom data format, the scope of channel index is
+		 * limited to umc instance
+		 */
+		/* TODO */
+		ret = -EOPNOTSUPP;
+	}
+
+	record->cur_nps = nps;
+
+	return ret;
+}
+
 static int ras_umc_get_new_records(struct ras_core_context *ras_core,
 			struct eeprom_umc_record *records, u32 num)
 {
@@ -343,12 +420,11 @@ static bool ras_umc_check_retired_record(struct ras_core_context *ras_core,
 
 	if (from_eeprom) {
 		nps = ras_umc->umc_err_data.umc_nps_mode;
-		if (ras_umc->ip_func && ras_umc->ip_func->eeprom_record_to_nps_record) {
-			ret = ras_umc->ip_func->eeprom_record_to_nps_record(ras_core, record, nps);
-			if (ret)
-				RAS_DEV_WARN_RATELIMITED(ras_core->dev,
-					"Failed to adjust eeprom record, ret:%d", ret);
-		}
+		ret = ras_umc_eeprom_rec2nps_rec(ras_core, record, nps);
+		if (ret)
+			RAS_DEV_WARN_RATELIMITED(ras_core->dev,
+				"Failed to adjust eeprom record, ret:%d", ret);
+
 		return false;
 	}
 
@@ -805,3 +881,14 @@ int ras_umc_translate_soc_pa_and_bank(struct ras_core_context *ras_core,
 
 	return ret;
 }
+
+bool ras_umc_bit_wise_xor(uint32_t val)
+{
+	bool result = 0;
+	int i;
+
+	for (i = 0; i < 32; i++)
+		result = result ^ ((val >> i) & 0x1);
+
+	return result;
+}
diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_umc.h b/drivers/gpu/drm/amd/ras/rascore/ras_umc.h
index 3d902b0d663a..9d32ac344316 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras_umc.h
+++ b/drivers/gpu/drm/amd/ras/rascore/ras_umc.h
@@ -119,8 +119,6 @@ struct umc_bank_addr {
 struct ras_umc_ip_func {
 	int (*bank_to_eeprom_record)(struct ras_core_context *ras_core,
 			struct ras_bank_ecc *bank, struct eeprom_umc_record *record);
-	int (*eeprom_record_to_nps_record)(struct ras_core_context *ras_core,
-			struct eeprom_umc_record *record, uint32_t nps);
 	int (*eeprom_record_to_nps_pages)(struct ras_core_context *ras_core,
 			struct eeprom_umc_record *record, uint32_t nps,
 			uint64_t *pfns, uint32_t num);
@@ -130,6 +128,11 @@ struct ras_umc_ip_func {
 			uint64_t soc_pa, struct umc_bank_addr *bank_addr);
 	void (*mca_ipid_parse)(struct ras_core_context *ras_core, uint64_t ipid,
 			uint32_t *did, uint32_t *ch, uint32_t *umc_inst, uint32_t *sid);
+	int (*ma2pa)(struct ras_core_context *ras_core,
+		struct umc_mca_addr *addr_in, struct umc_phy_addr *addr_out,
+		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);
 };
 
 struct eeprom_store_record {
@@ -184,7 +187,7 @@ int ras_umc_sw_init(struct ras_core_context *ras);
 int ras_umc_sw_fini(struct ras_core_context *ras);
 int ras_umc_hw_init(struct ras_core_context *ras);
 int ras_umc_hw_fini(struct ras_core_context *ras);
-int ras_umc_psp_convert_ma_to_pa(struct ras_core_context *ras_core,
+int ras_umc_psp_ma2pa(struct ras_core_context *ras_core,
 		struct umc_mca_addr *in, struct umc_phy_addr *out,
 		uint32_t nps);
 int ras_umc_handle_bad_pages(struct ras_core_context *ras_core, void *data);
@@ -207,4 +210,8 @@ int ras_umc_translate_soc_pa_and_bank(struct ras_core_context *ras_core,
 int ras_umc_convert_record_to_nps_pages(struct ras_core_context *ras_core,
 		struct eeprom_umc_record *record, uint32_t nps,
 		uint64_t *page_pfn, uint32_t max_pages);
+bool ras_umc_bit_wise_xor(uint32_t val);
+int ras_umc_ma2pa(struct ras_core_context *ras_core,
+	struct umc_mca_addr *addr_in, struct umc_phy_addr *addr_out,
+	uint32_t nps);
 #endif
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 6bf30dee8d17..73eb1dba16ec 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
@@ -48,17 +48,6 @@ static const uint32_t umc_v12_0_ma2na_mapping[] = {
 	24, 7,  29, 30,
 };
 
-static bool umc_v12_0_bit_wise_xor(uint32_t val)
-{
-	bool result = 0;
-	int i;
-
-	for (i = 0; i < 32; i++)
-		result = result ^ ((val >> i) & 0x1);
-
-	return result;
-}
-
 static void __get_nps_pa_flip_bits(struct ras_core_context *ras_core,
 			enum umc_memory_partition_mode nps,
 			struct umc_flip_bits *flip_bits)
@@ -159,7 +148,7 @@ static void __get_nps_pa_flip_bits(struct ras_core_context *ras_core,
 	}
 }
 
-static uint64_t  convert_nps_pa_to_row_pa(struct ras_core_context *ras_core,
+static uint64_t  umc_v12_0_nps_pa_to_row_pa(struct ras_core_context *ras_core,
 		uint64_t pa, enum umc_memory_partition_mode nps, bool zero_pfn_ok)
 {
 	struct umc_flip_bits flip_bits = {0};
@@ -193,7 +182,7 @@ static int lookup_bad_pages_in_a_row(struct ras_core_context *ras_core,
 
 	__get_nps_pa_flip_bits(ras_core, nps, &flip_bits);
 
-	row_pa = convert_nps_pa_to_row_pa(ras_core, retired_addr, nps, true);
+	row_pa = umc_v12_0_nps_pa_to_row_pa(ras_core, retired_addr, nps, true);
 
 	err_addr = record->address;
 	/* get column bit 0 and 1 in mca address */
@@ -240,7 +229,7 @@ static int lookup_bad_pages_in_a_row(struct ras_core_context *ras_core,
 	return idx;
 }
 
-static int umc_v12_convert_ma_to_pa(struct ras_core_context *ras_core,
+static int umc_v12_ma2pa(struct ras_core_context *ras_core,
 			struct umc_mca_addr *addr_in, struct umc_phy_addr *addr_out,
 			uint32_t nps)
 {
@@ -277,20 +266,20 @@ static int umc_v12_convert_ma_to_pa(struct ras_core_context *ras_core,
 	/* apply bank hash algorithm */
 	bank0 =
 		bank_hash0 ^ (UMC_V12_0_XOR_EN0 &
-		(umc_v12_0_bit_wise_xor(col & UMC_V12_0_COL_XOR0) ^
-		(umc_v12_0_bit_wise_xor(row & UMC_V12_0_ROW_XOR0))));
+		(ras_umc_bit_wise_xor(col & UMC_V12_0_COL_XOR0) ^
+		(ras_umc_bit_wise_xor(row & UMC_V12_0_ROW_XOR0))));
 	bank1 =
 		bank_hash1 ^ (UMC_V12_0_XOR_EN1 &
-		(umc_v12_0_bit_wise_xor(col & UMC_V12_0_COL_XOR1) ^
-		(umc_v12_0_bit_wise_xor(row & UMC_V12_0_ROW_XOR1))));
+		(ras_umc_bit_wise_xor(col & UMC_V12_0_COL_XOR1) ^
+		(ras_umc_bit_wise_xor(row & UMC_V12_0_ROW_XOR1))));
 	bank2 =
 		bank_hash2 ^ (UMC_V12_0_XOR_EN2 &
-		(umc_v12_0_bit_wise_xor(col & UMC_V12_0_COL_XOR2) ^
-		(umc_v12_0_bit_wise_xor(row & UMC_V12_0_ROW_XOR2))));
+		(ras_umc_bit_wise_xor(col & UMC_V12_0_COL_XOR2) ^
+		(ras_umc_bit_wise_xor(row & UMC_V12_0_ROW_XOR2))));
 	bank3 =
 		bank_hash3 ^ (UMC_V12_0_XOR_EN3 &
-		(umc_v12_0_bit_wise_xor(col & UMC_V12_0_COL_XOR3) ^
-		(umc_v12_0_bit_wise_xor(row & UMC_V12_0_ROW_XOR3))));
+		(ras_umc_bit_wise_xor(col & UMC_V12_0_COL_XOR3) ^
+		(ras_umc_bit_wise_xor(row & UMC_V12_0_ROW_XOR3))));
 
 	bank = bank0 | (bank1 << 1) | (bank2 << 2) | (bank3 << 3);
 	err_addr &= ~0x3c0ULL;
@@ -360,22 +349,6 @@ static int umc_v12_convert_ma_to_pa(struct ras_core_context *ras_core,
 	return 0;
 }
 
-static int convert_ma_to_pa(struct ras_core_context *ras_core,
-			struct umc_mca_addr *addr_in, struct umc_phy_addr *addr_out,
-			uint32_t nps)
-{
-	int ret;
-
-	if (ras_psp_check_supported_cmd(ras_core, RAS_TA_CMD_ID__QUERY_ADDRESS))
-		ret = ras_umc_psp_convert_ma_to_pa(ras_core,
-				addr_in, addr_out, nps);
-	else
-		ret = umc_v12_convert_ma_to_pa(ras_core,
-				addr_in, addr_out, nps);
-
-	return ret;
-}
-
 static int convert_bank_to_nps_addr(struct ras_core_context *ras_core,
 			struct ras_bank_ecc *bank, struct umc_phy_addr *pa_addr, uint32_t nps)
 {
@@ -392,10 +365,10 @@ static int convert_bank_to_nps_addr(struct ras_core_context *ras_core,
 	addr_in.node_inst = ACA_IPID_2_DIE_ID(bank->ipid);
 	addr_in.socket_id = ACA_IPID_2_SOCKET_ID(bank->ipid);
 
-	ret = convert_ma_to_pa(ras_core, &addr_in, &addr_out, nps);
+	ret = ras_umc_ma2pa(ras_core, &addr_in, &addr_out, nps);
 	if (!ret) {
 		pa_addr->pa =
-			convert_nps_pa_to_row_pa(ras_core, addr_out.pa, nps, false);
+			umc_v12_0_nps_pa_to_row_pa(ras_core, addr_out.pa, nps, false);
 		pa_addr->channel_idx = addr_out.channel_idx;
 		pa_addr->bank = addr_out.bank;
 	}
@@ -429,68 +402,6 @@ static int umc_v12_0_bank_to_eeprom_record(struct ras_core_context *ras_core,
 	return 0;
 }
 
-static int convert_eeprom_record_to_nps_addr(struct ras_core_context *ras_core,
-			struct eeprom_umc_record *record, uint64_t *pa, uint32_t nps)
-{
-	struct device_system_info dev_info = {0};
-	struct umc_mca_addr addr_in;
-	struct umc_phy_addr addr_out;
-	int ret;
-
-	memset(&addr_in, 0, sizeof(addr_in));
-	memset(&addr_out, 0, sizeof(addr_out));
-
-	ras_core_get_device_system_info(ras_core, &dev_info);
-
-	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.socket_id = dev_info.socket_id;
-
-	ret = convert_ma_to_pa(ras_core, &addr_in, &addr_out, nps);
-	if (ret)
-		return ret;
-
-	*pa = convert_nps_pa_to_row_pa(ras_core, addr_out.pa, nps, false);
-
-	return 0;
-}
-
-static int umc_v12_0_eeprom_record_to_nps_record(struct ras_core_context *ras_core,
-				struct eeprom_umc_record *record, uint32_t nps)
-{
-	uint64_t ch_idx_v2, pa = 0;
-	uint32_t save_nps;
-	int ret = 0;
-
-	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;
-
-	if (save_nps || ch_idx_v2) {
-		if ((nps == save_nps) && !ras_fw_eeprom_supported(ras_core)) {
-			record->cur_nps_retired_row_pfn =
-				EEPROM_RECORD_UMC_ADDR_PFN(record);
-		} else {
-			ret = convert_eeprom_record_to_nps_addr(ras_core,
-				record, &pa, nps);
-			if (!ret)
-				record->cur_nps_retired_row_pfn = RAS_ADDR_TO_PFN(pa);
-		}
-	} else {
-		/* old eeprom data format, the scope of channel index is
-		 * limited to umc instance
-		 */
-		/* TODO */
-		ret = -EOPNOTSUPP;
-	}
-
-	record->cur_nps = nps;
-
-	return ret;
-}
-
 static int umc_v12_0_eeprom_record_to_nps_pages(struct ras_core_context *ras_core,
 			struct eeprom_umc_record *record, uint32_t nps,
 			uint64_t *pfns, uint32_t num)
@@ -580,10 +491,11 @@ static void umc_v12_0_mca_ipid_parse(struct ras_core_context *ras_core, uint64_t
 
 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_record = umc_v12_0_eeprom_record_to_nps_record,
 	.eeprom_record_to_nps_pages = umc_v12_0_eeprom_record_to_nps_pages,
 	.bank_to_soc_pa = umc_12_0_bank_to_soc_pa,
 	.soc_pa_to_bank = umc_12_0_soc_pa_to_bank,
 	.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,
 };
 
-- 
2.34.1