Skip to content

Commit 73303ba

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 6398bac commit 73303ba

File tree

7 files changed

+80
-17
lines changed

7 files changed

+80
-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
systick_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/ec.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
ec-y += ec.c
44
ec-$(CONFIG_BUS_ESPI) += espi.c
5+
ec-y += etwd.c
56
ec-y += gpio.c
67
ec-y += i2c.c
78
ec-y += intc.c

src/ec/ite/etwd.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// SPDX-License-Identifier: GPL-3.0-only
2+
3+
// External Timer and External Watchdog (ETWD)
4+
5+
#include <ec/etwd.h>
6+
#include <common/macro.h>
7+
8+
enum EwtCfg {
9+
// Lock EWTCFG register
10+
LETWCFG = BIT(0),
11+
// Lock ET1PS register
12+
LETPS1 = BIT(1),
13+
// Lock ET1CNTLx registers
14+
LET1CNTL = BIT(2),
15+
// Lock EWDCNTLx registers
16+
LEWDCNTL = BIT(3),
17+
// External WDT clock source
18+
EWDSRC = BIT(4),
19+
// Enable key match function to touch the WDT
20+
EWDKEYEN = BIT(5),
21+
// Lock ET1 and EWDT registers
22+
LOCK_ALL = LETWCFG | LETPS1 | LET1CNTL | LEWDCNTL,
23+
};
24+
25+
enum EtwdPrescaler {
26+
ETWD_PRESCALER_32768_HZ = 0,
27+
ETWD_PRESCALER_1024_HZ = 1,
28+
ETWD_PRESCALER_32_HZ = 2,
29+
ETWD_PRESCALER_EC_CLK = 3, // Not available for ET1PS
30+
};
31+
32+
void wdt_init(void) {
33+
ET1PSR = ETWD_PRESCALER_1024_HZ;
34+
ETWCFG = EWDKEYEN | EWDSRC;
35+
36+
// Start ET1 so EWDT can be started
37+
ET1CNTLLR = 0xFF;
38+
39+
// Start EWDT with timeout of 8s
40+
// TODO: Determine time based on system performance
41+
EWDCNTLHR = 0x20;
42+
EWDCNTLLR = 0;
43+
44+
ETWCFG |= LOCK_ALL;
45+
}

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

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
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)
4+
5+
#ifndef _EC_ETWD_H
6+
#define _EC_ETWD_H
57

68
#include <stdint.h>
79

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

30-
#endif // _EC_ECWD_H
32+
// When the key match function of EWD is enabled (EWTCFG[5]), writing this
33+
// value to EWDKEY will restart the WDT.
34+
#define WDT_KEY 0x5C
35+
36+
void wdt_init(void);
37+
38+
// Restart WDT
39+
// NOTE: Must be inlined for compiling in Scratch ROM
40+
static inline void wdt_kick(void) {
41+
EWDKEYR = WDT_KEY;
42+
}
43+
44+
// Trigger EC reset by WDT key mismatch
45+
// NOTE: Must be inlined for compiling in Scratch ROM
46+
static inline void wdt_trigger(void) {
47+
EWDKEYR = 0;
48+
}
49+
50+
#endif // _EC_ETWD_H

0 commit comments

Comments
 (0)