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

Reply via email to