| // SPDX-License-Identifier: GPL-2.0-only |
| /* Copyright(c) 2023 Intel Corporation */ |
| #include "adf_common_drv.h" |
| #include "adf_gen4_hw_data.h" |
| #include "adf_gen4_ras.h" |
| #include "adf_sysfs_ras_counters.h" |
| |
| #define BITS_PER_REG(_n_) (sizeof(_n_) * BITS_PER_BYTE) |
| |
| static void enable_errsou_reporting(void __iomem *csr) |
| { |
| /* Enable correctable error reporting in ERRSOU0 */ |
| ADF_CSR_WR(csr, ADF_GEN4_ERRMSK0, 0); |
| |
| /* Enable uncorrectable error reporting in ERRSOU1 */ |
| ADF_CSR_WR(csr, ADF_GEN4_ERRMSK1, 0); |
| |
| /* |
| * Enable uncorrectable error reporting in ERRSOU2 |
| * but disable PM interrupt and CFC attention interrupt by default |
| */ |
| ADF_CSR_WR(csr, ADF_GEN4_ERRMSK2, |
| ADF_GEN4_ERRSOU2_PM_INT_BIT | |
| ADF_GEN4_ERRSOU2_CPP_CFC_ATT_INT_BITMASK); |
| |
| /* |
| * Enable uncorrectable error reporting in ERRSOU3 |
| * but disable RLT error interrupt and VFLR notify interrupt by default |
| */ |
| ADF_CSR_WR(csr, ADF_GEN4_ERRMSK3, |
| ADF_GEN4_ERRSOU3_RLTERROR_BIT | |
| ADF_GEN4_ERRSOU3_VFLRNOTIFY_BIT); |
| } |
| |
| static void disable_errsou_reporting(void __iomem *csr) |
| { |
| u32 val = 0; |
| |
| /* Disable correctable error reporting in ERRSOU0 */ |
| ADF_CSR_WR(csr, ADF_GEN4_ERRMSK0, ADF_GEN4_ERRSOU0_BIT); |
| |
| /* Disable uncorrectable error reporting in ERRSOU1 */ |
| ADF_CSR_WR(csr, ADF_GEN4_ERRMSK1, ADF_GEN4_ERRSOU1_BITMASK); |
| |
| /* Disable uncorrectable error reporting in ERRSOU2 */ |
| val = ADF_CSR_RD(csr, ADF_GEN4_ERRMSK2); |
| val |= ADF_GEN4_ERRSOU2_DIS_BITMASK; |
| ADF_CSR_WR(csr, ADF_GEN4_ERRMSK2, val); |
| |
| /* Disable uncorrectable error reporting in ERRSOU3 */ |
| ADF_CSR_WR(csr, ADF_GEN4_ERRMSK3, ADF_GEN4_ERRSOU3_BITMASK); |
| } |
| |
| static void enable_ae_error_reporting(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| u32 ae_mask = GET_HW_DATA(accel_dev)->ae_mask; |
| |
| /* Enable Acceleration Engine correctable error reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_HIAECORERRLOGENABLE_CPP0, ae_mask); |
| |
| /* Enable Acceleration Engine uncorrectable error reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_HIAEUNCERRLOGENABLE_CPP0, ae_mask); |
| } |
| |
| static void disable_ae_error_reporting(void __iomem *csr) |
| { |
| /* Disable Acceleration Engine correctable error reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_HIAECORERRLOGENABLE_CPP0, 0); |
| |
| /* Disable Acceleration Engine uncorrectable error reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_HIAEUNCERRLOGENABLE_CPP0, 0); |
| } |
| |
| static void enable_cpp_error_reporting(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev); |
| |
| /* Enable HI CPP Agents Command Parity Error Reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_HICPPAGENTCMDPARERRLOGENABLE, |
| err_mask->cppagentcmdpar_mask); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_CPP_CFC_ERR_CTRL, |
| ADF_GEN4_CPP_CFC_ERR_CTRL_BITMASK); |
| } |
| |
| static void disable_cpp_error_reporting(void __iomem *csr) |
| { |
| /* Disable HI CPP Agents Command Parity Error Reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_HICPPAGENTCMDPARERRLOGENABLE, 0); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_CPP_CFC_ERR_CTRL, |
| ADF_GEN4_CPP_CFC_ERR_CTRL_DIS_BITMASK); |
| } |
| |
| static void enable_ti_ri_error_reporting(void __iomem *csr) |
| { |
| u32 reg; |
| |
| /* Enable RI Memory error reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_RI_MEM_PAR_ERR_EN0, |
| ADF_GEN4_RIMEM_PARERR_STS_FATAL_BITMASK | |
| ADF_GEN4_RIMEM_PARERR_STS_UNCERR_BITMASK); |
| |
| /* Enable IOSF Primary Command Parity error Reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_RIMISCCTL, ADF_GEN4_RIMISCSTS_BIT); |
| |
| /* Enable TI Internal Memory Parity Error reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_TI_CI_PAR_ERR_MASK, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_TI_PULL0FUB_PAR_ERR_MASK, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_TI_PUSHFUB_PAR_ERR_MASK, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_TI_CD_PAR_ERR_MASK, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_TI_TRNSB_PAR_ERR_MASK, 0); |
| |
| /* Enable error handling in RI, TI CPP interface control registers */ |
| ADF_CSR_WR(csr, ADF_GEN4_RICPPINTCTL, ADF_GEN4_RICPPINTCTL_BITMASK); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_TICPPINTCTL, ADF_GEN4_TICPPINTCTL_BITMASK); |
| |
| /* |
| * Enable error detection and reporting in TIMISCSTS |
| * with bits 1, 2 and 30 value preserved |
| */ |
| reg = ADF_CSR_RD(csr, ADF_GEN4_TIMISCCTL); |
| reg &= ADF_GEN4_TIMSCCTL_RELAY_BITMASK; |
| reg |= ADF_GEN4_TIMISCCTL_BIT; |
| ADF_CSR_WR(csr, ADF_GEN4_TIMISCCTL, reg); |
| } |
| |
| static void disable_ti_ri_error_reporting(void __iomem *csr) |
| { |
| u32 reg; |
| |
| /* Disable RI Memory error reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_RI_MEM_PAR_ERR_EN0, 0); |
| |
| /* Disable IOSF Primary Command Parity error Reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_RIMISCCTL, 0); |
| |
| /* Disable TI Internal Memory Parity Error reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_TI_CI_PAR_ERR_MASK, |
| ADF_GEN4_TI_CI_PAR_STS_BITMASK); |
| ADF_CSR_WR(csr, ADF_GEN4_TI_PULL0FUB_PAR_ERR_MASK, |
| ADF_GEN4_TI_PULL0FUB_PAR_STS_BITMASK); |
| ADF_CSR_WR(csr, ADF_GEN4_TI_PUSHFUB_PAR_ERR_MASK, |
| ADF_GEN4_TI_PUSHFUB_PAR_STS_BITMASK); |
| ADF_CSR_WR(csr, ADF_GEN4_TI_CD_PAR_ERR_MASK, |
| ADF_GEN4_TI_CD_PAR_STS_BITMASK); |
| ADF_CSR_WR(csr, ADF_GEN4_TI_TRNSB_PAR_ERR_MASK, |
| ADF_GEN4_TI_TRNSB_PAR_STS_BITMASK); |
| |
| /* Disable error handling in RI, TI CPP interface control registers */ |
| ADF_CSR_WR(csr, ADF_GEN4_RICPPINTCTL, 0); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_TICPPINTCTL, 0); |
| |
| /* |
| * Disable error detection and reporting in TIMISCSTS |
| * with bits 1, 2 and 30 value preserved |
| */ |
| reg = ADF_CSR_RD(csr, ADF_GEN4_TIMISCCTL); |
| reg &= ADF_GEN4_TIMSCCTL_RELAY_BITMASK; |
| ADF_CSR_WR(csr, ADF_GEN4_TIMISCCTL, reg); |
| } |
| |
| static void enable_rf_error_reporting(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev); |
| |
| /* Enable RF parity error in Shared RAM */ |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITYMASK_SRC, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITYMASK_ATH_CPH, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITYMASK_CPR_XLT, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITYMASK_DCPR_UCS, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITYMASK_PKE, 0); |
| |
| if (err_mask->parerr_wat_wcp_mask) |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITYMASK_WAT_WCP, 0); |
| } |
| |
| static void disable_rf_error_reporting(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev); |
| |
| /* Disable RF Parity Error reporting in Shared RAM */ |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITYMASK_SRC, |
| ADF_GEN4_SSMSOFTERRORPARITY_SRC_BIT); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITYMASK_ATH_CPH, |
| err_mask->parerr_ath_cph_mask); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITYMASK_CPR_XLT, |
| err_mask->parerr_cpr_xlt_mask); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITYMASK_DCPR_UCS, |
| err_mask->parerr_dcpr_ucs_mask); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITYMASK_PKE, |
| err_mask->parerr_pke_mask); |
| |
| if (err_mask->parerr_wat_wcp_mask) |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITYMASK_WAT_WCP, |
| err_mask->parerr_wat_wcp_mask); |
| } |
| |
| static void enable_ssm_error_reporting(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev); |
| u32 val = 0; |
| |
| /* Enable SSM interrupts */ |
| ADF_CSR_WR(csr, ADF_GEN4_INTMASKSSM, 0); |
| |
| /* Enable shared memory error detection & correction */ |
| val = ADF_CSR_RD(csr, ADF_GEN4_SSMFEATREN); |
| val |= err_mask->ssmfeatren_mask; |
| ADF_CSR_WR(csr, ADF_GEN4_SSMFEATREN, val); |
| |
| /* Enable SER detection in SER_err_ssmsh register */ |
| ADF_CSR_WR(csr, ADF_GEN4_SER_EN_SSMSH, |
| ADF_GEN4_SER_EN_SSMSH_BITMASK); |
| |
| /* Enable SSM soft parity error */ |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPARERRMSK_ATH_CPH, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPARERRMSK_CPR_XLT, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPARERRMSK_DCPR_UCS, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPARERRMSK_PKE, 0); |
| |
| if (err_mask->parerr_wat_wcp_mask) |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPARERRMSK_WAT_WCP, 0); |
| |
| /* Enable slice hang interrupt reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_SHINTMASKSSM_ATH_CPH, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_SHINTMASKSSM_CPR_XLT, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_SHINTMASKSSM_DCPR_UCS, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_SHINTMASKSSM_PKE, 0); |
| |
| if (err_mask->parerr_wat_wcp_mask) |
| ADF_CSR_WR(csr, ADF_GEN4_SHINTMASKSSM_WAT_WCP, 0); |
| } |
| |
| static void disable_ssm_error_reporting(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev); |
| u32 val = 0; |
| |
| /* Disable SSM interrupts */ |
| ADF_CSR_WR(csr, ADF_GEN4_INTMASKSSM, |
| ADF_GEN4_INTMASKSSM_BITMASK); |
| |
| /* Disable shared memory error detection & correction */ |
| val = ADF_CSR_RD(csr, ADF_GEN4_SSMFEATREN); |
| val &= ADF_GEN4_SSMFEATREN_DIS_BITMASK; |
| ADF_CSR_WR(csr, ADF_GEN4_SSMFEATREN, val); |
| |
| /* Disable SER detection in SER_err_ssmsh register */ |
| ADF_CSR_WR(csr, ADF_GEN4_SER_EN_SSMSH, 0); |
| |
| /* Disable SSM soft parity error */ |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPARERRMSK_ATH_CPH, |
| err_mask->parerr_ath_cph_mask); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPARERRMSK_CPR_XLT, |
| err_mask->parerr_cpr_xlt_mask); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPARERRMSK_DCPR_UCS, |
| err_mask->parerr_dcpr_ucs_mask); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPARERRMSK_PKE, |
| err_mask->parerr_pke_mask); |
| |
| if (err_mask->parerr_wat_wcp_mask) |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPARERRMSK_WAT_WCP, |
| err_mask->parerr_wat_wcp_mask); |
| |
| /* Disable slice hang interrupt reporting */ |
| ADF_CSR_WR(csr, ADF_GEN4_SHINTMASKSSM_ATH_CPH, |
| err_mask->parerr_ath_cph_mask); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SHINTMASKSSM_CPR_XLT, |
| err_mask->parerr_cpr_xlt_mask); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SHINTMASKSSM_DCPR_UCS, |
| err_mask->parerr_dcpr_ucs_mask); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SHINTMASKSSM_PKE, |
| err_mask->parerr_pke_mask); |
| |
| if (err_mask->parerr_wat_wcp_mask) |
| ADF_CSR_WR(csr, ADF_GEN4_SHINTMASKSSM_WAT_WCP, |
| err_mask->parerr_wat_wcp_mask); |
| } |
| |
| static void enable_aram_error_reporting(void __iomem *csr) |
| { |
| ADF_CSR_WR(csr, ADF_GEN4_REG_ARAMCERRUERR_EN, |
| ADF_GEN4_REG_ARAMCERRUERR_EN_BITMASK); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_REG_ARAMCERR, |
| ADF_GEN4_REG_ARAMCERR_EN_BITMASK); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_REG_ARAMUERR, |
| ADF_GEN4_REG_ARAMUERR_EN_BITMASK); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_REG_CPPMEMTGTERR, |
| ADF_GEN4_REG_CPPMEMTGTERR_EN_BITMASK); |
| } |
| |
| static void disable_aram_error_reporting(void __iomem *csr) |
| { |
| ADF_CSR_WR(csr, ADF_GEN4_REG_ARAMCERRUERR_EN, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_REG_ARAMCERR, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_REG_ARAMUERR, 0); |
| ADF_CSR_WR(csr, ADF_GEN4_REG_CPPMEMTGTERR, 0); |
| } |
| |
| static void adf_gen4_enable_ras(struct adf_accel_dev *accel_dev) |
| { |
| void __iomem *aram_csr = adf_get_aram_base(accel_dev); |
| void __iomem *csr = adf_get_pmisc_base(accel_dev); |
| |
| enable_errsou_reporting(csr); |
| enable_ae_error_reporting(accel_dev, csr); |
| enable_cpp_error_reporting(accel_dev, csr); |
| enable_ti_ri_error_reporting(csr); |
| enable_rf_error_reporting(accel_dev, csr); |
| enable_ssm_error_reporting(accel_dev, csr); |
| enable_aram_error_reporting(aram_csr); |
| } |
| |
| static void adf_gen4_disable_ras(struct adf_accel_dev *accel_dev) |
| { |
| void __iomem *aram_csr = adf_get_aram_base(accel_dev); |
| void __iomem *csr = adf_get_pmisc_base(accel_dev); |
| |
| disable_errsou_reporting(csr); |
| disable_ae_error_reporting(csr); |
| disable_cpp_error_reporting(csr); |
| disable_ti_ri_error_reporting(csr); |
| disable_rf_error_reporting(accel_dev, csr); |
| disable_ssm_error_reporting(accel_dev, csr); |
| disable_aram_error_reporting(aram_csr); |
| } |
| |
| static void adf_gen4_process_errsou0(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| u32 aecorrerr = ADF_CSR_RD(csr, ADF_GEN4_HIAECORERRLOG_CPP0); |
| |
| aecorrerr &= GET_HW_DATA(accel_dev)->ae_mask; |
| |
| dev_warn(&GET_DEV(accel_dev), |
| "Correctable error detected in AE: 0x%x\n", |
| aecorrerr); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_CORR); |
| |
| /* Clear interrupt from ERRSOU0 */ |
| ADF_CSR_WR(csr, ADF_GEN4_HIAECORERRLOG_CPP0, aecorrerr); |
| } |
| |
| static bool adf_handle_cpp_aeunc(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| u32 aeuncorerr; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU1_HIAEUNCERRLOG_CPP0_BIT)) |
| return false; |
| |
| aeuncorerr = ADF_CSR_RD(csr, ADF_GEN4_HIAEUNCERRLOG_CPP0); |
| aeuncorerr &= GET_HW_DATA(accel_dev)->ae_mask; |
| |
| dev_err(&GET_DEV(accel_dev), |
| "Uncorrectable error detected in AE: 0x%x\n", |
| aeuncorerr); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_HIAEUNCERRLOG_CPP0, aeuncorerr); |
| |
| return false; |
| } |
| |
| static bool adf_handle_cppcmdparerr(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev); |
| u32 cmdparerr; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU1_HICPPAGENTCMDPARERRLOG_BIT)) |
| return false; |
| |
| cmdparerr = ADF_CSR_RD(csr, ADF_GEN4_HICPPAGENTCMDPARERRLOG); |
| cmdparerr &= err_mask->cppagentcmdpar_mask; |
| |
| dev_err(&GET_DEV(accel_dev), |
| "HI CPP agent command parity error: 0x%x\n", |
| cmdparerr); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_HICPPAGENTCMDPARERRLOG, cmdparerr); |
| |
| return true; |
| } |
| |
| static bool adf_handle_ri_mem_par_err(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| bool reset_required = false; |
| u32 rimem_parerr_sts; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU1_RIMEM_PARERR_STS_BIT)) |
| return false; |
| |
| rimem_parerr_sts = ADF_CSR_RD(csr, ADF_GEN4_RIMEM_PARERR_STS); |
| rimem_parerr_sts &= ADF_GEN4_RIMEM_PARERR_STS_UNCERR_BITMASK | |
| ADF_GEN4_RIMEM_PARERR_STS_FATAL_BITMASK; |
| |
| if (rimem_parerr_sts & ADF_GEN4_RIMEM_PARERR_STS_UNCERR_BITMASK) { |
| dev_err(&GET_DEV(accel_dev), |
| "RI Memory Parity uncorrectable error: 0x%x\n", |
| rimem_parerr_sts); |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| } |
| |
| if (rimem_parerr_sts & ADF_GEN4_RIMEM_PARERR_STS_FATAL_BITMASK) { |
| dev_err(&GET_DEV(accel_dev), |
| "RI Memory Parity fatal error: 0x%x\n", |
| rimem_parerr_sts); |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| reset_required = true; |
| } |
| |
| ADF_CSR_WR(csr, ADF_GEN4_RIMEM_PARERR_STS, rimem_parerr_sts); |
| |
| return reset_required; |
| } |
| |
| static bool adf_handle_ti_ci_par_sts(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| u32 ti_ci_par_sts; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU1_TIMEM_PARERR_STS_BIT)) |
| return false; |
| |
| ti_ci_par_sts = ADF_CSR_RD(csr, ADF_GEN4_TI_CI_PAR_STS); |
| ti_ci_par_sts &= ADF_GEN4_TI_CI_PAR_STS_BITMASK; |
| |
| if (ti_ci_par_sts) { |
| dev_err(&GET_DEV(accel_dev), |
| "TI Memory Parity Error: 0x%x\n", ti_ci_par_sts); |
| ADF_CSR_WR(csr, ADF_GEN4_TI_CI_PAR_STS, ti_ci_par_sts); |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| } |
| |
| return false; |
| } |
| |
| static bool adf_handle_ti_pullfub_par_sts(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| u32 ti_pullfub_par_sts; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU1_TIMEM_PARERR_STS_BIT)) |
| return false; |
| |
| ti_pullfub_par_sts = ADF_CSR_RD(csr, ADF_GEN4_TI_PULL0FUB_PAR_STS); |
| ti_pullfub_par_sts &= ADF_GEN4_TI_PULL0FUB_PAR_STS_BITMASK; |
| |
| if (ti_pullfub_par_sts) { |
| dev_err(&GET_DEV(accel_dev), |
| "TI Pull Parity Error: 0x%x\n", ti_pullfub_par_sts); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_TI_PULL0FUB_PAR_STS, |
| ti_pullfub_par_sts); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| } |
| |
| return false; |
| } |
| |
| static bool adf_handle_ti_pushfub_par_sts(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| u32 ti_pushfub_par_sts; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU1_TIMEM_PARERR_STS_BIT)) |
| return false; |
| |
| ti_pushfub_par_sts = ADF_CSR_RD(csr, ADF_GEN4_TI_PUSHFUB_PAR_STS); |
| ti_pushfub_par_sts &= ADF_GEN4_TI_PUSHFUB_PAR_STS_BITMASK; |
| |
| if (ti_pushfub_par_sts) { |
| dev_err(&GET_DEV(accel_dev), |
| "TI Push Parity Error: 0x%x\n", ti_pushfub_par_sts); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_TI_PUSHFUB_PAR_STS, |
| ti_pushfub_par_sts); |
| } |
| |
| return false; |
| } |
| |
| static bool adf_handle_ti_cd_par_sts(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| u32 ti_cd_par_sts; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU1_TIMEM_PARERR_STS_BIT)) |
| return false; |
| |
| ti_cd_par_sts = ADF_CSR_RD(csr, ADF_GEN4_TI_CD_PAR_STS); |
| ti_cd_par_sts &= ADF_GEN4_TI_CD_PAR_STS_BITMASK; |
| |
| if (ti_cd_par_sts) { |
| dev_err(&GET_DEV(accel_dev), |
| "TI CD Parity Error: 0x%x\n", ti_cd_par_sts); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_TI_CD_PAR_STS, ti_cd_par_sts); |
| } |
| |
| return false; |
| } |
| |
| static bool adf_handle_ti_trnsb_par_sts(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| u32 ti_trnsb_par_sts; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU1_TIMEM_PARERR_STS_BIT)) |
| return false; |
| |
| ti_trnsb_par_sts = ADF_CSR_RD(csr, ADF_GEN4_TI_TRNSB_PAR_STS); |
| ti_trnsb_par_sts &= ADF_GEN4_TI_TRNSB_PAR_STS_BITMASK; |
| |
| if (ti_trnsb_par_sts) { |
| dev_err(&GET_DEV(accel_dev), |
| "TI TRNSB Parity Error: 0x%x\n", ti_trnsb_par_sts); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_TI_TRNSB_PAR_STS, ti_trnsb_par_sts); |
| } |
| |
| return false; |
| } |
| |
| static bool adf_handle_iosfp_cmd_parerr(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| u32 rimiscsts; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU1_TIMEM_PARERR_STS_BIT)) |
| return false; |
| |
| rimiscsts = ADF_CSR_RD(csr, ADF_GEN4_RIMISCSTS); |
| rimiscsts &= ADF_GEN4_RIMISCSTS_BIT; |
| |
| dev_err(&GET_DEV(accel_dev), |
| "Command Parity error detected on IOSFP: 0x%x\n", |
| rimiscsts); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_RIMISCSTS, rimiscsts); |
| |
| return true; |
| } |
| |
| static void adf_gen4_process_errsou1(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou, |
| bool *reset_required) |
| { |
| *reset_required |= adf_handle_cpp_aeunc(accel_dev, csr, errsou); |
| *reset_required |= adf_handle_cppcmdparerr(accel_dev, csr, errsou); |
| *reset_required |= adf_handle_ri_mem_par_err(accel_dev, csr, errsou); |
| *reset_required |= adf_handle_ti_ci_par_sts(accel_dev, csr, errsou); |
| *reset_required |= adf_handle_ti_pullfub_par_sts(accel_dev, csr, errsou); |
| *reset_required |= adf_handle_ti_pushfub_par_sts(accel_dev, csr, errsou); |
| *reset_required |= adf_handle_ti_cd_par_sts(accel_dev, csr, errsou); |
| *reset_required |= adf_handle_ti_trnsb_par_sts(accel_dev, csr, errsou); |
| *reset_required |= adf_handle_iosfp_cmd_parerr(accel_dev, csr, errsou); |
| } |
| |
| static bool adf_handle_uerrssmsh(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 iastatssm) |
| { |
| u32 reg; |
| |
| if (!(iastatssm & ADF_GEN4_IAINTSTATSSM_UERRSSMSH_BIT)) |
| return false; |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_UERRSSMSH); |
| reg &= ADF_GEN4_UERRSSMSH_BITMASK; |
| |
| dev_err(&GET_DEV(accel_dev), |
| "Uncorrectable error on ssm shared memory: 0x%x\n", |
| reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_UERRSSMSH, reg); |
| |
| return false; |
| } |
| |
| static bool adf_handle_cerrssmsh(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 iastatssm) |
| { |
| u32 reg; |
| |
| if (!(iastatssm & ADF_GEN4_IAINTSTATSSM_CERRSSMSH_BIT)) |
| return false; |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_CERRSSMSH); |
| reg &= ADF_GEN4_CERRSSMSH_ERROR_BIT; |
| |
| dev_warn(&GET_DEV(accel_dev), |
| "Correctable error on ssm shared memory: 0x%x\n", |
| reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_CORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_CERRSSMSH, reg); |
| |
| return false; |
| } |
| |
| static bool adf_handle_pperr_err(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 iastatssm) |
| { |
| u32 reg; |
| |
| if (!(iastatssm & ADF_GEN4_IAINTSTATSSM_PPERR_BIT)) |
| return false; |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_PPERR); |
| reg &= ADF_GEN4_PPERR_BITMASK; |
| |
| dev_err(&GET_DEV(accel_dev), |
| "Uncorrectable error CPP transaction on memory target: 0x%x\n", |
| reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_PPERR, reg); |
| |
| return false; |
| } |
| |
| static void adf_poll_slicehang_csr(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 slice_hang_offset, |
| char *slice_name) |
| { |
| u32 slice_hang_reg = ADF_CSR_RD(csr, slice_hang_offset); |
| |
| if (!slice_hang_reg) |
| return; |
| |
| dev_err(&GET_DEV(accel_dev), |
| "Slice %s hang error encountered\n", slice_name); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| } |
| |
| static bool adf_handle_slice_hang_error(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 iastatssm) |
| { |
| struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev); |
| |
| if (!(iastatssm & ADF_GEN4_IAINTSTATSSM_SLICEHANG_ERR_BIT)) |
| return false; |
| |
| adf_poll_slicehang_csr(accel_dev, csr, |
| ADF_GEN4_SLICEHANGSTATUS_ATH_CPH, "ath_cph"); |
| adf_poll_slicehang_csr(accel_dev, csr, |
| ADF_GEN4_SLICEHANGSTATUS_CPR_XLT, "cpr_xlt"); |
| adf_poll_slicehang_csr(accel_dev, csr, |
| ADF_GEN4_SLICEHANGSTATUS_DCPR_UCS, "dcpr_ucs"); |
| adf_poll_slicehang_csr(accel_dev, csr, |
| ADF_GEN4_SLICEHANGSTATUS_PKE, "pke"); |
| |
| if (err_mask->parerr_wat_wcp_mask) |
| adf_poll_slicehang_csr(accel_dev, csr, |
| ADF_GEN4_SLICEHANGSTATUS_WAT_WCP, |
| "ath_cph"); |
| |
| return false; |
| } |
| |
| static bool adf_handle_spp_pullcmd_err(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev); |
| bool reset_required = false; |
| u32 reg; |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPULLCMDPARERR_ATH_CPH); |
| reg &= err_mask->parerr_ath_cph_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP pull command fatal error ATH_CPH: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPULLCMDPARERR_ATH_CPH, reg); |
| |
| reset_required = true; |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPULLCMDPARERR_CPR_XLT); |
| reg &= err_mask->parerr_cpr_xlt_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP pull command fatal error CPR_XLT: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPULLCMDPARERR_CPR_XLT, reg); |
| |
| reset_required = true; |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPULLCMDPARERR_DCPR_UCS); |
| reg &= err_mask->parerr_dcpr_ucs_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP pull command fatal error DCPR_UCS: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPULLCMDPARERR_DCPR_UCS, reg); |
| |
| reset_required = true; |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPULLCMDPARERR_PKE); |
| reg &= err_mask->parerr_pke_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP pull command fatal error PKE: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPULLCMDPARERR_PKE, reg); |
| |
| reset_required = true; |
| } |
| |
| if (err_mask->parerr_wat_wcp_mask) { |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPULLCMDPARERR_WAT_WCP); |
| reg &= err_mask->parerr_wat_wcp_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP pull command fatal error WAT_WCP: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPULLCMDPARERR_WAT_WCP, reg); |
| |
| reset_required = true; |
| } |
| } |
| |
| return reset_required; |
| } |
| |
| static bool adf_handle_spp_pulldata_err(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev); |
| u32 reg; |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPULLDATAPARERR_ATH_CPH); |
| reg &= err_mask->parerr_ath_cph_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP pull data err ATH_CPH: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPULLDATAPARERR_ATH_CPH, reg); |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPULLDATAPARERR_CPR_XLT); |
| reg &= err_mask->parerr_cpr_xlt_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP pull data err CPR_XLT: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPULLDATAPARERR_CPR_XLT, reg); |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPULLDATAPARERR_DCPR_UCS); |
| reg &= err_mask->parerr_dcpr_ucs_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP pull data err DCPR_UCS: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPULLDATAPARERR_DCPR_UCS, reg); |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPULLDATAPARERR_PKE); |
| reg &= err_mask->parerr_pke_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP pull data err PKE: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPULLDATAPARERR_PKE, reg); |
| } |
| |
| if (err_mask->parerr_wat_wcp_mask) { |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPULLDATAPARERR_WAT_WCP); |
| reg &= err_mask->parerr_wat_wcp_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP pull data err WAT_WCP: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPULLDATAPARERR_WAT_WCP, reg); |
| } |
| } |
| |
| return false; |
| } |
| |
| static bool adf_handle_spp_pushcmd_err(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev); |
| bool reset_required = false; |
| u32 reg; |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPUSHCMDPARERR_ATH_CPH); |
| reg &= err_mask->parerr_ath_cph_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP push command fatal error ATH_CPH: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPUSHCMDPARERR_ATH_CPH, reg); |
| |
| reset_required = true; |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPUSHCMDPARERR_CPR_XLT); |
| reg &= err_mask->parerr_cpr_xlt_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP push command fatal error CPR_XLT: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPUSHCMDPARERR_CPR_XLT, reg); |
| |
| reset_required = true; |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPUSHCMDPARERR_DCPR_UCS); |
| reg &= err_mask->parerr_dcpr_ucs_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP push command fatal error DCPR_UCS: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPUSHCMDPARERR_DCPR_UCS, reg); |
| |
| reset_required = true; |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPUSHCMDPARERR_PKE); |
| reg &= err_mask->parerr_pke_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP push command fatal error PKE: 0x%x\n", |
| reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPUSHCMDPARERR_PKE, reg); |
| |
| reset_required = true; |
| } |
| |
| if (err_mask->parerr_wat_wcp_mask) { |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPUSHCMDPARERR_WAT_WCP); |
| reg &= err_mask->parerr_wat_wcp_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP push command fatal error WAT_WCP: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPUSHCMDPARERR_WAT_WCP, reg); |
| |
| reset_required = true; |
| } |
| } |
| |
| return reset_required; |
| } |
| |
| static bool adf_handle_spp_pushdata_err(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev); |
| u32 reg; |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPUSHDATAPARERR_ATH_CPH); |
| reg &= err_mask->parerr_ath_cph_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP push data err ATH_CPH: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPUSHDATAPARERR_ATH_CPH, reg); |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPUSHDATAPARERR_CPR_XLT); |
| reg &= err_mask->parerr_cpr_xlt_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP push data err CPR_XLT: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPUSHDATAPARERR_CPR_XLT, reg); |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPUSHDATAPARERR_DCPR_UCS); |
| reg &= err_mask->parerr_dcpr_ucs_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP push data err DCPR_UCS: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPUSHDATAPARERR_DCPR_UCS, reg); |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPUSHDATAPARERR_PKE); |
| reg &= err_mask->parerr_pke_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP push data err PKE: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPUSHDATAPARERR_PKE, reg); |
| } |
| |
| if (err_mask->parerr_wat_wcp_mask) { |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SPPPUSHDATAPARERR_WAT_WCP); |
| reg &= err_mask->parerr_wat_wcp_mask; |
| if (reg) { |
| dev_err(&GET_DEV(accel_dev), |
| "SPP push data err WAT_WCP: 0x%x\n", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SPPPUSHDATAPARERR_WAT_WCP, |
| reg); |
| } |
| } |
| |
| return false; |
| } |
| |
| static bool adf_handle_spppar_err(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 iastatssm) |
| { |
| bool reset_required; |
| |
| if (!(iastatssm & ADF_GEN4_IAINTSTATSSM_SPPPARERR_BIT)) |
| return false; |
| |
| reset_required = adf_handle_spp_pullcmd_err(accel_dev, csr); |
| reset_required |= adf_handle_spp_pulldata_err(accel_dev, csr); |
| reset_required |= adf_handle_spp_pushcmd_err(accel_dev, csr); |
| reset_required |= adf_handle_spp_pushdata_err(accel_dev, csr); |
| |
| return reset_required; |
| } |
| |
| static bool adf_handle_ssmcpppar_err(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 iastatssm) |
| { |
| u32 reg, bits_num = BITS_PER_REG(reg); |
| bool reset_required = false; |
| unsigned long errs_bits; |
| u32 bit_iterator; |
| |
| if (!(iastatssm & ADF_GEN4_IAINTSTATSSM_SSMCPPERR_BIT)) |
| return false; |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SSMCPPERR); |
| reg &= ADF_GEN4_SSMCPPERR_FATAL_BITMASK | ADF_GEN4_SSMCPPERR_UNCERR_BITMASK; |
| if (reg & ADF_GEN4_SSMCPPERR_FATAL_BITMASK) { |
| dev_err(&GET_DEV(accel_dev), |
| "Fatal SSM CPP parity error: 0x%x\n", reg); |
| |
| errs_bits = reg & ADF_GEN4_SSMCPPERR_FATAL_BITMASK; |
| for_each_set_bit(bit_iterator, &errs_bits, bits_num) { |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| } |
| reset_required = true; |
| } |
| |
| if (reg & ADF_GEN4_SSMCPPERR_UNCERR_BITMASK) { |
| dev_err(&GET_DEV(accel_dev), |
| "non-Fatal SSM CPP parity error: 0x%x\n", reg); |
| errs_bits = reg & ADF_GEN4_SSMCPPERR_UNCERR_BITMASK; |
| |
| for_each_set_bit(bit_iterator, &errs_bits, bits_num) { |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| } |
| } |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SSMCPPERR, reg); |
| |
| return reset_required; |
| } |
| |
| static bool adf_handle_rf_parr_err(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 iastatssm) |
| { |
| struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev); |
| u32 reg; |
| |
| if (!(iastatssm & ADF_GEN4_IAINTSTATSSM_SSMSOFTERRORPARITY_BIT)) |
| return false; |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SSMSOFTERRORPARITY_SRC); |
| reg &= ADF_GEN4_SSMSOFTERRORPARITY_SRC_BIT; |
| if (reg) { |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITY_SRC, reg); |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SSMSOFTERRORPARITY_ATH_CPH); |
| reg &= err_mask->parerr_ath_cph_mask; |
| if (reg) { |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITY_ATH_CPH, reg); |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SSMSOFTERRORPARITY_CPR_XLT); |
| reg &= err_mask->parerr_cpr_xlt_mask; |
| if (reg) { |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITY_CPR_XLT, reg); |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SSMSOFTERRORPARITY_DCPR_UCS); |
| reg &= err_mask->parerr_dcpr_ucs_mask; |
| if (reg) { |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITY_DCPR_UCS, reg); |
| } |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SSMSOFTERRORPARITY_PKE); |
| reg &= err_mask->parerr_pke_mask; |
| if (reg) { |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITY_PKE, reg); |
| } |
| |
| if (err_mask->parerr_wat_wcp_mask) { |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SSMSOFTERRORPARITY_WAT_WCP); |
| reg &= err_mask->parerr_wat_wcp_mask; |
| if (reg) { |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITY_WAT_WCP, |
| reg); |
| } |
| } |
| |
| dev_err(&GET_DEV(accel_dev), "Slice ssm soft parity error reported"); |
| |
| return false; |
| } |
| |
| static bool adf_handle_ser_err_ssmsh(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 iastatssm) |
| { |
| u32 reg, bits_num = BITS_PER_REG(reg); |
| bool reset_required = false; |
| unsigned long errs_bits; |
| u32 bit_iterator; |
| |
| if (!(iastatssm & (ADF_GEN4_IAINTSTATSSM_SER_ERR_SSMSH_CERR_BIT | |
| ADF_GEN4_IAINTSTATSSM_SER_ERR_SSMSH_UNCERR_BIT))) |
| return false; |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_SER_ERR_SSMSH); |
| reg &= ADF_GEN4_SER_ERR_SSMSH_FATAL_BITMASK | |
| ADF_GEN4_SER_ERR_SSMSH_UNCERR_BITMASK | |
| ADF_GEN4_SER_ERR_SSMSH_CERR_BITMASK; |
| if (reg & ADF_GEN4_SER_ERR_SSMSH_FATAL_BITMASK) { |
| dev_err(&GET_DEV(accel_dev), |
| "Fatal SER_SSMSH_ERR: 0x%x\n", reg); |
| |
| errs_bits = reg & ADF_GEN4_SER_ERR_SSMSH_FATAL_BITMASK; |
| for_each_set_bit(bit_iterator, &errs_bits, bits_num) { |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| } |
| |
| reset_required = true; |
| } |
| |
| if (reg & ADF_GEN4_SER_ERR_SSMSH_UNCERR_BITMASK) { |
| dev_err(&GET_DEV(accel_dev), |
| "non-fatal SER_SSMSH_ERR: 0x%x\n", reg); |
| |
| errs_bits = reg & ADF_GEN4_SER_ERR_SSMSH_UNCERR_BITMASK; |
| for_each_set_bit(bit_iterator, &errs_bits, bits_num) { |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| } |
| } |
| |
| if (reg & ADF_GEN4_SER_ERR_SSMSH_CERR_BITMASK) { |
| dev_warn(&GET_DEV(accel_dev), |
| "Correctable SER_SSMSH_ERR: 0x%x\n", reg); |
| |
| errs_bits = reg & ADF_GEN4_SER_ERR_SSMSH_CERR_BITMASK; |
| for_each_set_bit(bit_iterator, &errs_bits, bits_num) { |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_CORR); |
| } |
| } |
| |
| ADF_CSR_WR(csr, ADF_GEN4_SER_ERR_SSMSH, reg); |
| |
| return reset_required; |
| } |
| |
| static bool adf_handle_iaintstatssm(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| u32 iastatssm = ADF_CSR_RD(csr, ADF_GEN4_IAINTSTATSSM); |
| bool reset_required; |
| |
| iastatssm &= ADF_GEN4_IAINTSTATSSM_BITMASK; |
| if (!iastatssm) |
| return false; |
| |
| reset_required = adf_handle_uerrssmsh(accel_dev, csr, iastatssm); |
| reset_required |= adf_handle_cerrssmsh(accel_dev, csr, iastatssm); |
| reset_required |= adf_handle_pperr_err(accel_dev, csr, iastatssm); |
| reset_required |= adf_handle_slice_hang_error(accel_dev, csr, iastatssm); |
| reset_required |= adf_handle_spppar_err(accel_dev, csr, iastatssm); |
| reset_required |= adf_handle_ssmcpppar_err(accel_dev, csr, iastatssm); |
| reset_required |= adf_handle_rf_parr_err(accel_dev, csr, iastatssm); |
| reset_required |= adf_handle_ser_err_ssmsh(accel_dev, csr, iastatssm); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_IAINTSTATSSM, iastatssm); |
| |
| return reset_required; |
| } |
| |
| static bool adf_handle_exprpssmcmpr(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| u32 reg = ADF_CSR_RD(csr, ADF_GEN4_EXPRPSSMCPR); |
| |
| reg &= ADF_GEN4_EXPRPSSMCPR_UNCERR_BITMASK; |
| if (!reg) |
| return false; |
| |
| dev_err(&GET_DEV(accel_dev), |
| "Uncorrectable error exception in SSM CMP: 0x%x", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_EXPRPSSMCPR, reg); |
| |
| return false; |
| } |
| |
| static bool adf_handle_exprpssmxlt(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| u32 reg = ADF_CSR_RD(csr, ADF_GEN4_EXPRPSSMXLT); |
| |
| reg &= ADF_GEN4_EXPRPSSMXLT_UNCERR_BITMASK | |
| ADF_GEN4_EXPRPSSMXLT_CERR_BIT; |
| if (!reg) |
| return false; |
| |
| if (reg & ADF_GEN4_EXPRPSSMXLT_UNCERR_BITMASK) { |
| dev_err(&GET_DEV(accel_dev), |
| "Uncorrectable error exception in SSM XLT: 0x%x", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| } |
| |
| if (reg & ADF_GEN4_EXPRPSSMXLT_CERR_BIT) { |
| dev_warn(&GET_DEV(accel_dev), |
| "Correctable error exception in SSM XLT: 0x%x", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_CORR); |
| } |
| |
| ADF_CSR_WR(csr, ADF_GEN4_EXPRPSSMXLT, reg); |
| |
| return false; |
| } |
| |
| static bool adf_handle_exprpssmdcpr(struct adf_accel_dev *accel_dev, |
| void __iomem *csr) |
| { |
| u32 reg; |
| int i; |
| |
| for (i = 0; i < ADF_GEN4_DCPR_SLICES_NUM; i++) { |
| reg = ADF_CSR_RD(csr, ADF_GEN4_EXPRPSSMDCPR(i)); |
| reg &= ADF_GEN4_EXPRPSSMDCPR_UNCERR_BITMASK | |
| ADF_GEN4_EXPRPSSMDCPR_CERR_BITMASK; |
| if (!reg) |
| continue; |
| |
| if (reg & ADF_GEN4_EXPRPSSMDCPR_UNCERR_BITMASK) { |
| dev_err(&GET_DEV(accel_dev), |
| "Uncorrectable error exception in SSM DCMP: 0x%x", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| } |
| |
| if (reg & ADF_GEN4_EXPRPSSMDCPR_CERR_BITMASK) { |
| dev_warn(&GET_DEV(accel_dev), |
| "Correctable error exception in SSM DCMP: 0x%x", reg); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_CORR); |
| } |
| |
| ADF_CSR_WR(csr, ADF_GEN4_EXPRPSSMDCPR(i), reg); |
| } |
| |
| return false; |
| } |
| |
| static bool adf_handle_ssm(struct adf_accel_dev *accel_dev, void __iomem *csr, |
| u32 errsou) |
| { |
| bool reset_required; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU2_SSM_ERR_BIT)) |
| return false; |
| |
| reset_required = adf_handle_iaintstatssm(accel_dev, csr); |
| reset_required |= adf_handle_exprpssmcmpr(accel_dev, csr); |
| reset_required |= adf_handle_exprpssmxlt(accel_dev, csr); |
| reset_required |= adf_handle_exprpssmdcpr(accel_dev, csr); |
| |
| return reset_required; |
| } |
| |
| static bool adf_handle_cpp_cfc_err(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| bool reset_required = false; |
| u32 reg; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU2_CPP_CFC_ERR_STATUS_BIT)) |
| return false; |
| |
| reg = ADF_CSR_RD(csr, ADF_GEN4_CPP_CFC_ERR_STATUS); |
| if (reg & ADF_GEN4_CPP_CFC_ERR_STATUS_DATAPAR_BIT) { |
| dev_err(&GET_DEV(accel_dev), |
| "CPP_CFC_ERR: data parity: 0x%x", reg); |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| } |
| |
| if (reg & ADF_GEN4_CPP_CFC_ERR_STATUS_CMDPAR_BIT) { |
| dev_err(&GET_DEV(accel_dev), |
| "CPP_CFC_ERR: command parity: 0x%x", reg); |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| reset_required = true; |
| } |
| |
| if (reg & ADF_GEN4_CPP_CFC_ERR_STATUS_MERR_BIT) { |
| dev_err(&GET_DEV(accel_dev), |
| "CPP_CFC_ERR: multiple errors: 0x%x", reg); |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| reset_required = true; |
| } |
| |
| ADF_CSR_WR(csr, ADF_GEN4_CPP_CFC_ERR_STATUS_CLR, |
| ADF_GEN4_CPP_CFC_ERR_STATUS_CLR_BITMASK); |
| |
| return reset_required; |
| } |
| |
| static void adf_gen4_process_errsou2(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou, |
| bool *reset_required) |
| { |
| *reset_required |= adf_handle_ssm(accel_dev, csr, errsou); |
| *reset_required |= adf_handle_cpp_cfc_err(accel_dev, csr, errsou); |
| } |
| |
| static bool adf_handle_timiscsts(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| u32 timiscsts; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU3_TIMISCSTS_BIT)) |
| return false; |
| |
| timiscsts = ADF_CSR_RD(csr, ADF_GEN4_TIMISCSTS); |
| |
| dev_err(&GET_DEV(accel_dev), |
| "Fatal error in Transmit Interface: 0x%x\n", timiscsts); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| return true; |
| } |
| |
| static bool adf_handle_ricppintsts(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| u32 ricppintsts; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU3_RICPPINTSTS_BITMASK)) |
| return false; |
| |
| ricppintsts = ADF_CSR_RD(csr, ADF_GEN4_RICPPINTSTS); |
| ricppintsts &= ADF_GEN4_RICPPINTSTS_BITMASK; |
| |
| dev_err(&GET_DEV(accel_dev), |
| "RI CPP Uncorrectable Error: 0x%x\n", ricppintsts); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_RICPPINTSTS, ricppintsts); |
| |
| return false; |
| } |
| |
| static bool adf_handle_ticppintsts(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| u32 ticppintsts; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU3_TICPPINTSTS_BITMASK)) |
| return false; |
| |
| ticppintsts = ADF_CSR_RD(csr, ADF_GEN4_TICPPINTSTS); |
| ticppintsts &= ADF_GEN4_TICPPINTSTS_BITMASK; |
| |
| dev_err(&GET_DEV(accel_dev), |
| "TI CPP Uncorrectable Error: 0x%x\n", ticppintsts); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_TICPPINTSTS, ticppintsts); |
| |
| return false; |
| } |
| |
| static bool adf_handle_aramcerr(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| u32 aram_cerr; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU3_REG_ARAMCERR_BIT)) |
| return false; |
| |
| aram_cerr = ADF_CSR_RD(csr, ADF_GEN4_REG_ARAMCERR); |
| aram_cerr &= ADF_GEN4_REG_ARAMCERR_BIT; |
| |
| dev_warn(&GET_DEV(accel_dev), |
| "ARAM correctable error : 0x%x\n", aram_cerr); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_CORR); |
| |
| aram_cerr |= ADF_GEN4_REG_ARAMCERR_EN_BITMASK; |
| |
| ADF_CSR_WR(csr, ADF_GEN4_REG_ARAMCERR, aram_cerr); |
| |
| return false; |
| } |
| |
| static bool adf_handle_aramuerr(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| bool reset_required = false; |
| u32 aramuerr; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU3_REG_ARAMUERR_BIT)) |
| return false; |
| |
| aramuerr = ADF_CSR_RD(csr, ADF_GEN4_REG_ARAMUERR); |
| aramuerr &= ADF_GEN4_REG_ARAMUERR_ERROR_BIT | |
| ADF_GEN4_REG_ARAMUERR_MULTI_ERRORS_BIT; |
| |
| if (!aramuerr) |
| return false; |
| |
| if (aramuerr & ADF_GEN4_REG_ARAMUERR_MULTI_ERRORS_BIT) { |
| dev_err(&GET_DEV(accel_dev), |
| "ARAM multiple uncorrectable errors: 0x%x\n", aramuerr); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| reset_required = true; |
| } else { |
| dev_err(&GET_DEV(accel_dev), |
| "ARAM uncorrectable error: 0x%x\n", aramuerr); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| } |
| |
| aramuerr |= ADF_GEN4_REG_ARAMUERR_EN_BITMASK; |
| |
| ADF_CSR_WR(csr, ADF_GEN4_REG_ARAMUERR, aramuerr); |
| |
| return reset_required; |
| } |
| |
| static bool adf_handle_reg_cppmemtgterr(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| bool reset_required = false; |
| u32 cppmemtgterr; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU3_REG_ARAMUERR_BIT)) |
| return false; |
| |
| cppmemtgterr = ADF_CSR_RD(csr, ADF_GEN4_REG_CPPMEMTGTERR); |
| cppmemtgterr &= ADF_GEN4_REG_CPPMEMTGTERR_BITMASK | |
| ADF_GEN4_REG_CPPMEMTGTERR_MULTI_ERRORS_BIT; |
| if (!cppmemtgterr) |
| return false; |
| |
| if (cppmemtgterr & ADF_GEN4_REG_CPPMEMTGTERR_MULTI_ERRORS_BIT) { |
| dev_err(&GET_DEV(accel_dev), |
| "Misc memory target multiple uncorrectable errors: 0x%x\n", |
| cppmemtgterr); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); |
| |
| reset_required = true; |
| } else { |
| dev_err(&GET_DEV(accel_dev), |
| "Misc memory target uncorrectable error: 0x%x\n", cppmemtgterr); |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| } |
| |
| cppmemtgterr |= ADF_GEN4_REG_CPPMEMTGTERR_EN_BITMASK; |
| |
| ADF_CSR_WR(csr, ADF_GEN4_REG_CPPMEMTGTERR, cppmemtgterr); |
| |
| return reset_required; |
| } |
| |
| static bool adf_handle_atufaultstatus(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, u32 errsou) |
| { |
| u32 i; |
| u32 max_rp_num = GET_HW_DATA(accel_dev)->num_banks; |
| |
| if (!(errsou & ADF_GEN4_ERRSOU3_ATUFAULTSTATUS_BIT)) |
| return false; |
| |
| for (i = 0; i < max_rp_num; i++) { |
| u32 atufaultstatus = ADF_CSR_RD(csr, ADF_GEN4_ATUFAULTSTATUS(i)); |
| |
| atufaultstatus &= ADF_GEN4_ATUFAULTSTATUS_BIT; |
| |
| if (atufaultstatus) { |
| dev_err(&GET_DEV(accel_dev), |
| "Ring Pair (%u) ATU detected fault: 0x%x\n", i, |
| atufaultstatus); |
| |
| ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); |
| |
| ADF_CSR_WR(csr, ADF_GEN4_ATUFAULTSTATUS(i), atufaultstatus); |
| } |
| } |
| |
| return false; |
| } |
| |
| static void adf_gen4_process_errsou3(struct adf_accel_dev *accel_dev, |
| void __iomem *csr, void __iomem *aram_csr, |
| u32 errsou, bool *reset_required) |
| { |
| *reset_required |= adf_handle_timiscsts(accel_dev, csr, errsou); |
| *reset_required |= adf_handle_ricppintsts(accel_dev, csr, errsou); |
| *reset_required |= adf_handle_ticppintsts(accel_dev, csr, errsou); |
| *reset_required |= adf_handle_aramcerr(accel_dev, aram_csr, errsou); |
| *reset_required |= adf_handle_aramuerr(accel_dev, aram_csr, errsou); |
| *reset_required |= adf_handle_reg_cppmemtgterr(accel_dev, aram_csr, errsou); |
| *reset_required |= adf_handle_atufaultstatus(accel_dev, csr, errsou); |
| } |
| |
| static bool adf_gen4_handle_interrupt(struct adf_accel_dev *accel_dev, |
| bool *reset_required) |
| { |
| void __iomem *aram_csr = adf_get_aram_base(accel_dev); |
| void __iomem *csr = adf_get_pmisc_base(accel_dev); |
| u32 errsou = ADF_CSR_RD(csr, ADF_GEN4_ERRSOU0); |
| bool handled = false; |
| |
| *reset_required = false; |
| |
| if (errsou & ADF_GEN4_ERRSOU0_BIT) { |
| adf_gen4_process_errsou0(accel_dev, csr); |
| handled = true; |
| } |
| |
| errsou = ADF_CSR_RD(csr, ADF_GEN4_ERRSOU1); |
| if (errsou & ADF_GEN4_ERRSOU1_BITMASK) { |
| adf_gen4_process_errsou1(accel_dev, csr, errsou, reset_required); |
| handled = true; |
| } |
| |
| errsou = ADF_CSR_RD(csr, ADF_GEN4_ERRSOU2); |
| if (errsou & ADF_GEN4_ERRSOU2_BITMASK) { |
| adf_gen4_process_errsou2(accel_dev, csr, errsou, reset_required); |
| handled = true; |
| } |
| |
| errsou = ADF_CSR_RD(csr, ADF_GEN4_ERRSOU3); |
| if (errsou & ADF_GEN4_ERRSOU3_BITMASK) { |
| adf_gen4_process_errsou3(accel_dev, csr, aram_csr, errsou, reset_required); |
| handled = true; |
| } |
| |
| return handled; |
| } |
| |
| void adf_gen4_init_ras_ops(struct adf_ras_ops *ras_ops) |
| { |
| ras_ops->enable_ras_errors = adf_gen4_enable_ras; |
| ras_ops->disable_ras_errors = adf_gen4_disable_ras; |
| ras_ops->handle_interrupt = adf_gen4_handle_interrupt; |
| } |
| EXPORT_SYMBOL_GPL(adf_gen4_init_ras_ops); |