From: YiPeng Chai <[email protected]>

Support obtaining bad page info at boot time for 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/ras/core/ras_mp1_v15_0.c | 71 +++++++++++++++++++-
 1 file changed, 70 insertions(+), 1 deletion(-)

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 2cd0f266b5855..fc977396d9cb0 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
@@ -29,13 +29,82 @@
 #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
+#define regMP1_SMN_C2PMSG_41_BASE_IDX                     2
+#define regMP1_SMN_C2PMSG_42                              0x006a
+#define regMP1_SMN_C2PMSG_42_BASE_IDX                     2
+#define regMP1_SMN_C2PMSG_43                              0x006b
+#define regMP1_SMN_C2PMSG_43_BASE_IDX                     2
+#define regMP1_SMN_C2PMSG_44                              0x006c
+#define regMP1_SMN_C2PMSG_44_BASE_IDX                     2
+#define regMP1_SMN_C2PMSG_45                              0x006d
+#define regMP1_SMN_C2PMSG_45_BASE_IDX                     2
+
+#define MP1_RESP_OK  1
+
+static u32 ras_mp1_msg_codes[RAS_MP1_MSG_MAX] = {
+       [RAS_MP1_MSG_GetRasTableVersion] = 0x1F,
+       [RAS_MP1_MSG_GetRmaStatus] =    0x20,
+       [RAS_MP1_MSG_GetBadPageCount] = 0x21,
+       [RAS_MP1_MSG_GetBadPageMcaAddr] = 0x22,
+       [RAS_MP1_MSG_GetBadPagePaAddr] =  0x23,
+       [RAS_MP1_MSG_SetTimestamp] = 0x24,
+       [RAS_MP1_MSG_GetTimestamp] = 0x25,
+       [RAS_MP1_MSG_GetRasPolicy] = 0x26,
+       [RAS_MP1_MSG_GetBadPageIpId] = 0x27,
+       [RAS_MP1_MSG_EraseRasTable] =  0x28,
+};
+
+static int __direct_send_mp1_msg(struct ras_core_context *ras_core,
+               enum ras_mp1_msg_id msg_id, u32 input, u32 *output)
+{
+       u32 msg_code = 0;
+       int timeout = 100000;  //100 ms
+       u32 reg = 0;
+
+       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);
+       RAS_DEV_WREG32_SOC15(ras_core->dev, MP1, 0, regMP1_SMN_C2PMSG_40, 
msg_code);
+
+       /* Poll MP1 response */
+       while (timeout--) {
+               reg = RAS_DEV_RREG32_SOC15(ras_core->dev, MP1, 0, 
regMP1_SMN_C2PMSG_41);
+               if (reg)
+                       break;
+
+               udelay(1);
+       };
+
+       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);
+               return -EIO;
+       }
+
+       /* Read output data */
+       if (output)
+               *output = RAS_DEV_RREG32_SOC15(ras_core->dev, MP1, 0, 
regMP1_SMN_C2PMSG_42);
+
+       return 0;
+}
+
 static int __send_mp1_msg(struct ras_core_context *ras_core,
                enum ras_mp1_msg_id msg_id, u32 input, u32 *output)
 {
        if (msg_id >= RAS_MP1_MSG_MAX)
                return -EINVAL;
 
-       return ras_core->ras_mp1.sys_func->mp1_send_eeprom_msg(ras_core,
+       if (ras_core_in_early_init(ras_core))
+               return __direct_send_mp1_msg(ras_core, msg_id, input, output);
+       else
+               return ras_core->ras_mp1.sys_func->mp1_send_eeprom_msg(ras_core,
                                msg_id, input, output);
 }
 
-- 
2.55.0

Reply via email to