summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0049-Add-WDT-to-u-boot-to-cover-booting-failures.patch
blob: 4de12fd82ffda6405220701c2b19b8c01f83afae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
From bd79f95696957ee1e63e4506e7f4d0693b7d1c6a Mon Sep 17 00:00:00 2001
From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
Date: Mon, 14 Sep 2020 17:38:28 -0700
Subject: [PATCH] Add WDT to u-boot to cover booting failures

This commit enables WDT1 in early booting phase in u-boot to make BMC
reset to cover booting failures. If BMC meet any failure or if
systemd can't initiate watchdog timer service properly, BMC will
be reset by this watchdog. This watchdog will get feeding by
WATCHDOG_RESET macro calls from several points in u-boot loop
code. The early u-boot WD timeout is 5 seconds and kernel booting WD
timeout is 100 seconds.

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
---
 arch/arm/mach-aspeed/flash.c       |  7 +++++++
 arch/arm/mach-aspeed/platform_g5.S | 13 +++++++++++++
 board/aspeed/ast-g5/ast-g5-intel.c |  3 +++
 board/aspeed/ast-g5/ast-g5.c       | 30 ++++++++++++++++++++++++++++--
 common/bootm_os.c                  |  5 +++++
 5 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-aspeed/flash.c b/arch/arm/mach-aspeed/flash.c
index d33fb9e0fe78..31bbf77e9e67 100644
--- a/arch/arm/mach-aspeed/flash.c
+++ b/arch/arm/mach-aspeed/flash.c
@@ -30,6 +30,7 @@
 #include <asm/byteorder.h>
 #include <asm/io.h>
 #include <environment.h>
+#include <watchdog.h>
 
 #include <asm/arch/ast_scu.h>
 #include <asm/arch/aspeed.h>
@@ -610,6 +611,9 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
                         }
 
 			putc ('.');
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+			WATCHDOG_RESET();
+#endif
 		}
 	}
 	puts (" done\n");
@@ -679,6 +683,9 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 		src += count;
 		cnt -= count;
 		printf("%c\b", pat[(patcnt++) & 0x03]);
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+		WATCHDOG_RESET();
+#endif
 	}
 
 	reset_flash(info);
diff --git a/arch/arm/mach-aspeed/platform_g5.S b/arch/arm/mach-aspeed/platform_g5.S
index f221c97b19dc..3a06557fa99d 100644
--- a/arch/arm/mach-aspeed/platform_g5.S
+++ b/arch/arm/mach-aspeed/platform_g5.S
@@ -582,6 +582,19 @@ espi_early_init_done:
     mov   r1, #0xAE
     str   r1, [r0]
 
+#ifdef CONFIG_HW_WATCHDOG
+    /* Enable WDT2 to recover u-boot hang */
+    ldr   r0, =0x1e785024
+    ldr   r1, =0x00500000             @ ~5 seconds
+    str   r1, [r0]
+    ldr   r0, =0x1e785028
+    ldr   r1, =0x00004755
+    str   r1, [r0]
+    ldr   r0, =0x1e78502c
+    ldr   r1, =0x00000033
+    str   r1, [r0]
+#endif
+
 /* Test - DRAM initial time */
     ldr   r0, =0x1e78203c
     ldr   r1, =0x0000F000
diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
index c46bd70b71b2..92518a66fa67 100644
--- a/board/aspeed/ast-g5/ast-g5-intel.c
+++ b/board/aspeed/ast-g5/ast-g5-intel.c
@@ -701,6 +701,9 @@ void ast_g5_intel(void)
 	timer8_init();
 	enable_onboard_tpm();
 	if (intel_force_firmware_jumper_enabled()) {
+#ifdef CONFIG_HW_WATCHDOG
+		hw_watchdog_disable();
+#endif
 		/* FFUJ mode:- ChassisID: Solid Blue, StatusLED: Solid Amber */
 		id_led_control(GPIO_ID_LED, EIDLED_On);
 		id_led_control(GPIO_GREEN_LED, EIDLED_Off);
diff --git a/board/aspeed/ast-g5/ast-g5.c b/board/aspeed/ast-g5/ast-g5.c
index 00bd92ae5f94..3f27503bce62 100644
--- a/board/aspeed/ast-g5/ast-g5.c
+++ b/board/aspeed/ast-g5/ast-g5.c
@@ -125,9 +125,35 @@ int board_eth_init(bd_t *bd)
 
 /* Called by macro WATCHDOG_RESET */
 #if defined(CONFIG_HW_WATCHDOG)
+#define AST_WDT_COUNTER_STATUS		0x00
+#define AST_WDT_COUNTER_RELOAD_VALUE	0x04
+#define AST_WDT_COUNTER_RESTART_CTRL	0x08
+#define  AST_WDT_RESTART_VALUE		0x4755
+#define AST_WDT_CTRL			0x0c
+#define  AST_WDT_EN_1MHZ_CLK		BIT(4)
+#define  AST_WDT_SYS_RESET		BIT(1)
+#define  AST_WDT_ENABLE			BIT(0)
+#define AST_WDT_TIMEOUT_DEFAULT		0x6000000 /* ~100 seconds */
 void hw_watchdog_reset(void)
 {
-	/* Restart WD2 timer */
-	writel(0x4755, AST_WDT2_BASE + 0x08);
+	/* Restart WDT2 */
+	writel(AST_WDT_RESTART_VALUE,
+	       AST_WDT2_BASE + AST_WDT_COUNTER_RESTART_CTRL);
+}
+
+void hw_watchdog_init(void)
+{
+	writel(0, AST_WDT2_BASE + AST_WDT_CTRL);
+	writel(AST_WDT_TIMEOUT_DEFAULT,
+	       AST_WDT2_BASE + AST_WDT_COUNTER_RELOAD_VALUE);
+	writel(AST_WDT_RESTART_VALUE,
+	       AST_WDT2_BASE + AST_WDT_COUNTER_RESTART_CTRL);
+	writel(AST_WDT_EN_1MHZ_CLK | AST_WDT_SYS_RESET | AST_WDT_ENABLE,
+	       AST_WDT2_BASE + AST_WDT_CTRL);
+}
+
+void hw_watchdog_disable(void)
+{
+	writel(0, AST_WDT2_BASE + AST_WDT_CTRL);
 }
 #endif /* CONFIG_WATCHDOG */
diff --git a/common/bootm_os.c b/common/bootm_os.c
index b56eb39780e8..ec0e12ac84b9 100644
--- a/common/bootm_os.c
+++ b/common/bootm_os.c
@@ -473,11 +473,16 @@ __weak void arch_preboot_os(void)
 	/* please define platform specific arch_preboot_os() */
 }
 
+extern void hw_watchdog_init(void);
+
 int boot_selected_os(int argc, char * const argv[], int state,
 		     bootm_headers_t *images, boot_os_fn *boot_fn)
 {
 	disable_interrupts();
 	arch_preboot_os();
+#ifdef CONFIG_HW_WATCHDOG
+	hw_watchdog_init(); /* Re-init WDT with 100 seconds timeout */
+#endif
 	boot_fn(state, argc, argv, images);
 
 	/* Stand-alone may return when 'autostart' is 'no' */
-- 
2.17.1