Commit ddc6076928ad160e9638c200ee78caa2601e6e6d

Authored by Ye Li
1 parent dea8b7b9da

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 SPL Exception vectors table
and the SError exception, take the exception to eret immediately to clear the SError.

Signed-off-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
(cherry picked from commit f05dd45251ca82cc54e13a616f00744c26faab53)
(cherry picked from commit 25d059411e702a4002f1aa157839001f796dd9f6)

Showing 3 changed files with 47 additions and 0 deletions Side-by-side Diff

arch/arm/mach-imx/imx8m/Kconfig
... ... @@ -4,6 +4,7 @@
4 4 bool
5 5 select HAS_CAAM
6 6 select ROM_UNIFIED_SECTIONS
  7 + select ARMV8_SPL_EXCEPTION_VECTORS
7 8  
8 9 config SYS_SOC
9 10 default "imx8m"
arch/arm/mach-imx/imx8m/soc.c
... ... @@ -25,6 +25,7 @@
25 25 #include <fsl_caam.h>
26 26 #endif
27 27 #include <environment.h>
  28 +#include <efi_loader.h>
28 29  
29 30 DECLARE_GLOBAL_DATA_PTR;
30 31  
... ... @@ -905,6 +906,40 @@
905 906 writel((tca_en << 31) |(tca_hr <<16) | tca_rt, (ulong)reg_base + 0x30);
906 907 }
907 908 }
  909 +
  910 +#if defined(CONFIG_SPL_BUILD)
  911 +#if defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN)
  912 +bool serror_need_skip = true;
  913 +void do_error(struct pt_regs *pt_regs, unsigned int esr)
  914 +{
  915 + /* If stack is still in ROM reserved OCRAM not switch to SPL, it is the ROM SError */
  916 + ulong sp;
  917 + asm volatile("mov %0, sp" : "=r"(sp) : );
  918 +
  919 + if (serror_need_skip &&
  920 + sp < 0x910000 && sp >= 0x900000) {
  921 +
  922 + /* Check for ERR050342, imx8mq HDCP enabled parts */
  923 + if (is_imx8mq() && !(readl(OCOTP_BASE_ADDR + 0x450) & 0x08000000)) {
  924 + serror_need_skip = false;
  925 + return; /* Do nothing skip the SError in ROM */
  926 + }
  927 +
  928 + /* Check for ERR050350, field return mode for imx8mq, mm and mn */
  929 + if (readl(OCOTP_BASE_ADDR + 0x630) & 0x1) {
  930 + serror_need_skip = false;
  931 + return; /* Do nothing skip the SError in ROM */
  932 + }
  933 + }
  934 +
  935 + efi_restore_gd();
  936 + printf("\"Error\" handler, esr 0x%08x\n", esr);
  937 + show_regs(pt_regs);
  938 + panic("Resetting CPU ...\n");
  939 +
  940 +}
  941 +#endif
  942 +#endif
908 943  
909 944 #if defined(CONFIG_IMX8MN)
910 945 enum env_location env_get_location(enum env_operation op, int prio)
arch/arm/mach-imx/lowlevel.S
... ... @@ -6,7 +6,17 @@
6 6 #include <linux/linkage.h>
7 7  
8 8 ENTRY(lowlevel_init)
  9 +#ifdef CONFIG_SPL_BUILD
9 10 mrs x0, CurrentEL
  11 + cmp x0, #12
  12 + b.eq 1f
  13 + ret
  14 +1:
  15 + msr daifclr, #4
  16 + isb
  17 + ret
  18 +#else
  19 + mrs x0, CurrentEL
10 20 cmp x0, #8
11 21 b.eq 1f
12 22 ret
... ... @@ -19,5 +29,6 @@
19 29 msr hcr_el2, x0
20 30 isb
21 31 ret
  32 +#endif
22 33 ENDPROC(lowlevel_init)