xref: /aosp_15_r20/external/coreboot/src/soc/mediatek/common/wdt.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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