blob: 4daa354d69ee9ce687e79a94b2b4d47cf6e9793e [file] [log] [blame]
Alexander Filippovfbf6e132020-04-07 17:40:12 +03001From cf39fde2c1cfb55aa756bfb551c4087ba2fd4b6c Mon Sep 17 00:00:00 2001
2From: Alexander Filippov <a.filippov@yadro.com>
3Date: Tue, 7 Apr 2020 16:45:41 +0300
4Subject: [PATCH] Add system reset status support
5
6This is backport of patch file from intel-bmc/openbmc repository.
7 https://github.com/Intel-BMC/openbmc/blob/intel/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Add-system-reset-status-support.patch
8
9Will display the reset reasons in u-boot,
10and save the reset reasons into kernel command line,
11for applications to query.
12
13Signed-off-by: Alexander Filippov <a.filippov@yadro.com>
14
15---
16 arch/arm/include/asm/arch-aspeed/ast_g5_platform.h | 1 +
17 arch/arm/include/asm/arch-aspeed/ast_scu.h | 2 +-
18 arch/arm/mach-aspeed/ast-scu.c | 6 +-
19 board/aspeed/ast-g5/ast-g5.c | 98 ++++++++++++++++++++++
20 4 files changed, 105 insertions(+), 2 deletions(-)
21
22diff --git a/arch/arm/include/asm/arch-aspeed/ast_g5_platform.h b/arch/arm/include/asm/arch-aspeed/ast_g5_platform.h
23index 4210873..d2a4268cd 100644
24--- a/arch/arm/include/asm/arch-aspeed/ast_g5_platform.h
25+++ b/arch/arm/include/asm/arch-aspeed/ast_g5_platform.h
26@@ -188,5 +188,6 @@
27 #define AST_FORMATTER_MEM_SIZE 0xC00000 /* 12MB */
28 #define AST_FORMATTER_MEM_BASE (AST_H264_MEM_BASE + AST_H264_MEM_SIZE)
29
30+#define CONFIG_BOARD_LATE_INIT 1 /* Call board_late_init */
31
32 #endif
33diff --git a/arch/arm/include/asm/arch-aspeed/ast_scu.h b/arch/arm/include/asm/arch-aspeed/ast_scu.h
34index dcbc673..b428f38 100644
35--- a/arch/arm/include/asm/arch-aspeed/ast_scu.h
36+++ b/arch/arm/include/asm/arch-aspeed/ast_scu.h
37@@ -29,7 +29,7 @@
38 #define __AST_SCU_H
39
40 extern void ast_scu_show_system_info (void);
41-extern void ast_scu_sys_rest_info(void);
42+extern u32 ast_scu_sys_rest_info(void);
43 extern void ast_scu_security_info(void);
44 extern u32 ast_scu_revision_id(void);
45 extern u32 ast_scu_get_vga_memsize(void);
46diff --git a/arch/arm/mach-aspeed/ast-scu.c b/arch/arm/mach-aspeed/ast-scu.c
47index 12de9b8..5afd379 100644
48--- a/arch/arm/mach-aspeed/ast-scu.c
49+++ b/arch/arm/mach-aspeed/ast-scu.c
50@@ -482,22 +482,26 @@ void ast_scu_security_info(void)
51 }
52 }
53
54-void ast_scu_sys_rest_info(void)
55+u32 ast_scu_sys_rest_info(void)
56 {
57 u32 rest = ast_scu_read(AST_SCU_SYS_CTRL);
58
59 if (rest & SCU_SYS_EXT_RESET_FLAG) {
60 printf("RST : External\n");
61 ast_scu_write(SCU_SYS_EXT_RESET_FLAG, AST_SCU_SYS_CTRL);
62+ rest = SCU_SYS_EXT_RESET_FLAG;
63 } else if (rest & SCU_SYS_WDT_RESET_FLAG) {
64 printf("RST : Watchdog\n");
65 ast_scu_write(SCU_SYS_WDT_RESET_FLAG, AST_SCU_SYS_CTRL);
66+ rest = SCU_SYS_WDT_RESET_FLAG;
67 } else if (rest & SCU_SYS_PWR_RESET_FLAG) {
68 printf("RST : Power On\n");
69 ast_scu_write(SCU_SYS_PWR_RESET_FLAG, AST_SCU_SYS_CTRL);
70+ rest = SCU_SYS_PWR_RESET_FLAG;
71 } else {
72 printf("RST : CLK en\n");
73 }
74+ return rest;
75 }
76
77 u32 ast_scu_get_vga_memsize(void)
78diff --git a/board/aspeed/ast-g5/ast-g5.c b/board/aspeed/ast-g5/ast-g5.c
79index 12496ce..42d7496 100644
80--- a/board/aspeed/ast-g5/ast-g5.c
81+++ b/board/aspeed/ast-g5/ast-g5.c
82@@ -105,3 +105,104 @@ void hw_watchdog_reset(void)
83 writel(0x4755, AST_WDT2_BASE + 0x08);
84 }
85 #endif /* CONFIG_WATCHDOG */
86+
87+#ifdef CONFIG_BOARD_LATE_INIT
88+static void update_bootargs_cmd(const char *key, const char *value)
89+{
90+ int buf_len;
91+ char *buf;
92+ char *cmdline;
93+ char *end = NULL;
94+
95+ if (!key || (key[0] == '\0'))
96+ {
97+ printf("%s: Empty key not allowed\n", __func__);
98+ return;
99+ }
100+
101+ cmdline = getenv("bootargs");
102+
103+ /* Allocate space for maximum possible new command line */
104+ buf_len = (cmdline ? strlen(cmdline) : 0)
105+ + 1 /* spacebar as delimiter */
106+ + strlen(key)
107+ + (value ? 1 /* equal sign */ + strlen(value) : 0)
108+ + 1 /* terminating null */;
109+
110+ buf = calloc(buf_len, sizeof(char));
111+ if (!buf)
112+ {
113+ printf("%s: out of memory\n", __func__);
114+ return;
115+ }
116+
117+ if (cmdline)
118+ {
119+ char *start = strstr(cmdline, key);
120+
121+ /* Check for full word match. Match should be start of cmdline
122+ * or there should be space before match */
123+ if (start && ((start == cmdline) || (*(start - 1) == ' ')))
124+ {
125+ strncat(buf, cmdline, (start - cmdline));
126+
127+ /* Find the end of the keyword[=value] pair,
128+ * including a single training space character, if any.
129+ * Skip the found substring, mark the tail of cmdline.
130+ */
131+ end = strchr(start, ' ');
132+ if (end)
133+ {
134+ end++;
135+ }
136+ }
137+ else
138+ {
139+ strcat(buf, cmdline);
140+ strcat(buf, " ");
141+ }
142+ }
143+
144+ strcat(buf, key);
145+ if (value)
146+ {
147+ strcat(buf, "=");
148+ strcat(buf, value);
149+ }
150+
151+ if (end)
152+ {
153+ strcat(buf, " ");
154+ strcat(buf, end);
155+ }
156+
157+ setenv("bootargs", buf);
158+ free(buf);
159+}
160+
161+int board_late_init(void)
162+{
163+ u32 reset_reason = ast_scu_sys_rest_info();
164+
165+ if (reset_reason & SCU_SYS_EXT_RESET_FLAG)
166+ {
167+ update_bootargs_cmd("resetreason", "external");
168+ }
169+ else if (reset_reason & SCU_SYS_WDT_RESET_FLAG)
170+ {
171+ update_bootargs_cmd("resetreason", "watchdog");
172+ }
173+ else if (reset_reason & SCU_SYS_PWR_RESET_FLAG)
174+ {
175+ update_bootargs_cmd("resetreason", "power");
176+ }
177+ else
178+ {
179+ char value[32];
180+ snprintf(value, sizeof(value) - 1, "0x%x", reset_reason);
181+ update_bootargs_cmd("resetreason", value);
182+ }
183+
184+ return 0;
185+}
186+#endif /* CONFIG_BOARD_LATE_INIT */