1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #include <arch/cache.h>
4 #include <delay.h>
5 #include <device/mmio.h>
6 #include <console/console.h>
7 #include <halt.h>
8 #include <soc/wdt.h>
9 #include <vendorcode/google/chromeos/chromeos.h>
10
mtk_wdt_clr_status(void)11 __weak void mtk_wdt_clr_status(void) { /* do nothing */ }
mtk_wdt_set_req(void)12 __weak void mtk_wdt_set_req(void) { /* do nothing */ }
13
mtk_wdt_swreset(void)14 static inline void mtk_wdt_swreset(void)
15 {
16 /*
17 * We trigger a secondary reset by triggering WDT hardware to send the
18 * signal to EC.
19 * We do not use do_board_reset() to send the signal to EC which is
20 * controlled by software driver.
21 * Before triggering the secondary reset, clean the data cache so the
22 * logs in cbmem console (either in SRAM or DRAM) can be flushed.
23 */
24 printk(BIOS_INFO, "%s() called!\n", __func__);
25
26 dcache_clean_all();
27 write32(&mtk_wdt->wdt_restart, MTK_WDT_RESTART_KEY);
28 setbits32(&mtk_wdt->wdt_mode, MTK_WDT_MODE_EXTEN | MTK_WDT_MODE_KEY);
29 udelay(100);
30 write32(&mtk_wdt->wdt_swrst, MTK_WDT_SWRST_KEY);
31
32 halt();
33 }
34
mtk_wdt_init(void)35 int mtk_wdt_init(void)
36 {
37 uint32_t wdt_sta;
38
39 mtk_wdt_set_req();
40
41 /* Writing mode register will clear status register */
42 wdt_sta = read32(&mtk_wdt->wdt_status);
43
44 mtk_wdt_clr_status();
45
46 printk(BIOS_INFO, "WDT: Status = %#x\n", wdt_sta);
47
48 printk(BIOS_INFO, "WDT: Last reset was ");
49 if (!wdt_sta) {
50 printk(BIOS_INFO, "cold boot\n");
51 } else {
52 if (wdt_sta & MTK_WDT_STA_HW_RST)
53 printk(BIOS_INFO, "hardware watchdog\n");
54 else if (wdt_sta & MTK_WDT_STA_SW_RST)
55 printk(BIOS_INFO, "normal software reboot\n");
56 else if (wdt_sta & MTK_WDT_STA_SPM_RST)
57 printk(BIOS_INFO, "SPM reboot\n");
58 else
59 printk(BIOS_INFO, "other reset type: %#.8x\n", wdt_sta);
60
61 mark_watchdog_tombstone();
62 mtk_wdt_swreset();
63 }
64
65 /* Config watchdog reboot mode:
66 * Clearing bits:
67 * DUAL_MODE & IRQ: trigger reset instead of irq then reset.
68 * EXT_POL: select watchdog output signal as active low.
69 * ENABLE: disable watchdog on initialization.
70 * Setting bit EXTEN to enable watchdog output.
71 */
72 clrsetbits32(&mtk_wdt->wdt_mode,
73 MTK_WDT_MODE_DUAL_MODE | MTK_WDT_MODE_IRQ |
74 MTK_WDT_MODE_EXT_POL | MTK_WDT_MODE_ENABLE,
75 MTK_WDT_MODE_EXTEN | MTK_WDT_MODE_KEY);
76
77 return wdt_sta;
78 }
79