Skip to content

Commit 0d3361c

Browse files
committed
Enable system WDT with timeout of 8s
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>
1 parent da5b83e commit 0d3361c

File tree

5 files changed

+49
-17
lines changed

5 files changed

+49
-17
lines changed

src/board/system76/common/include/board/smfi.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include <stdint.h>
77

88
void smfi_init(void);
9-
void smfi_watchdog(void);
109
void smfi_event(void);
1110
void smfi_debug(uint8_t byte);
1211

src/board/system76/common/main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <common/macro.h>
3131
#include <common/version.h>
3232
#include <ec/ec.h>
33+
#include <ec/etwd.h>
3334

3435
#ifdef PARALLEL_DEBUG
3536
#include <board/parallel.h>
@@ -96,6 +97,8 @@ void main(void) {
9697
gpio_debug();
9798
#endif
9899

100+
wdt_init();
101+
99102
INFO("System76 EC board '%s', version '%s'\n", board(), version());
100103

101104
uint32_t last_time_battery = 0;
@@ -164,6 +167,9 @@ void main(void) {
164167
pmc_event(&PMC_1);
165168
// AP/EC communication over SMFI
166169
smfi_event();
170+
171+
wdt_kick();
172+
167173
// Idle until next timer interrupt
168174
//Disabled until interrupts used: PCON |= 1;
169175
}

src/board/system76/common/scratch.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <board/dgpu.h>
77
#include <board/smfi.h>
88
#include <common/macro.h>
9+
#include <ec/etwd.h>
910
#include <ec/pwm.h>
1011
#include <ec/scratch.h>
1112

@@ -24,8 +25,8 @@ void scratch_trampoline(void) {
2425

2526
//TODO: Clear keyboard presses
2627

27-
// Start watchdog timer
28-
smfi_watchdog();
28+
// Restart WDT before entry to scratch ROM
29+
wdt_kick();
2930

3031
// Disable interrupts
3132
EA = 0;

src/board/system76/common/smfi.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -337,26 +337,17 @@ static enum Result cmd_reset(void) {
337337

338338
#endif // !defined(__SCRATCH__)
339339

340-
// Attempt to trigger watchdog reset
341-
ETWCFG |= BIT(5);
342-
EWDKEYR = 0;
340+
wdt_trigger();
343341

344342
// Failed if it got this far
345343
return RES_ERR;
346344
}
347345

348-
// Set a watchdog timer of 10 seconds
349-
void smfi_watchdog(void) {
350-
ET1CNTLLR = 0xFF;
351-
EWDCNTLLR = 0xFF;
352-
EWDCNTLHR = 0x04;
353-
}
354-
355346
void smfi_event(void) {
356347
if (smfi_cmd[SMFI_CMD_CMD]) {
357348
#if defined(__SCRATCH__)
358349
// If in scratch ROM, restart watchdog timer when command received
359-
smfi_watchdog();
350+
wdt_kick();
360351
#endif
361352

362353
switch (smfi_cmd[SMFI_CMD_CMD]) {

src/ec/ite/include/ec/etwd.h

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// SPDX-License-Identifier: GPL-3.0-only
22

3-
#ifndef _EC_ECWD_H
4-
#define _EC_ECWD_H
3+
// External Timer and External Watchdog (ETWD)
54

5+
#ifndef _EC_ETWD_H
6+
#define _EC_ETWD_H
7+
8+
#include <common/macro.h>
69
#include <stdint.h>
710

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

30-
#endif // _EC_ECWD_H
33+
enum EtwdPrescaler {
34+
ETWD_PRESCALER_32768_HZ = 0,
35+
ETWD_PRESCALER_1024_HZ = 1,
36+
ETWD_PRESCALER_32_HZ = 2,
37+
ETWD_PRESCALER_EC_CLK = 3, // NOTE: Not available for ET1PS
38+
};
39+
40+
// When the key match function of EWD is enabled (EWTCFG[5]), writing this
41+
// value to EWDKEY will reset the WDT.
42+
#define WDT_KEY 0x5C
43+
44+
static inline void wdt_init(void) {
45+
ET1PSR = ETWD_PRESCALER_1024_HZ;
46+
47+
// Enable WDT key match, use ET1 prescaler for WDT clock
48+
ETWCFG = BIT(5) | BIT(4);
49+
50+
// Start WDT with timeout of 8s
51+
// TODO: Determine time based on system performance
52+
EWDCNTLHR = 0x20;
53+
EWDCNTLLR = 0;
54+
}
55+
56+
static inline void wdt_kick(void) {
57+
EWDKEYR = WDT_KEY;
58+
}
59+
60+
static inline void wdt_trigger(void) {
61+
// Trigger watchdog reset by key mismatch
62+
EWDKEYR = 0;
63+
}
64+
65+
#endif // _EC_ETWD_H

0 commit comments

Comments
 (0)