diff options
author | Jun Lin <CHLin56@nuvoton.com> | 2023-04-19 09:41:30 +0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-04-27 18:29:01 +0000 |
commit | 93423aabd0654b796ab8222685913e1ab942e391 (patch) | |
tree | 2de39061860ba7e7d574cfe8d6ac84d1d5f71eea | |
parent | f96da3b06082417054f108cd18397eb8067509fc (diff) | |
download | chrome-ec-93423aabd0654b796ab8222685913e1ab942e391.tar.gz |
npcx: watchdog: support the longer watchdog timeout
In the current pre-scalar setting (fixed to 0), the max watchdog timeout
that the user can set is ~8 seconds. It is not enough for some
application requirements such as FPMCU. This commit extends the max
timeout by adjusting the pre-scalar dynamically.
BRANCH=none
BUG=b:273577369
TEST=pass "make buildall -j"
TEST=Change the CONFIG_WATCHDOG_PERIOD_MS > 8 seconds; type console
command "watims ${timeout}"; make sure watchdog panic occurs as
expected.
TEST=Set the CONFIG_WATCHDOG_PERIOD_MS to the default (1600); make sure
WDCNT and WDCP are the same before/after applying this commit.
Change-Id: I11b764811f65f0956593ab6725a619a1a44464c4
Signed-off-by: Jun Lin <CHLin56@nuvoton.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4444452
Reviewed-by: David Cross <davidmcross@google.com>
Tested-by: David Cross <davidmcross@google.com>
Commit-Queue: David Cross <davidmcross@google.com>
Reviewed-by: Bobby Casey <bobbycasey@google.com>
-rw-r--r-- | chip/npcx/watchdog.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/chip/npcx/watchdog.c b/chip/npcx/watchdog.c index 7998378565..1172f3ac12 100644 --- a/chip/npcx/watchdog.c +++ b/chip/npcx/watchdog.c @@ -142,14 +142,14 @@ DECLARE_HOOK(HOOK_TICK, watchdog_reload, HOOK_PRIO_DEFAULT); int watchdog_init(void) { #if SUPPORT_WDG + const uint32_t pre_wdcnt = WDCNT_VALUE; + /* Touch watchdog before init if it is already running */ if (IS_BIT_SET(NPCX_T0CSR, NPCX_T0CSR_WD_RUN)) touch_watchdog_count(); /* Keep prescaler ratio timer0 clock to 1:1024 */ NPCX_TWCP = 0x0A; - /* Keep prescaler ratio watchdog clock to 1:1 */ - NPCX_WDCP = 0; /* Clear watchdog reset status initially*/ SET_BIT(NPCX_T0CSR, NPCX_T0CSR_WDRST_STS); @@ -164,10 +164,30 @@ int watchdog_init(void) SET_BIT(NPCX_T0CSR, NPCX_T0CSR_TESDIS); /* - * Set WDCNT initial reload value and T0OUT timeout period - * WDCNT = 0 will generate watchdog reset + * Calculate and set WDCNT initial reload value and T0OUT timeout + * period + * When WDCNT counts down to 0: generate watchdog reset */ - NPCX_WDCNT = WDCNT_VALUE; + if (pre_wdcnt <= 255) { + /* Keep prescaler ratio watchdog clock to 1:1 */ + NPCX_WDCP = 0; + NPCX_WDCNT = pre_wdcnt; + } else { + uint8_t wdcp; + uint8_t pre_scal; + + pre_scal = DIV_ROUND_UP(pre_wdcnt, 255); + + /* + * Find the smallest power of 2 greater than or equal to the + * prescaler + */ + wdcp = __fls(pre_scal - 1) + 1; + pre_scal = 1 << wdcp; + + NPCX_WDCP = wdcp; + NPCX_WDCNT = pre_wdcnt / pre_scal; + } /* Disable interrupt */ interrupt_disable(); |