summaryrefslogtreecommitdiff
path: root/chip/it83xx/espi.c
diff options
context:
space:
mode:
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();
-}