Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable system WDT with timeout of 8s #487

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
11 changes: 11 additions & 0 deletions src/board/system76/common/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <common/macro.h>
#include <common/version.h>
#include <ec/ec.h>
#include <ec/etwd.h>

#if CONFIG_PLATFORM_INTEL
#include <board/peci.h>
Expand Down Expand Up @@ -105,6 +106,14 @@ void main(void) {
gpio_debug();
#endif

// XXX: Currently, EC upgrade process will trigger a WDT reset after it
// finishes writing the flash.
if (ec_reset_source() == RESET_SOURCE_WDT) {
ERROR("\n<<< WDT reset occurred! >>>\n\n");
} else {
wdt_init();
}

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

systick_t last_time_1ms = 0;
Expand Down Expand Up @@ -176,6 +185,8 @@ void main(void) {
fan_update_target();
}

wdt_kick();

// Idle until next timer interrupt
//PCON |= BIT(0);
}
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
38 changes: 38 additions & 0 deletions src/ec/ite/ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,45 @@
#include <common/debug.h>
#include <common/macro.h>

static enum EcResetSource ec_lsr = RESET_SOURCE_NORMAL;

enum EcResetSource ec_reset_source(void) {
return ec_lsr;
}

static void ec_check_reset_source(void) {
// LSR field in RSTS only reports WDT reset.
uint8_t rsts = RSTS & 0b11;
// Only write bit 0 to clear field.
RSTS |= BIT(0);

switch (rsts) {
case 0:
case 1:
// VSTBY or WRST#
ec_lsr = RESET_SOURCE_NORMAL;
break;
case 2:
case 3:
// Internal/External WDT
ec_lsr = RESET_SOURCE_WDT;
break;
}

// SPCTRL4 reports more reset sources.
uint8_t lsr = SPCTRL4;
// All bits are write-clear.
SPCTRL4 = 0xFF;

if (lsr & BIT(1)) {
// PWRSW WDT
ec_lsr = RESET_SOURCE_PWRSW_TIMEOUT;
}
}

void ec_init(void) {
ec_check_reset_source();

#if CONFIG_EC_ITE_IT8587E
RSTS = (0b10U << 6) | BIT(2);
#else
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;
}
8 changes: 8 additions & 0 deletions src/ec/ite/include/ec/ec.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
#ifndef _EC_EC_H
#define _EC_EC_H

// Last reset source
enum EcResetSource {
RESET_SOURCE_NORMAL,
RESET_SOURCE_WDT,
RESET_SOURCE_PWRSW_TIMEOUT,
};

void ec_init(void);
void ec_read_post_codes(void);
enum EcResetSource ec_reset_source(void);

#endif // _EC_EC_H
41 changes: 38 additions & 3 deletions src/ec/ite/include/ec/etwd.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,50 @@
// 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>

volatile uint8_t __xdata __at(0x1F01) ETWCFG;
volatile uint8_t __xdata __at(0x1F02) ET1PSR;
#if CONFIG_EC_ITE_IT8587E
volatile uint8_t __xdata __at(0x1F03) ET1CNTLHR;
#endif
volatile uint8_t __xdata __at(0x1F04) ET1CNTLLR;
volatile uint8_t __xdata __at(0x1F05) ETWCTRL;
volatile uint8_t __xdata __at(0x1F06) EWDCNTLLR;
volatile uint8_t __xdata __at(0x1F07) EWDKEYR;
volatile uint8_t __xdata __at(0x1F09) EWDCNTLHR;
volatile uint8_t __xdata __at(0x1F0A) ET2PSR;
volatile uint8_t __xdata __at(0x1F0B) ET2CNTLHR;
volatile uint8_t __xdata __at(0x1F0C) ET2CNTLLR;
volatile uint8_t __xdata __at(0x1F0E) ET2CNTLH2R;
#if CONFIG_EC_ITE_IT5570E || CONFIG_EC_ITE_IT5571E
volatile uint8_t __xdata __at(0x1F10) ET3PSR;
volatile uint8_t __xdata __at(0x1F11) ET3CNTLHR;
volatile uint8_t __xdata __at(0x1F12) ET3CNTLLR;
volatile uint8_t __xdata __at(0x1F13) ET3CNTLH2R;
volatile uint8_t __xdata __at(0x1F16) ET4CNTLLR;
#endif

// 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_ECWD_H
#endif // _EC_ETWD_H
4 changes: 4 additions & 0 deletions src/ec/ite/include/ec/gctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
volatile uint8_t __xdata __at(0x2006) RSTS;
volatile uint8_t __xdata __at(0x200A) BADRSEL;
volatile uint8_t __xdata __at(0x200D) SPCTRL1;
volatile uint8_t __xdata __at(0x2012) SPCTRL2;
volatile uint8_t __xdata __at(0x201C) SPCTRL4;
#if CONFIG_EC_ITE_IT5570E || CONFIG_EC_ITE_IT5571E
volatile uint8_t __xdata __at(0x200C) SPCTRL5;
volatile uint8_t __xdata __at(0x2016) SPCTRL3;
volatile uint8_t __xdata __at(0x2030) P80H81HS;
volatile uint8_t __xdata __at(0x2031) P80HD;
volatile uint8_t __xdata __at(0x2032) P81HD;
Expand Down
Loading