
From: Peng Fan peng.fan@nxp.com
Add reset cause print to u-boot log on i.MX93. Since the SRC GENERAL registers are read only for non-secure mode. We have to clear SRSR in secure mode (SPL) and pass the value to non-secure mode via GPR1 register.
Signed-off-by: Ye Li ye.li@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com --- arch/arm/mach-imx/imx9/soc.c | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+)
diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach-imx/imx9/soc.c index ed75be6e195..60044155a63 100644 --- a/arch/arm/mach-imx/imx9/soc.c +++ b/arch/arm/mach-imx/imx9/soc.c @@ -461,10 +461,59 @@ err: printf("%s: fuse read err: %d\n", __func__, ret); }
+const char *reset_cause[] = { + "POR ", + "JTAG ", + "IPP USER ", + "WDOG1 ", + "WDOG2 ", + "WDOG3 ", + "WDOG4 ", + "WDOG5 ", + "TEMPSENSE ", + "CSU ", + "JTAG_SW ", + "M33_REQ ", + "M33_LOCKUP " + "UNK ", + "UNK ", + "UNK " +}; + +static void save_reset_cause(void) +{ + struct src_general_regs *src = (struct src_general_regs *)SRC_GLOBAL_RBASE; + u32 srsr = readl(&src->srsr); + + /* clear srsr in sec mode */ + writel(srsr, &src->srsr); + /* Save value to GPR1 to pass to nonsecure */ + writel(srsr, &src->gpr[0]); +} + +static const char *get_reset_cause(u32 *srsr_ret) +{ + struct src_general_regs *src = (struct src_general_regs *)SRC_GLOBAL_RBASE; + u32 srsr; + u32 i; + + srsr = readl(&src->gpr[0]); + if (srsr_ret) + *srsr_ret = srsr; + + for (i = ARRAY_SIZE(reset_cause); i > 0; i--) { + if (srsr & (BIT(i - 1))) + return reset_cause[i - 1]; + } + + return "unknown reset"; +} + int print_cpuinfo(void) { u32 cpurev, max_freq; int minc, maxc; + u32 ssrs_ret;
cpurev = get_cpu_rev();
@@ -495,6 +544,8 @@ int print_cpuinfo(void) } printf("(%dC to %dC)", minc, maxc);
+ printf("\nReset cause: %s (0x%x)\n", get_reset_cause(&ssrs_ret), ssrs_ret); + return 0; }
@@ -528,6 +579,9 @@ int arch_cpu_init(void) clock_init();
trdc_early_init(); + + /* Save SRC SRSR to GPR1 and clear it */ + save_reset_cause(); }
return 0;