From 8290d879dab1fbba805cfcdb4f2409bdee803dc6 Mon Sep 17 00:00:00 2001 From: Dino Li Date: Tue, 5 Jun 2018 14:41:03 +0800 Subject: [PATCH] it83xx: espi: enable eSPI_reset# With this patch, EC will reset peripheral, OOB message, virtual wire, and flash access channels to default settings while the eSPI_reset# pin is asserted. BUG=b:80250980 BRANCH=none TEST=ran console command `hibernate` or 'apshutdown' during system boot to kernel and then wake system up by power button x 100. Change-Id: Iceb7ddf1a045937c004f429fc46a7346578b0cce Signed-off-by: Dino Li Reviewed-on: https://chromium-review.googlesource.com/1074672 Tested-by: Stephanie Payton Reviewed-by: Furquan Shaikh Reviewed-by: Jett Rink --- board/bip/board.c | 1 + board/bip/gpio.inc | 4 ++++ board/glkrvp_ite/board.c | 1 + board/glkrvp_ite/gpio.inc | 4 ++++ chip/it83xx/espi.c | 34 ++++++++++++++++++++++++++++++++++ chip/it83xx/intc.h | 1 + 6 files changed, 45 insertions(+) diff --git a/board/bip/board.c b/board/bip/board.c index bbc1cce661..171e873dfb 100644 --- a/board/bip/board.c +++ b/board/bip/board.c @@ -17,6 +17,7 @@ #include "gpio.h" #include "hooks.h" #include "i2c.h" +#include "intc.h" #include "keyboard_scan.h" #include "lid_switch.h" #include "power.h" diff --git a/board/bip/gpio.inc b/board/bip/gpio.inc index 9b984eb480..9cb43a5d22 100644 --- a/board/bip/gpio.inc +++ b/board/bip/gpio.inc @@ -32,6 +32,10 @@ GPIO_INT(RSMRST_L_PGOOD, PIN(F, 1), GPIO_INT_BOTH, power_signal_interrupt) /* PM GPIO_INT(ALL_SYS_PGOOD, PIN(F, 0), GPIO_INT_BOTH, power_signal_interrupt) /* PMIC_EC_PWROK_OD */ GPIO_INT(AC_PRESENT, PIN(A, 7), GPIO_INT_BOTH, extpower_interrupt) /* ACOK_OD */ +#ifdef CONFIG_HOSTCMD_ESPI +/* enable 1.8v input of EC's espi_reset pin, and then this pin takes effect. */ +GPIO_INT(ESPI_RESET_L, PIN(D, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, espi_reset_pin_asserted_interrupt) /* eSPI_reset# */ +#endif GPIO(PCH_PLTRST_L, PIN(E, 3), GPIO_INPUT) /* PLT_RST_L: Platform Reset from SoC */ GPIO(SYS_RESET_L, PIN(B, 6), GPIO_ODR_HIGH) /* SYS_RST_ODL */ diff --git a/board/glkrvp_ite/board.c b/board/glkrvp_ite/board.c index 7194259fa6..fab4e8dde7 100644 --- a/board/glkrvp_ite/board.c +++ b/board/glkrvp_ite/board.c @@ -15,6 +15,7 @@ #include "host_command.h" #include "i2c.h" #include "ioexpander_pca9555.h" +#include "intc.h" #include "keyboard_scan.h" #include "lid_switch.h" #include "power.h" diff --git a/board/glkrvp_ite/gpio.inc b/board/glkrvp_ite/gpio.inc index bd37b1dd61..2cda04e59c 100644 --- a/board/glkrvp_ite/gpio.inc +++ b/board/glkrvp_ite/gpio.inc @@ -29,6 +29,10 @@ GPIO_INT(POWER_BUTTON_L,PIN(E, 4), GPIO_INT_BOTH, power_button_interrupt) GPIO_INT(AC_PRESENT, PIN(A, 6), GPIO_INT_BOTH, extpower_interrupt) GPIO_INT(UART1_RX, PIN(B, 0), GPIO_INT_FALLING, uart_deepsleep_interrupt) /* UART1 RX input */ +#ifdef CONFIG_HOSTCMD_ESPI +/* enable 1.8v input of EC's espi_reset pin, and then this pin takes effect. */ +GPIO_INT(ESPI_RESET_L, PIN(D, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, espi_reset_pin_asserted_interrupt) /* eSPI_reset# */ +#endif /* Type-C interrupts */ UNIMPLEMENTED(USB_C0_PD_INT_ODL) diff --git a/chip/it83xx/espi.c b/chip/it83xx/espi.c index 6bd74fec1e..5f6d48f6b1 100644 --- a/chip/it83xx/espi.c +++ b/chip/it83xx/espi.c @@ -417,6 +417,37 @@ static void espi_reset_vw_index_flags(void) vw_index_flag[i] = IT83XX_ESPI_VWIDX(vw_isr_list[i].vw_index); } +void espi_reset_pin_asserted_interrupt(enum gpio_signal signal) +{ + /* reset vw_index_flag when espi_reset# asserted. */ + espi_reset_vw_index_flags(); +} + +static void espi_enable_reset(void) +{ + const struct gpio_info *espi_rst = gpio_list + GPIO_ESPI_RESET_L; + + /* + * bit[2-1]: + * 00b: reserved. + * 01b: espi_reset# is enabled on GPB7. + * 10b: espi_reset# is enabled on GPD2. + * 11b: reset is disabled. + */ + if (espi_rst->port == GPIO_D && espi_rst->mask == (1 << 2)) { + IT83XX_GPIO_GCR = (IT83XX_GPIO_GCR & ~0x6) | (1 << 2); + } else if (espi_rst->port == GPIO_B && espi_rst->mask == (1 << 7)) { + IT83XX_GPIO_GCR = (IT83XX_GPIO_GCR & ~0x6) | (1 << 1); + } else { + IT83XX_GPIO_GCR |= 0x6; + CPRINTS("EC's espi_reset pin is not enabled correctly"); + } + + /* enable interrupt of EC's espi_reset pin */ + gpio_clear_pending_interrupt(GPIO_ESPI_RESET_L); + gpio_enable_interrupt(GPIO_ESPI_RESET_L); +} + /* Interrupt event of master enables the VW channel. */ static void espi_vw_en_asserted(uint8_t evt) { @@ -515,4 +546,7 @@ void espi_init(void) /* bit4: eSPI to WUC enable */ IT83XX_ESPI_ESGCTRL2 |= (1 << 4); task_enable_irq(IT83XX_IRQ_ESPI); + + /* enable interrupt and reset from eSPI_reset# */ + espi_enable_reset(); } diff --git a/chip/it83xx/intc.h b/chip/it83xx/intc.h index b24d17fd2b..1b085498fc 100644 --- a/chip/it83xx/intc.h +++ b/chip/it83xx/intc.h @@ -21,6 +21,7 @@ void i2c_interrupt(int port); void clock_sleep_mode_wakeup_isr(void); int clock_ec_wake_from_sleep(void); void __enter_hibernate(uint32_t seconds, uint32_t microseconds); +void espi_reset_pin_asserted_interrupt(enum gpio_signal signal); void espi_interrupt(void); void espi_vw_interrupt(void); void espi_init(void);