arm64: zynqmp: Show reset reason
authorMichal Simek <michal.simek@xilinx.com>
Thu, 17 May 2018 12:06:06 +0000 (14:06 +0200)
committerMichal Simek <michal.simek@xilinx.com>
Thu, 31 May 2018 11:50:39 +0000 (13:50 +0200)
Read reset reason reg and show it in log and also save it as variable.
Clearing reset reason when it is read to show only one status

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
arch/arm/include/asm/arch-zynqmp/hardware.h
board/xilinx/zynqmp/zynqmp.c

index acc68251be94275d37eda634164bb863f2b42082..f31725030b55dcaad46aa38332f22c3b252cbf5e 100644 (file)
 #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 */
@@ -37,7 +45,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 */
index e41fec32df3176c0440788378324868c92724d5d..d3450ef63725a61fc515dec4a983efabff518daf 100644 (file)
@@ -449,6 +449,47 @@ void reset_cpu(ulong addr)
 {
 }
 
+static const struct {
+       u32 bit;
+       const char *name;
+} reset_reasons[] = {
+       { RESET_REASON_DEBUG_SYS, "DEBUG" },
+       { RESET_REASON_SOFT, "SOFT" },
+       { RESET_REASON_SRST, "SRST" },
+       { RESET_REASON_PSONLY, "PS-ONLY" },
+       { RESET_REASON_PMU, "PMU" },
+       { RESET_REASON_INTERNAL, "INTERNAL" },
+       { RESET_REASON_EXTERNAL, "EXTERNAL" },
+       {}
+};
+
+static u32 reset_reason(void)
+{
+       u32 ret;
+       int i;
+       const char *reason = NULL;
+
+       ret = readl(&crlapb_base->reset_reason);
+
+       puts("Reset reason:\t");
+
+       for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) {
+               if (ret & reset_reasons[i].bit) {
+                       reason = reset_reasons[i].name;
+                       printf("%s ", reset_reasons[i].name);
+                       break;
+               }
+       }
+
+       puts("\n");
+
+       env_set("reset_reason", reason);
+
+       writel(~0, &crlapb_base->reset_reason);
+
+       return ret;
+}
+
 int board_late_init(void)
 {
        u32 reg = 0;
@@ -540,6 +581,8 @@ int board_late_init(void)
 
        env_set("boot_targets", new_targets);
 
+       reset_reason();
+
        return 0;
 }