coreboot-libre-fam15h-rdimm/3rdparty/chromeec/chip/ish/watchdog.c

67 lines
1.9 KiB
C

/* Copyright 2019 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 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 "task.h"
#include "registers.h"
#include "system.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);