From 5720a7534ddd0800e6fedb93ac8ff43ed8e29b7b Mon Sep 17 00:00:00 2001 From: Arvind M Date: Fri, 10 Feb 2023 11:22:56 +0000 Subject: [PATCH] nvdla: kmd: support HSI corrected error injection Jira DLA-6136 Jira DLA-6595 Change-Id: I4ca1b5f1e07566638951bc1d0c64613195779aa2 Signed-off-by: Arvind M Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2856422 Reviewed-by: svcacv Reviewed-by: svc_kernel_abi Reviewed-by: Amit Sharma (SW-TEGRA) Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: Ken Adams GVS: Gerrit_Virtual_Submit --- drivers/video/tegra/host/nvdla/nvdla.c | 49 ++++++++++--------- drivers/video/tegra/host/nvdla/nvdla.h | 20 ++++++-- drivers/video/tegra/host/nvdla/nvdla_debug.c | 24 +++++++-- .../video/tegra/host/nvdla/nvdla_hw_flcn.h | 5 ++ 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/drivers/video/tegra/host/nvdla/nvdla.c b/drivers/video/tegra/host/nvdla/nvdla.c index 2b9cb751..fa70a97f 100644 --- a/drivers/video/tegra/host/nvdla/nvdla.c +++ b/drivers/video/tegra/host/nvdla/nvdla.c @@ -58,17 +58,23 @@ int nvdla_error_inj_handler(unsigned int instance_id, struct platform_device *pdev = nvdla_dev->pdev; struct nvhost_device_data *pdata = platform_get_drvdata(pdev); unsigned int device_instance_id; - unsigned int device_reporter_id; - unsigned int device_error_code; + unsigned int device_ue_reporter_id; + unsigned int device_ce_reporter_id; + unsigned int device_ue_error_code; + unsigned int device_ce_error_code; if (pdata->class == NV_DLA0_CLASS_ID) { device_instance_id = 0U; - device_reporter_id = NVDLA0_HSM_REPORTER_ID; - device_error_code = NVDLA0_HSM_ERROR_CODE; + device_ue_reporter_id = NVDLA0_UE_HSM_REPORTER_ID; + device_ce_reporter_id = NVDLA0_CE_HSM_REPORTER_ID; + device_ue_error_code = NVDLA0_UE_HSM_ERROR_CODE; + device_ce_error_code = NVDLA0_CE_HSM_ERROR_CODE; } else { device_instance_id = 1U; - device_reporter_id = NVDLA1_HSM_REPORTER_ID; - device_error_code = NVDLA1_HSM_ERROR_CODE; + device_ue_reporter_id = NVDLA1_UE_HSM_REPORTER_ID; + device_ce_reporter_id = NVDLA1_CE_HSM_REPORTER_ID; + device_ue_error_code = NVDLA1_UE_HSM_ERROR_CODE; + device_ce_error_code = NVDLA1_CE_HSM_ERROR_CODE; } if (device_instance_id != instance_id) { @@ -77,20 +83,6 @@ int nvdla_error_inj_handler(unsigned int instance_id, goto fail; } - if (device_reporter_id != frame.reporter_id) { - nvdla_dbg_err(pdev, "Invalid reporter ID: %u", - frame.reporter_id); - err = -EINVAL; - goto fail; - } - - if (device_error_code != frame.error_code) { - nvdla_dbg_err(pdev, "Invalid error code: %u", - frame.error_code); - err = -EINVAL; - goto fail; - } - err = nvhost_module_busy(pdev); if (err < 0) { nvdla_dbg_err(pdev, "failed to power on\n"); @@ -98,8 +90,21 @@ int nvdla_error_inj_handler(unsigned int instance_id, goto fail; } - host1x_writel(pdev, flcn_safety_erb_r(), - flcn_safety_erb_data_uncorrected_err_v()); + if ((frame.reporter_id == device_ue_reporter_id) && + (frame.error_code == device_ue_error_code)) { + /* Inject uncorrected error. */ + host1x_writel(pdev, flcn_safety_erb_r(), + flcn_safety_erb_data_uncorrected_err_v()); + } else if ((frame.reporter_id == device_ce_reporter_id) && + (frame.error_code == device_ce_error_code)) { + /* Inject corrected error. */ + host1x_writel(pdev, flcn_safety_erb_r(), + flcn_safety_erb_data_corrected_err_v()); + } else { + nvdla_dbg_err(pdev, "Invalid Reported ID: %x, Error Code: %x", + frame.reporter_id, frame.error_code); + err = -EINVAL; + } nvhost_module_idle(pdev); diff --git a/drivers/video/tegra/host/nvdla/nvdla.h b/drivers/video/tegra/host/nvdla/nvdla.h index c55d4e46..c0bf8e39 100644 --- a/drivers/video/tegra/host/nvdla/nvdla.h +++ b/drivers/video/tegra/host/nvdla/nvdla.h @@ -33,11 +33,23 @@ #if (IS_ENABLED(CONFIG_TEGRA_HSIERRRPTINJ)) #include -#define NVDLA0_HSM_REPORTER_ID 0xE085U -#define NVDLA1_HSM_REPORTER_ID 0xE086U +/* + * HSM Reporter IDs. + */ +#define NVDLA0_CE_HSM_REPORTER_ID 0xE01EU +#define NVDLA1_CE_HSM_REPORTER_ID 0xE01FU -#define NVDLA0_HSM_ERROR_CODE 0x290BU -#define NVDLA1_HSM_ERROR_CODE 0x290CU +#define NVDLA0_UE_HSM_REPORTER_ID 0xE085U +#define NVDLA1_UE_HSM_REPORTER_ID 0xE086U + +/* + * HSM Error Codes. + */ +#define NVDLA0_CE_HSM_ERROR_CODE 0x2DF6U +#define NVDLA1_CE_HSM_ERROR_CODE 0x2DF7U + +#define NVDLA0_UE_HSM_ERROR_CODE 0x290BU +#define NVDLA1_UE_HSM_ERROR_CODE 0x290CU #endif /* CONFIG_TEGRA_HSIERRRPTINJ */ diff --git a/drivers/video/tegra/host/nvdla/nvdla_debug.c b/drivers/video/tegra/host/nvdla/nvdla_debug.c index 65d4ff76..761f8298 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_debug.c +++ b/drivers/video/tegra/host/nvdla/nvdla_debug.c @@ -1098,16 +1098,32 @@ static ssize_t debug_dla_err_inj_write(struct file *file, if (pdata->class == NV_DLA0_CLASS_ID) { instance_id = 0U; - frame.error_code = NVDLA0_HSM_ERROR_CODE; frame.error_attribute = 0U; frame.timestamp = 0U; - frame.reporter_id = NVDLA0_HSM_REPORTER_ID; + if (write_value == 1) { + frame.reporter_id = NVDLA0_UE_HSM_REPORTER_ID; + frame.error_code = NVDLA0_UE_HSM_ERROR_CODE; + } else if (write_value == 2) { + frame.reporter_id = NVDLA0_CE_HSM_REPORTER_ID; + frame.error_code = NVDLA0_CE_HSM_ERROR_CODE; + } else { + nvdla_dbg_err(pdev, "Write value out of range: [0,2]"); + goto fail; + } } else { instance_id = 1U; - frame.error_code = NVDLA1_HSM_ERROR_CODE; frame.error_attribute = 0U; frame.timestamp = 0U; - frame.reporter_id = NVDLA1_HSM_REPORTER_ID; + if (write_value == 1) { + frame.reporter_id = NVDLA1_UE_HSM_REPORTER_ID; + frame.error_code = NVDLA1_UE_HSM_ERROR_CODE; + } else if (write_value == 2) { + frame.reporter_id = NVDLA1_CE_HSM_REPORTER_ID; + frame.error_code = NVDLA1_CE_HSM_ERROR_CODE; + } else { + nvdla_dbg_err(pdev, "Write value out of range: [0,2]"); + goto fail; + } } err = nvdla_error_inj_handler(instance_id, frame, diff --git a/drivers/video/tegra/host/nvdla/nvdla_hw_flcn.h b/drivers/video/tegra/host/nvdla/nvdla_hw_flcn.h index 188b1271..43926b19 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_hw_flcn.h +++ b/drivers/video/tegra/host/nvdla/nvdla_hw_flcn.h @@ -303,6 +303,11 @@ static inline u32 flcn_safety_erb_r(void) return 0x000012ec; } +static inline u32 flcn_safety_erb_data_corrected_err_v(void) +{ + return 0xeafe0c00; +} + static inline u32 flcn_safety_erb_data_uncorrected_err_v(void) { return 0xeafe1cff;