diff options
-rw-r--r-- | chip/it83xx/config_chip.h | 5 | ||||
-rw-r--r-- | chip/it83xx/espi.c | 53 | ||||
-rw-r--r-- | chip/it83xx/registers.h | 4 |
3 files changed, 58 insertions, 4 deletions
diff --git a/chip/it83xx/config_chip.h b/chip/it83xx/config_chip.h index 9da6944a36..d719c3e834 100644 --- a/chip/it83xx/config_chip.h +++ b/chip/it83xx/config_chip.h @@ -79,6 +79,11 @@ #define CONFIG_FLASH_SIZE 0x00080000 /* The slave frequency is adjustable (bit[2-0] at register IT83XX_ESPI_GCAC1) */ #define IT83XX_ESPI_SLAVE_MAX_FREQ_CONFIGURABLE +/* + * TODO(b/111480168): eSPI HW reset can't be used because the DMA address + * gets set incorrectly resulting in a memory access exception. + */ +#define IT83XX_ESPI_RESET_MODULE_BY_FW /* Watchdog reset supports hardware reset. */ /* TODO(b/111264984): watchdog hardware reset function failed. */ #undef IT83XX_ETWD_HW_RESET_SUPPORT diff --git a/chip/it83xx/espi.c b/chip/it83xx/espi.c index c31326f386..a38cab9f3f 100644 --- a/chip/it83xx/espi.c +++ b/chip/it83xx/espi.c @@ -417,17 +417,42 @@ static void espi_reset_vw_index_flags(void) vw_index_flag[i] = IT83XX_ESPI_VWIDX(vw_isr_list[i].vw_index); } +#ifdef IT83XX_ESPI_RESET_MODULE_BY_FW +void __ram_code espi_fw_reset_module(void) +{ + /* + * (b/111480168): Force a reset of logic VCC domain in EC. This will + * reset both LPC and eSPI blocks. The IT8320DX spec describes the + * purpose of these bits as deciding whether VCC power status is used as + * an internal "power good" signal. However, toggling this field while + * VCC is applied results in resettig VCC domain logic in EC. This code + * must reside in SRAM to prevent DMA address corruption. + * + * bit[7-6]: + * 00b: The VCC power status is treated as power-off. + * 01b: The VCC power status is treated as power-on. + */ + IT83XX_GCTRL_RSTS = (IT83XX_GCTRL_RSTS & ~0xc0); + IT83XX_GCTRL_RSTS = (IT83XX_GCTRL_RSTS & ~0xc0) | (1 << 6); +} +#endif + void espi_reset_pin_asserted_interrupt(enum gpio_signal signal) { +#ifdef IT83XX_ESPI_RESET_MODULE_BY_FW + espi_fw_reset_module(); +#endif /* reset vw_index_flag when espi_reset# asserted. */ espi_reset_vw_index_flags(); } -static void espi_enable_reset(void) +static int espi_get_reset_enable_config(void) { + uint8_t config; const struct gpio_info *espi_rst = gpio_list + GPIO_ESPI_RESET_L; /* + * Determine if eSPI HW reset is connected to eiter B7 or D2. * bit[2-1]: * 00b: reserved. * 01b: espi_reset# is enabled on GPB7. @@ -435,14 +460,34 @@ static void espi_enable_reset(void) * 11b: reset is disabled. */ if (espi_rst->port == GPIO_D && espi_rst->mask == (1 << 2)) { - IT83XX_GPIO_GCR = (IT83XX_GPIO_GCR & ~0x6) | (1 << 2); + config = IT83XX_GPIO_GCR_LPC_RST_D2; } else if (espi_rst->port == GPIO_B && espi_rst->mask == (1 << 7)) { - IT83XX_GPIO_GCR = (IT83XX_GPIO_GCR & ~0x6) | (1 << 1); + config = IT83XX_GPIO_GCR_LPC_RST_B7; } else { - IT83XX_GPIO_GCR |= 0x6; + config = IT83XX_GPIO_GCR_LPC_RST_DISABLE; CPRINTS("EC's espi_reset pin is not enabled correctly"); } + return config; +} + +static void espi_enable_reset(void) +{ + int config = espi_get_reset_enable_config(); + +#ifdef IT83XX_ESPI_RESET_MODULE_BY_FW + /* + * Need to overwrite the config to ensure that eSPI HW reset is + * disabled. The reset function is instead handled by FW in the + * interrupt handler. + */ + config = IT83XX_GPIO_GCR_LPC_RST_DISABLE; + CPRINTS("EC's espi_reset pin hw auto reset is disabled"); + +#endif + IT83XX_GPIO_GCR = (IT83XX_GPIO_GCR & ~0x6) | + (config << IT83XX_GPIO_GCR_LPC_RST_POS); + /* enable interrupt of EC's espi_reset pin */ gpio_clear_pending_interrupt(GPIO_ESPI_RESET_L); gpio_enable_interrupt(GPIO_ESPI_RESET_L); diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h index b91c18817e..227cdc2f99 100644 --- a/chip/it83xx/registers.h +++ b/chip/it83xx/registers.h @@ -538,6 +538,10 @@ #define IT83XX_GPIO_BASE 0x00F01600 #define IT83XX_GPIO_GCR REG8(IT83XX_GPIO_BASE+0x00) +#define IT83XX_GPIO_GCR_LPC_RST_B7 0x1 +#define IT83XX_GPIO_GCR_LPC_RST_D2 0x2 +#define IT83XX_GPIO_GCR_LPC_RST_DISABLE 0x3 +#define IT83XX_GPIO_GCR_LPC_RST_POS 1 #define IT83XX_GPIO_GPDRA REG8(IT83XX_GPIO_BASE+0x01) #define IT83XX_GPIO_GPDRB REG8(IT83XX_GPIO_BASE+0x02) |