From 268a18d58c629fd39bf8e77935f49f94352cb9e3 Mon Sep 17 00:00:00 2001 From: Runyang Chen Date: Thu, 5 Jan 2023 15:46:29 +0800 Subject: soc/mediatek/common: Reset the watchdog timer before triggering reset When the watchdog timer reaches 0, the timer value won't reset to the default value unless there is an external reset or a kick. It will result in the watchdog failing to trigger the reset signal. We kick the watchdog to reset the timer to the default value. Also, because WDT hardware needs about 94us to synchronize the registers, add a 100us delay before triggering the reset signal. BUG=b:264003005, b:264017048 BRANCH=corsola TEST= Reboot successfully with the following cmd stop daisydog sleep 60 > /dev/watchdog& Signed-off-by: Runyang Chen Signed-off-by: Kuan-Hsun Cheng Change-Id: Ic4964103d54910c4a1e675b59c362e93c2213b19 Reviewed-on: https://review.coreboot.org/c/coreboot/+/71754 Reviewed-by: Yidi Lin Reviewed-by: Yu-Ping Wu Reviewed-by: Rex-BC Chen Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/soc/mediatek/common/include/soc/wdt_common.h | 5 +++++ src/soc/mediatek/common/wdt.c | 3 +++ 2 files changed, 8 insertions(+) (limited to 'src/soc') diff --git a/src/soc/mediatek/common/include/soc/wdt_common.h b/src/soc/mediatek/common/include/soc/wdt_common.h index 5587d504e8..6d6d2ba758 100644 --- a/src/soc/mediatek/common/include/soc/wdt_common.h +++ b/src/soc/mediatek/common/include/soc/wdt_common.h @@ -32,6 +32,11 @@ enum { MTK_WDT_MODE_ENABLE = 1 << 0 }; +/* WDT_RESTART */ +enum { + MTK_WDT_RESTART_KEY = 0x1971 +}; + /* WDT_RESET */ enum { MTK_WDT_SWRST_KEY = 0x1209, diff --git a/src/soc/mediatek/common/wdt.c b/src/soc/mediatek/common/wdt.c index 7ae4661011..663fc2fd30 100644 --- a/src/soc/mediatek/common/wdt.c +++ b/src/soc/mediatek/common/wdt.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include #include @@ -23,7 +24,9 @@ static inline void mtk_wdt_swreset(void) printk(BIOS_INFO, "%s() called!\n", __func__); dcache_clean_all(); + write32(&mtk_wdt->wdt_restart, MTK_WDT_RESTART_KEY); setbits32(&mtk_wdt->wdt_mode, MTK_WDT_MODE_EXTEN | MTK_WDT_MODE_KEY); + udelay(100); write32(&mtk_wdt->wdt_swrst, MTK_WDT_SWRST_KEY); halt(); -- cgit v1.2.3