From d64c94dd4ce0f3ed294c391c61facba7b6775c2d Mon Sep 17 00:00:00 2001 From: Dino Li Date: Tue, 18 Aug 2020 10:28:33 +0800 Subject: iteflash: Reset EC's GPIOs while flashing BUG=b:161957387 BRANCH=none TEST=- EC's GPIOs go back to default while flashing (No power rails are turned on). - EC will be only reset once after flashing. Change-Id: I776da7f5052219df18d570f23fb7fab93583c7fa Signed-off-by: Dino Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1270299 Reviewed-by: Jett Rink --- util/iteflash.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 4 deletions(-) (limited to 'util/iteflash.c') diff --git a/util/iteflash.c b/util/iteflash.c index de5c6ce4a7..26edd2af9e 100644 --- a/util/iteflash.c +++ b/util/iteflash.c @@ -688,6 +688,42 @@ static int dbgr_reset(struct common_hnd *chnd, unsigned char val) return 0; } +/* Exit DBGR mode */ +static int exit_dbgr_mode(struct common_hnd *chnd) +{ + int ret = 0; + + printf("Exit DBGR mode...\n"); + if (chnd->dbgr_addr_3bytes) + ret |= i2c_write_byte(chnd, 0x80, 0xf0); + ret |= i2c_write_byte(chnd, 0x2f, 0x1c); + ret |= i2c_write_byte(chnd, 0x2e, 0x08); + ret |= i2c_write_byte(chnd, 0x30, BIT(4)); + + if (ret < 0) + fprintf(stderr, "EXIT DBGR MODE FAILED\n"); + + return 0; +} + +/* DBGR reset GPIOs to default */ +static int dbgr_reset_gpio(struct common_hnd *chnd) +{ + int ret = 0; + + printf("Reset GPIOs to default.\n"); + if (chnd->dbgr_addr_3bytes) + ret |= i2c_write_byte(chnd, 0x80, 0xf0); + ret |= i2c_write_byte(chnd, 0x2f, 0x20); + ret |= i2c_write_byte(chnd, 0x2e, 0x07); + ret |= i2c_write_byte(chnd, 0x30, BIT(1)); + + if (ret < 0) + fprintf(stderr, "DBGR RESET GPIO FAILED\n"); + + return 0; +} + /* disable watchdog */ static int dbgr_disable_watchdog(struct common_hnd *chnd) { @@ -764,6 +800,20 @@ static int spi_flash_follow_mode_exit(struct common_hnd *chnd, char *desc) return ret; } +/* Stop EC by sending follow mode command */ +static int dbgr_stop_ec(struct common_hnd *chnd) +{ + int ret = 0; + + ret |= spi_flash_follow_mode(chnd, "enter follow mode"); + ret |= spi_flash_follow_mode_exit(chnd, "exit follow mode"); + + if (ret < 0) + fprintf(stderr, "DBGR STOP EC FAILED!\n"); + + return ret; +} + /* SPI Flash generic command, short version */ static int spi_flash_command_short(struct common_hnd *chnd, uint8_t cmd, char *desc) @@ -1053,8 +1103,8 @@ static int send_special_waveform(struct common_hnd *chnd) /* wait for PLL stable for 5ms (plus remaining USB transfers) */ usleep(10 * MSEC); - if (spi_flash_follow_mode(chnd, "enter follow mode") >= 0) { - spi_flash_follow_mode_exit(chnd, "exit follow mode"); + /* Stop EC ASAP after sending special waveform. */ + if (dbgr_stop_ec(chnd) >= 0) { /* * If we can talk to chip, then we can break the retry * loop. @@ -2277,6 +2327,9 @@ int main(int argc, char **argv) if (send_special_waveform(&chnd)) goto return_after_init; } else { + /* Stop EC ASAP after sending special waveform. */ + dbgr_stop_ec(&chnd); + ret = check_chipid(&chnd); if (ret) { fprintf(stderr, "Failed to get ITE chip ID. This " @@ -2286,6 +2339,9 @@ int main(int argc, char **argv) } } + /* Turn off power rails by reset GPIOs to default (input). */ + dbgr_reset_gpio(&chnd); + check_flashid(&chnd); ret = post_waveform_work(&chnd); @@ -2355,8 +2411,12 @@ int main(int argc, char **argv) ret = 0; return_after_init: - /* Enable EC Host Global Reset to reset EC resource and EC domain. */ - dbgr_reset(&chnd, RSTS_VCCDO_PW_ON|RSTS_HGRST|RSTS_GRST); + /* + * Exit DBGR mode. This ensures EC won't hold clock/data pins of I2C. + * Avoid resetting EC here because flash_ec will after iteflash exits. + * This avoids double reset after flash sequence. + */ + exit_dbgr_mode(&chnd); if (chnd.conf.i2c_mux) { printf("configuring I2C MUX to none.\n"); -- cgit v1.2.1