diff options
author | Andrew McRae <amcrae@google.com> | 2020-06-20 11:48:59 +1000 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-06-23 03:17:54 +0000 |
commit | 131f7dc96e1c794befabdd8b182c7d5a190b58cc (patch) | |
tree | cdab2380508491fe000509b8544f3b41677d87af /chip | |
parent | baceadc0e81945b1ca0e58ae09d3d4724a991d40 (diff) | |
download | chrome-ec-131f7dc96e1c794befabdd8b182c7d5a190b58cc.tar.gz |
npcx: Add a new flag to check for initial power-on
The CR50 will reset the EC on some platforms after power-on.
Add a reset flag to detect this and treat the second
restart as a power-on restart rather than reset.
Subsume the CONFIG_GPIO_INIT_POWER_ON_DELAY_MS config
to make it clear what the behaviour will be.
BUG=b:151329011
TEST=Confirm on dalboz, puff & variants that second reset is
treated correctly.
BRANCH=none
Change-Id: Ib66de920403f08099b87d1eff797270606b44f8f
Signed-off-by: Andrew McRae <amcrae@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2255830
Reviewed-by: Peter Marheine <pmarheine@chromium.org>
Commit-Queue: Andrew McRae <amcrae@chromium.org>
Tested-by: Andrew McRae <amcrae@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/npcx/gpio.c | 8 | ||||
-rw-r--r-- | chip/npcx/system.c | 63 |
2 files changed, 60 insertions, 11 deletions
diff --git a/chip/npcx/gpio.c b/chip/npcx/gpio.c index e20319ab0f..26d5345b22 100644 --- a/chip/npcx/gpio.c +++ b/chip/npcx/gpio.c @@ -506,7 +506,6 @@ void gpio_pre_init(void) system_check_bbram_on_reset(); is_warm = system_is_reboot_warm(); -#ifdef CONFIG_GPIO_INIT_POWER_ON_DELAY_MS /* * On power-on of some boards, H1 releases the EC from reset but then * quickly asserts and releases the reset a second time. This means the @@ -517,11 +516,12 @@ void gpio_pre_init(void) * * Make sure to set up the timer before using udelay(). */ - if (system_get_reset_flags() & EC_RESET_FLAG_POWER_ON) { + if (IS_ENABLED(CONFIG_BOARD_RESET_AFTER_POWER_ON) && + system_get_reset_flags() & EC_RESET_FLAG_INITIAL_PWR) { __hw_early_init_hwtimer(0); - udelay(CONFIG_GPIO_INIT_POWER_ON_DELAY_MS * MSEC); + udelay(2 * SECOND); + /* Shouldn't get here, but proceeding anyway... */ } -#endif #ifdef CHIP_FAMILY_NPCX7 /* diff --git a/chip/npcx/system.c b/chip/npcx/system.c index 14e5b4ced6..2a1407d4f8 100644 --- a/chip/npcx/system.c +++ b/chip/npcx/system.c @@ -321,7 +321,8 @@ uint32_t chip_read_reset_flags(void) static void check_reset_cause(void) { uint32_t hib_wake_flags = bbram_data_read(BBRM_DATA_INDEX_WAKE); - uint32_t flags = chip_read_reset_flags(); + uint32_t chip_flags = chip_read_reset_flags(); + uint32_t flags = chip_flags; /* Clear saved reset flags in bbram */ #ifdef CONFIG_POWER_BUTTON_INIT_IDLE @@ -329,9 +330,9 @@ static void check_reset_cause(void) * We're not sure whether we're booting or not. AP_IDLE will be cleared * on S5->S3 transition. */ - chip_save_reset_flags(flags & EC_RESET_FLAG_AP_IDLE); + chip_flags &= EC_RESET_FLAG_AP_IDLE; #else - chip_save_reset_flags(0); + chip_flags = 0; #endif /* Clear saved hibernate wake flag in bbram , too */ bbram_data_write(BBRM_DATA_INDEX_WAKE, 0); @@ -343,12 +344,60 @@ static void check_reset_cause(void) flags |= EC_RESET_FLAG_RESET_PIN; #else /* Check for VCC1 reset */ - if (IS_BIT_SET(NPCX_RSTCTL, NPCX_RSTCTL_VCC1_RST_STS)) - flags |= EC_RESET_FLAG_RESET_PIN; - else - flags |= EC_RESET_FLAG_POWER_ON; + int reset = IS_BIT_SET(NPCX_RSTCTL, NPCX_RSTCTL_VCC1_RST_STS); + + /* + * If configured, check the saved flags to see whether + * the previous restart was a power-on, in which case + * treat this restart as a power-on as well. + * This is to workaround the fact that the H1 will + * reset the EC at power up. + */ + if (IS_ENABLED(CONFIG_BOARD_RESET_AFTER_POWER_ON)) { + /* + * Reset pin restart rather than power-on, so check + * for any flag set from a previous power-on. + */ + if (reset) { + if (flags & EC_RESET_FLAG_INITIAL_PWR) + /* + * The previous restart was a power-on + * so treat this restart as that, and + * clear the flag so later code will + * not wait for the second reset. + */ + flags = + (flags & ~EC_RESET_FLAG_INITIAL_PWR) + | EC_RESET_FLAG_POWER_ON; + else + /* + * No previous power-on flag, + * so this is a subsequent restart + * i.e any restarts after the + * second restart caused by the H1. + */ + flags |= EC_RESET_FLAG_RESET_PIN; + } else { + /* + * Power-on restart, so set a flag and save it + * for the next imminent reset. Later code + * will check for this flag and wait for the + * second reset. + */ + flags |= EC_RESET_FLAG_POWER_ON + | EC_RESET_FLAG_INITIAL_PWR; + chip_flags |= EC_RESET_FLAG_INITIAL_PWR; + } + } else + /* + * No second reset after power-on, so + * set the flags according to the restart reason. + */ + flags |= reset ? EC_RESET_FLAG_RESET_PIN + : EC_RESET_FLAG_POWER_ON; #endif } + chip_save_reset_flags(chip_flags); /* * Set scratch bit to distinguish VCC1RST# is asserted again |