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 <[email protected]>
  • Loading branch information
crawfxrd committed Jul 16, 2024
1 parent 7cb9731 commit f0791b7
Show file tree
Hide file tree
Showing 5 changed files with 49 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());

uint32_t last_time_battery = 0;
Expand Down Expand Up @@ -155,6 +158,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 @@ -6,6 +6,7 @@
#include <board/dgpu.h>
#include <board/smfi.h>
#include <common/macro.h>
#include <ec/etwd.h>
#include <ec/pwm.h>
#include <ec/scratch.h>

Expand All @@ -27,8 +28,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 @@ -335,26 +335,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
41 changes: 38 additions & 3 deletions src/ec/ite/include/ec/etwd.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
// 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 <common/macro.h>
#include <stdint.h>

volatile uint8_t __xdata __at(0x1F01) ETWCFG;
Expand All @@ -27,4 +30,36 @@ volatile uint8_t __xdata __at(0x1F13) ET3CNTLH2R;
volatile uint8_t __xdata __at(0x1F16) ET4CNTLLR;
#endif

#endif // _EC_ECWD_H
enum EtwdPrescaler {
ETWD_PRESCALER_32768_HZ = 0,
ETWD_PRESCALER_1024_HZ = 1,
ETWD_PRESCALER_32_HZ = 2,
ETWD_PRESCALER_9200_KHZ = 3, // NOTE: Not available for ET1PS
};

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

static inline void wdt_init(void) {
ET1PSR = ETWD_PRESCALER_1024_HZ;

// Enable WDT key match, use ET1 prescaler for WDT clock
ETWCFG = BIT(5) | BIT(4);

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

static inline void wdt_kick(void) {
EWDKEYR = WDT_KEY;
}

static inline void wdt_trigger(void) {
// Trigger watchdog reset by key mismatch
EWDKEYR = 0;
}

#endif // _EC_ETWD_H

0 comments on commit f0791b7

Please sign in to comment.