| /* Copyright 2019 The ChromiumOS Authors |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| * |
| * Watchdog Timer |
| * |
| * In ISH, there is a watchdog timer available from the hardware. It is |
| * controlled by a few registers: |
| * |
| * - WDT_CONTROL (consists of enable bit, T1, and T2 values): When T1 |
| * reaches 0, a warning is fired. After T2 then reaches 0, the system |
| * will reset. |
| * - WDT_RELOAD: Pet the watchdog by setting to 1 |
| * - WDT_VALUES: Gives software access to T1 and T2 if needed |
| * |
| * For ISH implementation, we wish to reset only the ISH. Waiting until |
| * T2 expires will kill the whole system. The functionality of T2 is |
| * ignored, and we simply call system_reset when T1 expires. T2 will |
| * only be used if the system cannot reset when T1 expires. |
| */ |
| |
| #include "common.h" |
| #include "ec_commands.h" |
| #include "hooks.h" |
| #include "ish_persistent_data.h" |
| #include "registers.h" |
| #include "system.h" |
| #include "task.h" |
| #include "watchdog.h" |
| |
| /* Units are hundreds of milliseconds */ |
| #define WDT_T1_PERIOD (100) /* 10 seconds */ |
| #define WDT_T2_PERIOD (10) /* 1 second */ |
| |
| int watchdog_init(void) |
| { |
| /* |
| * Put reset counter back at zero if last reset was not caused |
| * by watchdog |
| */ |
| if ((system_get_reset_flags() & EC_RESET_FLAG_WATCHDOG) == 0) |
| ish_persistent_data.watchdog_counter = 0; |
| |
| /* Initialize WDT clock divider */ |
| CCU_WDT_CD = WDT_CLOCK_HZ / 10; /* 10 Hz => 100 ms period */ |
| |
| /* Enable the watchdog timer and set initial T1/T2 values */ |
| WDT_CONTROL = WDT_CONTROL_ENABLE_BIT | (WDT_T2_PERIOD << 8) | |
| WDT_T1_PERIOD; |
| |
| task_enable_irq(ISH_WDT_IRQ); |
| |
| return EC_SUCCESS; |
| } |
| |
| void watchdog_reload(void) |
| { |
| /* |
| * ISH Supplemental Registers Info, 1.2.6.2: |
| * "When firmware writes a 1 to this bit, hardware reloads |
| * the values in WDT_T1 and WDT_T2..." |
| */ |
| WDT_RELOAD = 1; |
| } |
| DECLARE_HOOK(HOOK_TICK, watchdog_reload, HOOK_PRIO_DEFAULT); |