summaryrefslogtreecommitdiff
path: root/chip/it83xx/espi.c
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /chip/it83xx/espi.c
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-252457d4b21f46889eebad61d4c0a65331919cec.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'chip/it83xx/espi.c')
-rw-r--r--chip/it83xx/espi.c624
1 files changed, 0 insertions, 624 deletions
diff --git a/chip/it83xx/espi.c b/chip/it83xx/espi.c
deleted file mode 100644
index 7385e83a93..0000000000
--- a/chip/it83xx/espi.c
+++ /dev/null
@@ -1,624 +0,0 @@
-/* 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"
-
-/* 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 after the controller enables the VW channel. */
-static const struct vw_channel_t en_vw_setting[] = {
- /* EC sends SUS_ACK# = 1 VW to PCH. That does not apply to GLK SoC. */
-#ifndef CONFIG_CHIPSET_GEMINILAKE
- {ESPI_SYSTEM_EVENT_VW_IDX_40,
- VW_LEVEL_FIELD(0),
- VW_VALID_FIELD(VW_IDX_40_SUS_ACK)},
-#endif
-};
-
-/* VW settings after the controller enables the OOB channel. */
-static const struct vw_channel_t en_oob_setting[] = {
- {ESPI_SYSTEM_EVENT_VW_IDX_4,
- VW_LEVEL_FIELD(0),
- VW_VALID_FIELD(VW_IDX_4_OOB_RST_ACK)},
-};
-
-/* VW settings after the controller enables the flash channel. */
-static const struct vw_channel_t en_flash_setting[] = {
- {ESPI_SYSTEM_EVENT_VW_IDX_5,
- VW_LEVEL_FIELD(VW_IDX_5_BTLD_STATUS_DONE),
- VW_VALID_FIELD(VW_IDX_5_BTLD_STATUS_DONE)},
-};
-
-/* 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_START)] = {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: controller to peripheral. */
- 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: controller to peripheral. */
- 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: peripheral to controller. */
- 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: peripheral to controller. */
- 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_PERIPHERAL_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: peripheral to controller. */
- 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: controller to peripheral. */
- 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: peripheral to controller. */
- 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: controller to peripheral. */
- 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: controller to peripheral. */
- 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_COUNT);
-
-/* 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_START;
-
- 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;
-}
-
-/* Configure virtual wire outputs */
-static void espi_configure_vw(const struct vw_channel_t *settings,
- size_t entries)
-{
- size_t i;
-
- for (i = 0; i < entries; i++)
- IT83XX_ESPI_VWIDX(settings[i].index) |=
- (settings[i].level_mask | settings[i].valid_mask);
-}
-
-static void espi_vw_host_startup(void)
-{
- espi_configure_vw(vw_host_startup_setting,
- ARRAY_SIZE(vw_host_startup_setting));
-}
-
-static void espi_vw_no_isr(uint8_t flag_changed, uint8_t vw_evt)
-{
- CPRINTS("espi VW interrupt event is ignored! (bit%d at VWCTRL1)",
- vw_evt);
-}
-
-#ifndef CONFIG_CHIPSET_GEMINILAKE
-static void espi_vw_idx41_isr(uint8_t flag_changed, uint8_t vw_evt)
-{
- 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));
-}
-#endif
-
-static void espi_vw_idx7_isr(uint8_t flag_changed, uint8_t vw_evt)
-{
- 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));
-}
-
-#ifdef CONFIG_CHIPSET_RESET_HOOK
-static void espi_chipset_reset(void)
-{
- hook_notify(HOOK_CHIPSET_RESET);
-}
-DECLARE_DEFERRED(espi_chipset_reset);
-#endif
-
-static void espi_vw_idx3_isr(uint8_t flag_changed, uint8_t vw_evt)
-{
- 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 {
-#ifdef CONFIG_CHIPSET_RESET_HOOK
- hook_call_deferred(&espi_chipset_reset_data, MSEC);
-#endif
- /* Store port 80 reset event */
- port_80_write(PORT_80_EVENT_RESET);
- }
-
- CPRINTS("VW 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, uint8_t vw_evt)
-{
- 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_evt);
- uint8_t vw_index;
-};
-
-/*
- * The ISR of espi VW interrupt in array needs to match bit order in
- * IT83XX_ESPI_VWCTRL1 register.
- */
-#ifdef CONFIG_CHIPSET_GEMINILAKE
-static const struct vw_interrupt_t vw_isr_list[] = {
- [0] = {espi_vw_idx2_isr, ESPI_SYSTEM_EVENT_VW_IDX_2},
- [1] = {espi_vw_idx3_isr, ESPI_SYSTEM_EVENT_VW_IDX_3},
- [2] = {espi_vw_idx7_isr, ESPI_SYSTEM_EVENT_VW_IDX_7},
- [3] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_41},
- [4] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_42},
- [5] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_43},
- [6] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_44},
- [7] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_47},
-};
-#else
-static const struct vw_interrupt_t vw_isr_list[] = {
- [0] = {espi_vw_idx2_isr, ESPI_SYSTEM_EVENT_VW_IDX_2},
- [1] = {espi_vw_idx3_isr, ESPI_SYSTEM_EVENT_VW_IDX_3},
- [2] = {espi_vw_idx7_isr, ESPI_SYSTEM_EVENT_VW_IDX_7},
- [3] = {espi_vw_idx41_isr, ESPI_SYSTEM_EVENT_VW_IDX_41},
- [4] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_42},
- [5] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_43},
- [6] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_44},
- [7] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_47},
-};
-#endif
-
-/*
- * 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[ARRAY_SIZE(vw_isr_list)];
-
-void espi_vw_interrupt(void)
-{
- int i;
- uint8_t vwidx_updated = IT83XX_ESPI_VWCTRL1;
-
-#ifdef IT83XX_ESPI_VWCTRL1_WRITE_FF_CLEAR
- /* For IT8320BX, we have to write 0xff to clear pending bit.*/
- IT83XX_ESPI_VWCTRL1 = 0xff;
-#else
- /* write-1 to clear */
- IT83XX_ESPI_VWCTRL1 = vwidx_updated;
-#endif
- task_clear_pending_irq(IT83XX_IRQ_ESPI_VW);
-
- for (i = 0; i < ARRAY_SIZE(vw_isr_list); i++) {
- if (vwidx_updated & BIT(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, i);
- vw_index_flag[i] = idx_flag;
- }
- }
-}
-
-static void espi_reset_vw_index_flags(void)
-{
- int i;
-
- /* reset vw_index_flag */
- for (i = 0; i < ARRAY_SIZE(vw_isr_list); i++)
- 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) | BIT(6);
-}
-#endif
-
-void espi_reset_pin_asserted_interrupt(enum gpio_signal signal)
-{
-#ifdef IT83XX_ESPI_RESET_MODULE_BY_FW
- espi_fw_reset_module();
- /*
- * bit[7], enable P80L function.
- * bit[6], accept port 80h cycle.
- * bit[1-0], 10b: I2EC is read-only.
- */
- IT83XX_GCTRL_SPCTRL1 |= 0xC2;
-#endif
- /* reset vw_index_flag when espi_reset# asserted. */
- espi_reset_vw_index_flags();
-}
-
-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.
- * 10b: espi_reset# is enabled on GPD2.
- * 11b: reset is disabled.
- */
- if (espi_rst->port == GPIO_D && espi_rst->mask == BIT(2)) {
- config = IT83XX_GPIO_GCR_LPC_RST_D2;
- } else if (espi_rst->port == GPIO_B && espi_rst->mask == BIT(7)) {
- config = IT83XX_GPIO_GCR_LPC_RST_B7;
- } else {
- 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);
-}
-
-/* Interrupt event of controller enables the VW channel. */
-static void espi_vw_en_asserted(uint8_t evt)
-{
- /*
- * Configure peripheral to controller virtual wire outputs after
- * receiving the event of controller enables the VW channel.
- */
- espi_configure_vw(en_vw_setting, ARRAY_SIZE(en_vw_setting));
-}
-
-/* Interrupt event of controller enables the OOB channel. */
-static void espi_oob_en_asserted(uint8_t evt)
-{
- /*
- * Configure peripheral to controller virtual wire outputs after
- * receiving the event of controller enables the OOB channel.
- */
- espi_configure_vw(en_oob_setting, ARRAY_SIZE(en_oob_setting));
-}
-
-/* Interrupt event of controller enables the flash channel. */
-static void espi_flash_en_asserted(uint8_t evt)
-{
- /*
- * Configure peripheral to controller virtual wire outputs after
- * receiving the event of controller enables the flash channel.
- */
- espi_configure_vw(en_flash_setting, ARRAY_SIZE(en_flash_setting));
-}
-
-static void espi_no_isr(uint8_t evt)
-{
- CPRINTS("espi interrupt event is ignored! (bit%d at ESGCTRL0)", evt);
-}
-
-/*
- * The ISR of espi interrupt event in array need to be matched bit order in
- * IT83XX_ESPI_ESGCTRL0 register.
- */
-static void (*espi_isr[])(uint8_t evt) = {
- [0] = espi_no_isr,
- [1] = espi_vw_en_asserted,
- [2] = espi_oob_en_asserted,
- [3] = espi_flash_en_asserted,
- [4] = espi_no_isr,
- [5] = espi_no_isr,
- [6] = espi_no_isr,
- [7] = espi_no_isr,
-};
-
-void espi_interrupt(void)
-{
- int i;
- /* get espi interrupt events */
- uint8_t espi_event = IT83XX_ESPI_ESGCTRL0;
-
- /* write-1 to clear */
- IT83XX_ESPI_ESGCTRL0 = espi_event;
- /* process espi interrupt events */
- for (i = 0; i < ARRAY_SIZE(espi_isr); i++) {
- if (espi_event & BIT(i))
- espi_isr[i](i);
- }
- /*
- * bit7: the peripheral has received a peripheral posted/completion.
- * This bit indicates the peripheral has received a packet from eSPI
- * peripheral channel. We can check cycle type (bit[3-0] at ESPCTRL0)
- * and make corresponding modification if needed.
- */
- if (IT83XX_ESPI_ESPCTRL0 & ESPI_INTERRUPT_EVENT_PUT_PC) {
- /* write-1-clear to release PC_FREE */
- IT83XX_ESPI_ESPCTRL0 = ESPI_INTERRUPT_EVENT_PUT_PC;
- CPRINTS("A packet from peripheral channel is ignored!");
- }
-
- task_clear_pending_irq(IT83XX_IRQ_ESPI);
-}
-
-#ifdef IT83XX_ESPI_INHIBIT_CS_BY_PAD_DISABLED
-/* Enable/Disable eSPI pad */
-void espi_enable_pad(int enable)
-{
- if (enable)
- /* Enable eSPI pad. */
- IT83XX_ESPI_ESGCTRL2 &= ~BIT(6);
- else
- /* Disable eSPI pad. */
- IT83XX_ESPI_ESGCTRL2 |= BIT(6);
-}
-#endif
-
-void espi_init(void)
-{
- /*
- * bit[2-0], the maximum frequency of operation supported by peripheral:
- * 000b: 20MHz
- * 001b: 25MHz
- * 010b: 33MHz
- * 011b: 50MHz
- * 100b: 66MHz
- */
-#ifdef IT83XX_ESPI_PERIPHERAL_MAX_FREQ_CONFIGURABLE
- IT83XX_ESPI_GCAC1 = (IT83XX_ESPI_GCAC1 & ~0x7) | BIT(2);
-#endif
- /* reset vw_index_flag at initialization */
- espi_reset_vw_index_flags();
-
- /*
- * bit[3]: The reset source of PNPCFG is RSTPNP bit in RSTCH
- * register and WRST#.
- */
- IT83XX_GCTRL_RSTS &= ~BIT(3);
- task_clear_pending_irq(IT83XX_IRQ_ESPI_VW);
- /* bit7: VW interrupt enable */
- IT83XX_ESPI_VWCTRL0 |= BIT(7);
- task_enable_irq(IT83XX_IRQ_ESPI_VW);
-
- /* bit7: eSPI interrupt enable */
- IT83XX_ESPI_ESGCTRL1 |= BIT(7);
- /* bit4: eSPI to WUC enable */
- IT83XX_ESPI_ESGCTRL2 |= BIT(4);
- task_enable_irq(IT83XX_IRQ_ESPI);
-
- /* enable interrupt and reset from eSPI_reset# */
- espi_enable_reset();
-}