summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
authorYe Li <ye.li@nxp.com>2019-09-06 01:21:00 -0700
committerYe Li <ye.li@nxp.com>2019-09-27 00:25:56 -0700
commitf05dd45251ca82cc54e13a616f00744c26faab53 (patch)
tree60923f1759ab96d5bae1b14f36409ec66ff1cbf0 /arch/arm/mach-imx
parent33da22c4793e56077033a4f6c567894badb8e907 (diff)
MLK-22622 imx8m: Add Workaround for ROM SError issue
ROM SError happens on two cases: 1. ERR050342, on iMX8MQ HDCP enabled parts ROM writes to GPV1 register, but when ROM patch lock is fused, this write will cause SError. 2. ERR050350, on iMX8MQ/MM/MN, when the field return fuse is burned, HAB is field return mode, but the last 4K of ROM is still protected and cause SError. Since ROM mask SError until ATF unmask it, so then ATF always meets the exception. This patch works around the issue in SPL by enabling the SError exception and take it to eret immediately to clear the SError. Signed-off-by: Ye Li <ye.li@nxp.com> Reviewed-by: Peng Fan <peng.fan@nxp.com>
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/imx8m/soc.c35
-rw-r--r--arch/arm/mach-imx/lowlevel.S11
2 files changed, 46 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c
index 7a561b1a85..1f90d6681d 100644
--- a/arch/arm/mach-imx/imx8m/soc.c
+++ b/arch/arm/mach-imx/imx8m/soc.c
@@ -26,6 +26,7 @@
#include <fsl_caam.h>
#endif
#include <environment.h>
+#include <efi_loader.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -905,6 +906,40 @@ void nxp_tmu_arch_init(void *reg_base)
}
}
+#if defined(CONFIG_SPL_BUILD)
+#if defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN)
+bool serror_need_skip = true;
+void do_error(struct pt_regs *pt_regs, unsigned int esr)
+{
+ /* If stack is still in ROM reserved OCRAM not switch to SPL, it is the ROM SError */
+ ulong sp;
+ asm volatile("mov %0, sp" : "=r"(sp) : );
+
+ if (serror_need_skip &&
+ sp < 0x910000 && sp >= 0x900000) {
+
+ /* Check for ERR050342, imx8mq HDCP enabled parts */
+ if (is_imx8mq() && !(readl(OCOTP_BASE_ADDR + 0x450) & 0x08000000)) {
+ serror_need_skip = false;
+ return; /* Do nothing skip the SError in ROM */
+ }
+
+ /* Check for ERR050350, field return mode for imx8mq, mm and mn */
+ if (readl(OCOTP_BASE_ADDR + 0x630) & 0x1) {
+ serror_need_skip = false;
+ return; /* Do nothing skip the SError in ROM */
+ }
+ }
+
+ efi_restore_gd();
+ printf("\"Error\" handler, esr 0x%08x\n", esr);
+ show_regs(pt_regs);
+ panic("Resetting CPU ...\n");
+
+}
+#endif
+#endif
+
#if defined(CONFIG_IMX8MN)
enum env_location env_get_location(enum env_operation op, int prio)
{
diff --git a/arch/arm/mach-imx/lowlevel.S b/arch/arm/mach-imx/lowlevel.S
index 158fdb7d87..2cb2d056a9 100644
--- a/arch/arm/mach-imx/lowlevel.S
+++ b/arch/arm/mach-imx/lowlevel.S
@@ -6,6 +6,16 @@
#include <linux/linkage.h>
ENTRY(lowlevel_init)
+#ifdef CONFIG_SPL_BUILD
+ mrs x0, CurrentEL
+ cmp x0, #12
+ b.eq 1f
+ ret
+1:
+ msr daifclr, #4
+ isb
+ ret
+#else
mrs x0, CurrentEL
cmp x0, #8
b.eq 1f
@@ -19,4 +29,5 @@ ENTRY(lowlevel_init)
msr hcr_el2, x0
isb
ret
+#endif
ENDPROC(lowlevel_init)