#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 */
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 */
{
}
+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;
env_set("boot_targets", new_targets);
+ reset_reason();
+
return 0;
}