[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, ¶m, 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