[PATCH 050/109] drm/amd/ras: Support obtaining bad page info at boot time for ras_mp1_v15_0
Alex Deucher <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
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