Messages in this thread Patch in this message | | | From | thor.thayer@linux ... | Subject | [PATCH] EDAC/altera: Warm Reset option for Stratix10 peripheral DBE | Date | Mon, 3 Jun 2019 15:37:49 -0500 |
| |
From: Thor Thayer <thor.thayer@linux.intel.com>
The Stratix10 peripheral FIFO memories can recover from double bit errors with a warm reset instead of a cold reset. Add the option of a warm reset for peripheral (USB, Ethernet) memories.
CPU memories such as SDRAM and OCRAM require a cold reset for DBEs. Filter on whether the error is a SDRAM/OCRAM or a peripheral FIFO memory to determine which reset to use when the warm reset option is configured.
Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com> --- drivers/edac/Kconfig | 9 +++++++++ drivers/edac/altera_edac.c | 31 +++++++++++++++++++++++++++++-- drivers/edac/altera_edac.h | 4 ++++ 3 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 47eb4d13ed5f..e47c428d485d 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -394,6 +394,15 @@ config EDAC_ALTERA Altera SOCs. This is the global enable for the various Altera peripherals. +config EDAC_ALTERA_ARM64_WARM_RESET + bool "Altera ARM64 Peripheral Warm Reset" + depends on EDAC_ALTERA=y && ARM64 + help + Support for Warm Reset on peripheral FIFO double bit errors + on SoCFPGA ARM64 platforms. Otherwise a peripheral FIFO DBE + will cause a cold reset. SDRAM and OCRAM DBEs always cause + a cold reset. + config EDAC_ALTERA_SDRAM bool "Altera SDRAM ECC" depends on EDAC_ALTERA=y diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index 8816f74a22b4..179601f14b48 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -2036,6 +2036,19 @@ static const struct irq_domain_ops a10_eccmgr_ic_ops = { /* panic routine issues reboot on non-zero panic_timeout */ extern int panic_timeout; +#ifdef CONFIG_EDAC_ALTERA_ARM64_WARM_RESET +/* EL3 SMC call to setup CPUs for warm reset */ +void panic_smp_self_stop(void) +{ + struct arm_smccc_res result; + + __cpu_disable(); + cpu_relax(); + arm_smccc_smc(INTEL_SIP_SMC_ECC_DBE, S10_WARM_RESET_WFI_FLAG, + S10_WARM_RESET_WFI_FLAG, 0, 0, 0, 0, 0, &result); +} +#endif + /* * The double bit error is handled through SError which is fatal. This is * called as a panic notifier to printout ECC error info as part of the panic. @@ -2067,14 +2080,28 @@ static int s10_edac_dberr_handler(struct notifier_block *this, regmap_write(edac->ecc_mgr_map, S10_SYSMGR_UE_ADDR_OFST, err_addr); edac_printk(KERN_ERR, EDAC_DEVICE, - "EDAC: [Fatal DBE on %s @ 0x%08X]\n", - ed->edac_dev_name, err_addr); + "EDAC: [Fatal DBE on %s [CPU=%d] @ 0x%08X]\n", + ed->edac_dev_name, raw_smp_processor_id(), + err_addr); break; } /* Notify the System through SMC. Reboot delay = 1 second */ +#ifdef CONFIG_EDAC_ALTERA_ARM64_WARM_RESET + /* Handle peripheral FIFO DBE as Warm Resets */ + if (dberror & S10_COLD_RESET_MASK) { + panic_timeout = 1; + arm_smccc_smc(INTEL_SIP_SMC_ECC_DBE, dberror, 0, 0, 0, + 0, 0, 0, &result); + } else { + arm_smccc_smc(INTEL_SIP_SMC_ECC_DBE, + S10_WARM_RESET_WFI_FLAG | dberror, 0, 0, + 0, 0, 0, 0, &result); + } +#else panic_timeout = 1; arm_smccc_smc(INTEL_SIP_SMC_ECC_DBE, dberror, 0, 0, 0, 0, 0, 0, &result); +#endif } return NOTIFY_DONE; diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h index 55654cc4bcdf..e5936fbe3964 100644 --- a/drivers/edac/altera_edac.h +++ b/drivers/edac/altera_edac.h @@ -327,6 +327,10 @@ struct altr_sdram_mc_data { #define ECC_READ_EOVR 0x2 #define ECC_READ_EDOVR 0x3 +/* DRAM and OCRAM require cold reset */ +#define S10_COLD_RESET_MASK 0x30002 +#define S10_WARM_RESET_WFI_FLAG BIT(31) + struct altr_edac_device_dev; struct edac_device_prv_data { -- 2.7.4
| |