driver: espi: add notification and opcodes for ec host command support.

This CL add a new notification event, ESPI_PERIPHERAL_EC_HOST_CMD, and
two response opcodes, ECUSTOM_HOST_CMD_GET_PARAM_MEMORY and
ECUSTOM_HOST_CMD_SEND_RESULT, to connect with host command sub-system
between host and ec.

It also introduced three configurations to increase the flexibility of
ec host command settings:
1. ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM:
   Host I/O peripheral port number for ec host command data. The default
   value is 0x0200.
2. ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM:
   Host I/O peripheral port number for ec host command parameters. The
   default value is 0x0800.

3. ESPI_NPCX_PERIPHERAL_HOST_CMD_PARAM_SIZE:
   Host I/O peripheral port size for ec host command in npcx series. 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.

Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This commit is contained in:
Mulin Chao 2020-12-10 21:27:55 -08:00 committed by Anas Nashif
commit fa7843d12c
4 changed files with 83 additions and 12 deletions

View file

@ -141,6 +141,28 @@ config ESPI_PERIPHERAL_CUSTOM_OPCODE
Enables opcode is customized for certain platforms such as Chromebook Enables opcode is customized for certain platforms such as Chromebook
and so on over eSPI peripheral channel. and so on over eSPI peripheral channel.
config ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM
hex "Host I/O peripheral port number for ec host command data"
depends on ESPI_PERIPHERAL_EC_HOST_CMD
default 0x0200
help
This is the port number used by the Host and EC to communicate over
the eSPI peripheral channel to send EC host command data and its
result. Please ensure the Host code is configured to use for accessing
host command data and result. Also, ensure the port number selected
doesn't clash with the existing ports.
config ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM
hex "Host I/O peripheral port number for ec host command parameters"
depends on ESPI_PERIPHERAL_EC_HOST_CMD
default 0x0800
help
This is the port number used by the Host and EC to communicate over
the eSPI peripheral channel to access the host command request and
response data. Please ensure the Host code is configured to use for
accessing these package data. Also, ensure the port number selected
doesn't clash with the existing ports.
endif # ESPI_PERIPHERAL_CHANNEL endif # ESPI_PERIPHERAL_CHANNEL
endif # ESPI endif # ESPI

View file

@ -20,6 +20,16 @@ config ESPI_NPCX_PERIPHERAL_ACPI_SHD_MEM_SIZE
notice the valid value in npcx ec series for this option is 8/16/32/ notice the valid value in npcx ec series for this option is 8/16/32/
64/128/256/512/1024/2048/4096 bytes. 64/128/256/512/1024/2048/4096 bytes.
config ESPI_NPCX_PERIPHERAL_HOST_CMD_PARAM_SIZE
int "Host I/O peripheral port size for ec host command in npcx series"
depends on ESPI_NPCX || ESPI_PERIPHERAL_EC_HOST_CMD
default 256
help
This is the port size used by the Host and EC to communicate over
the shared memory region to return the host command parameter 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

View file

@ -340,17 +340,26 @@ 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_host_cmd[CONFIG_ESPI_NPCX_PERIPHERAL_HOST_CMD_PARAM_SIZE]
__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)
{ {
/* TODO: Handle host request data here */ struct espi_event evt = { ESPI_BUS_PERIPHERAL_NOTIFICATION,
ESPI_PERIPHERAL_EC_HOST_CMD, ESPI_PERIPHERAL_NODATA
};
evt.evt_data = data;
LOG_DBG("%s: host cmd data 0x%02x", __func__, evt.evt_data);
espi_send_callbacks(host_sub_data.callbacks, host_sub_data.host_bus_dev,
evt);
} }
static void host_hcmd_init(void) static void host_hcmd_init(void)
{ {
struct pmch_reg *const inst_hcmd = host_sub_cfg.inst_pm_hcmd; struct pmch_reg *const inst_hcmd = host_sub_cfg.inst_pm_hcmd;
struct shm_reg *const inst_shm = host_sub_cfg.inst_shm; struct shm_reg *const inst_shm = host_sub_cfg.inst_shm;
uint32_t win_size = CONFIG_ESPI_NPCX_PERIPHERAL_HOST_CMD_PARAM_SIZE;
/* Don't stall SHM transactions */ /* Don't stall SHM transactions */
inst_shm->SHM_CTL &= ~0x40; inst_shm->SHM_CTL &= ~0x40;
@ -358,9 +367,10 @@ static void host_hcmd_init(void)
inst_shm->WIN1_WR_PROT = 0; inst_shm->WIN1_WR_PROT = 0;
inst_shm->WIN1_RD_PROT = 0; inst_shm->WIN1_RD_PROT = 0;
/* Configure Win1 for Host CMD and MEMMAP. Their sizes are 256B */ /* Configure Win1 size for ec host command. */
SET_FIELD(inst_shm->WIN_SIZE, NPCX_WIN_SIZE_RWIN1_SIZE_FIELD, 0x08); SET_FIELD(inst_shm->WIN_SIZE, NPCX_WIN_SIZE_RWIN1_SIZE_FIELD,
inst_shm->WIN_BASE1 = (uint32_t)shm_mem_host_cmd; host_shd_mem_wnd_size_sl(win_size));
inst_shm->WIN_BASE1 = (uint32_t)shm_host_cmd;
/* /*
* Clear processing flag before enabling host's interrupts in case * Clear processing flag before enabling host's interrupts in case
@ -750,6 +760,9 @@ int npcx_host_periph_read_request(enum lpc_peripheral_opcode op,
else if (op >= ECUSTOM_START_OPCODE && op <= ECUSTOM_MAX_OPCODE) { else if (op >= ECUSTOM_START_OPCODE && op <= ECUSTOM_MAX_OPCODE) {
/* Other customized op codes */ /* Other customized op codes */
switch (op) { switch (op) {
case ECUSTOM_HOST_CMD_GET_PARAM_MEMORY:
*data = (uint32_t)shm_host_cmd;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
@ -843,6 +856,8 @@ int npcx_host_periph_write_request(enum lpc_peripheral_opcode op,
#if defined(CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE) #if defined(CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE)
else if (op >= ECUSTOM_START_OPCODE && op <= ECUSTOM_MAX_OPCODE) { else if (op >= ECUSTOM_START_OPCODE && op <= ECUSTOM_MAX_OPCODE) {
/* Other customized op codes */ /* Other customized op codes */
struct pmch_reg *const inst_hcmd = host_sub_cfg.inst_pm_hcmd;
switch (op) { switch (op) {
case ECUSTOM_HOST_SUBS_INTERRUPT_EN: case ECUSTOM_HOST_SUBS_INTERRUPT_EN:
if (*data != 0) { if (*data != 0) {
@ -851,6 +866,15 @@ int npcx_host_periph_write_request(enum lpc_peripheral_opcode op,
host_cus_opcode_disable_interrupts(); host_cus_opcode_disable_interrupts();
} }
break; break;
case ECUSTOM_HOST_CMD_SEND_RESULT:
/*
* Write result to the data byte. This sets the TOH
* status bit.
*/
inst_hcmd->HIPMDO = (*data & 0xff);
/* Clear processing flag */
inst_hcmd->HIPMST &= ~BIT(NPCX_HIPMST_F0);
break;
default: default:
return -EINVAL; return -EINVAL;
} }
@ -895,12 +919,18 @@ void npcx_host_init_subs_host_domain(void)
|| defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION) || 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);
#if defined(CONFIG_ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM)
/* Configure IO address of CMD port (0x200) */ /* Configure IO address of CMD port (0x200) */
host_c2h_write_io_cfg_reg(EC_CFG_IDX_CMD_IO_ADDR_H, 0x02); host_c2h_write_io_cfg_reg(EC_CFG_IDX_CMD_IO_ADDR_H,
host_c2h_write_io_cfg_reg(EC_CFG_IDX_CMD_IO_ADDR_L, 0x00); (CONFIG_ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM >> 8) & 0xff);
host_c2h_write_io_cfg_reg(EC_CFG_IDX_CMD_IO_ADDR_L,
CONFIG_ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM & 0xff);
/* Configure IO address of Data port (0x204) */ /* Configure IO address of Data port (0x204) */
host_c2h_write_io_cfg_reg(EC_CFG_IDX_DATA_IO_ADDR_H, 0x02); host_c2h_write_io_cfg_reg(EC_CFG_IDX_DATA_IO_ADDR_H,
host_c2h_write_io_cfg_reg(EC_CFG_IDX_DATA_IO_ADDR_L, 0x04); ((CONFIG_ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM + 4) >> 8) & 0xff);
host_c2h_write_io_cfg_reg(EC_CFG_IDX_DATA_IO_ADDR_L,
(CONFIG_ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM + 4) & 0xff);
#endif
/* Enable 'Host Command' io port (PM Channel 2) */ /* Enable 'Host Command' io port (PM Channel 2) */
host_c2h_write_io_cfg_reg(EC_CFG_IDX_CTRL, 0x01); host_c2h_write_io_cfg_reg(EC_CFG_IDX_CTRL, 0x01);
@ -910,8 +940,12 @@ void npcx_host_init_subs_host_domain(void)
host_c2h_write_io_cfg_reg(0xF1, host_c2h_write_io_cfg_reg(0xF1,
host_c2h_read_io_cfg_reg(0xF1) | 0x30); host_c2h_read_io_cfg_reg(0xF1) | 0x30);
/* 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); #if defined(CONFIG_ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM)
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_1,
(CONFIG_ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM >> 8) & 0xff);
host_c2h_write_io_cfg_reg(EC_CFG_IDX_SHM_WND1_ADDR_0,
CONFIG_ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM & 0xff);
#endif
/* Set WIN2 as MEMMAP on the configured IO address */ /* Set WIN2 as MEMMAP on the configured IO address */
#if defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION_PORT_NUM) #if defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION_PORT_NUM)
host_c2h_write_io_cfg_reg(EC_CFG_IDX_SHM_WND2_ADDR_1, host_c2h_write_io_cfg_reg(EC_CFG_IDX_SHM_WND2_ADDR_1,

View file

@ -156,7 +156,10 @@ enum espi_virtual_peripheral {
ESPI_PERIPHERAL_8042_KBC, ESPI_PERIPHERAL_8042_KBC,
ESPI_PERIPHERAL_HOST_IO, ESPI_PERIPHERAL_HOST_IO,
ESPI_PERIPHERAL_DEBUG_PORT80, ESPI_PERIPHERAL_DEBUG_PORT80,
ESPI_PERIPHERAL_HOST_IO_PVT ESPI_PERIPHERAL_HOST_IO_PVT,
#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD)
ESPI_PERIPHERAL_EC_HOST_CMD,
#endif /* CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD */
}; };
/** /**
@ -245,6 +248,8 @@ enum lpc_peripheral_opcode {
#if defined(CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE) #if defined(CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE)
/* Other customized transactions */ /* Other customized transactions */
ECUSTOM_HOST_SUBS_INTERRUPT_EN = ECUSTOM_START_OPCODE, ECUSTOM_HOST_SUBS_INTERRUPT_EN = ECUSTOM_START_OPCODE,
ECUSTOM_HOST_CMD_GET_PARAM_MEMORY,
ECUSTOM_HOST_CMD_SEND_RESULT,
#endif /* CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE */ #endif /* CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE */
}; };