summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorAndrew McRae <amcrae@google.com>2020-06-20 11:48:59 +1000
committerCommit Bot <commit-bot@chromium.org>2020-06-23 03:17:54 +0000
commit131f7dc96e1c794befabdd8b182c7d5a190b58cc (patch)
treecdab2380508491fe000509b8544f3b41677d87af /chip
parentbaceadc0e81945b1ca0e58ae09d3d4724a991d40 (diff)
downloadchrome-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.c8
-rw-r--r--chip/npcx/system.c63
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