diff options
author | Mulin Chao <mlchao@nuvoton.com> | 2016-08-04 11:20:45 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-08-10 22:16:57 -0700 |
commit | ef6e93dc1bbf92821c9d3ff149f691fbdad1c015 (patch) | |
tree | 793e53f708df2537811314916ca00e43e269cb50 /chip | |
parent | a625b710c3e4d64a659ae20682b85dd552657b6c (diff) | |
download | chrome-ec-ef6e93dc1bbf92821c9d3ff149f691fbdad1c015.tar.gz |
npcx: Add espi driver of npcx5mng for x86-based platform.
Add espi driver for x86-based platform which support espi interface such
as skylake and so on.
Added source:
1. espi.c: Add drivers which supports the utilities of peripheral and
virtual-wire channels so far.
2. espi.h: Add espi virtual-wire declaration for power sequence FW.
Modified sources:
1. lpc.c: Add interrupts and initialization steps for espi.
2. gpio.c: Add interrupt handler of espi reset.
BRANCH=none
BUG=chrome-os-partner:34346
TEST=make buildall -j; test nuvoton IC specific drivers
Change-Id: Ie80afe79d85aba47fc0b72898a8374c2898ec114
Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
Reviewed-on: https://chromium-review.googlesource.com/366181
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/npcx/build.mk | 1 | ||||
-rw-r--r-- | chip/npcx/espi.c | 656 | ||||
-rw-r--r-- | chip/npcx/gpio.c | 19 | ||||
-rw-r--r-- | chip/npcx/lpc.c | 40 | ||||
-rw-r--r-- | chip/npcx/lpc_chip.h | 13 | ||||
-rw-r--r-- | chip/npcx/registers.h | 201 |
6 files changed, 919 insertions, 11 deletions
diff --git a/chip/npcx/build.mk b/chip/npcx/build.mk index 8240634be6..bf0ddf69d7 100644 --- a/chip/npcx/build.mk +++ b/chip/npcx/build.mk @@ -20,6 +20,7 @@ chip-$(CONFIG_FANS)+=fan.o chip-$(CONFIG_FLASH)+=flash.o chip-$(CONFIG_I2C)+=i2c.o chip-$(CONFIG_LPC)+=lpc.o +chip-$(CONFIG_ESPI)+=espi.o chip-$(CONFIG_PECI)+=peci.o chip-$(CONFIG_HOSTCMD_SPS)+=shi.o # pwm functions are implemented with the fan functions diff --git a/chip/npcx/espi.c b/chip/npcx/espi.c new file mode 100644 index 0000000000..f998c7bb16 --- /dev/null +++ b/chip/npcx/espi.c @@ -0,0 +1,656 @@ +/* Copyright (c) 2016 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 "registers.h" +#include "system.h" +#include "task.h" +#include "console.h" +#include "uart.h" +#include "util.h" +#include "power.h" +#include "espi.h" +#include "lpc_chip.h" + +/* Console output macros */ +#if !(DEBUG_ESPI) +#define CPUTS(...) +#define CPRINTS(...) +#else +#define CPUTS(outstr) cputs(CC_LPC, outstr) +#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args) +#endif + +/* Default eSPI configuration for VW events */ +struct vwevms_config_t { + uint8_t idx; /* VW index */ + uint8_t idx_en; /* Index enable */ + uint8_t pltrst_en; /* Enable reset by PLTRST assert */ + uint8_t espirst_en; /* Enable reset by eSPI_RST assert */ + uint8_t int_en; /* Interrupt/Wake-up enable */ +}; + +struct vwevsm_config_t { + uint8_t idx; /* VW index */ + uint8_t idx_en; /* Index enable */ + uint8_t pltrst_en; /* Enable reset by PLTRST assert */ + uint8_t cdrst_en; /* Enable cold reset */ + uint8_t valid; /* Valid VW mask */ +}; + +/* Default MIWU configurations for VW events */ +struct host_wui_item { + uint16_t table : 2; /* MIWU table 0-2 */ + uint16_t group : 3; /* MIWU group 0-7 */ + uint16_t num : 3; /* MIWU bit 0-7 */ + uint16_t edge : 4; /* MIWU edge trigger type rising/falling/any */ +}; + +/* Mapping item between VW signal, index and value */ +struct vw_event_t { + uint16_t name; /* Name of signal */ + uint8_t evt_idx; /* VW index of signal */ + uint8_t evt_val; /* VW value of signal */ +}; + +/* Default settings of VWEVMS registers (Please refer Table.43/44) */ +static const struct vwevms_config_t espi_in_list[] = { + /*IDX EN ENPL ENESP IE VW Event Bit 3 -0 (M->S) */ + {0x02, 1, 0, 0, 0}, /* SLP_S3#, SLP_S4#, SLP_S5, Reserve */ + {0x03, 1, 0, 1, 0}, /* SUS_STAT#, PLTRST#, ORST_WARN, Reserve */ + {0x07, 1, 1, 1, 0}, /* HRST_WARN, SMIOUT#, NMIOUT#, Reserve */ + {0x41, 1, 0, 1, 0}, /* SUS_WARN#, SPWRDN_ACK, Reserve, SLP_A# */ + {0x42, 1, 0, 0, 0}, /* SLP_LAN#, SLP_WAN#, Reserve, Reserve */ + {0x47, 1, 1, 1, 0}, /* HOST_C10, Reserve, Reserve, Reserve */ +}; + +/* Default settings of VWEVSM registers (Please refer Table.43/44) */ +static const struct vwevsm_config_t espi_out_list[] = { + /*IDX EN ENPL ENCDR VDMASK VW Event Bit 3 -0 (S->M) */ + {0x04, 1, 0, 0, 0x0D}, /* PME#, WAKE#, Reserve, ORST_ACK */ + {0x05, 1, 0, 0, 0x0F}, /* SLV_BL_STS, ERR_NF, ERR_F, SLV_BL_DONE*/ + {0x06, 1, 1, 0, 0x0C}, /* HRST_ACK, RCIN#, SMI#, SCI# */ + {0x40, 1, 0, 0, 0x01}, /* Reserve, Reserve, Reserve, SUS_ACK# */ +}; + +/* eSPI interrupts used in MIWU */ +static const struct host_wui_item espi_vw_int_list[] = { + /* ESPI_RESET */ + {MIWU_TABLE_0, MIWU_GROUP_5, 5, MIWU_EDGE_RISING}, + /* SLP_S3 */ + {MIWU_TABLE_2, MIWU_GROUP_1, 0, MIWU_EDGE_ANYING}, + /* SLP_S4 */ + {MIWU_TABLE_2, MIWU_GROUP_1, 1, MIWU_EDGE_ANYING}, + /* SLP_S5 */ + {MIWU_TABLE_2, MIWU_GROUP_1, 2, MIWU_EDGE_ANYING}, + /* VW_WIRE_PLTRST */ + {MIWU_TABLE_2, MIWU_GROUP_1, 5, MIWU_EDGE_RISING}, + /* VW_WIRE_OOB_RST_WARN */ + {MIWU_TABLE_2, MIWU_GROUP_1, 6, MIWU_EDGE_ANYING}, + /* VW_WIRE_HOST_RST_WARN */ + {MIWU_TABLE_2, MIWU_GROUP_2, 0, MIWU_EDGE_ANYING}, + /* VW_WIRE_SUS_WARN */ + {MIWU_TABLE_2, MIWU_GROUP_2, 4, MIWU_EDGE_RISING}, +}; + +/* VW signals used in eSPI */ +static const struct vw_event_t vw_events_list[] = { + {VW_SLP_S3_L, 0x02, 0x01}, /* index 02h (In) */ + {VW_SLP_S4_L, 0x02, 0x02}, + {VW_SLP_S5_L, 0x02, 0x04}, + {VW_SUS_STAT_L, 0x03, 0x01}, /* index 03h (In) */ + {VW_PLTRST_L, 0x03, 0x02}, + {VW_OOB_RST_WARN, 0x03, 0x04}, + {VW_OOB_RST_ACK, 0x04, 0x01}, /* index 04h (Out) */ + {VW_WAKE_L, 0x04, 0x04}, + {VW_PME_L, 0x04, 0x08}, + {VW_ERROR_FATAL, 0x05, 0x02}, /* index 05h (Out) */ + {VW_ERROR_NON_FATAL, 0x05, 0x04}, + {VW_SLAVE_BTLD_STATUS_DONE, 0x05, 0x09}, + {VW_SCI_L, 0x06, 0x01}, /* index 06h (Out) */ + {VW_SMI_L, 0x06, 0x02}, + {VW_RCIN_L, 0x06, 0x04}, + {VW_HOST_RST_ACK, 0x06, 0x08}, + {VW_HOST_RST_WARN, 0x07, 0x01}, /* index 07h (In) */ + {VW_SUS_ACK, 0x40, 0x01}, /* index 40h (Out) */ + {VW_SUS_WARN_L, 0x41, 0x01}, /* index 41h (In) */ + {VW_SUS_PWRDN_ACK_L, 0x41, 0x02}, + {VW_SLP_A_L, 0x41, 0x08}, + {VW_SLP_LAN, 0x42, 0x01}, /* index 42h (In) */ + {VW_SLP_WLAN, 0x42, 0x02}, +}; + +/* Flag for SLAVE_BOOT_LOAD siganls */ +static uint8_t boot_load_done; + +/*****************************************************************************/ +/* eSPI internal utilities */ + +/* Recovery utility for eSPI reset */ +static void espi_reset_recovery(void) +{ + /* TODO: Put recovery stuff related to eSPI reset here */ + + /* Clear boot load flag */ + boot_load_done = 0; +} + +/* Configure Master-to-Slave virtual wire inputs */ +static void espi_vw_config_in(const struct vwevms_config_t *config) +{ + uint32_t val; + uint8_t i, index; + + switch (VM_TYPE(config->idx)) { + case ESPI_VW_TYPE_SYS_EV: + case ESPI_VW_TYPE_PLT: + for (i = 0; i < ESPI_VWEVMS_NUM; i++) { + index = VWEVMS_IDX_GET(NPCX_VWEVMS(i)); + /* Set VW input register */ + if (index == config->idx) { + /* Get Wire field */ + val = NPCX_VWEVMS(i) & 0x0F; + val |= VWEVMS_FIELD(config->idx, + config->idx_en, + config->pltrst_en, + config->int_en, + config->espirst_en); + NPCX_VWEVMS(i) = val; + return; + } + } + CPRINTS("No match index of all VWEVMSs"); + break; + default: + CPRINTS("No support type of VWEVMS"); + break; + } +} + +/* Configure Slave-to-Master virtual wire outputs */ +static void espi_vw_config_out(const struct vwevsm_config_t *config) +{ + uint32_t val; + uint8_t i, index; + + switch (VM_TYPE(config->idx)) { + case ESPI_VW_TYPE_SYS_EV: + case ESPI_VW_TYPE_PLT: + for (i = 0; i < ESPI_VWEVSM_NUM; i++) { + index = VWEVSM_IDX_GET(NPCX_VWEVSM(i)); + /* Set VW output register */ + if (index == config->idx) { + /* Get Wire field */ + val = NPCX_VWEVSM(i) & 0x0F; + val |= VWEVSM_FIELD(config->idx, + config->idx_en, + config->valid, + config->pltrst_en, + config->cdrst_en); + NPCX_VWEVSM(i) = val; + return; + } + } + CPRINTS("No match index of all VWEVSMs"); + break; + default: + CPRINTS("No support type of VWEVSM"); + break; + } +} + +/* Config Master-to-Slave VWire interrupt edge type and enable it */ +static void espi_enable_vw_int(const struct host_wui_item *vwire_int) +{ + uint8_t table = vwire_int->table; + uint8_t group = vwire_int->group; + uint8_t num = vwire_int->num; + uint8_t edge = vwire_int->edge; + + /* Set detection mode to edge */ + CLEAR_BIT(NPCX_WKMOD(table, group), num); + + if (edge != MIWU_EDGE_ANYING) { + /* Disable Any Edge */ + CLEAR_BIT(NPCX_WKAEDG(table, group), num); + /* Enable Rising Edge */ + if (edge == MIWU_EDGE_RISING) + CLEAR_BIT(NPCX_WKEDG(table, group), num); + /* Enable Falling Edge */ + else + SET_BIT(NPCX_WKEDG(table, group), num); + } else + /* enable Any Edge */ + SET_BIT(NPCX_WKAEDG(table, group), num); + + /* Enable wake-up input sources */ + SET_BIT(NPCX_WKEN(table, group), num); +} + +/* Get vw index & value information by signal */ +static int espi_vw_get_signal_index(enum espi_vw_signal event) +{ + int index; + + /* Find the vw index by signal name first */ + for (index = 0; index < ARRAY_SIZE(vw_events_list); index++) { + if (vw_events_list[index].name == event) + break; + } + /* Cannot find the index */ + if (index == ARRAY_SIZE(vw_events_list)) + return -1; + + return index; +} + +/* The ISRs of VW signals which used for power sequences */ +void espi_vw_power_signal_interrupt(enum espi_vw_signal signal) +{ + /* TODO: Add VW handler in power/common.c */ + power_signal_interrupt((enum gpio_signal) signal); +} + +/*****************************************************************************/ +/* IC specific low-level driver */ + +/** + * 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) +{ + uint8_t offset, sig_idx, value; + + /* Get index of vw signal list by signale name */ + sig_idx = espi_vw_get_signal_index(signal); + + /* Cannot find index by signal name */ + if (sig_idx < 0) + return EC_ERROR_PARAM1; + + /* Find the output register offset by vw index */ + for (offset = 0; offset < ESPI_VWEVSM_NUM; offset++) { + uint8_t vw_idx = VWEVSM_IDX_GET(NPCX_VWEVSM(offset)); + /* If index matches. break */ + if (vw_idx == vw_events_list[sig_idx].evt_idx) + break; + } + + /* Cannot match index */ + if (offset == ESPI_VWEVSM_NUM) + return EC_ERROR_PARAM1; + + value = GET_FIELD(NPCX_VWEVSM(offset), NPCX_VWEVSM_WIRE); + /* Set wire */ + if (level) + value |= vw_events_list[sig_idx].evt_val; + else /* Clear wire */ + value &= (~vw_events_list[sig_idx].evt_val); + + SET_FIELD(NPCX_VWEVSM(offset), NPCX_VWEVSM_WIRE, value); + + 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) +{ + uint8_t offset, sig_idx, value; + + /* Get index of vw signal list by signale name */ + sig_idx = espi_vw_get_signal_index(signal); + + /* Cannot find index by signal name */ + if (sig_idx < 0) + return -1; + + /* Find the input register offset by vw index */ + for (offset = 0; offset < ESPI_VWEVMS_NUM; offset++) { + uint8_t vw_idx = VWEVMS_IDX_GET(NPCX_VWEVMS(offset)); + /* If index matches. break */ + if (vw_idx == vw_events_list[sig_idx].evt_idx) + break; + } + + /* Cannot match index */ + if (offset == ESPI_VWEVMS_NUM) + return -1; + + /* Get wire & check with valid bits */ + value = GET_FIELD(NPCX_VWEVMS(offset), NPCX_VWEVMS_WIRE); + value &= GET_FIELD(NPCX_VWEVMS(offset), NPCX_VWEVMS_VALID); + + return !!(value & vw_events_list[sig_idx].evt_val); +} + +/** + * 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) +{ + if (signal == VW_SLP_S3_L) + SET_BIT(NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_1), 0); + else if (signal == VW_SLP_S4_L) + SET_BIT(NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_1), 1); + else if (signal == VW_SLP_S5_L) + SET_BIT(NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_1), 2); + else + return EC_ERROR_PARAM1; + + 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) +{ + if (signal == VW_SLP_S3_L) + CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_1), 0); + else if (signal == VW_SLP_S4_L) + CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_1), 1); + else if (signal == VW_SLP_S5_L) + CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_1), 2); + else + return EC_ERROR_PARAM1; + + return EC_SUCCESS; +} + +/*****************************************************************************/ +/* VW event handlers */ + +/* PLTRST# event handler */ +void espi_vw_evt_pltrst(void) +{ + CPRINTS("VW PLTRST: %d", espi_vw_get_wire(VW_PLTRST_L)); + + /* Disable eSPI peripheral channel support first */ + CLEAR_BIT(NPCX_ESPICFG, NPCX_ESPICFG_PCCHN_SUPP); + + /* Enable eSPI peripheral channel */ + SET_BIT(NPCX_ESPICFG, NPCX_ESPICFG_PCHANEN); + /* Initialize host settings */ + host_register_init(); + + /* Re-enable eSPI peripheral channel support */ + SET_BIT(NPCX_ESPICFG, NPCX_ESPICFG_PCCHN_SUPP); + +#ifdef CONFIG_CHIPSET_RESET_HOOK + if (lpc_get_pltrst_asserted()) { + /* Notify HOOK_CHIPSET_RESET */ + hook_call_deferred(lpc_chipset_reset, MSEC); + } +#endif +} + +/* SLP_Sx event handler */ +void espi_vw_evt_slp_s3(void) +{ + CPRINTS("VW SLP_S3: %d", espi_vw_get_wire(VW_SLP_S3_L)); + espi_vw_power_signal_interrupt(VW_SLP_S3_L); +} + +void espi_vw_evt_slp_s4(void) +{ + CPRINTS("VW SLP_S4: %d", espi_vw_get_wire(VW_SLP_S4_L)); + espi_vw_power_signal_interrupt(VW_SLP_S4_L); +} + +void espi_vw_evt_slp_s5(void) +{ + CPRINTS("VW SLP_S5: %d", espi_vw_get_wire(VW_SLP_S5_L)); + espi_vw_power_signal_interrupt(VW_SLP_S5_L); +} + +/* OOB Reset event handler */ +void espi_vw_evt_oobrst(void) +{ + CPRINTS("VW OOB_RST: %d", espi_vw_get_wire(VW_OOB_RST_WARN)); + + /* Send ACK to host by WARN#'s wire */ + espi_vw_set_wire(VW_OOB_RST_ACK, espi_vw_get_wire(VW_OOB_RST_WARN)); +} + +/* SUS_WARN# event handler */ +void espi_vw_evt_sus_warn(void) +{ + CPRINTS("VW SUS_WARN#: %d", espi_vw_get_wire(VW_SUS_WARN_L)); + + udelay(100); + + /* Send ACK to host by WARN#'s wire */ + espi_vw_set_wire(VW_SUS_ACK, espi_vw_get_wire(VW_SUS_WARN_L)); +} + +/* HOSTRST WARN event handler */ +void espi_vw_evt_hostrst_warn(void) +{ + CPRINTS("VW HOST_RST_WARN#: %d", espi_vw_get_wire(VW_HOST_RST_WARN)); + + /* Send ACK to host by WARN#'s wire */ + espi_vw_set_wire(VW_HOST_RST_ACK, espi_vw_get_wire(VW_HOST_RST_WARN)); +} + +/*****************************************************************************/ +/* Interrupt handlers */ + +/* eSPI reset assert/de-assert interrupt */ +void espi_espirst_handler(void) +{ + /* Clear pending bit of WUI */ + SET_BIT(NPCX_WKPCL(MIWU_TABLE_0, MIWU_GROUP_5), 5); + + CPRINTS("eSPI RST issued!"); +} + +/* Handle eSPI virtual wire interrupt 1 */ +void __espi_wk2a_interrupt(void) +{ + uint8_t pending_bits = NPCX_WKPND(MIWU_TABLE_2, MIWU_GROUP_1); + + /* Clear pending bits of MIWU */ + NPCX_WKPCL(MIWU_TABLE_2, MIWU_GROUP_1) = pending_bits; + + /* Handle events of virtual-wire */ + if (IS_BIT_SET(pending_bits, 0)) + espi_vw_evt_slp_s3(); + if (IS_BIT_SET(pending_bits, 1)) + espi_vw_evt_slp_s4(); + if (IS_BIT_SET(pending_bits, 2)) + espi_vw_evt_slp_s5(); + if (IS_BIT_SET(pending_bits, 5)) + espi_vw_evt_pltrst(); + if (IS_BIT_SET(pending_bits, 6)) + espi_vw_evt_oobrst(); +} +DECLARE_IRQ(NPCX_IRQ_WKINTA_2, __espi_wk2a_interrupt, 2); + +/* Handle eSPI virtual wire interrupt 2 */ +void __espi_wk2b_interrupt(void) +{ + uint8_t pending_bits = NPCX_WKPND(MIWU_TABLE_2, MIWU_GROUP_2); + + /* Clear pending bits of MIWU */ + NPCX_WKPCL(MIWU_TABLE_2, MIWU_GROUP_2) = pending_bits; + + /* Handle events of virtual-wire */ + if (IS_BIT_SET(pending_bits, 4)) + espi_vw_evt_sus_warn(); + if (IS_BIT_SET(pending_bits, 0)) + espi_vw_evt_hostrst_warn(); +} +DECLARE_IRQ(NPCX_IRQ_WKINTB_2, __espi_wk2b_interrupt, 2); + +/* Interrupt handler for eSPI status changed */ +void espi_interrupt(void) +{ + int chan; + uint32_t mask, status; + + mask = NPCX_ESPIIE; + status = NPCX_ESPISTS & mask; + + while (status) { + /* Clear pending bits first */ + NPCX_ESPISTS = status; + + if (IS_BIT_SET(status, NPCX_ESPISTS_BERR)) + CPRINTS("eSPI Bus Error"); + + /* eSPI inband reset(from VW) */ + if (IS_BIT_SET(status, NPCX_ESPISTS_IBRST)) { + CPRINTS("eSPI RST inband RST"); + espi_reset_recovery(); + + } /* eSPI reset (from eSPI_rst pin) */ + else if (IS_BIT_SET(status, NPCX_ESPISTS_ESPIRST)) { + CPRINTS("eSPI RST"); + espi_reset_recovery(); + } + + /* eSPI configuration is updated */ + if (IS_BIT_SET(status, NPCX_ESPISTS_CFGUPD)) { + /* + * If host enable/disable channel for VW/OOB/FLASH, EC + * should follow except Peripheral channel. It is + * handled by PLTRST separately. + */ + for (chan = NPCX_ESPI_CH_VW; chan < NPCX_ESPI_CH_COUNT; + chan++) { + if (!IS_SLAVE_CHAN_ENABLE(chan) && + IS_HOST_CHAN_EN(chan)) + ENABLE_ESPI_CHAN(chan); + else if (IS_SLAVE_CHAN_ENABLE(chan) && + !IS_HOST_CHAN_EN(chan)) + DISABLE_ESPI_CHAN(chan); + } + + /* + * Send SLAVE_BOOTLOAD_DONE and SLAVE_BOOTLOAD_STATUS + * events to host simultaneously. To indicate the + * completion of EC firmware code loading. + */ + if (boot_load_done == 0 && + IS_SLAVE_CHAN_ENABLE(NPCX_ESPI_CH_VW)) { + + espi_vw_set_wire(VW_SLAVE_BTLD_STATUS_DONE, 1); + boot_load_done = 1; + } + } + + /* Any VW signal sent by Host - leave it, handle in MIWU ISR */ + if (IS_BIT_SET(status, NPCX_ESPISTS_VWUPD)) + CPRINTS("VW Updated INT"); + + /* Get status again */ + status = NPCX_ESPISTS & mask; + } +} +DECLARE_IRQ(NPCX_IRQ_ESPI, espi_interrupt, 3); + +/*****************************************************************************/ +/* eSPI Initialization functions */ +void espi_init(void) +{ + int i; + + /* Support all channels */ + NPCX_ESPICFG |= ESPI_SUPP_CH_ALL; + + /* Support all I/O modes */ + SET_FIELD(NPCX_ESPICFG, NPCX_ESPICFG_IOMODE_FILED, + NPCX_ESPI_IO_MODE_ALL); + + /* Max freq 66 MHz of eSPI */ + SET_FIELD(NPCX_ESPICFG, NPCX_ESPICFG_MAXFREQ_FILED, + NPCX_ESPI_MAXFREQ_66); + + /* Configure Master-to-Slave Virtual Wire indexes (Inputs) */ + for (i = 0; i < ARRAY_SIZE(espi_in_list); i++) + espi_vw_config_in(&espi_in_list[i]); + + /* Configure Slave-to-Master Virtual Wire indexes (Outputs) */ + for (i = 0; i < ARRAY_SIZE(espi_out_list); i++) + espi_vw_config_out(&espi_out_list[i]); + + /* Configure MIWU for eSPI VW */ + for (i = 0; i < ARRAY_SIZE(espi_vw_int_list); i++) + espi_enable_vw_int(&espi_vw_int_list[i]); +} + +static int command_espi(int argc, char **argv) +{ + uint32_t chan; + char *e; + + if (argc == 1) { + return EC_ERROR_INVAL; + /* Get value of eSPI registers */ + } else if (argc == 2) { + int i; + + if (strcasecmp(argv[1], "cfg") == 0) { + ccprintf("ESPICFG [0x%08x]\n", NPCX_ESPICFG); + } else if (strcasecmp(argv[1], "vsm") == 0) { + for (i = 0; i < ESPI_VWEVSM_NUM; i++) { + uint32_t val = NPCX_VWEVSM(i); + uint8_t idx = VWEVSM_IDX_GET(val); + + ccprintf("VWEVSM%d: %02x [0x%08x]\n", i, idx, + val); + } + } else if (strcasecmp(argv[1], "vms") == 0) { + for (i = 0; i < ESPI_VWEVMS_NUM; i++) { + uint32_t val = NPCX_VWEVMS(i); + uint8_t idx = VWEVMS_IDX_GET(val); + + ccprintf("VWEVMS%d: %02x [0x%08x]\n", i, idx, + val); + } + } + /* Enable/Disable the channels of eSPI */ + } else if (argc == 3) { + uint32_t m = (uint32_t) strtoi(argv[2], &e, 0); + + if (*e) + return EC_ERROR_PARAM2; + if (m < 0 || m > 4) + return EC_ERROR_PARAM2; + else if (m == 4) + chan = 0x0F; + else + chan = 0x01 << m; + if (strcasecmp(argv[1], "en") == 0) + NPCX_ESPICFG = NPCX_ESPICFG | chan; + else if (strcasecmp(argv[1], "dis") == 0) + NPCX_ESPICFG = NPCX_ESPICFG & ~chan; + else + return EC_ERROR_PARAM1; + ccprintf("ESPICFG [0x%08x]\n", NPCX_ESPICFG); + } + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(espi, command_espi, + "cfg/vms/vsm/en/dis [channel]", + "eSPI configurations", + NULL); + diff --git a/chip/npcx/gpio.c b/chip/npcx/gpio.c index b5bf0f80c3..1d701203c7 100644 --- a/chip/npcx/gpio.c +++ b/chip/npcx/gpio.c @@ -786,18 +786,25 @@ void _irq_func(void) \ /* If we need to handle the other type interrupts except GPIO, add code here */ void __gpio_wk0efgh_interrupt(void) { -#ifdef CONFIG_LPC - /* Pending bit 7 or 6 ? */ +#if defined(CONFIG_LPC) || defined(CONFIG_ESPI) + /* Pending bit 7 or 6 or 5? */ if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0 , MIWU_GROUP_5), 6) && IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0 , MIWU_GROUP_5), 6)) { /* Disable host wake-up */ CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 6); /* Clear pending bit of WUI */ - SET_BIT(NPCX_WKPCL(MIWU_TABLE_0 , MIWU_GROUP_5), 6); - } else if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0 , MIWU_GROUP_5), 7) && - IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0 , MIWU_GROUP_5), 7)) + SET_BIT(NPCX_WKPCL(MIWU_TABLE_0, MIWU_GROUP_5), 6); + } +#ifdef CONFIG_ESPI + else if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 5) && + IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_5), 5)) + espi_espirst_handler(); +#else + else if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 7) && + IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_5), 7)) lpc_lreset_pltrst_handler(); - else /* FW will jump into ISR again if other GPIOs' INT still issued */ +#endif + else #endif gpio_interrupt(NPCX_IRQ_WKINTEFGH_0); } diff --git a/chip/npcx/lpc.c b/chip/npcx/lpc.c index 7c37c06da7..6f4a08364a 100644 --- a/chip/npcx/lpc.c +++ b/chip/npcx/lpc.c @@ -24,6 +24,7 @@ #include "uart.h" #include "util.h" #include "system_chip.h" +#include "lpc_chip.h" /* Console output macros */ #if !(DEBUG_LPC) @@ -92,6 +93,15 @@ static void lpc_task_enable_irq(void) task_enable_irq(NPCX_IRQ_KBC_IBF); task_enable_irq(NPCX_IRQ_PM_CHAN_IBF); task_enable_irq(NPCX_IRQ_PORT80); +#ifdef CONFIG_ESPI + task_enable_irq(NPCX_IRQ_ESPI); + /* Virtual Wire: SLP_S3/4/5, SUS_STAT, PLTRST, OOB_RST_WARN */ + task_enable_irq(NPCX_IRQ_WKINTA_2); + /* Virtual Wire: HOST_RST_WARN, SUS_WARN, SUS_PWRDN_ACK, SLP_A */ + task_enable_irq(NPCX_IRQ_WKINTB_2); + /* Enable eSPI module interrupts */ + NPCX_ESPIIE |= (ESPIIE_GENERIC | ESPIIE_VW); +#endif } static void lpc_task_disable_irq(void) @@ -99,6 +109,15 @@ static void lpc_task_disable_irq(void) task_disable_irq(NPCX_IRQ_KBC_IBF); task_disable_irq(NPCX_IRQ_PM_CHAN_IBF); task_disable_irq(NPCX_IRQ_PORT80); +#ifdef CONFIG_ESPI + task_disable_irq(NPCX_IRQ_ESPI); + /* Virtual Wire: SLP_S3/4/5, SUS_STAT, PLTRST, OOB_RST_WARN */ + task_disable_irq(NPCX_IRQ_WKINTA_2); + /* Virtual Wire: HOST_RST_WARN,SUS_WARN, SUS_PWRDN_ACK, SLP_A */ + task_disable_irq(NPCX_IRQ_WKINTB_2); + /* Disable eSPI module interrupts */ + NPCX_ESPIIE &= ~(ESPIIE_GENERIC | ESPIIE_VW); +#endif } /** * Generate SMI pulse to the host chipset via GPIO. @@ -688,7 +707,7 @@ uint8_t lpc_sib_read_reg(uint8_t io_offset, uint8_t index_value) } /* For LPC host register initial via SIB module */ -void lpc_host_register_init(void) +void host_register_init(void) { /* enable ACPI*/ lpc_sib_write_reg(SIO_OFFSET, 0x07, 0x11); @@ -751,6 +770,7 @@ int lpc_get_pltrst_asserted(void) return (NPCX_MSWCTL1 & 0x04) ? 1 : 0; } +#ifndef CONFIG_ESPI /* Initialize host settings by interrupt */ void lpc_lreset_pltrst_handler(void) { @@ -774,7 +794,7 @@ void lpc_lreset_pltrst_handler(void) * won't be reset by Host domain reset but Core domain does. */ if (!pltrst_asserted) - lpc_host_register_init(); + host_register_init(); else { #ifdef CONFIG_CHIPSET_RESET_HOOK /* Notify HOOK_CHIPSET_RESET */ @@ -782,14 +802,26 @@ void lpc_lreset_pltrst_handler(void) #endif } } +#endif + +/*****************************************************************************/ +/* LPC/eSPI Initialization functions */ static void lpc_init(void) { /* Enable clock for LPC peripheral */ clock_enable_peripheral(CGC_OFFSET_LPC, CGC_LPC_MASK, CGC_MODE_RUN | CGC_MODE_SLEEP); +#ifdef CONFIG_ESPI + /* Enable clock for eSPI peripheral */ + clock_enable_peripheral(CGC_OFFSET_ESPI, CGC_ESPI_MASK, + CGC_MODE_RUN | CGC_MODE_SLEEP); + /* Initialize eSPI IP */ + espi_init(); +#else /* Switching to LPC interface */ NPCX_DEVCNT |= 0x04; +#endif /* Enable 4E/4F */ if (!IS_BIT_SET(NPCX_MSWCTL1, 3)) { NPCX_HCBAL = 0x4E; @@ -798,11 +830,13 @@ static void lpc_init(void) /* Clear Host Access Hold state */ NPCX_SMC_CTL = 0xC0; +#ifndef CONFIG_ESPI /* * Set alternative pin from GPIO to CLKRUN no matter SERIRQ is under * continuous or quiet mode. */ SET_BIT(NPCX_DEVALT(1), NPCX_DEVALT1_CLKRN_SL); +#endif /* Initialize Hardware for UART Host */ #if CONFIG_UART_HOST @@ -897,7 +931,7 @@ static void lpc_init(void) */ #ifdef BOARD_NPCX_EVB /* initial IO port address via SIB-write modules */ - lpc_host_register_init(); + host_register_init(); #else /* Initialize LRESET# interrupt */ /* Set detection mode to edge */ diff --git a/chip/npcx/lpc_chip.h b/chip/npcx/lpc_chip.h index b87c2779fa..5a7cf2e6fb 100644 --- a/chip/npcx/lpc_chip.h +++ b/chip/npcx/lpc_chip.h @@ -8,7 +8,16 @@ #ifndef __CROS_EC_LPC_CHIP_H #define __CROS_EC_LPC_CHIP_H -/* Initialize host settings by interrupt */ -void lpc_lreset_pltrst_handler(void); +/* For host registers initialization via SIB module */ +void host_register_init(void); +#ifdef CONFIG_ESPI +/* eSPI Initialization functions */ +void espi_init(void); +/* eSPI reset assert/de-assert interrupt */ +void espi_espirst_handler(void); +#else +/* LPC PLTRST assert/de-assert interrupt */ +void lpc_lreset_pltrst_handler(void); +#endif #endif /* __CROS_EC_LPC_CHIP_H */ diff --git a/chip/npcx/registers.h b/chip/npcx/registers.h index 247c99cbb8..e21f164269 100644 --- a/chip/npcx/registers.h +++ b/chip/npcx/registers.h @@ -63,6 +63,7 @@ #define DEBUG_SHI 0 #define DEBUG_CLK 0 #define DEBUG_LPC 0 +#define DEBUG_ESPI 0 /* Modules Map */ #define NPCX_MDC_BASE_ADDR 0x4000C000 @@ -84,6 +85,7 @@ #define NPCX_SPI_BASE_ADDR 0x400D2000 #define NPCX_PECI_BASE_ADDR 0x400D4000 #define NPCX_TWD_BASE_ADDR 0x400D8000 +#define NPCX_ESPI_BASE_ADDR 0x4000A000 /* Multi-Modules Map */ #define NPCX_PWM_BASE_ADDR(mdl) (0x40080000 + ((mdl) * 0x2000L)) @@ -184,6 +186,7 @@ #define NPCX_IRQ16_NOUSED NPCX_IRQ_16 #define NPCX_IRQ_ITIM16_3 NPCX_IRQ_17 #define NPCX_IRQ_SHI NPCX_IRQ_18 +#define NPCX_IRQ_ESPI NPCX_IRQ_18 #define NPCX_IRQ19_NOUSED NPCX_IRQ_19 #define NPCX_IRQ20_NOUSED NPCX_IRQ_20 #define NPCX_IRQ_PS2 NPCX_IRQ_21 @@ -347,6 +350,7 @@ enum { enum { MIWU_EDGE_RISING, MIWU_EDGE_FALLING, + MIWU_EDGE_ANYING, }; /* MIWU utilities */ @@ -464,6 +468,7 @@ enum { /* SCFG register fields */ #define NPCX_DEVCNT_F_SPI_TRIS 6 +#define NPCX_DEVCNT_HIF_TYP_SEL_FIELD FIELD(2, 2) #define NPCX_DEVCNT_JEN1_HEN 5 #define NPCX_DEVCNT_JEN0_HEN 4 #define NPCX_STRPST_TRIST 1 @@ -1228,6 +1233,202 @@ enum ITIM16_MODULE_T { #define NPCX_LPRAM_CTRL REG32(0x40001044) /******************************************************************************/ +/* eSPI Registers */ +#define NPCX_ESPIID REG32(NPCX_ESPI_BASE_ADDR + 0X00) +#define NPCX_ESPICFG REG32(NPCX_ESPI_BASE_ADDR + 0X04) +#define NPCX_ESPISTS REG32(NPCX_ESPI_BASE_ADDR + 0X08) +#define NPCX_ESPIIE REG32(NPCX_ESPI_BASE_ADDR + 0X0C) +#define NPCX_ESPIIWE REG32(NPCX_ESPI_BASE_ADDR + 0X10) +#define NPCX_VWREGIDX REG32(NPCX_ESPI_BASE_ADDR + 0X14) +#define NPCX_VWREGDATA REG32(NPCX_ESPI_BASE_ADDR + 0X18) +#define NPCX_OOBCTL REG32(NPCX_ESPI_BASE_ADDR + 0X24) +#define NPCX_FLASHRXRDHEAD REG32(NPCX_ESPI_BASE_ADDR + 0X28) +#define NPCX_FLASHTXWRHEAD REG32(NPCX_ESPI_BASE_ADDR + 0X2C) +#define NPCX_FLASHCFG REG32(NPCX_ESPI_BASE_ADDR + 0X34) +#define NPCX_FLASHCTL REG32(NPCX_ESPI_BASE_ADDR + 0X38) +#define NPCX_ESPIIERR REG32(NPCX_ESPI_BASE_ADDR + 0X3C) + +/* eSPI Virtual Wire channel registers */ +#define NPCX_VWEVSM(n) REG32(NPCX_ESPI_BASE_ADDR + 0x100 + (4*(n))) +#define NPCX_VWEVMS(n) REG32(NPCX_ESPI_BASE_ADDR + 0x140 + (4*(n))) +#define NPCX_VWGPSM(n) REG32(NPCX_ESPI_BASE_ADDR + 0x180 + (4*(n))) +#define NPCX_VWGPMS(n) REG32(NPCX_ESPI_BASE_ADDR + 0x1C0 + (4*(n))) +#define NPCX_VWPING REG32(NPCX_ESPI_BASE_ADDR + 0x2F8) +#define NPCX_VWCTL REG32(NPCX_ESPI_BASE_ADDR + 0x2FC) + +/* eSPI register fields */ +#define NPCX_ESPICFG_PCHANEN 0 +#define NPCX_ESPICFG_VWCHANEN 1 +#define NPCX_ESPICFG_OOBCHANEN 2 +#define NPCX_ESPICFG_FLASHCHANEN 3 +#define NPCX_ESPICFG_IOMODE_FILED FIELD(8, 9) +#define NPCX_ESPICFG_MAXFREQ_FILED FIELD(10, 12) +#define NPCX_ESPICFG_PCCHN_SUPP 24 +#define NPCX_ESPICFG_VWCHN_SUPP 25 +#define NPCX_ESPICFG_OOBCHN_SUPP 26 +#define NPCX_ESPICFG_FLASHCHN_SUPP 27 +#define NPCX_ESPIIE_IBRSTIE 0 +#define NPCX_ESPIIE_CFGUPDIE 1 +#define NPCX_ESPIIE_BERRIE 2 +#define NPCX_ESPIIE_OOBRXIE 3 +#define NPCX_ESPIIE_FLASHRXIE 4 +#define NPCX_ESPIIE_SFLASHRDIE 5 +#define NPCX_ESPIIE_PERACCIE 6 +#define NPCX_ESPIIE_DFRDIE 7 +#define NPCX_ESPIIE_VWUPDIE 8 +#define NPCX_ESPIIE_ESPIRSTIE 9 +#define NPCX_ESPIIE_PLTRSTIE 10 +#define NPCX_ESPIIE_VW1IE 11 +#define NPCX_ESPIIE_VW2IE 12 +#define NPCX_ESPIIE_VW3IE 13 +#define NPCX_ESPIIE_VW4IE 14 +#define NPCX_ESPIIE_AMERRIE 15 +#define NPCX_ESPIIE_AMDONEIE 16 +#define NPCX_ESPISTS_IBRST 0 +#define NPCX_ESPISTS_CFGUPD 1 +#define NPCX_ESPISTS_BERR 2 +#define NPCX_ESPISTS_OOBRX 3 +#define NPCX_ESPISTS_FLASHRX 4 +#define NPCX_ESPISTS_SFLASHRD 5 +#define NPCX_ESPISTS_PERACC 6 +#define NPCX_ESPISTS_DFRD 7 +#define NPCX_ESPISTS_VWUPD 8 +#define NPCX_ESPISTS_ESPIRST 9 +#define NPCX_ESPISTS_PLTRST 10 +#define NPCX_ESPISTS_VW1 11 +#define NPCX_ESPISTS_VW2 12 +#define NPCX_ESPISTS_VW3 13 +#define NPCX_ESPISTS_VW4 14 +#define NPCX_ESPISTS_AMERR 15 +#define NPCX_ESPISTS_AMDONE 16 +/* eSPI Virtual Wire channel register fields */ +#define NPCX_VWEVSM_WIRE FIELD(0, 4) +#define NPCX_VWEVMS_WIRE FIELD(0, 4) +#define NPCX_VWEVSM_VALID FIELD(4, 4) +#define NPCX_VWEVMS_VALID FIELD(4, 4) + +/* Marco functions for eSPI CFG & IE */ +#define IS_SLAVE_CHAN_ENABLE(ch) IS_BIT_SET(NPCX_ESPICFG, ch) +#define IS_HOST_CHAN_EN(ch) IS_BIT_SET(NPCX_ESPICFG, (ch+4)) +#define ENABLE_ESPI_CHAN(ch) SET_BIT(NPCX_ESPICFG, ch) +#define DISABLE_ESPI_CHAN(ch) CLEAR_BIT(NPCX_ESPICFG, ch) +/* ESPI Slave Channel Support Definitions */ +#define ESPI_SUPP_CH_PC (1 << NPCX_ESPICFG_PCCHN_SUPP) +#define ESPI_SUPP_CH_VM (1 << NPCX_ESPICFG_VWCHN_SUPP) +#define ESPI_SUPP_CH_OOB (1 << NPCX_ESPICFG_OOBCHN_SUPP) +#define ESPI_SUPP_CH_FLASH (1 << NPCX_ESPICFG_FLASHCHN_SUPP) +#define ESPI_SUPP_CH_ALL (ESPI_SUPP_CH_PC | ESPI_SUPP_CH_VM | \ + ESPI_SUPP_CH_OOB | ESPI_SUPP_CH_FLASH) +/* ESPI Interrupts Enable Definitions */ +#define ESPIIE_IBRST (1 << NPCX_ESPIIE_IBRSTIE) +#define ESPIIE_CFGUPD (1 << NPCX_ESPIIE_CFGUPDIE) +#define ESPIIE_BERR (1 << NPCX_ESPIIE_BERRIE) +#define ESPIIE_OOBRX (1 << NPCX_ESPIIE_OOBRXIE) +#define ESPIIE_FLASHRX (1 << NPCX_ESPIIE_FLASHRXIE) +#define ESPIIE_SFLASHRD (1 << NPCX_ESPIIE_SFLASHRDIE) +#define ESPIIE_PERACC (1 << NPCX_ESPIIE_PERACCIE) +#define ESPIIE_DFRD (1 << NPCX_ESPIIE_DFRDIE) +#define ESPIIE_VWUPD (1 << NPCX_ESPIIE_VWUPDIE) +#define ESPIIE_ESPIRST (1 << NPCX_ESPIIE_ESPIRSTIE) +#define ESPIIE_PLTRST (1 << NPCX_ESPIIE_PLTRSTIE) +#define ESPIIE_VW1 (1 << NPCX_ESPIIE_VW1IE) +#define ESPIIE_VW2 (1 << NPCX_ESPIIE_VW2IE) +#define ESPIIE_VW3 (1 << NPCX_ESPIIE_VW3IE) +#define ESPIIE_VW4 (1 << NPCX_ESPIIE_VW4IE) +#define ESPIIE_AMERR (1 << NPCX_ESPIIE_AMERRIE) +#define ESPIIE_AMDONE (1 << NPCX_ESPIIE_AMDONEIE) +/* eSPI Interrupts for VW */ +#define ESPIIE_VW (ESPIIE_VWUPD | ESPIIE_VW1 | ESPIIE_VW2 | \ + ESPIIE_VW3 | ESPIIE_VW4 | ESPIIE_PLTRST) +/* eSPI Interrupts for Generic */ +#define ESPIIE_GENERIC (ESPIIE_IBRST | ESPIIE_CFGUPD | \ + ESPIIE_BERR | ESPIIE_ESPIRST) + +/* Marco functions for eSPI VW */ +#define ESPI_VWEVMS_NUM 12 +#define ESPI_VWEVSM_NUM 10 +#define ESPI_VWGPMS_NUM 16 +#define ESPI_VW_IDX_WIRE_NUM 4 +/* Determine Virtual Wire type */ +#define VM_TYPE(i) ((i >= 0 && i <= 1) ? ESPI_VW_TYPE_INT_EV : \ + (i >= 2 && i <= 7) ? ESPI_VW_TYPE_SYS_EV : \ + (i >= 64 && i <= 127) ? ESPI_VW_TYPE_PLT : \ + (i >= 128 && i <= 255) ? ESPI_VW_TYPE_GPIO : \ + ESPI_VW_TYPE_NONE) + +/* Bit filed manipulation for VWEVMS Value */ +#define VWEVMS_INX(i) ((i<<8) & 0x00007F00) +#define VWEVMS_INX_EN(n) ((n<<15) & 0x00008000) +#define VWEVMS_PLTRST_EN(p) ((p<<17) & 0x00020000) +#define VWEVMS_INT_EN(e) ((e<<18) & 0x00040000) +#define VWEVMS_ESPIRST_EN(r) ((r<<19) & 0x00080000) +#define VWEVMS_FIELD(i, n, p, e, r) (VWEVMS_INX(i) | VWEVMS_INX_EN(n) | \ + VWEVMS_PLTRST_EN(p) | VWEVMS_INT_EN(e) | \ + VWEVMS_ESPIRST_EN(r)) +#define VWEVMS_IDX_GET(reg) (((reg & 0x00007F00)>>8)) + +/* Bit filed manipulation for VWEVSM Value */ +#define VWEVSM_VALID_N(v) ((v<<4) & 0x000000F0) +#define VWEVSM_INX(i) ((i<<8) & 0x00007F00) +#define VWEVSM_INX_EN(n) ((n<<15) & 0x00008000) +#define VWEVSM_DIRTY(d) ((d<<16) & 0x00010000) +#define VWEVSM_PLTRST_EN(p) ((p<<17) & 0x00020000) +#define VWEVSM_CDRST_EN(c) ((c<<19) & 0x00080000) +#define VWEVSM_FIELD(i, n, v, p, c) (VWEVSM_INX(i) | VWEVSM_INX_EN(n) | \ + VWEVSM_VALID_N(v) | VWEVSM_PLTRST_EN(p) |\ + VWEVSM_CDRST_EN(c)) +#define VWEVSM_IDX_GET(reg) (((reg & 0x00007F00)>>8)) + +/* Bit filed manpulation for VWGPMS Value */ +#define VWGPMS_INX_EN(n) (((n<<15) & 0x00008000)) +#define VWGPMS_MODIFIED(m) (((m<<16) & 0x00010000)) +#define VWGPMS_PLTRST_EN(p) (((p<<17) & 0x00020000)) +#define VWGPMS_INT_EN(e) (((e<<18) & 0x00040000)) +#define VWGPMS_FIELD(n, m, p, e) (VMGPMS_INX_EN(n) | VWGPMS_MODIFIED(m) | \ + VWGPMS_PLTRST_EN(p) | VWGPMS_INT_EN(e)) + +/* eSPI enumeration */ +/* eSPI channels */ +enum { + NPCX_ESPI_CH_PC = 0, + NPCX_ESPI_CH_VW, + NPCX_ESPI_CH_OOB, + NPCX_ESPI_CH_FLASH, + NPCX_ESPI_CH_COUNT, + NPCX_ESPI_CH_GENERIC, + NPCX_ESPI_CH_NONE = 0xFF +}; + +/* eSPI IO modes */ +enum { + NPCX_ESPI_IO_MODE_SINGLE = 0, + NPCX_ESPI_IO_MODE_DUAL = 1, + NPCX_ESPI_IO_MODE_Quad = 2, + NPCX_ESPI_IO_MODE_ALL = 3, + NPCX_ESPI_IO_MODE_NONE = 0xFF +}; + +/* eSPI max supported frequency */ +enum { + NPCX_ESPI_MAXFREQ_20 = 0, + NPCX_ESPI_MAXFREQ_25 = 1, + NPCX_ESPI_MAXFREQ_33 = 2, + NPCX_ESPI_MAXFREQ_50 = 3, + NPCX_ESPI_MAXFREQ_66 = 4, + NPCX_ESPI_MAXFREQ_NOOE = 0xFF +}; + +/* VW types */ +enum { + ESPI_VW_TYPE_INT_EV, /* Interrupt event */ + ESPI_VW_TYPE_SYS_EV, /* System Event */ + ESPI_VW_TYPE_PLT, /* Platform specific */ + ESPI_VW_TYPE_GPIO, /* General Purpose I/O Expander */ + ESPI_VW_TYPE_NUM, + ESPI_VW_TYPE_NONE = 0xFF +}; + +/******************************************************************************/ /* Nuvoton internal used only registers */ #define NPCX_INTERNAL_CTRL1 REG8(0x400DB000) #define NPCX_INTERNAL_CTRL2 REG8(0x400DD000) |