Skip to content

Commit

Permalink
Enable system WDT with timeout of 8s
Browse files Browse the repository at this point in the history
Enable WDT to ensure the system:

- Does not hang processing any task, such as previous cases of PECI
  commands never completing.
- Does not take longer than the timeout period to complete all
  outstanding tasks.

A timeout of 8s is used to remain close to the existing use of the WDT
in scratch ROM, which was set to 10s.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
  • Loading branch information
crawfxrd committed Aug 29, 2024
1 parent 84c2da9 commit 6289155
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 17 deletions.
1 change: 0 additions & 1 deletion src/board/system76/common/include/board/smfi.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <stdint.h>

void smfi_init(void);
void smfi_watchdog(void);
void smfi_event(void);
void smfi_debug(uint8_t byte);

Expand Down
6 changes: 6 additions & 0 deletions src/board/system76/common/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <common/macro.h>
#include <common/version.h>
#include <ec/ec.h>
#include <ec/etwd.h>

#ifdef PARALLEL_DEBUG
#include <board/parallel.h>
Expand Down Expand Up @@ -96,6 +97,8 @@ void main(void) {
gpio_debug();
#endif

wdt_init();

INFO("System76 EC board '%s', version '%s'\n", board(), version());

systick_t last_time_100ms = 0;
Expand Down Expand Up @@ -160,6 +163,9 @@ void main(void) {
pmc_event(&PMC_1);
// AP/EC communication over SMFI
smfi_event();

wdt_kick();

// Idle until next timer interrupt
//Disabled until interrupts used: PCON |= 1;
}
Expand Down
5 changes: 3 additions & 2 deletions src/board/system76/common/scratch.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <board/fan.h>
#include <board/smfi.h>
#include <common/macro.h>
#include <ec/etwd.h>
#include <ec/pwm.h>
#include <ec/scratch.h>

Expand All @@ -25,8 +26,8 @@ void scratch_trampoline(void) {

//TODO: Clear keyboard presses

// Start watchdog timer
smfi_watchdog();
// Restart WDT before entry to scratch ROM
wdt_kick();

// Disable interrupts
EA = 0;
Expand Down
13 changes: 2 additions & 11 deletions src/board/system76/common/smfi.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,26 +337,17 @@ static enum Result cmd_reset(void) {

#endif // !defined(__SCRATCH__)

// Attempt to trigger watchdog reset
ETWCFG |= BIT(5);
EWDKEYR = 0;
wdt_trigger();

// Failed if it got this far
return RES_ERR;
}

// Set a watchdog timer of 10 seconds
void smfi_watchdog(void) {
ET1CNTLLR = 0xFF;
EWDCNTLLR = 0xFF;
EWDCNTLHR = 0x04;
}

void smfi_event(void) {
if (smfi_cmd[SMFI_CMD_CMD]) {
#if defined(__SCRATCH__)
// If in scratch ROM, restart watchdog timer when command received
smfi_watchdog();
wdt_kick();
#endif

switch (smfi_cmd[SMFI_CMD_CMD]) {
Expand Down
1 change: 1 addition & 0 deletions src/ec/ite/ec.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

ec-y += ec.c
ec-$(CONFIG_BUS_ESPI) += espi.c
ec-y += etwd.c
ec-y += gpio.c
ec-y += i2c.c
ec-y += intc.c
Expand Down
45 changes: 45 additions & 0 deletions src/ec/ite/etwd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-3.0-only

// External Timer and External Watchdog (ETWD)

#include <ec/etwd.h>
#include <common/macro.h>

enum EwtCfg {
// Lock EWTCFG register
LETWCFG = BIT(0),
// Lock ET1PS register
LETPS1 = BIT(1),
// Lock ET1CNTLx registers
LET1CNTL = BIT(2),
// Lock EWDCNTLx registers
LEWDCNTL = BIT(3),
// External WDT clock source
EWDSRC = BIT(4),
// Enable key match function to touch the WDT
EWDKEYEN = BIT(5),
// Lock ET1 and EWDT registers
LOCK_ALL = LETWCFG | LETPS1 | LET1CNTL | LEWDCNTL,
};

enum EtwdPrescaler {
ETWD_PRESCALER_32768_HZ = 0,
ETWD_PRESCALER_1024_HZ = 1,
ETWD_PRESCALER_32_HZ = 2,
ETWD_PRESCALER_EC_CLK = 3, // Not available for ET1PS
};

void wdt_init(void) {
ET1PSR = ETWD_PRESCALER_1024_HZ;
ETWCFG = EWDKEYEN | EWDSRC;

// Start ET1 so EWDT can be started
ET1CNTLLR = 0xFF;

// Start EWDT with timeout of 8s
// TODO: Determine time based on system performance or requirement
EWDCNTLHR = 0x20;
EWDCNTLLR = 0;

ETWCFG |= LOCK_ALL;
}
26 changes: 23 additions & 3 deletions src/ec/ite/include/ec/etwd.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only

#ifndef _EC_ECWD_H
#define _EC_ECWD_H
// External Timer and External Watchdog (ETWD)

#ifndef _EC_ETWD_H
#define _EC_ETWD_H

#include <stdint.h>

Expand All @@ -27,4 +29,22 @@ volatile uint8_t __xdata __at(0x1F13) ET3CNTLH2R;
volatile uint8_t __xdata __at(0x1F16) ET4CNTLLR;
#endif

#endif // _EC_ECWD_H
// When the key match function of EWD is enabled (EWTCFG[5]), writing this
// value to EWDKEY will restart the WDT.
#define WDT_KEY 0x5C

void wdt_init(void);

// Restart WDT
// NOTE: Must be inlined for compiling in Scratch ROM
static inline void wdt_kick(void) {
EWDKEYR = WDT_KEY;
}

// Trigger EC reset by WDT key mismatch
// NOTE: Must be inlined for compiling in Scratch ROM
static inline void wdt_trigger(void) {
EWDKEYR = 0;
}

#endif // _EC_ETWD_H

0 comments on commit 6289155

Please sign in to comment.