summaryrefslogtreecommitdiff
path: root/chip/npcx/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/npcx/system.c')
-rw-r--r--chip/npcx/system.c63
1 files changed, 56 insertions, 7 deletions
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