diff options
author | Peng Fan <peng.fan@nxp.com> | 2023-04-28 12:08:27 +0800 |
---|---|---|
committer | Stefano Babic <sbabic@denx.de> | 2023-05-21 16:54:40 +0200 |
commit | 5f2ecac54868dc0adb778f524a12c428009721ed (patch) | |
tree | 3d5e86b5634fde5d9fd995738f462a01a9960eb4 | |
parent | fee8cf214af0807823865cfa4cc3d5e39eb8da3c (diff) | |
download | u-boot-5f2ecac54868dc0adb778f524a12c428009721ed.zip u-boot-5f2ecac54868dc0adb778f524a12c428009721ed.tar.gz u-boot-5f2ecac54868dc0adb778f524a12c428009721ed.tar.bz2 |
imx9: soc: support reset cause
Support print reset cause. Since SRSR is not accessible from non-secure
world, so first save it to grp0, then read it in non-secure world.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
-rw-r--r-- | arch/arm/mach-imx/imx9/soc.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach-imx/imx9/soc.c index a884e08..e476581 100644 --- a/arch/arm/mach-imx/imx9/soc.c +++ b/arch/arm/mach-imx/imx9/soc.c @@ -19,6 +19,8 @@ #include <asm/mach-imx/boot_mode.h> #include <asm/mach-imx/syscounter.h> #include <asm/armv8/mmu.h> +#include <dm/device.h> +#include <dm/device_compat.h> #include <dm/uclass.h> #include <env.h> #include <env_internal.h> @@ -408,6 +410,18 @@ void get_board_serial(struct tag_serialnr *serialnr) } #endif +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]); +} + int arch_cpu_init(void) { if (IS_ENABLED(CONFIG_SPL_BUILD)) { @@ -417,6 +431,9 @@ int arch_cpu_init(void) clock_init(); trdc_early_init(); + + /* Save SRC SRSR to GPR1 and clear it */ + save_reset_cause(); } return 0; @@ -650,3 +667,45 @@ int m33_prepare(void) return 0; } + +int psci_sysreset_get_status(struct udevice *dev, char *buf, int size) +{ + static const char *reset_cause[] = { + "POR ", + "JTAG ", + "IPP USER ", + "WDOG1 ", + "WDOG2 ", + "WDOG3 ", + "WDOG4 ", + "WDOG5 ", + "TEMPSENSE ", + "CSU ", + "JTAG_SW ", + "M33_REQ ", + "M33_LOCKUP ", + "UNK ", + "UNK ", + "UNK " + }; + + struct src_general_regs *src = (struct src_general_regs *)SRC_GLOBAL_RBASE; + u32 srsr; + u32 i; + int res; + + srsr = readl(&src->gpr[0]); + + for (i = ARRAY_SIZE(reset_cause); i > 0; i--) { + if (srsr & (BIT(i - 1))) + break; + } + + res = snprintf(buf, size, "Reset Status: %s\n", i ? reset_cause[i - 1] : "unknown reset"); + if (res < 0) { + dev_err(dev, "Could not write reset status message (err = %d)\n", res); + return -EIO; + } + + return 0; +} |