[U-Boot] arm64: zynqmp: Show reset reason

Message ID c261899d12d6697b010349da7b66371218899c56.1526563863.git.michal.simek@xilinx.com
State Superseded
Headers show
Series
  • [U-Boot] arm64: zynqmp: Show reset reason
Related show

Commit Message

Michal Simek May 17, 2018, 1:31 p.m.
Read reset reason reg and show it in log and also save it as variable.
reset_reasons table is setting up priorities for variable.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 arch/arm/include/asm/arch-zynqmp/hardware.h | 12 +++++-
 board/xilinx/zynqmp/zynqmp.c                | 43 +++++++++++++++++++++
 2 files changed, 54 insertions(+), 1 deletion(-)

Comments

Michal Simek May 17, 2018, 2:11 p.m. | #1
On 17.5.2018 15:31, Michal Simek wrote:
> Read reset reason reg and show it in log and also save it as variable.
> reset_reasons table is setting up priorities for variable.
> 
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
> 
>  arch/arm/include/asm/arch-zynqmp/hardware.h | 12 +++++-
>  board/xilinx/zynqmp/zynqmp.c                | 43 +++++++++++++++++++++
>  2 files changed, 54 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/include/asm/arch-zynqmp/hardware.h b/arch/arm/include/asm/arch-zynqmp/hardware.h
> index 3f1f9498e356..7961a247e196 100644
> --- a/arch/arm/include/asm/arch-zynqmp/hardware.h
> +++ b/arch/arm/include/asm/arch-zynqmp/hardware.h
> @@ -33,6 +33,14 @@
>  #define PS_MODE2	BIT(2)
>  #define PS_MODE3	BIT(3)
>  
> +#define RESET_REASON_DEBUG_SYS	BIT(6)
> +#define RESET_REASON_SOFT	BIT(5)
> +#define RESET_REASON_SRST	BIT(4)
> +#define RESET_REASON_PSONLY	BIT(3)
> +#define RESET_REASON_PMU	BIT(2)
> +#define RESET_REASON_INTERNAL	BIT(1)
> +#define RESET_REASON_EXTERNAL	BIT(0)
> +
>  struct crlapb_regs {
>  	u32 reserved0[36];
>  	u32 cpu_r5_ctrl; /* 0x90 */
> @@ -40,7 +48,9 @@ struct crlapb_regs {
>  	u32 timestamp_ref_ctrl; /* 0x128 */
>  	u32 reserved2[53];
>  	u32 boot_mode; /* 0x200 */
> -	u32 reserved3[14];
> +	u32 reserved3_0[7];
> +	u32 reset_reason; /* 0x220 */
> +	u32 reserved3_1[6];
>  	u32 rst_lpd_top; /* 0x23C */
>  	u32 reserved4[4];
>  	u32 boot_pin_ctrl; /* 0x250 */
> diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
> index 551921b888a0..4d886a914fa9 100644
> --- a/board/xilinx/zynqmp/zynqmp.c
> +++ b/board/xilinx/zynqmp/zynqmp.c
> @@ -476,6 +476,47 @@ static int create_mmc_boot_commands(void)
>  	return 0;
>  }
>  
> +static const struct {
> +	u32 bit;
> +	const char *name;
> +} reset_reasons[] = {
> +	{ RESET_REASON_EXTERNAL, "EXTERNAL" },
> +	{ RESET_REASON_INTERNAL, "INTERNAL" },
> +	{ RESET_REASON_SOFT, "SOFT" },
> +	{ RESET_REASON_PSONLY, "PS-ONLY" },
> +	{ RESET_REASON_SRST, "SRST" },
> +	{ RESET_REASON_PMU, "PMU" },
> +	{ RESET_REASON_DEBUG_SYS, "DEBUG" },
> +	{}
> +};
> +
> +static u32 reset_reason(bool print)
> +{
> +	u32 ret;
> +	int i;
> +	const char *reason = NULL;
> +
> +	ret = readl(&crlapb_base->reset_reason);
> +
> +	if (print)
> +		puts("Reset reason:\t");
> +
> +	for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) {
> +		if (ret & reset_reasons[i].bit) {
> +			reason = reset_reasons[i].name;
> +			if (print)
> +				printf("%s ", reset_reasons[i].name);
> +		}
> +	}
> +
> +	if (print)
> +		puts("\n");
> +
> +	env_set("reset_reason", reason);

Here should be this line to clear status after read.
 writel(~0, &crlapb_base->reset_reason);


Will add it to v2 when this concept is approved.

Thanks,
Michal

Patch

diff --git a/arch/arm/include/asm/arch-zynqmp/hardware.h b/arch/arm/include/asm/arch-zynqmp/hardware.h
index 3f1f9498e356..7961a247e196 100644
--- a/arch/arm/include/asm/arch-zynqmp/hardware.h
+++ b/arch/arm/include/asm/arch-zynqmp/hardware.h
@@ -33,6 +33,14 @@ 
 #define PS_MODE2	BIT(2)
 #define PS_MODE3	BIT(3)
 
+#define RESET_REASON_DEBUG_SYS	BIT(6)
+#define RESET_REASON_SOFT	BIT(5)
+#define RESET_REASON_SRST	BIT(4)
+#define RESET_REASON_PSONLY	BIT(3)
+#define RESET_REASON_PMU	BIT(2)
+#define RESET_REASON_INTERNAL	BIT(1)
+#define RESET_REASON_EXTERNAL	BIT(0)
+
 struct crlapb_regs {
 	u32 reserved0[36];
 	u32 cpu_r5_ctrl; /* 0x90 */
@@ -40,7 +48,9 @@  struct crlapb_regs {
 	u32 timestamp_ref_ctrl; /* 0x128 */
 	u32 reserved2[53];
 	u32 boot_mode; /* 0x200 */
-	u32 reserved3[14];
+	u32 reserved3_0[7];
+	u32 reset_reason; /* 0x220 */
+	u32 reserved3_1[6];
 	u32 rst_lpd_top; /* 0x23C */
 	u32 reserved4[4];
 	u32 boot_pin_ctrl; /* 0x250 */
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 551921b888a0..4d886a914fa9 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -476,6 +476,47 @@  static int create_mmc_boot_commands(void)
 	return 0;
 }
 
+static const struct {
+	u32 bit;
+	const char *name;
+} reset_reasons[] = {
+	{ RESET_REASON_EXTERNAL, "EXTERNAL" },
+	{ RESET_REASON_INTERNAL, "INTERNAL" },
+	{ RESET_REASON_SOFT, "SOFT" },
+	{ RESET_REASON_PSONLY, "PS-ONLY" },
+	{ RESET_REASON_SRST, "SRST" },
+	{ RESET_REASON_PMU, "PMU" },
+	{ RESET_REASON_DEBUG_SYS, "DEBUG" },
+	{}
+};
+
+static u32 reset_reason(bool print)
+{
+	u32 ret;
+	int i;
+	const char *reason = NULL;
+
+	ret = readl(&crlapb_base->reset_reason);
+
+	if (print)
+		puts("Reset reason:\t");
+
+	for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) {
+		if (ret & reset_reasons[i].bit) {
+			reason = reset_reasons[i].name;
+			if (print)
+				printf("%s ", reset_reasons[i].name);
+		}
+	}
+
+	if (print)
+		puts("\n");
+
+	env_set("reset_reason", reason);
+
+	return ret;
+}
+
 int board_late_init(void)
 {
 	u32 reg = 0;
@@ -593,6 +634,8 @@  int board_late_init(void)
 
 	env_set("boot_targets", new_targets);
 
+	reset_reason(true);
+
 	return 0;
 }