diff options
Diffstat (limited to 'chip/npcx/watchdog.c')
-rw-r--r-- | chip/npcx/watchdog.c | 186 |
1 files changed, 0 insertions, 186 deletions
diff --git a/chip/npcx/watchdog.c b/chip/npcx/watchdog.c deleted file mode 100644 index 55b8df8c1c..0000000000 --- a/chip/npcx/watchdog.c +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Watchdog driver */ - -#include "clock.h" -#include "common.h" -#include "console.h" -#include "registers.h" -#include "hwtimer_chip.h" -#include "gpio.h" -#include "hooks.h" -#include "timer.h" -#include "task.h" -#include "util.h" -#include "system_chip.h" -#include "watchdog.h" - -/* WDCNT value for watchdog period */ -#define WDCNT_VALUE \ - ((CONFIG_WATCHDOG_PERIOD_MS * INT_32K_CLOCK) / (1024 * 1000)) - -void watchdog_init_warning_timer(void) -{ - /* init watchdog timer first */ - init_hw_timer(ITIM_WDG_NO, ITIM_SOURCE_CLOCK_32K); - - /* - * prescaler to TIMER_TICK - * Ttick_unit = (PRE_8+1) * T32k - * PRE_8 = (Ttick_unit/T32K) - 1 - * Unit: 1 msec - */ - NPCX_ITPRE(ITIM_WDG_NO) = - DIV_ROUND_NEAREST(1000 * INT_32K_CLOCK, SECOND) - 1; - - /* Event module disable */ - CLEAR_BIT(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN); - /* ITIM count down : event expired */ - NPCX_ITCNT(ITIM_WDG_NO) = CONFIG_AUX_TIMER_PERIOD_MS; - /* Event module enable */ - SET_BIT(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN); - /* Enable interrupt of ITIM */ - task_enable_irq(ITIM_INT(ITIM_WDG_NO)); -} - -static timestamp_t last_watchdog_touch; -void watchdog_stop_and_unlock(void) -{ - /* - * Ensure we have waited at least 3 watchdog ticks since touching WD - * timer. 3 / (32768 / 1024) HZ = 93.75ms - */ - while (time_since32(last_watchdog_touch) < (100 * MSEC)) - continue; - - NPCX_WDSDM = 0x87; - NPCX_WDSDM = 0x61; - NPCX_WDSDM = 0x63; -} - -static void touch_watchdog_count(void) -{ - NPCX_WDSDM = 0x5C; - last_watchdog_touch = get_time(); -} - -static void watchdog_reload_warning_timer(void) -{ - /* Disable warning timer module */ - CLEAR_BIT(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN); - /* Wait for module disable to take effect before updating count */ - while (IS_BIT_SET(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN)) - ; - - /* Reload the warning timer count */ - NPCX_ITCNT(ITIM_WDG_NO) = CONFIG_AUX_TIMER_PERIOD_MS; - - /* enable warning timer module */ - SET_BIT(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN); - /* Wait for module enable */ - while (!IS_BIT_SET(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN)) - ; -} - -void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp) -{ -#ifdef CONFIG_TASK_PROFILING - /* - * Perform IRQ profiling accounting. This is normally done by - * DECLARE_IRQ(), but we are not using that for ITIM_WDG_NO. - */ - task_start_irq_handler((void *)excep_lr); -#endif - - /* Clear timeout status for event */ - SET_BIT(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_TO_STS); - - /* Print panic info */ - watchdog_trace(excep_lr, excep_sp); -} - -/* ISR for watchdog warning naked will keep SP & LR */ -void IRQ_HANDLER(ITIM_INT(ITIM_WDG_NO))(void) __attribute__((naked)); -void IRQ_HANDLER(ITIM_INT(ITIM_WDG_NO))(void) -{ - /* Naked call so we can extract raw LR and SP */ - asm volatile("mov r0, lr\n" - "mov r1, sp\n" - /* Must push registers in pairs to keep 64-bit aligned - * stack for ARM EABI. This also conveninently saves - * R0=LR so we can pass it to task_resched_if_needed. */ - "push {r0, lr}\n" - "bl watchdog_check\n" - "pop {r0, lr}\n" - "b task_resched_if_needed\n"); -} -const struct irq_priority __keep IRQ_PRIORITY(ITIM_INT(ITIM_WDG_NO)) -__attribute__((section(".rodata.irqprio"))) -= {ITIM_INT(ITIM_WDG_NO), 0}; -/* put the watchdog at the highest priority */ - -void watchdog_reload(void) -{ - /* Disable watchdog interrupt */ - task_disable_irq(ITIM_INT(ITIM_WDG_NO)); - - watchdog_reload_warning_timer(); - -#if 1 /* mark this for testing watchdog */ - /* Touch watchdog & reset software counter */ - touch_watchdog_count(); -#endif - - /* Enable watchdog interrupt */ - task_enable_irq(ITIM_INT(ITIM_WDG_NO)); -} -DECLARE_HOOK(HOOK_TICK, watchdog_reload, HOOK_PRIO_DEFAULT); - -int watchdog_init(void) -{ -#if SUPPORT_WDG - /* 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); - - /* Reset TWCFG */ - NPCX_TWCFG = 0; - /* Watchdog touch by writing 5Ch to WDSDM */ - SET_BIT(NPCX_TWCFG, NPCX_TWCFG_WDSDME); - /* Select T0IN clock as watchdog prescaler clock */ - SET_BIT(NPCX_TWCFG, NPCX_TWCFG_WDCT0I); - /* Disable early touch functionality */ - SET_BIT(NPCX_T0CSR, NPCX_T0CSR_TESDIS); - - /* - * Set WDCNT initial reload value and T0OUT timeout period - * WDCNT = 0 will generate watchdog reset - */ - NPCX_WDCNT = WDCNT_VALUE; - - /* Disable interrupt */ - interrupt_disable(); - /* Reload TWDT0/WDCNT */ - SET_BIT(NPCX_T0CSR, NPCX_T0CSR_RST); - /* Wait for timer is loaded and restart */ - while (IS_BIT_SET(NPCX_T0CSR, NPCX_T0CSR_RST)) - ; - /* Enable interrupt */ - interrupt_enable(); - - /* Init watchdog warning timer */ - watchdog_init_warning_timer(); -#endif - return EC_SUCCESS; -} |