mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
ite: Watchdog module added
Watchdog module added. Off by default because of following limitations: - When programming, the WD fires, and programming fails. For now, you have to program twice. BRANCH=none BUG=chrome-os-partner:23575 TEST=Manually wrote in a while(1); and made sure watchdog warning triggers first, prints IPC register, and then soon after the watchdog timer resets the chip. Signed-off-by: Alec Berg <alecaberg@chromium.org> Change-Id: Ia83f58f3ae108f755d2f139ada22a22e2fbdc2fa Reviewed-on: https://chromium-review.googlesource.com/177397 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
committed by
chrome-internal-fetch
parent
727053a376
commit
5edde63ac2
@@ -13,6 +13,7 @@
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
/* 128us (2^7 us) between 2 ticks */
|
||||
#define TICK_INTERVAL_LOG2 7
|
||||
@@ -64,6 +65,11 @@ void __hw_clock_source_set(uint32_t ts)
|
||||
|
||||
static void __hw_clock_source_irq(void)
|
||||
{
|
||||
#ifdef CONFIG_WATCHDOG
|
||||
/* Determine interrupt number. */
|
||||
int irq = IT83XX_INTC_IVCT3 - 16;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this is a SW interrupt, then process the timers, but don't
|
||||
* increment the time_us.
|
||||
@@ -73,6 +79,18 @@ static void __hw_clock_source_irq(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WATCHDOG
|
||||
/*
|
||||
* Both the external timer for the watchdog warning and the HW timer
|
||||
* go through this irq. So, if this interrupt was caused by watchdog
|
||||
* warning timer, then call that function.
|
||||
*/
|
||||
if (irq == IT83XX_IRQ_EXT_TIMER3) {
|
||||
watchdog_warning_irq();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* clear interrupt status */
|
||||
task_clear_pending_irq(IT83XX_IRQ_TMR_B0);
|
||||
|
||||
|
||||
83
chip/it83xx/watchdog.c
Normal file
83
chip/it83xx/watchdog.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/* Copyright (c) 2013 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 "common.h"
|
||||
#include "cpu.h"
|
||||
#include "hooks.h"
|
||||
#include "panic.h"
|
||||
#include "registers.h"
|
||||
#include "task.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
/*
|
||||
* We use timer3 to trigger an interrupt just before the watchdog timer
|
||||
* will fire so that we can capture important state information before
|
||||
* being reset.
|
||||
*/
|
||||
|
||||
/* Magic value to tickle the watchdog register. */
|
||||
#define ITE83XX_WATCHDOG_MAGIC_WORD 0x5C
|
||||
|
||||
void watchdog_warning_irq(void)
|
||||
{
|
||||
/* clear interrupt status */
|
||||
task_clear_pending_irq(IT83XX_IRQ_EXT_TIMER3);
|
||||
|
||||
/* Reset warning timer (timer 3). */
|
||||
IT83XX_ETWD_ET3CTRL = 0x03;
|
||||
|
||||
panic_printf("Pre-watchdog warning! IPC: %08x\n", get_ipc());
|
||||
}
|
||||
|
||||
void watchdog_reload(void)
|
||||
{
|
||||
/* Reset warning timer (timer 3). */
|
||||
IT83XX_ETWD_ET3CTRL = 0x03;
|
||||
|
||||
/* Restart (tickle) watchdog timer. */
|
||||
IT83XX_ETWD_EWDKEYR = ITE83XX_WATCHDOG_MAGIC_WORD;
|
||||
}
|
||||
DECLARE_HOOK(HOOK_TICK, watchdog_reload, HOOK_PRIO_DEFAULT);
|
||||
|
||||
int watchdog_init(void)
|
||||
{
|
||||
/* Unlock access to watchdog registers. */
|
||||
IT83XX_ETWD_ETWCFG = 0x00;
|
||||
|
||||
/* Set timer 3 and WD timer to use 1.024kHz clock. */
|
||||
IT83XX_ETWD_ET3PSR = 0x01;
|
||||
IT83XX_ETWD_ET1PSR = 0x01;
|
||||
|
||||
/* Set WDT key match enabled and WDT clock to use ET1PSR. */
|
||||
IT83XX_ETWD_ETWCFG = 0x30;
|
||||
|
||||
/* Specify that watchdog cannot be stopped. */
|
||||
IT83XX_ETWD_ETWCTRL = 0x00;
|
||||
|
||||
/* Set timer 3 load value to 1024 (~1.05 seconds). */
|
||||
IT83XX_ETWD_ET3CNTLH2R = 0x00;
|
||||
IT83XX_ETWD_ET3CNTLHR = 0x04;
|
||||
IT83XX_ETWD_ET3CNTLLR = 0x00;
|
||||
|
||||
/* Enable interrupt on timer 3 expiration. */
|
||||
task_enable_irq(IT83XX_IRQ_EXT_TIMER3);
|
||||
|
||||
/* Start timer 3. */
|
||||
IT83XX_ETWD_ET3CTRL = 0x03;
|
||||
|
||||
/* Start timer 1 (must be started for watchdog timer to run). */
|
||||
IT83XX_ETWD_ET1CNTLLR = 0x00;
|
||||
|
||||
/* Set watchdog timer to ~1.3 seconds. Writing CNTLL starts timer. */
|
||||
IT83XX_ETWD_EWDCNTLHR = 0x05;
|
||||
IT83XX_ETWD_EWDCNTLLR = 0x00;
|
||||
|
||||
/* Lock access to watchdog registers. */
|
||||
IT83XX_ETWD_ETWCFG = 0x3f;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
@@ -31,6 +31,12 @@ int watchdog_init(void);
|
||||
*/
|
||||
void watchdog_trace(uint32_t excep_lr, uint32_t excep_sp);
|
||||
|
||||
/**
|
||||
* Watchdog has not been tickled recently warning. This function should be
|
||||
* called when the watchdog is close to firing.
|
||||
*/
|
||||
void watchdog_warning_irq(void);
|
||||
|
||||
/* Reload the watchdog counter */
|
||||
#ifdef CONFIG_WATCHDOG
|
||||
void watchdog_reload(void);
|
||||
|
||||
Reference in New Issue
Block a user