From 9de4d3cab058d592a5ffffea1935dc84b8570ab9 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Tue, 10 Sep 2024 12:43:36 -0600 Subject: [PATCH] Enable system WDT with timeout of 8s Enable WDT to ensure the system: - Does not hang processing any task, such as previous cases of PECI commands never completing. - Does not take longer than the timeout period to complete all outstanding tasks. A timeout of 8s is used to remain close to the existing use of the WDT in scratch ROM, which was set to 10s. Signed-off-by: Tim Crawford --- .../system76/common/include/board/smfi.h | 1 - src/board/system76/common/main.c | 6 +++ src/board/system76/common/scratch.c | 5 ++- src/board/system76/common/smfi.c | 13 +----- src/ec/ite/ec.mk | 1 + src/ec/ite/etwd.c | 45 +++++++++++++++++++ src/ec/ite/include/ec/etwd.h | 26 +++++++++-- 7 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 src/ec/ite/etwd.c diff --git a/src/board/system76/common/include/board/smfi.h b/src/board/system76/common/include/board/smfi.h index 56b4a119d..8335b1c28 100644 --- a/src/board/system76/common/include/board/smfi.h +++ b/src/board/system76/common/include/board/smfi.h @@ -6,7 +6,6 @@ #include void smfi_init(void); -void smfi_watchdog(void); void smfi_event(void); void smfi_debug(uint8_t byte); diff --git a/src/board/system76/common/main.c b/src/board/system76/common/main.c index 4d2c24b52..6fd5d0d97 100644 --- a/src/board/system76/common/main.c +++ b/src/board/system76/common/main.c @@ -29,6 +29,7 @@ #include #include #include +#include #if CONFIG_PLATFORM_INTEL #include @@ -101,6 +102,8 @@ void main(void) { gpio_debug(); #endif + wdt_init(); + INFO("System76 EC board '%s', version '%s'\n", board(), version()); systick_t last_time_100ms = 0; @@ -167,6 +170,9 @@ void main(void) { pmc_event(&PMC_1); // AP/EC communication over SMFI smfi_event(); + + wdt_kick(); + // Idle until next timer interrupt //Disabled until interrupts used: PCON |= 1; } diff --git a/src/board/system76/common/scratch.c b/src/board/system76/common/scratch.c index e7e9ed023..d79fd57cb 100644 --- a/src/board/system76/common/scratch.c +++ b/src/board/system76/common/scratch.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -25,8 +26,8 @@ void scratch_trampoline(void) { //TODO: Clear keyboard presses - // Start watchdog timer - smfi_watchdog(); + // Restart WDT before entry to scratch ROM + wdt_kick(); // Disable interrupts EA = 0; diff --git a/src/board/system76/common/smfi.c b/src/board/system76/common/smfi.c index 225675aa8..55e6f2b3a 100644 --- a/src/board/system76/common/smfi.c +++ b/src/board/system76/common/smfi.c @@ -337,26 +337,17 @@ static enum Result cmd_reset(void) { #endif // !defined(__SCRATCH__) - // Attempt to trigger watchdog reset - ETWCFG |= BIT(5); - EWDKEYR = 0; + wdt_trigger(); // Failed if it got this far return RES_ERR; } -// Set a watchdog timer of 10 seconds -void smfi_watchdog(void) { - ET1CNTLLR = 0xFF; - EWDCNTLLR = 0xFF; - EWDCNTLHR = 0x04; -} - void smfi_event(void) { if (smfi_cmd[SMFI_CMD_CMD]) { #if defined(__SCRATCH__) // If in scratch ROM, restart watchdog timer when command received - smfi_watchdog(); + wdt_kick(); #endif switch (smfi_cmd[SMFI_CMD_CMD]) { diff --git a/src/ec/ite/ec.mk b/src/ec/ite/ec.mk index d61fa25ef..048008009 100644 --- a/src/ec/ite/ec.mk +++ b/src/ec/ite/ec.mk @@ -2,6 +2,7 @@ ec-y += ec.c ec-$(CONFIG_BUS_ESPI) += espi.c +ec-y += etwd.c ec-y += gpio.c ec-y += i2c.c ec-y += intc.c diff --git a/src/ec/ite/etwd.c b/src/ec/ite/etwd.c new file mode 100644 index 000000000..e46537e47 --- /dev/null +++ b/src/ec/ite/etwd.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-3.0-only + +// External Timer and External Watchdog (ETWD) + +#include +#include + +enum EwtCfg { + // Lock EWTCFG register + LETWCFG = BIT(0), + // Lock ET1PS register + LETPS1 = BIT(1), + // Lock ET1CNTLx registers + LET1CNTL = BIT(2), + // Lock EWDCNTLx registers + LEWDCNTL = BIT(3), + // External WDT clock source + EWDSRC = BIT(4), + // Enable key match function to touch the WDT + EWDKEYEN = BIT(5), + // Lock ET1 and EWDT registers + LOCK_ALL = LETWCFG | LETPS1 | LET1CNTL | LEWDCNTL, +}; + +enum EtwdPrescaler { + ETWD_PRESCALER_32768_HZ = 0, + ETWD_PRESCALER_1024_HZ = 1, + ETWD_PRESCALER_32_HZ = 2, + ETWD_PRESCALER_EC_CLK = 3, // Not available for ET1PS +}; + +void wdt_init(void) { + ET1PSR = ETWD_PRESCALER_1024_HZ; + ETWCFG = EWDKEYEN | EWDSRC; + + // Start ET1 so EWDT can be started + ET1CNTLLR = 0xFF; + + // Start EWDT with timeout of 8s + // TODO: Determine time based on system performance or requirement + EWDCNTLHR = 0x20; + EWDCNTLLR = 0; + + ETWCFG |= LOCK_ALL; +} diff --git a/src/ec/ite/include/ec/etwd.h b/src/ec/ite/include/ec/etwd.h index bfc75616f..467d7ac17 100644 --- a/src/ec/ite/include/ec/etwd.h +++ b/src/ec/ite/include/ec/etwd.h @@ -1,7 +1,9 @@ // SPDX-License-Identifier: GPL-3.0-only -#ifndef _EC_ECWD_H -#define _EC_ECWD_H +// External Timer and External Watchdog (ETWD) + +#ifndef _EC_ETWD_H +#define _EC_ETWD_H #include @@ -27,4 +29,22 @@ volatile uint8_t __xdata __at(0x1F13) ET3CNTLH2R; volatile uint8_t __xdata __at(0x1F16) ET4CNTLLR; #endif -#endif // _EC_ECWD_H +// When the key match function of EWD is enabled (EWTCFG[5]), writing this +// value to EWDKEY will restart the WDT. +#define WDT_KEY 0x5C + +void wdt_init(void); + +// Restart WDT +// NOTE: Must be inlined for compiling in Scratch ROM +static inline void wdt_kick(void) { + EWDKEYR = WDT_KEY; +} + +// Trigger EC reset by WDT key mismatch +// NOTE: Must be inlined for compiling in Scratch ROM +static inline void wdt_trigger(void) { + EWDKEYR = 0; +} + +#endif // _EC_ETWD_H