driver: espi: add acpi and customized op codes for lpc r/w request func.

This CL introduces two kinds of op codes for espi_api_lpc_read_request
and espi_api_lpc_write_request Zephyr espi api functions.

One is for supporting ACPI and shared memory region to access ACPI data.
The other is customized for certain platforms such as Chromebook and so
on.

This CL also introduced the following configurations to add the
flexibility of these settings.

1. ESPI_PERIPHERAL_ACPI_SHM_REGION_PORT_NUM:
   Host I/O peripheral port number for shared memory region. The default
   value is default 0x0900

2. ESPI_NPCX_PERIPHERAL_ACPI_SHD_MEM_SIZE:
   Host I/O peripheral port size for shared memory in npcx series.
   Please notice the valid value in npcx ec series for this option is
   8/16/32/64/128/256/512/1024/2048/4096 bytes. The default value is 256
   bytes.

This CL also turn off hardware-wire feature which generates VW events
that connected to hardware signals such as SMI and SCI. We will set
VW output events directly via espi_api_send_vwire() api function.

Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This commit is contained in:
Mulin Chao 2020-12-09 21:28:48 -08:00 committed by Anas Nashif
commit 988a7a4826
7 changed files with 353 additions and 36 deletions

View file

@ -118,6 +118,29 @@ config ESPI_PERIPHERAL_EC_HOST_CMD
Enables Embedded Controller (EC) host command subsystem via eSPI Enables Embedded Controller (EC) host command subsystem via eSPI
peripheral channel. peripheral channel.
config ESPI_PERIPHERAL_ACPI_SHM_REGION
bool "Host peripheral device support shared memory region"
help
Enables shared memory region over eSPI peripheral channel to access
the ACPI response data.
config ESPI_PERIPHERAL_ACPI_SHM_REGION_PORT_NUM
hex "Host I/O peripheral port number for shared memory region"
depends on ESPI_PERIPHERAL_ACPI_SHM_REGION
default 0x0900
help
This is the port number used by the Host and EC to communicate over
the shared memory region to access the ACPI response data. Please
ensure the Host code is configured to use for accessing ACPI response
data. Also, ensure the port number selected doesn't clash with the
existing ports.
config ESPI_PERIPHERAL_CUSTOM_OPCODE
bool "Host peripheral device support customized opcode"
help
Enables opcode is customized for certain platforms such as Chromebook
and so on over eSPI peripheral channel.
endif # ESPI_PERIPHERAL_CHANNEL endif # ESPI_PERIPHERAL_CHANNEL
endif # ESPI endif # ESPI

View file

@ -10,6 +10,16 @@ config ESPI_NPCX
This option enables the Intel Enhanced Serial Peripheral Interface This option enables the Intel Enhanced Serial Peripheral Interface
(eSPI) for NPCX family of processors. (eSPI) for NPCX family of processors.
config ESPI_NPCX_PERIPHERAL_ACPI_SHD_MEM_SIZE
int "Host I/O peripheral port size for shared memory in npcx series"
depends on ESPI_NPCX || ESPI_PERIPHERAL_ACPI_SHM_REGION
default 256
help
This is the port size used by the Host and EC to communicate over
the shared memory region to return the ACPI response data. Please
notice the valid value in npcx ec series for this option is 8/16/32/
64/128/256/512/1024/2048/4096 bytes.
# The default value 'y' for the existing options if ESPI_NPCX is selected. # The default value 'y' for the existing options if ESPI_NPCX is selected.
if ESPI_NPCX if ESPI_NPCX
@ -25,4 +35,13 @@ config ESPI_PERIPHERAL_HOST_IO
config ESPI_PERIPHERAL_DEBUG_PORT_80 config ESPI_PERIPHERAL_DEBUG_PORT_80
default y default y
config ESPI_PERIPHERAL_EC_HOST_CMD
default y
config ESPI_PERIPHERAL_ACPI_SHM_REGION
default y
config ESPI_PERIPHERAL_CUSTOM_OPCODE
default y
endif #ESPI_NPCX endif #ESPI_NPCX

View file

@ -326,6 +326,12 @@ static void espi_vw_config_output(const struct device *dev,
valid |= config_out->bitmask; valid |= config_out->bitmask;
SET_FIELD(inst->VWEVSM[idx], NPCX_VWEVSM_VALID, valid); SET_FIELD(inst->VWEVSM[idx], NPCX_VWEVSM_VALID, valid);
/*
* Turn off hardware-wire feature which generates VW events that
* connected to hardware signals. We will set it manually by software.
*/
SET_FIELD(inst->VWEVSM[idx], NPCX_VWEVSM_HW_WIRE, 0);
LOG_DBG("VWEVSM%d 0x%08X", idx, inst->VWEVSM[idx]); LOG_DBG("VWEVSM%d 0x%08X", idx, inst->VWEVSM[idx]);
} }
@ -628,10 +634,6 @@ static int espi_npcx_read_lpc_request(const struct device *dev,
uint32_t *data) uint32_t *data)
{ {
ARG_UNUSED(dev); ARG_UNUSED(dev);
struct espi_reg *const inst = HAL_INSTANCE(dev);
if (!IS_BIT_SET(inst->ESPICFG, NPCX_ESPICFG_PCHANEN))
return -ENOTSUP;
return npcx_host_periph_read_request(op, data); return npcx_host_periph_read_request(op, data);
} }
@ -641,10 +643,6 @@ static int espi_npcx_write_lpc_request(const struct device *dev,
uint32_t *data) uint32_t *data)
{ {
ARG_UNUSED(dev); ARG_UNUSED(dev);
struct espi_reg *const inst = HAL_INSTANCE(dev);
if (!IS_BIT_SET(inst->ESPICFG, NPCX_ESPICFG_PCHANEN))
return -ENOTSUP;
return npcx_host_periph_write_request(op, data); return npcx_host_periph_write_request(op, data);
} }
@ -787,6 +785,33 @@ static int espi_npcx_receive_oob(const struct device *dev,
} }
#endif #endif
/* Platform specific espi module functions */
void npcx_espi_enable_interrupts(const struct device *dev)
{
ARG_UNUSED(dev);
/* Enable eSPI bus interrupt */
irq_enable(DT_INST_IRQN(0));
/* Turn on all VW inputs' MIWU interrupts */
for (int idx = 0; idx < ARRAY_SIZE(vw_in_tbl); idx++) {
npcx_miwu_irq_enable(&(vw_in_tbl[idx].vw_wui));
}
}
void npcx_espi_disable_interrupts(const struct device *dev)
{
ARG_UNUSED(dev);
/* Disable eSPI bus interrupt */
irq_disable(DT_INST_IRQN(0));
/* Turn off all VW inputs' MIWU interrupts */
for (int idx = 0; idx < ARRAY_SIZE(vw_in_tbl); idx++) {
npcx_miwu_irq_disable(&(vw_in_tbl[idx].vw_wui));
}
}
/* eSPI driver registration */ /* eSPI driver registration */
static int espi_npcx_init(const struct device *dev); static int espi_npcx_init(const struct device *dev);

View file

@ -120,6 +120,7 @@
#include <soc.h> #include <soc.h>
#include "espi_utils.h" #include "espi_utils.h"
#include "soc_host.h" #include "soc_host.h"
#include "soc_espi.h"
#include "soc_miwu.h" #include "soc_miwu.h"
#include <logging/log.h> #include <logging/log.h>
@ -171,10 +172,6 @@ struct host_sub_npcx_data host_sub_data;
/* IO base address of EC Logical Device Configuration */ /* IO base address of EC Logical Device Configuration */
#define NPCX_EC_CFG_IO_ADDR 0x4E #define NPCX_EC_CFG_IO_ADDR 0x4E
/* 8042 event data */
#define NPCX_8042_DATA_POS 8U
#define NPCX_8042_TYPE_POS 0U
/* Timeout to wait for Core-to-Host transaction to be completed. */ /* Timeout to wait for Core-to-Host transaction to be completed. */
#define NPCX_C2H_TRANSACTION_TIMEOUT_US 200 #define NPCX_C2H_TRANSACTION_TIMEOUT_US 200
@ -204,6 +201,26 @@ struct host_sub_npcx_data host_sub_data;
#define EC_CFG_IDX_SHM_WND2_ADDR_2 0xFA #define EC_CFG_IDX_SHM_WND2_ADDR_2 0xFA
#define EC_CFG_IDX_SHM_WND2_ADDR_3 0xFB #define EC_CFG_IDX_SHM_WND2_ADDR_3 0xFB
/* Host sub-device local inline functions */
static inline uint8_t host_shd_mem_wnd_size_sl(uint32_t size)
{
/* The minimum supported shared memory region size is 8 bytes */
if (size <= 8U) {
size = 8U;
}
/* The maximum supported shared memory region size is 4K bytes */
if (size >= 4096U) {
size = 4096U;
}
/*
* If window size is not a power-of-two, it is rounded-up to the next
* power-of-two value, and return value corresponds to RWINx_SIZE field.
*/
return (32 - __builtin_clz(size - 1U)) & 0xff;
}
/* Host KBC sub-device local functions */ /* Host KBC sub-device local functions */
#if defined(CONFIG_ESPI_PERIPHERAL_8042_KBC) #if defined(CONFIG_ESPI_PERIPHERAL_8042_KBC)
static void host_kbc_ibf_isr(void *arg) static void host_kbc_ibf_isr(void *arg)
@ -237,7 +254,12 @@ static void host_kbc_obe_isr(void *arg)
LOG_DBG("%s: kbc status 0x%02x", __func__, inst_kbc->HIKMST); LOG_DBG("%s: kbc status 0x%02x", __func__, inst_kbc->HIKMST);
/* TODO: notify application that host already read out data here? */ /*
* TODO: Notify application that host already read out data. We might
* use E8042_SET_FLAG in espi_api_lpc_write_request() instead of setting
* status of HIKMST here directly.
*/
inst_kbc->HIKMST &= ~BIT(NPCX_HIKMST_ST1);
} }
static void host_kbc_init(void) static void host_kbc_init(void)
@ -269,6 +291,7 @@ static void host_kbc_init(void)
#if defined(CONFIG_ESPI_PERIPHERAL_HOST_IO) #if defined(CONFIG_ESPI_PERIPHERAL_HOST_IO)
static void host_acpi_process_input_data(uint8_t data) static void host_acpi_process_input_data(uint8_t data)
{ {
struct pmch_reg *const inst_acpi = host_sub_cfg.inst_pm_acpi;
struct espi_event evt = { struct espi_event evt = {
.evt_type = ESPI_BUS_PERIPHERAL_NOTIFICATION, .evt_type = ESPI_BUS_PERIPHERAL_NOTIFICATION,
.evt_details = ESPI_PERIPHERAL_HOST_IO, .evt_details = ESPI_PERIPHERAL_HOST_IO,
@ -276,7 +299,14 @@ static void host_acpi_process_input_data(uint8_t data)
}; };
LOG_DBG("%s: acpi data 0x%02x", __func__, data); LOG_DBG("%s: acpi data 0x%02x", __func__, data);
evt.evt_data = data;
/*
* The high byte contains information from the host, and the lower byte
* indicates if the host sent a command or data. 1 = Command.
*/
evt.evt_data = (data << NPCX_ACPI_DATA_POS) |
(IS_BIT_SET(inst_acpi->HIPMST, NPCX_HIPMST_CMD) <<
NPCX_ACPI_TYPE_POS);
espi_send_callbacks(host_sub_data.callbacks, host_sub_data.host_bus_dev, espi_send_callbacks(host_sub_data.callbacks, host_sub_data.host_bus_dev,
evt); evt);
} }
@ -311,8 +341,6 @@ static void host_acpi_init(void)
#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) #if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD)
/* Host command argument and memory map buffers */ /* Host command argument and memory map buffers */
static uint8_t shm_mem_host_cmd[256] __aligned(8); static uint8_t shm_mem_host_cmd[256] __aligned(8);
static uint8_t shm_memmap[256] __aligned(8);
/* Host command sub-device local functions */ /* Host command sub-device local functions */
static void host_hcmd_process_input_data(uint8_t data) static void host_hcmd_process_input_data(uint8_t data)
{ {
@ -326,19 +354,13 @@ static void host_hcmd_init(void)
/* Don't stall SHM transactions */ /* Don't stall SHM transactions */
inst_shm->SHM_CTL &= ~0x40; inst_shm->SHM_CTL &= ~0x40;
/* Disable Window 1 & 2 protection */ /* Disable Window 1 protection */
inst_shm->WIN1_WR_PROT = 0; inst_shm->WIN1_WR_PROT = 0;
inst_shm->WIN2_WR_PROT = 0;
inst_shm->WIN1_RD_PROT = 0; inst_shm->WIN1_RD_PROT = 0;
inst_shm->WIN2_RD_PROT = 0;
/* Configure Win1/2 for Host CMD and MEMMAP. Their sizes are 256B */
inst_shm->WIN_SIZE = 0x88;
inst_shm->WIN_BASE1 = (uint32_t)shm_mem_host_cmd;
inst_shm->WIN_BASE2 = (uint32_t)shm_memmap;
/* Enable write protect of Share memory window 2 */
inst_shm->WIN2_WR_PROT = 0xFF;
/* TODO: Initialize shm_memmap buffer for host command flags here */ /* Configure Win1 for Host CMD and MEMMAP. Their sizes are 256B */
SET_FIELD(inst_shm->WIN_SIZE, NPCX_WIN_SIZE_RWIN1_SIZE_FIELD, 0x08);
inst_shm->WIN_BASE1 = (uint32_t)shm_mem_host_cmd;
/* /*
* Clear processing flag before enabling host's interrupts in case * Clear processing flag before enabling host's interrupts in case
@ -352,7 +374,36 @@ static void host_hcmd_init(void)
* 2. BIT 7 must be 1. * 2. BIT 7 must be 1.
*/ */
inst_hcmd->HIPMCTL |= BIT(7) | BIT(NPCX_HIPMCTL_IBFIE); inst_hcmd->HIPMCTL |= BIT(7) | BIT(NPCX_HIPMCTL_IBFIE);
}
#endif
#if defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
/* Host command argument and memory map buffers */
static uint8_t shm_acpi_mmap[CONFIG_ESPI_NPCX_PERIPHERAL_ACPI_SHD_MEM_SIZE]
__aligned(8);
static void host_shared_mem_region_init(void)
{
struct shm_reg *const inst_shm = host_sub_cfg.inst_shm;
uint32_t win_size = CONFIG_ESPI_NPCX_PERIPHERAL_ACPI_SHD_MEM_SIZE;
/* Don't stall SHM transactions */
inst_shm->SHM_CTL &= ~0x40;
/* Disable Window 2 protection */
inst_shm->WIN2_WR_PROT = 0;
inst_shm->WIN2_RD_PROT = 0;
/* Configure Win2 size for ACPI shared mem region. */
SET_FIELD(inst_shm->WIN_SIZE, NPCX_WIN_SIZE_RWIN2_SIZE_FIELD,
host_shd_mem_wnd_size_sl(win_size));
inst_shm->WIN_BASE2 = (uint32_t)shm_acpi_mmap;
/* Enable write protect of Share memory window 2 */
inst_shm->WIN2_WR_PROT = 0xFF;
/*
* TODO: Initialize shm_acpi_mmap buffer for host command flags. We might
* use EACPI_GET_SHARED_MEMORY in espi_api_lpc_read_request() intead of
* setting host command flags here directly.
*/
} }
#endif #endif
@ -437,6 +488,58 @@ static void host_port80_init(void)
} }
#endif #endif
#if defined(CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE)
static void host_cus_opcode_enable_interrupts(void)
{
/* Enable host KBC sub-device interrupt */
#if defined(CONFIG_ESPI_PERIPHERAL_8042_KBC)
irq_enable(DT_INST_IRQ_BY_NAME(0, kbc_ibf, irq));
irq_enable(DT_INST_IRQ_BY_NAME(0, kbc_obe, irq));
#endif
/* Enable host PM channel (Host IO) sub-device interrupt */
#if defined(CONFIG_ESPI_PERIPHERAL_HOST_IO) || \
defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD)
irq_enable(DT_INST_IRQ_BY_NAME(0, pmch_ibf, irq));
#endif
/* Enable host Port80 sub-device interrupt installation */
#if defined(CONFIG_ESPI_PERIPHERAL_DEBUG_PORT_80)
irq_enable(DT_INST_IRQ_BY_NAME(0, p80_fifo, irq));
#endif
/* Enable host interface interrupts if its interface is eSPI */
#if defined(CONFIG_ESPI)
npcx_espi_enable_interrupts(host_sub_data.host_bus_dev);
#endif
}
static void host_cus_opcode_disable_interrupts(void)
{
/* Disable host KBC sub-device interrupt */
#if defined(CONFIG_ESPI_PERIPHERAL_8042_KBC)
irq_disable(DT_INST_IRQ_BY_NAME(0, kbc_ibf, irq));
irq_disable(DT_INST_IRQ_BY_NAME(0, kbc_obe, irq));
#endif
/* Disable host PM channel (Host IO) sub-device interrupt */
#if defined(CONFIG_ESPI_PERIPHERAL_HOST_IO) || \
defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD)
irq_disable(DT_INST_IRQ_BY_NAME(0, pmch_ibf, irq));
#endif
/* Disable host Port80 sub-device interrupt installation */
#if defined(CONFIG_ESPI_PERIPHERAL_DEBUG_PORT_80)
irq_disable(DT_INST_IRQ_BY_NAME(0, p80_fifo, irq));
#endif
/* Disable host interface interrupts if its interface is eSPI */
#if defined(CONFIG_ESPI)
npcx_espi_disable_interrupts(host_sub_data.host_bus_dev);
#endif
}
#endif /* CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE */
#if defined(CONFIG_ESPI_PERIPHERAL_UART) #if defined(CONFIG_ESPI_PERIPHERAL_UART)
/* host uart pinmux configuration */ /* host uart pinmux configuration */
static const struct npcx_alt host_uart_alts[] = static const struct npcx_alt host_uart_alts[] =
@ -586,9 +689,9 @@ uint8_t host_c2h_read_io_cfg_reg(uint8_t reg_index)
int npcx_host_periph_read_request(enum lpc_peripheral_opcode op, int npcx_host_periph_read_request(enum lpc_peripheral_opcode op,
uint32_t *data) uint32_t *data)
{ {
struct kbc_reg *const inst_kbc = host_sub_cfg.inst_kbc;
if (op >= E8042_START_OPCODE && op <= E8042_MAX_OPCODE) { if (op >= E8042_START_OPCODE && op <= E8042_MAX_OPCODE) {
struct kbc_reg *const inst_kbc = host_sub_cfg.inst_kbc;
/* Make sure kbc 8042 is on */ /* Make sure kbc 8042 is on */
if (!IS_BIT_SET(inst_kbc->HICTRL, NPCX_HICTRL_OBFKIE) || if (!IS_BIT_SET(inst_kbc->HICTRL, NPCX_HICTRL_OBFKIE) ||
!IS_BIT_SET(inst_kbc->HICTRL, NPCX_HICTRL_OBFMIE)) { !IS_BIT_SET(inst_kbc->HICTRL, NPCX_HICTRL_OBFMIE)) {
@ -612,8 +715,47 @@ int npcx_host_periph_read_request(enum lpc_peripheral_opcode op,
default: default:
return -EINVAL; return -EINVAL;
} }
} else { } else if (op >= EACPI_START_OPCODE && op <= EACPI_MAX_OPCODE) {
/* TODO: Support more op code besides 8042 here */ struct pmch_reg *const inst_acpi = host_sub_cfg.inst_pm_acpi;
/* Make sure pm channel for apci is on */
if (!IS_BIT_SET(inst_acpi->HIPMCTL, NPCX_HIPMCTL_IBFIE)) {
return -ENOTSUP;
}
switch (op) {
case EACPI_OBF_HAS_CHAR:
/* EC has written data back to host. OBF is
* automatically cleared after host reads
* the data
*/
*data = IS_BIT_SET(inst_acpi->HIPMST, NPCX_HIPMST_OBF);
break;
case EACPI_IBF_HAS_CHAR:
*data = IS_BIT_SET(inst_acpi->HIPMST, NPCX_HIPMST_IBF);
break;
case EACPI_READ_STS:
*data = inst_acpi->HIPMST;
break;
#if defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
case EACPI_GET_SHARED_MEMORY:
*data = (uint32_t)shm_acpi_mmap;
break;
#endif /* CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION */
default:
return -EINVAL;
}
}
#if defined(CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE)
else if (op >= ECUSTOM_START_OPCODE && op <= ECUSTOM_MAX_OPCODE) {
/* Other customized op codes */
switch (op) {
default:
return -EINVAL;
}
}
#endif /* CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE */
else {
return -ENOTSUP; return -ENOTSUP;
} }
@ -679,8 +821,42 @@ int npcx_host_periph_write_request(enum lpc_peripheral_opcode op,
default: default:
return -EINVAL; return -EINVAL;
} }
} else { } else if (op >= EACPI_START_OPCODE && op <= EACPI_MAX_OPCODE) {
/* TODO: Support more op code besides 8042 here! */ struct pmch_reg *const inst_acpi = host_sub_cfg.inst_pm_acpi;
/* Make sure pm channel for apci is on */
if (!IS_BIT_SET(inst_acpi->HIPMCTL, NPCX_HIPMCTL_IBFIE)) {
return -ENOTSUP;
}
switch (op) {
case EACPI_WRITE_CHAR:
inst_acpi->HIPMDO = (*data & 0xff);
break;
case EACPI_WRITE_STS:
inst_acpi->HIPMST = (*data & 0xff);
break;
default:
return -EINVAL;
}
}
#if defined(CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE)
else if (op >= ECUSTOM_START_OPCODE && op <= ECUSTOM_MAX_OPCODE) {
/* Other customized op codes */
switch (op) {
case ECUSTOM_HOST_SUBS_INTERRUPT_EN:
if (*data != 0) {
host_cus_opcode_enable_interrupts();
} else {
host_cus_opcode_disable_interrupts();
}
break;
default:
return -EINVAL;
}
}
#endif /* CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE */
else {
return -ENOTSUP; return -ENOTSUP;
} }
@ -715,7 +891,8 @@ void npcx_host_init_subs_host_domain(void)
host_c2h_write_io_cfg_reg(EC_CFG_IDX_CTRL, 0x01); host_c2h_write_io_cfg_reg(EC_CFG_IDX_CTRL, 0x01);
#endif #endif
#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) #if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) \
|| defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
/* Select 'Host Command' bank which LDN are 0x12 (PM Channel 2) */ /* Select 'Host Command' bank which LDN are 0x12 (PM Channel 2) */
host_c2h_write_io_cfg_reg(EC_CFG_IDX_LDN, EC_CFG_LDN_HCMD); host_c2h_write_io_cfg_reg(EC_CFG_IDX_LDN, EC_CFG_LDN_HCMD);
/* Configure IO address of CMD port (0x200) */ /* Configure IO address of CMD port (0x200) */
@ -735,9 +912,13 @@ void npcx_host_init_subs_host_domain(void)
/* WIN1 as Host Command on the IO address 0x0800 */ /* WIN1 as Host Command on the IO address 0x0800 */
host_c2h_write_io_cfg_reg(EC_CFG_IDX_SHM_WND1_ADDR_1, 0x08); host_c2h_write_io_cfg_reg(EC_CFG_IDX_SHM_WND1_ADDR_1, 0x08);
host_c2h_write_io_cfg_reg(EC_CFG_IDX_SHM_WND1_ADDR_0, 0x00); host_c2h_write_io_cfg_reg(EC_CFG_IDX_SHM_WND1_ADDR_0, 0x00);
/* WIN2 as MEMMAP on the IO address 0x900 */ /* Set WIN2 as MEMMAP on the configured IO address */
host_c2h_write_io_cfg_reg(EC_CFG_IDX_SHM_WND2_ADDR_1, 0x09); #if defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION_PORT_NUM)
host_c2h_write_io_cfg_reg(EC_CFG_IDX_SHM_WND2_ADDR_0, 0x00); host_c2h_write_io_cfg_reg(EC_CFG_IDX_SHM_WND2_ADDR_1,
(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION_PORT_NUM >> 8) & 0xff);
host_c2h_write_io_cfg_reg(EC_CFG_IDX_SHM_WND2_ADDR_0,
CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION_PORT_NUM & 0xff);
#endif
/* Enable SHM direct memory access */ /* Enable SHM direct memory access */
host_c2h_write_io_cfg_reg(EC_CFG_IDX_CTRL, 0x01); host_c2h_write_io_cfg_reg(EC_CFG_IDX_CTRL, 0x01);
#endif #endif
@ -790,6 +971,9 @@ int npcx_host_init_subs_core_domain(const struct device *host_bus_dev,
#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) #if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD)
host_hcmd_init(); host_hcmd_init();
#endif #endif
#if defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
host_shared_mem_region_init();
#endif
#if defined(CONFIG_ESPI_PERIPHERAL_DEBUG_PORT_80) #if defined(CONFIG_ESPI_PERIPHERAL_DEBUG_PORT_80)
host_port80_init(); host_port80_init();
#endif #endif

View file

@ -137,6 +137,12 @@ enum espi_bus_event {
#define E8042_START_OPCODE 0x50 #define E8042_START_OPCODE 0x50
#define E8042_MAX_OPCODE 0x5F #define E8042_MAX_OPCODE 0x5F
#define EACPI_START_OPCODE 0x60
#define EACPI_MAX_OPCODE 0x6F
#define ECUSTOM_START_OPCODE 0xF0
#define ECUSTOM_MAX_OPCODE 0xFF
/** @endcond */ /** @endcond */
/** /**
@ -224,6 +230,22 @@ enum lpc_peripheral_opcode {
E8042_READ_KB_STS, E8042_READ_KB_STS,
E8042_SET_FLAG, E8042_SET_FLAG,
E8042_CLEAR_FLAG, E8042_CLEAR_FLAG,
/* ACPI read transactions */
EACPI_OBF_HAS_CHAR = EACPI_START_OPCODE,
EACPI_IBF_HAS_CHAR,
/* ACPI write transactions */
EACPI_WRITE_CHAR,
/* ACPI status transactions */
EACPI_READ_STS,
EACPI_WRITE_STS,
#if defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
/* Shared memory region support to return the ACPI response data */
EACPI_GET_SHARED_MEMORY,
#endif /* CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION */
#if defined(CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE)
/* Other customized transactions */
ECUSTOM_HOST_SUBS_INTERRUPT_EN = ECUSTOM_START_OPCODE,
#endif /* CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE */
}; };
/** /**

View file

@ -570,6 +570,7 @@ struct espi_reg {
#define NPCX_VWEVSM_WIRE FIELD(0, 4) #define NPCX_VWEVSM_WIRE FIELD(0, 4)
#define NPCX_VWEVSM_VALID FIELD(4, 4) #define NPCX_VWEVSM_VALID FIELD(4, 4)
#define NPCX_VWEVSM_BIT_VALID(n) (4+n) #define NPCX_VWEVSM_BIT_VALID(n) (4+n)
#define NPCX_VWEVSM_HW_WIRE FIELD(24, 4)
#define NPCX_OOBCTL_OOB_FREE 0 #define NPCX_OOBCTL_OOB_FREE 0
#define NPCX_OOBCTL_OOB_AVAIL 1 #define NPCX_OOBCTL_OOB_AVAIL 1
#define NPCX_OOBCTL_RSTBUFHEADS 2 #define NPCX_OOBCTL_RSTBUFHEADS 2
@ -731,6 +732,8 @@ struct shm_reg {
#define NPCX_SMC_CTL_HOSTWAIT 7 #define NPCX_SMC_CTL_HOSTWAIT 7
#define NPCX_FLASH_SIZE_STALL_HOST 6 #define NPCX_FLASH_SIZE_STALL_HOST 6
#define NPCX_FLASH_SIZE_RD_BURST 7 #define NPCX_FLASH_SIZE_RD_BURST 7
#define NPCX_WIN_SIZE_RWIN1_SIZE_FIELD FIELD(0, 4)
#define NPCX_WIN_SIZE_RWIN2_SIZE_FIELD FIELD(4, 4)
#define NPCX_WIN_PROT_RW1L_RP 0 #define NPCX_WIN_PROT_RW1L_RP 0
#define NPCX_WIN_PROT_RW1L_WP 1 #define NPCX_WIN_PROT_RW1L_WP 1
#define NPCX_WIN_PROT_RW1H_RP 2 #define NPCX_WIN_PROT_RW1H_RP 2
@ -837,6 +840,7 @@ struct pmch_reg {
#define NPCX_HIPMIE_SCIE 1 #define NPCX_HIPMIE_SCIE 1
#define NPCX_HIPMIE_SMIE 2 #define NPCX_HIPMIE_SMIE 2
#define NPCX_HIPMCTL_IBFIE 0 #define NPCX_HIPMCTL_IBFIE 0
#define NPCX_HIPMCTL_OBEIE 1
#define NPCX_HIPMCTL_SCIPOL 6 #define NPCX_HIPMCTL_SCIPOL 6
#define NPCX_HIPMST_OBF 0 #define NPCX_HIPMST_OBF 0
#define NPCX_HIPMST_IBF 1 #define NPCX_HIPMST_IBF 1

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2020 Nuvoton Technology Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _NUVOTON_NPCX_SOC_ESPI_H_
#define _NUVOTON_NPCX_SOC_ESPI_H_
#ifdef __cplusplus
extern "C" {
#endif
/* 8042 event data format */
#define NPCX_8042_DATA_POS 8U
#define NPCX_8042_TYPE_POS 0U
/* ACPI event data format */
#define NPCX_ACPI_DATA_POS 8U
#define NPCX_ACPI_TYPE_POS 0U
/**
* @brief Turn on all interrupts of eSPI host interface module.
*
* @param dev Pointer to structure device of eSPI module
*/
void npcx_espi_enable_interrupts(const struct device *dev);
/**
* @brief Turn off all interrupts of eSPI host interface module.
*
* @param dev Pointer to structure device of eSPI module
*/
void npcx_espi_disable_interrupts(const struct device *dev);
#ifdef __cplusplus
}
#endif
#endif /* _NUVOTON_NPCX_SOC_ESPI_H_ */