diff options
author | Dino Li <Dino.Li@ite.com.tw> | 2018-07-18 17:42:21 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-07-20 15:10:14 -0700 |
commit | 8a6674329235c0446aa1ce8b7ac36371c40308fe (patch) | |
tree | 833f7d63183db1acdc84153ff724bbcc8d62fa52 /chip/it83xx/espi.c | |
parent | ea1e1d667ae46556f86f072223030e9a57fe32cc (diff) | |
download | chrome-ec-8a6674329235c0446aa1ce8b7ac36371c40308fe.tar.gz |
IT8320DX: espi: reset espi module by FW
There is a bug on DX's espi_reset# pin.
So we can't enable hardware mechanism of espi_reset#.
To workaround this issue, this CL introduces a new macro to
config_chip.h IT83XX_ESPI_RESET_MODULE_BY_FW which is defined when
CHIP_VRAIANT is IT8320DX. When this macro is defined, the epsi hw
reset pin function is disabled. Instead, the interrupt handler for
this espi reset pin uses the GCTRL_RSTS register to force a reset of
VCC domain logic in the EC which resets the eSPI and LPC modules.
BUG=b:111480168
BRANCH=none
TEST=The eSPI module is reset when EC's espi_reset# pin is asserted.
Change-Id: Id7dfe746e7463c95735dde9a17777f3fce1030d0
Signed-off-by: Dino Li <Dino.Li@ite.com.tw>
Reviewed-on: https://chromium-review.googlesource.com/1138134
Commit-Ready: Scott Collyer <scollyer@chromium.org>
Tested-by: Scott Collyer <scollyer@chromium.org>
Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'chip/it83xx/espi.c')
-rw-r--r-- | chip/it83xx/espi.c | 53 |
1 files changed, 49 insertions, 4 deletions
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); |