summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorDino Li <Dino.Li@ite.com.tw>2017-11-14 10:55:55 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-11-14 21:52:39 -0800
commit2bb1811f074db4d33fa22209d4be1b303d93ef04 (patch)
treec960bd3feabe48829937dd19fb057570905a69f3 /chip
parent385c276e4bf50c9a9816b8cf9a8abc9b86dab329 (diff)
downloadchrome-ec-2bb1811f074db4d33fa22209d4be1b303d93ef04.tar.gz
it83xx: add espi module
Add espi control module for it83xx. Signed-off-by: Dino Li <dino.li@ite.com.tw> BRANCH=none BUG=none TEST=1. it8390+Intel SKL-Y RVP3 and boot to shell. 2. console command "kbpress 1 4" to test keyboard data. (board code for espi module test on CL:392587) Change-Id: I1b32bd16f7e01abf07b9c9a68ebef2399cc9828d Reviewed-on: https://chromium-review.googlesource.com/394471 Commit-Ready: Dino Li <Dino.Li@ite.com.tw> Tested-by: Dino Li <Dino.Li@ite.com.tw> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r--chip/it83xx/build.mk1
-rw-r--r--chip/it83xx/espi.c387
-rw-r--r--chip/it83xx/intc.c9
-rw-r--r--chip/it83xx/intc.h3
-rw-r--r--chip/it83xx/lpc.c25
-rw-r--r--chip/it83xx/registers.h70
-rw-r--r--chip/it83xx/uart.c6
7 files changed, 501 insertions, 0 deletions
diff --git a/chip/it83xx/build.mk b/chip/it83xx/build.mk
index 2179b8c17e..cff3cea031 100644
--- a/chip/it83xx/build.mk
+++ b/chip/it83xx/build.mk
@@ -21,6 +21,7 @@ chip-$(CONFIG_PWM)+=pwm.o
chip-$(CONFIG_ADC)+=adc.o
chip-$(CONFIG_EC2I)+=ec2i.o
chip-$(CONFIG_LPC)+=lpc.o
+chip-$(CONFIG_ESPI)+=espi.o
chip-$(CONFIG_SPI)+=spi.o
chip-$(CONFIG_PECI)+=peci.o
chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o
diff --git a/chip/it83xx/espi.c b/chip/it83xx/espi.c
new file mode 100644
index 0000000000..9d105d4af8
--- /dev/null
+++ b/chip/it83xx/espi.c
@@ -0,0 +1,387 @@
+/* Copyright 2017 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* ESPI module for Chrome EC */
+
+#include "console.h"
+#include "espi.h"
+#include "hooks.h"
+#include "port80.h"
+#include "power.h"
+#include "registers.h"
+#include "system.h"
+#include "task.h"
+#include "uart.h"
+#include "util.h"
+
+#define CHIP_ESPI_VW_INTERRUPT_NUM 8
+
+/* Console output macros */
+#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args)
+
+struct vw_channel_t {
+ uint8_t index; /* VW index of signal */
+ uint8_t level_mask; /* level bit of signal */
+ uint8_t valid_mask; /* valid bit of signal */
+};
+
+/* VW settings at initialization */
+static const struct vw_channel_t vw_init_setting[] = {
+ {ESPI_SYSTEM_EVENT_VW_IDX_4,
+ VW_LEVEL_FIELD(0),
+ VW_VALID_FIELD(VW_IDX_4_OOB_RST_ACK)},
+ {ESPI_SYSTEM_EVENT_VW_IDX_5,
+ VW_LEVEL_FIELD(VW_IDX_5_BTLD_STATUS_DONE),
+ VW_VALID_FIELD(VW_IDX_5_BTLD_STATUS_DONE)},
+ {ESPI_SYSTEM_EVENT_VW_IDX_40,
+ VW_LEVEL_FIELD(0),
+ VW_VALID_FIELD(VW_IDX_40_SUS_ACK)},
+};
+
+/* VW settings at host startup */
+static const struct vw_channel_t vw_host_startup_setting[] = {
+ {ESPI_SYSTEM_EVENT_VW_IDX_6,
+ VW_LEVEL_FIELD(VW_IDX_6_SCI | VW_IDX_6_SMI |
+ VW_IDX_6_RCIN | VW_IDX_6_HOST_RST_ACK),
+ VW_VALID_FIELD(VW_IDX_6_SCI | VW_IDX_6_SMI |
+ VW_IDX_6_RCIN | VW_IDX_6_HOST_RST_ACK)},
+};
+
+#define VW_CHAN(name, idx, level, valid) \
+ [(name - VW_SIGNAL_BASE)] = {idx, level, valid}
+
+/* VW signals used in eSPI (NOTE: must match order of enum espi_vw_signal). */
+static const struct vw_channel_t vw_channel_list[] = {
+ /* index 02h: master to slave. */
+ VW_CHAN(VW_SLP_S3_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_2,
+ VW_LEVEL_FIELD(VW_IDX_2_SLP_S3),
+ VW_VALID_FIELD(VW_IDX_2_SLP_S3)),
+ VW_CHAN(VW_SLP_S4_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_2,
+ VW_LEVEL_FIELD(VW_IDX_2_SLP_S4),
+ VW_VALID_FIELD(VW_IDX_2_SLP_S4)),
+ VW_CHAN(VW_SLP_S5_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_2,
+ VW_LEVEL_FIELD(VW_IDX_2_SLP_S5),
+ VW_VALID_FIELD(VW_IDX_2_SLP_S5)),
+ /* index 03h: master to slave. */
+ VW_CHAN(VW_SUS_STAT_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_3,
+ VW_LEVEL_FIELD(VW_IDX_3_SUS_STAT),
+ VW_VALID_FIELD(VW_IDX_3_SUS_STAT)),
+ VW_CHAN(VW_PLTRST_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_3,
+ VW_LEVEL_FIELD(VW_IDX_3_PLTRST),
+ VW_VALID_FIELD(VW_IDX_3_PLTRST)),
+ VW_CHAN(VW_OOB_RST_WARN,
+ ESPI_SYSTEM_EVENT_VW_IDX_3,
+ VW_LEVEL_FIELD(VW_IDX_3_OOB_RST_WARN),
+ VW_VALID_FIELD(VW_IDX_3_OOB_RST_WARN)),
+ /* index 04h: slave to master. */
+ VW_CHAN(VW_OOB_RST_ACK,
+ ESPI_SYSTEM_EVENT_VW_IDX_4,
+ VW_LEVEL_FIELD(VW_IDX_4_OOB_RST_ACK),
+ VW_VALID_FIELD(VW_IDX_4_OOB_RST_ACK)),
+ VW_CHAN(VW_WAKE_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_4,
+ VW_LEVEL_FIELD(VW_IDX_4_WAKE),
+ VW_VALID_FIELD(VW_IDX_4_WAKE)),
+ VW_CHAN(VW_PME_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_4,
+ VW_LEVEL_FIELD(VW_IDX_4_PME),
+ VW_VALID_FIELD(VW_IDX_4_PME)),
+ /* index 05h: slave to master. */
+ VW_CHAN(VW_ERROR_FATAL,
+ ESPI_SYSTEM_EVENT_VW_IDX_5,
+ VW_LEVEL_FIELD(VW_IDX_5_FATAL),
+ VW_VALID_FIELD(VW_IDX_5_FATAL)),
+ VW_CHAN(VW_ERROR_NON_FATAL,
+ ESPI_SYSTEM_EVENT_VW_IDX_5,
+ VW_LEVEL_FIELD(VW_IDX_5_NON_FATAL),
+ VW_VALID_FIELD(VW_IDX_5_NON_FATAL)),
+ VW_CHAN(VW_SLAVE_BTLD_STATUS_DONE,
+ ESPI_SYSTEM_EVENT_VW_IDX_5,
+ VW_LEVEL_FIELD(VW_IDX_5_BTLD_STATUS_DONE),
+ VW_VALID_FIELD(VW_IDX_5_BTLD_STATUS_DONE)),
+ /* index 06h: slave to master. */
+ VW_CHAN(VW_SCI_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_6,
+ VW_LEVEL_FIELD(VW_IDX_6_SCI),
+ VW_VALID_FIELD(VW_IDX_6_SCI)),
+ VW_CHAN(VW_SMI_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_6,
+ VW_LEVEL_FIELD(VW_IDX_6_SMI),
+ VW_VALID_FIELD(VW_IDX_6_SMI)),
+ VW_CHAN(VW_RCIN_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_6,
+ VW_LEVEL_FIELD(VW_IDX_6_RCIN),
+ VW_VALID_FIELD(VW_IDX_6_RCIN)),
+ VW_CHAN(VW_HOST_RST_ACK,
+ ESPI_SYSTEM_EVENT_VW_IDX_6,
+ VW_LEVEL_FIELD(VW_IDX_6_HOST_RST_ACK),
+ VW_VALID_FIELD(VW_IDX_6_HOST_RST_ACK)),
+ /* index 07h: master to slave. */
+ VW_CHAN(VW_HOST_RST_WARN,
+ ESPI_SYSTEM_EVENT_VW_IDX_7,
+ VW_LEVEL_FIELD(VW_IDX_7_HOST_RST_WARN),
+ VW_VALID_FIELD(VW_IDX_7_HOST_RST_WARN)),
+ /* index 40h: slave to master. */
+ VW_CHAN(VW_SUS_ACK,
+ ESPI_SYSTEM_EVENT_VW_IDX_40,
+ VW_LEVEL_FIELD(VW_IDX_40_SUS_ACK),
+ VW_VALID_FIELD(VW_IDX_40_SUS_ACK)),
+ /* index 41h: master to slave. */
+ VW_CHAN(VW_SUS_WARN_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_41,
+ VW_LEVEL_FIELD(VW_IDX_41_SUS_WARN),
+ VW_VALID_FIELD(VW_IDX_41_SUS_WARN)),
+ VW_CHAN(VW_SUS_PWRDN_ACK_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_41,
+ VW_LEVEL_FIELD(VW_IDX_41_SUS_PWRDN_ACK),
+ VW_VALID_FIELD(VW_IDX_41_SUS_PWRDN_ACK)),
+ VW_CHAN(VW_SLP_A_L,
+ ESPI_SYSTEM_EVENT_VW_IDX_41,
+ VW_LEVEL_FIELD(VW_IDX_41_SLP_A),
+ VW_VALID_FIELD(VW_IDX_41_SLP_A)),
+ /* index 42h: master to slave. */
+ VW_CHAN(VW_SLP_LAN,
+ ESPI_SYSTEM_EVENT_VW_IDX_42,
+ VW_LEVEL_FIELD(VW_IDX_42_SLP_LAN),
+ VW_VALID_FIELD(VW_IDX_42_SLP_LAN)),
+ VW_CHAN(VW_SLP_WLAN,
+ ESPI_SYSTEM_EVENT_VW_IDX_42,
+ VW_LEVEL_FIELD(VW_IDX_42_SLP_WLAN),
+ VW_VALID_FIELD(VW_IDX_42_SLP_WLAN)),
+};
+BUILD_ASSERT(ARRAY_SIZE(vw_channel_list) ==
+ (VW_SIGNAL_BASE_END - VW_SIGNAL_BASE));
+
+/* Get vw index & value information by signal */
+static int espi_vw_get_signal_index(enum espi_vw_signal event)
+{
+ uint32_t i = event - VW_SIGNAL_BASE;
+
+ return (i < ARRAY_SIZE(vw_channel_list)) ? i : -1;
+}
+
+/**
+ * Set eSPI Virtual-Wire signal to Host
+ *
+ * @param signal vw signal needs to set
+ * @param level level of vw signal
+ * @return EC_SUCCESS, or non-zero if error.
+ */
+int espi_vw_set_wire(enum espi_vw_signal signal, uint8_t level)
+{
+ /* Get index of vw signal list by signale name */
+ int i = espi_vw_get_signal_index(signal);
+
+ if (i < 0)
+ return EC_ERROR_PARAM1;
+
+ /* critical section with interrupts off */
+ interrupt_disable();
+ if (level)
+ IT83XX_ESPI_VWIDX(vw_channel_list[i].index) |=
+ vw_channel_list[i].level_mask;
+ else
+ IT83XX_ESPI_VWIDX(vw_channel_list[i].index) &=
+ ~vw_channel_list[i].level_mask;
+ /* restore interrupts */
+ interrupt_enable();
+
+ return EC_SUCCESS;
+}
+
+/**
+ * Get eSPI Virtual-Wire signal from host
+ *
+ * @param signal vw signal needs to get
+ * @return 1: set by host, otherwise: no signal
+ */
+int espi_vw_get_wire(enum espi_vw_signal signal)
+{
+ /* Get index of vw signal list by signale name */
+ int i = espi_vw_get_signal_index(signal);
+
+ if (i < 0)
+ return 0;
+
+ /* Not valid */
+ if (!(IT83XX_ESPI_VWIDX(vw_channel_list[i].index) &
+ vw_channel_list[i].valid_mask))
+ return 0;
+
+ return !!(IT83XX_ESPI_VWIDX(vw_channel_list[i].index) &
+ vw_channel_list[i].level_mask);
+}
+
+/**
+ * Enable VW interrupt of power sequence signal
+ *
+ * @param signal vw signal needs to enable interrupt
+ * @return EC_SUCCESS, or non-zero if error.
+ */
+int espi_vw_enable_wire_int(enum espi_vw_signal signal)
+{
+ /*
+ * Common code calls this function to enable VW interrupt of power
+ * sequence signal.
+ * IT83xx only use a bit (bit7@IT83XX_ESPI_VWCTRL0) to enable VW
+ * interrupt.
+ * VW interrupt will be triggerd with any updated VW index flag
+ * if this control bit is set.
+ * So we will always return success here.
+ */
+ return EC_SUCCESS;
+}
+
+/**
+ * Disable VW interrupt of power sequence signal
+ *
+ * @param signal vw signal needs to disable interrupt
+ * @return EC_SUCCESS, or non-zero if error.
+ */
+int espi_vw_disable_wire_int(enum espi_vw_signal signal)
+{
+ /*
+ * We can't disable VW interrupt of power sequence signal
+ * individually.
+ */
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+static void espi_vw_host_startup(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vw_host_startup_setting); i++)
+ IT83XX_ESPI_VWIDX(vw_host_startup_setting[i].index) =
+ (vw_host_startup_setting[i].level_mask |
+ vw_host_startup_setting[i].valid_mask);
+}
+
+static void espi_vw_no_isr(uint8_t flag_changed)
+{
+}
+
+static void espi_vw_idx41_isr(uint8_t flag_changed)
+{
+ if (flag_changed & VW_LEVEL_FIELD(VW_IDX_41_SUS_WARN))
+ espi_vw_set_wire(VW_SUS_ACK, espi_vw_get_wire(VW_SUS_WARN_L));
+}
+
+static void espi_vw_idx7_isr(uint8_t flag_changed)
+{
+ if (flag_changed & VW_LEVEL_FIELD(VW_IDX_7_HOST_RST_WARN))
+ espi_vw_set_wire(VW_HOST_RST_ACK,
+ espi_vw_get_wire(VW_HOST_RST_WARN));
+}
+
+static void espi_vw_idx3_isr(uint8_t flag_changed)
+{
+ if (flag_changed & VW_LEVEL_FIELD(VW_IDX_3_PLTRST)) {
+ int pltrst = espi_vw_get_wire(VW_PLTRST_L);
+
+ if (pltrst)
+ espi_vw_host_startup();
+ else
+ /* Store port 80 reset event */
+ port_80_write(PORT_80_EVENT_RESET);
+
+ CPRINTS("PLTRST_L %sasserted", pltrst ? "de" : "");
+ }
+
+ if (flag_changed & VW_LEVEL_FIELD(VW_IDX_3_OOB_RST_WARN))
+ espi_vw_set_wire(VW_OOB_RST_ACK,
+ espi_vw_get_wire(VW_OOB_RST_WARN));
+}
+
+static void espi_vw_idx2_isr(uint8_t flag_changed)
+{
+ if (flag_changed & VW_LEVEL_FIELD(VW_IDX_2_SLP_S3))
+ power_signal_interrupt(VW_SLP_S3_L);
+ if (flag_changed & VW_LEVEL_FIELD(VW_IDX_2_SLP_S4))
+ power_signal_interrupt(VW_SLP_S4_L);
+ if (flag_changed & VW_LEVEL_FIELD(VW_IDX_2_SLP_S5))
+ power_signal_interrupt(VW_SLP_S5_L);
+}
+
+struct vw_interrupt_t {
+ void (*vw_isr)(uint8_t flag_changed);
+ uint8_t vw_index;
+};
+
+static const struct vw_interrupt_t vw_isr_list[CHIP_ESPI_VW_INTERRUPT_NUM] = {
+ {espi_vw_idx2_isr, ESPI_SYSTEM_EVENT_VW_IDX_2},
+ {espi_vw_idx3_isr, ESPI_SYSTEM_EVENT_VW_IDX_3},
+ {espi_vw_idx7_isr, ESPI_SYSTEM_EVENT_VW_IDX_7},
+ {espi_vw_idx41_isr, ESPI_SYSTEM_EVENT_VW_IDX_41},
+ {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_42},
+ {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_43},
+ {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_44},
+ {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_47},
+};
+
+/*
+ * This is used to record the previous VW valid / level field state to discover
+ * changes. Then do following sequence only when state is changed.
+ */
+static uint8_t vw_index_flag[CHIP_ESPI_VW_INTERRUPT_NUM];
+
+void espi_vw_interrupt(void)
+{
+ int i;
+ uint8_t vwidx_updated = IT83XX_ESPI_VWCTRL1;
+
+ /*
+ * TODO(b:68918637): write-1 clear bug.
+ * for now, we have to write 0xff to clear pending bit.
+ */
+#if 0
+ IT83XX_ESPI_VWCTRL1 = vwidx_updated;
+#else
+ IT83XX_ESPI_VWCTRL1 = 0xff;
+#endif
+ task_clear_pending_irq(IT83XX_IRQ_ESPI_VW);
+
+ for (i = 0; i < CHIP_ESPI_VW_INTERRUPT_NUM; i++) {
+ if (vwidx_updated & (1 << i)) {
+ uint8_t idx_flag;
+
+ idx_flag = IT83XX_ESPI_VWIDX(vw_isr_list[i].vw_index);
+ vw_isr_list[i].vw_isr(vw_index_flag[i] ^ idx_flag);
+ vw_index_flag[i] = idx_flag;
+ }
+ }
+}
+
+void espi_interrupt(void)
+{
+}
+
+void espi_init(void)
+{
+ int i;
+
+ /* TODO: PLL change won't success if eSPI chip select is low. */
+#if (PLL_CLOCK != 48000000)
+#error "Not support PLL change if eSPI module is enabled. "
+#endif
+
+ for (i = 0; i < ARRAY_SIZE(vw_init_setting); i++)
+ IT83XX_ESPI_VWIDX(vw_init_setting[i].index) =
+ (vw_init_setting[i].level_mask |
+ vw_init_setting[i].valid_mask);
+
+ for (i = 0; i < CHIP_ESPI_VW_INTERRUPT_NUM; i++)
+ vw_index_flag[i] = IT83XX_ESPI_VWIDX(vw_isr_list[i].vw_index);
+
+ task_clear_pending_irq(IT83XX_IRQ_ESPI_VW);
+ /* bit7: VW interrupt enable */
+ IT83XX_ESPI_VWCTRL0 |= (1 << 7);
+ task_enable_irq(IT83XX_IRQ_ESPI_VW);
+}
diff --git a/chip/it83xx/intc.c b/chip/it83xx/intc.c
index cd4e147d01..a2fd06dea4 100644
--- a/chip/it83xx/intc.c
+++ b/chip/it83xx/intc.c
@@ -106,6 +106,15 @@ void intc_cpu_int_group_12(void)
peci_interrupt();
break;
#endif
+#ifdef CONFIG_ESPI
+ case IT83XX_IRQ_ESPI:
+ espi_interrupt();
+ break;
+
+ case IT83XX_IRQ_ESPI_VW:
+ espi_vw_interrupt();
+ break;
+#endif
#ifdef CONFIG_USB_PD_TCPM_ITE83XX
case IT83XX_IRQ_USBPD0:
chip_pd_irq(USBPD_PORT_A);
diff --git a/chip/it83xx/intc.h b/chip/it83xx/intc.h
index 8c6d35aa02..508b7e0f3b 100644
--- a/chip/it83xx/intc.h
+++ b/chip/it83xx/intc.h
@@ -23,5 +23,8 @@ 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_interrupt(void);
+void espi_vw_interrupt(void);
+void espi_init(void);
#endif /* __CROS_EC_INTC_H */
diff --git a/chip/it83xx/lpc.c b/chip/it83xx/lpc.c
index e1ce1be832..ed83a85c01 100644
--- a/chip/it83xx/lpc.c
+++ b/chip/it83xx/lpc.c
@@ -11,9 +11,11 @@
#include "common.h"
#include "console.h"
#include "ec2i_chip.h"
+#include "espi.h"
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
+#include "intc.h"
#include "irq_chip.h"
#include "keyboard_protocol.h"
#include "lpc.h"
@@ -363,10 +365,12 @@ void lpc_clear_acpi_status_mask(uint8_t mask)
pm_set_status(LPC_ACPI_CMD, mask, 0);
}
+#ifndef CONFIG_ESPI_VW_SIGNALS
int lpc_get_pltrst_asserted(void)
{
return !gpio_get_level(GPIO_PCH_PLTRST_L);
}
+#endif
/* KBC and PMC control modules */
void lpc_kbc_ibf_interrupt(void)
@@ -663,7 +667,9 @@ static void lpc_init(void)
*/
IT83XX_GCTRL_SPCTRL1 |= 0xC2;
+#ifndef CONFIG_ESPI_VW_SIGNALS
gpio_enable_interrupt(GPIO_PCH_PLTRST_L);
+#endif
task_clear_pending_irq(IT83XX_IRQ_KBC_OUT);
task_disable_irq(IT83XX_IRQ_KBC_OUT);
@@ -682,6 +688,9 @@ static void lpc_init(void)
task_clear_pending_irq(IT83XX_IRQ_PMC3_IN);
task_enable_irq(IT83XX_IRQ_PMC3_IN);
+#ifdef CONFIG_ESPI
+ espi_init();
+#endif
/* Sufficiently initialized */
init_done = 1;
@@ -694,6 +703,21 @@ static void lpc_init(void)
*/
DECLARE_HOOK(HOOK_INIT, lpc_init, HOOK_PRIO_INIT_LPC);
+void lpc_host_reset(void)
+{
+ /* Host Reset Control will assert RCIN# */
+#ifdef CONFIG_ESPI_VW_SIGNALS
+ espi_vw_set_wire(VW_RCIN_L, 0);
+ udelay(10);
+ espi_vw_set_wire(VW_RCIN_L, 1);
+#else
+ gpio_set_level(GPIO_PCH_RCIN_L, 0);
+ udelay(10);
+ gpio_set_level(GPIO_PCH_RCIN_L, 1);
+#endif
+}
+
+#ifndef CONFIG_ESPI_VW_SIGNALS
void lpcrst_interrupt(enum gpio_signal signal)
{
if (lpc_get_pltrst_asserted())
@@ -703,6 +727,7 @@ void lpcrst_interrupt(enum gpio_signal signal)
CPRINTS("LPC RESET# %sasserted",
lpc_get_pltrst_asserted() ? "" : "de");
}
+#endif
/* Enable LPC ACPI-EC interrupts */
void lpc_enable_acpi_interrupts(void)
diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h
index 21d8e7fc1a..93417e08b9 100644
--- a/chip/it83xx/registers.h
+++ b/chip/it83xx/registers.h
@@ -761,6 +761,7 @@ enum clock_gate_offsets {
#define IT83XX_GCTRL_RSTS REG8(IT83XX_GCTRL_BASE+0x06)
#define IT83XX_GCTRL_BADRSEL REG8(IT83XX_GCTRL_BASE+0x0A)
#define IT83XX_GCTRL_SPCTRL1 REG8(IT83XX_GCTRL_BASE+0x0D)
+#define IT83XX_GCTRL_RSTDMMC REG8(IT83XX_GCTRL_BASE+0x10)
#define IT83XX_GCTRL_RSTC4 REG8(IT83XX_GCTRL_BASE+0x11)
#define IT83XX_GCTRL_SPCTRL4 REG8(IT83XX_GCTRL_BASE+0x1C)
#define IT83XX_GCTRL_MCCR REG8(IT83XX_GCTRL_BASE+0x30)
@@ -1203,6 +1204,75 @@ enum usbpd_port {
#define USB_VID_ITE 0x048d
+#define IT83XX_ESPI_BASE 0x00F03100
+
+/* eSPI VW */
+#define IT83XX_ESPI_VW_BASE 0x00F03200
+#define IT83XX_ESPI_VWIDX(i) REG8(IT83XX_ESPI_VW_BASE+(i))
+
+#define VW_LEVEL_FIELD(f) ((f) << 0)
+#define VW_VALID_FIELD(f) ((f) << 4)
+
+#define ESPI_SYSTEM_EVENT_VW_IDX_2 0x2
+#define VW_IDX_2_SLP_S3 (1 << 0)
+#define VW_IDX_2_SLP_S4 (1 << 1)
+#define VW_IDX_2_SLP_S5 (1 << 2)
+
+#define ESPI_SYSTEM_EVENT_VW_IDX_3 0x3
+#define VW_IDX_3_SUS_STAT (1 << 0)
+#define VW_IDX_3_PLTRST (1 << 1)
+#define VW_IDX_3_OOB_RST_WARN (1 << 2)
+
+#define ESPI_SYSTEM_EVENT_VW_IDX_4 0x4
+#define VW_IDX_4_OOB_RST_ACK (1 << 0)
+#define VW_IDX_4_WAKE (1 << 2)
+#define VW_IDX_4_PME (1 << 3)
+
+#define ESPI_SYSTEM_EVENT_VW_IDX_5 0x5
+#define VW_IDX_5_SLAVE_BTLD_DONE (1 << 0)
+#define VW_IDX_5_FATAL (1 << 1)
+#define VW_IDX_5_NON_FATAL (1 << 2)
+#define VW_IDX_5_SLAVE_BTLD_STATUS (1 << 3)
+#define VW_IDX_5_BTLD_STATUS_DONE (VW_IDX_5_SLAVE_BTLD_DONE | \
+ VW_IDX_5_SLAVE_BTLD_STATUS)
+
+#define ESPI_SYSTEM_EVENT_VW_IDX_6 0x6
+#define VW_IDX_6_SCI (1 << 0)
+#define VW_IDX_6_SMI (1 << 1)
+#define VW_IDX_6_RCIN (1 << 2)
+#define VW_IDX_6_HOST_RST_ACK (1 << 3)
+
+#define ESPI_SYSTEM_EVENT_VW_IDX_7 0x7
+#define VW_IDX_7_HOST_RST_WARN (1 << 0)
+
+#define ESPI_SYSTEM_EVENT_VW_IDX_40 0x40
+#define VW_IDX_40_SUS_ACK (1 << 0)
+
+#define ESPI_SYSTEM_EVENT_VW_IDX_41 0x41
+#define VW_IDX_41_SUS_WARN (1 << 0)
+#define VW_IDX_41_SUS_PWRDN_ACK (1 << 1)
+#define VW_IDX_41_SLP_A (1 << 3)
+
+#define ESPI_SYSTEM_EVENT_VW_IDX_42 0x42
+#define VW_IDX_42_SLP_LAN (1 << 0)
+#define VW_IDX_42_SLP_WLAN (1 << 1)
+
+#define ESPI_SYSTEM_EVENT_VW_IDX_43 0x43
+#define ESPI_SYSTEM_EVENT_VW_IDX_44 0x44
+#define ESPI_SYSTEM_EVENT_VW_IDX_47 0x47
+
+#define IT83XX_ESPI_VWCTRL0 REG8(IT83XX_ESPI_VW_BASE+0x90)
+#define IT83XX_ESPI_VWCTRL1 REG8(IT83XX_ESPI_VW_BASE+0x91)
+#define IT83XX_ESPI_VWCTRL2 REG8(IT83XX_ESPI_VW_BASE+0x92)
+#define IT83XX_ESPI_VWCTRL3 REG8(IT83XX_ESPI_VW_BASE+0x93)
+
+/* eSPI Queue 0 */
+#define IT83XX_ESPI_QUEUE_BASE 0x00F03300
+/* PUT_PC data byte 0 - 63 */
+#define IT83XX_ESPI_QUEUE_PUT_PC(i) REG8(IT83XX_ESPI_QUEUE_BASE+(i))
+/* PUT_OOB data byte 0 - 79 */
+#define IT83XX_ESPI_QUEUE_PUT_OOB(i) REG8(IT83XX_ESPI_QUEUE_BASE+0x80+(i))
+
/* Wake pin definitions, defined at board-level */
extern const enum gpio_signal hibernate_wake_pins[];
extern const int hibernate_wake_pins_used;
diff --git a/chip/it83xx/uart.c b/chip/it83xx/uart.c
index 91624d4930..24dc2ec4c6 100644
--- a/chip/it83xx/uart.c
+++ b/chip/it83xx/uart.c
@@ -205,6 +205,12 @@ void uart_deepsleep_interrupt(enum gpio_signal signal)
void uart_init(void)
{
+ /*
+ * bit3: uart1 belongs to the EC side.
+ * This is necessary for enabling eSPI module.
+ */
+ IT83XX_GCTRL_RSTDMMC |= (1 << 3);
+
/* reset uart before config it */
IT83XX_GCTRL_RSTC4 |= (1 << 1);