diff options
Diffstat (limited to 'chip/it83xx/espi.c')
-rw-r--r-- | chip/it83xx/espi.c | 624 |
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(); -} |