summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJun Lin <CHLin56@nuvoton.com>2023-04-19 09:41:30 +0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-04-27 18:29:01 +0000
commit93423aabd0654b796ab8222685913e1ab942e391 (patch)
tree2de39061860ba7e7d574cfe8d6ac84d1d5f71eea
parentf96da3b06082417054f108cd18397eb8067509fc (diff)
downloadchrome-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.c30
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();