[PATCH 065/109] drm/amd/ras: support multi-parameter communication with mp1 in ras_mp1_v15_0

Alex Deucher <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
From: YiPeng Chai <[email protected]>

support multi-parameter communication with mp1 in ras_mp1_v15_0.

Signed-off-by: YiPeng Chai <[email protected]>
Reviewed-by: Hawking Zhang <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c     |   7 -
 drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |   2 -
 drivers/gpu/drm/amd/ras/core/ras.h            |   2 +
 drivers/gpu/drm/amd/ras/core/ras_mp1.c        |   2 +-
 drivers/gpu/drm/amd/ras/core/ras_mp1.h        |  24 +---
 drivers/gpu/drm/amd/ras/core/ras_mp1_v15_0.c  | 121 +++++++++++++-----
 .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mp1.c  |  10 +-
 7 files changed, 99 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index 649fdc4471487..4e8950a143e98 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -667,13 +667,6 @@ int amdgpu_smu_ras_send_msg(struct amdgpu_device *adev, enum smu_message_type ms
 	return ret;
 }
 
-int amdgpu_smu_ras_send_msg_legacy(struct amdgpu_device *adev,
-		enum smu_message_type msg, uint32_t param, uint32_t *read_arg)
-{
-	return amdgpu_smu_ras_send_msg(adev, msg, &param, 1,
-			read_arg, read_arg ? 1 : 0);
-}
-
 int amdgpu_smu_ras_feature_is_enabled(struct amdgpu_device *adev,
 						enum smu_feature_mask mask)
 {
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
index b77723f04268d..f1f61efb968ab 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -1993,8 +1993,6 @@ ssize_t smu_get_pm_policy_info(struct smu_context *smu,
 int amdgpu_smu_ras_send_msg(struct amdgpu_device *adev, enum smu_message_type msg,
 			const uint32_t *params, size_t num_params,
 			uint32_t *read_args, size_t num_read_args);
-int amdgpu_smu_ras_send_msg_legacy(struct amdgpu_device *adev,
-		enum smu_message_type msg, uint32_t param, uint32_t *read_arg);
 int amdgpu_smu_ras_feature_is_enabled(struct amdgpu_device *adev,
 						enum smu_feature_mask mask);
 #endif
diff --git a/drivers/gpu/drm/amd/ras/core/ras.h b/drivers/gpu/drm/amd/ras/core/ras.h
index 2311d988b3e52..38ab1aa9be0f9 100644
--- a/drivers/gpu/drm/amd/ras/core/ras.h
+++ b/drivers/gpu/drm/amd/ras/core/ras.h
@@ -213,6 +213,8 @@ struct ras_mp1_sys_func {
 	int (*mp1_get_ras_enabled_mask)(struct ras_core_context *ras_core,
 			uint64_t *enabled_mask);
 	int (*mp1_set_debug_mode)(struct ras_core_context *ras_core, bool enable);
+	int (*mp1_send_ras_msg)(struct ras_core_context *ras_core, u32 msg_id,
+		u32 *params, u32 num_params, u32 *read_args, u32 num_read_args);
 };
 
 struct ras_eeprom_param_config {
diff --git a/drivers/gpu/drm/amd/ras/core/ras_mp1.c b/drivers/gpu/drm/amd/ras/core/ras_mp1.c
index 7ba872732efd2..34578806ef3c0 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_mp1.c
+++ b/drivers/gpu/drm/amd/ras/core/ras_mp1.c
@@ -111,7 +111,7 @@ bool ras_mp1_rma_detected(struct ras_core_context *ras_core)
 }
 
 int ras_mp1_set_timestamp(struct ras_core_context *ras_core,
-		u32 timestamp)
+		u64 timestamp)
 {
 	struct ras_mp1 *mp1 = &ras_core->ras_mp1;
 	int ret;
diff --git a/drivers/gpu/drm/amd/ras/core/ras_mp1.h b/drivers/gpu/drm/amd/ras/core/ras_mp1.h
index 6eac9488843e1..d70070645cede 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_mp1.h
+++ b/drivers/gpu/drm/amd/ras/core/ras_mp1.h
@@ -40,23 +40,9 @@ enum ras_mp1_msg_id {
 };
 
 struct eeprom_err_record {
-	u32 timestamp;
-
-	union {
-		struct {
-			u32 mca_addr_low;
-			u32 mca_addr_high;
-		};
-		u64 mca_addr;
-	};
-
-	union {
-		struct {
-			u32 ipid_low;
-			u32 ipid_high;
-		};
-		u64 ipid;
-	};
+	u64 timestamp;
+	u64 mca_addr;
+	u64 ipid;
 };
 
 enum ras_err_type;
@@ -72,7 +58,7 @@ struct ras_mp1_ip_func {
 			u32 *table_version);
 	bool (*rma_detected)(struct ras_core_context *ras_core);
 	int (*set_timestamp)(struct ras_core_context *ras_core,
-			u32 timestamp);
+			u64 timestamp);
 	int (*reset_ras_table)(struct ras_core_context *ras_core,
 			u32 *result);
 	int (*get_record_count)(struct ras_core_context *ras_core,
@@ -102,7 +88,7 @@ int ras_mp1_get_table_version(struct ras_core_context *ras_core,
 		u32 *table_version);
 bool ras_mp1_rma_detected(struct ras_core_context *ras_core);
 int ras_mp1_set_timestamp(struct ras_core_context *ras_core,
-		u32 timestamp);
+		u64 timestamp);
 int ras_mp1_reset_ras_table(struct ras_core_context *ras_core,
 		u32 *result);
 int ras_mp1_get_record_count(struct ras_core_context *ras_core, u32 *count);
diff --git a/drivers/gpu/drm/amd/ras/core/ras_mp1_v15_0.c b/drivers/gpu/drm/amd/ras/core/ras_mp1_v15_0.c
index fc977396d9cb0..9b3c6651bb852 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_mp1_v15_0.c
+++ b/drivers/gpu/drm/amd/ras/core/ras_mp1_v15_0.c
@@ -26,9 +26,6 @@
 #include "core_status.h"
 #include "ras_mp1_v13_0.h"
 
-#define MSG_DATA_LOW32(idx)   (idx | (0x1 << 16))
-#define MSG_DATA_HIGH32(idx)  (idx | (0x2 << 16))
-
 #define regMP1_SMN_C2PMSG_40                              0x0068
 #define regMP1_SMN_C2PMSG_40_BASE_IDX                     2
 #define regMP1_SMN_C2PMSG_41                              0x0069
@@ -58,19 +55,33 @@ static u32 ras_mp1_msg_codes[RAS_MP1_MSG_MAX] = {
 };
 
 static int __direct_send_mp1_msg(struct ras_core_context *ras_core,
-		enum ras_mp1_msg_id msg_id, u32 input, u32 *output)
+		enum ras_mp1_msg_id msg_id, u32 *inputs, u32 num_inputs,
+		u32 *outputs, u32 num_outputs)
 {
 	u32 msg_code = 0;
 	int timeout = 100000;  //100 ms
 	u32 reg = 0;
 
+	if (num_inputs > 2 || num_outputs > 2)
+		return -EINVAL;
+
 	msg_code = ras_mp1_msg_codes[msg_id];
 	if (!msg_code)
 		return -EOPNOTSUPP;
 
 	/* Send message and parameter to fw */
 	RAS_DEV_WREG32_SOC15(ras_core->dev, MP1, 0, regMP1_SMN_C2PMSG_41, 0);
-	RAS_DEV_WREG32_SOC15(ras_core->dev, MP1, 0, regMP1_SMN_C2PMSG_42, input);
+	if (num_inputs == 1) {
+		/* Input u32 parameter */
+		RAS_DEV_WREG32_SOC15(ras_core->dev,
+			MP1, 0, regMP1_SMN_C2PMSG_42, inputs[0]);
+	} else if (num_inputs == 2) {
+		/* Input u64 parameter */
+		RAS_DEV_WREG32_SOC15(ras_core->dev,
+			MP1, 0, regMP1_SMN_C2PMSG_42, inputs[0]);
+		RAS_DEV_WREG32_SOC15(ras_core->dev,
+			MP1, 0, regMP1_SMN_C2PMSG_43, inputs[1]);
+	}
 	RAS_DEV_WREG32_SOC15(ras_core->dev, MP1, 0, regMP1_SMN_C2PMSG_40, msg_code);
 
 	/* Poll MP1 response */
@@ -83,35 +94,85 @@ static int __direct_send_mp1_msg(struct ras_core_context *ras_core,
 	};
 
 	if (reg != MP1_RESP_OK) {
-		RAS_DEV_ERR(ras_core->dev, "MP1 fail to ack 0x%x for msg: 0x%x, 0x%x, %p\n",
-			reg, msg_code, input, output);
+		RAS_DEV_ERR(ras_core->dev, "MP1 fail to ack 0x%x for msg: 0x%x\n",
+			reg, msg_code);
 		return -EIO;
 	}
 
 	/* Read output data */
-	if (output)
-		*output = RAS_DEV_RREG32_SOC15(ras_core->dev, MP1, 0, regMP1_SMN_C2PMSG_42);
+	if (outputs && num_outputs) {
+		if (num_outputs == 1) {
+			/* Output u32 parameter */
+			outputs[0] = RAS_DEV_RREG32_SOC15(ras_core->dev,
+						MP1, 0, regMP1_SMN_C2PMSG_42);
+		} else if (num_outputs == 2) {
+			/* Output u64 parameter */
+			outputs[0] = RAS_DEV_RREG32_SOC15(ras_core->dev,
+						MP1, 0, regMP1_SMN_C2PMSG_42);
+			outputs[1] = RAS_DEV_RREG32_SOC15(ras_core->dev,
+						MP1, 0, regMP1_SMN_C2PMSG_43);
+		}
+	}
 
 	return 0;
 }
 
+static int __sys_send_mp1_msg(struct ras_core_context *ras_core,
+		enum ras_mp1_msg_id msg_id, u32 *inputs, u32 num_inputs,
+		u32 *outputs, u32 num_outputs)
+{
+	if (!ras_core->ras_mp1.sys_func ||
+	    !ras_core->ras_mp1.sys_func->mp1_send_ras_msg)
+		return -EOPNOTSUPP;
+
+	return ras_core->ras_mp1.sys_func->mp1_send_ras_msg(ras_core,
+				msg_id, inputs, num_inputs, outputs, num_outputs);
+}
+
 static int __send_mp1_msg(struct ras_core_context *ras_core,
-		enum ras_mp1_msg_id msg_id, u32 input, u32 *output)
+		enum ras_mp1_msg_id msg_id, u32 *inputs, u32 num_inputs,
+		u32 *outputs, u32 num_outputs)
 {
 	if (msg_id >= RAS_MP1_MSG_MAX)
 		return -EINVAL;
 
 	if (ras_core_in_early_init(ras_core))
-		return __direct_send_mp1_msg(ras_core, msg_id, input, output);
+		return __direct_send_mp1_msg(ras_core, msg_id,
+				inputs, num_inputs, outputs, num_outputs);
 	else
-		return ras_core->ras_mp1.sys_func->mp1_send_eeprom_msg(ras_core,
-				msg_id, input, output);
+		return __sys_send_mp1_msg(ras_core, msg_id,
+				inputs, num_inputs, outputs, num_outputs);
+}
+
+static int __send_mp1_msg32(struct ras_core_context *ras_core,
+		enum ras_mp1_msg_id msg_id, u32 input, u32 *output)
+{
+	return __send_mp1_msg(ras_core, msg_id,
+			&input, 1, output, output ? 1 : 0);
+}
+
+static int __send_mp1_msg64(struct ras_core_context *ras_core,
+		enum ras_mp1_msg_id msg_id, u64 input, u64 *output)
+{
+	u32 in[2] = {lower_32_bits(input), upper_32_bits(input)};
+	u32 out[2] = {0};
+	int ret;
+
+	ret = __send_mp1_msg(ras_core, msg_id,
+			in, 2, output ? out : NULL, output ? 2 : 0);
+	if (!ret && output)
+		*output = ((u64)out[1] << 32) | out[0];
+
+	return ret;
 }
 
 static int ras_mp1_v15_get_table_version(struct ras_core_context *ras_core,
 				     u32 *table_ver)
 {
-	return __send_mp1_msg(ras_core, RAS_MP1_MSG_GetRasTableVersion,
+	if (!table_ver)
+		return -EINVAL;
+
+	return __send_mp1_msg32(ras_core, RAS_MP1_MSG_GetRasTableVersion,
 			0, table_ver);
 }
 
@@ -119,19 +180,19 @@ static bool ras_mp1_v15_rma_detected(struct ras_core_context *ras_core)
 {
 	u32 rma = 0;
 
-	if (__send_mp1_msg(ras_core, RAS_MP1_MSG_GetRmaStatus, 0, &rma))
+	if (__send_mp1_msg32(ras_core, RAS_MP1_MSG_GetRmaStatus, 0, &rma))
 		return false;
 
 	return rma;
 }
 
 static int ras_mp1_v15_set_timestamp(struct ras_core_context *ras_core,
-			u32 timestamp)
+			u64 timestamp)
 {
 	if (!timestamp)
 		return -EINVAL;
 
-	return __send_mp1_msg(ras_core, RAS_MP1_MSG_SetTimestamp, timestamp, NULL);
+	return __send_mp1_msg64(ras_core, RAS_MP1_MSG_SetTimestamp, timestamp, NULL);
 }
 
 static int ras_mp1_v15_reset_ras_table(struct ras_core_context *ras_core,
@@ -140,7 +201,7 @@ static int ras_mp1_v15_reset_ras_table(struct ras_core_context *ras_core,
 	if (!result)
 		return -EINVAL;
 
-	return __send_mp1_msg(ras_core, RAS_MP1_MSG_EraseRasTable, 0, result);
+	return __send_mp1_msg32(ras_core, RAS_MP1_MSG_EraseRasTable, 0, result);
 }
 
 static int ras_mp1_v15_get_record_count(struct ras_core_context *ras_core,
@@ -151,7 +212,7 @@ static int ras_mp1_v15_get_record_count(struct ras_core_context *ras_core,
 
 	*count = 0;
 
-	return __send_mp1_msg(ras_core, RAS_MP1_MSG_GetBadPageCount, 0, count);
+	return __send_mp1_msg32(ras_core, RAS_MP1_MSG_GetBadPageCount, 0, count);
 }
 
 static int ras_mp1_v15_get_record(struct ras_core_context *ras_core,
@@ -160,30 +221,20 @@ static int ras_mp1_v15_get_record(struct ras_core_context *ras_core,
 	int ret;
 
 	if (!rec)
-		return 0;
+		return -EINVAL;
 
-	ret = __send_mp1_msg(ras_core, RAS_MP1_MSG_GetTimestamp,
+	ret = __send_mp1_msg64(ras_core, RAS_MP1_MSG_GetTimestamp,
 			idx, &rec->timestamp);
 	if (ret)
 		return ret;
 
-	ret = __send_mp1_msg(ras_core, RAS_MP1_MSG_GetBadPageMcaAddr,
-			MSG_DATA_LOW32(idx), &rec->mca_addr_low);
-	if (ret)
-		return ret;
-
-	ret = __send_mp1_msg(ras_core, RAS_MP1_MSG_GetBadPageMcaAddr,
-			MSG_DATA_HIGH32(idx), &rec->mca_addr_high);
-	if (ret)
-		return ret;
-
-	ret = __send_mp1_msg(ras_core, RAS_MP1_MSG_GetBadPageIpId,
-			MSG_DATA_LOW32(idx), &rec->ipid_low);
+	ret = __send_mp1_msg64(ras_core, RAS_MP1_MSG_GetBadPageMcaAddr,
+			idx, &rec->mca_addr);
 	if (ret)
 		return ret;
 
-	ret = __send_mp1_msg(ras_core, RAS_MP1_MSG_GetBadPageIpId,
-			MSG_DATA_HIGH32(idx), &rec->ipid_high);
+	ret = __send_mp1_msg64(ras_core, RAS_MP1_MSG_GetBadPageIpId,
+			idx, &rec->ipid);
 
 	return ret;
 }
diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mp1.c b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mp1.c
index 698a373005092..baf5f156fc6fb 100644
--- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mp1.c
+++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mp1.c
@@ -44,8 +44,8 @@ static enum smu_message_type
 	return ras_smu_msg_maps[msg_id];
 }
 
-static int amdgpu_ras_send_mp1_msg(struct ras_core_context *ras_core,
-			u32 msg_id, uint32_t param, uint32_t *read_arg)
+static int amdgpu_ras_send_mp1_msg(struct ras_core_context *ras_core, u32 msg_id,
+		u32 *params, u32 num_params, u32 *read_args, u32 num_read_args)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)ras_core->dev;
 	enum smu_message_type smu_msg;
@@ -56,8 +56,8 @@ static int amdgpu_ras_send_mp1_msg(struct ras_core_context *ras_core,
 		return -EOPNOTSUPP;
 
 	if (down_read_trylock(&adev->reset_domain->sem)) {
-		ret = amdgpu_smu_ras_send_msg_legacy(adev, smu_msg,
-				param, read_arg);
+		ret = amdgpu_smu_ras_send_msg(adev, smu_msg,
+				params, num_params, read_args, num_read_args);
 		up_read(&adev->reset_domain->sem);
 	} else {
 		ret = -RAS_CORE_GPU_IN_MODE1_RESET;
@@ -67,5 +67,5 @@ static int amdgpu_ras_send_mp1_msg(struct ras_core_context *ras_core,
 }
 
 const struct ras_mp1_sys_func amdgpu_ras_mp1_sys_func = {
-	.mp1_send_eeprom_msg = amdgpu_ras_send_mp1_msg,
+	.mp1_send_ras_msg = amdgpu_ras_send_mp1_msg,
 };
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.