espi: it8xxx2: enable configuration of Chromebook
This enables the below configuration so the AP and EC are able to communicate over eSPI: CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE Signed-off-by: Dino Li <Dino.Li@ite.com.tw>
This commit is contained in:
parent
f3c1acaeea
commit
36164c29c1
8 changed files with 434 additions and 7 deletions
|
@ -21,6 +21,101 @@ config ESPI_PERIPHERAL_HOST_IO
|
|||
config ESPI_PERIPHERAL_DEBUG_PORT_80
|
||||
default y
|
||||
|
||||
config ESPI_PERIPHERAL_EC_HOST_CMD
|
||||
default y
|
||||
|
||||
choice IT8XXX2_H2RAM_HC_SIZE_CHOICE
|
||||
prompt "H2RAM space for ec host command"
|
||||
default IT8XXX2_H2RAM_HC_SIZE_256
|
||||
depends on ESPI_PERIPHERAL_EC_HOST_CMD
|
||||
|
||||
config IT8XXX2_H2RAM_HC_SIZE_16
|
||||
bool "16"
|
||||
|
||||
config IT8XXX2_H2RAM_HC_SIZE_32
|
||||
bool "32"
|
||||
|
||||
config IT8XXX2_H2RAM_HC_SIZE_64
|
||||
bool "64"
|
||||
|
||||
config IT8XXX2_H2RAM_HC_SIZE_128
|
||||
bool "128"
|
||||
|
||||
config IT8XXX2_H2RAM_HC_SIZE_256
|
||||
bool "256"
|
||||
|
||||
config IT8XXX2_H2RAM_HC_SIZE_512
|
||||
bool "512"
|
||||
|
||||
config IT8XXX2_H2RAM_HC_SIZE_1024
|
||||
bool "1024"
|
||||
|
||||
config IT8XXX2_H2RAM_HC_SIZE_2048
|
||||
bool "2048"
|
||||
|
||||
endchoice
|
||||
|
||||
config ESPI_IT8XXX2_HC_H2RAM_SIZE
|
||||
int
|
||||
depends on ESPI_PERIPHERAL_EC_HOST_CMD
|
||||
default 16 if IT8XXX2_H2RAM_HC_SIZE_16
|
||||
default 32 if IT8XXX2_H2RAM_HC_SIZE_32
|
||||
default 64 if IT8XXX2_H2RAM_HC_SIZE_64
|
||||
default 128 if IT8XXX2_H2RAM_HC_SIZE_128
|
||||
default 256 if IT8XXX2_H2RAM_HC_SIZE_256
|
||||
default 512 if IT8XXX2_H2RAM_HC_SIZE_512
|
||||
default 1024 if IT8XXX2_H2RAM_HC_SIZE_1024
|
||||
default 2048 if IT8XXX2_H2RAM_HC_SIZE_2048
|
||||
|
||||
config ESPI_PERIPHERAL_ACPI_SHM_REGION
|
||||
default y
|
||||
|
||||
choice IT8XXX2_H2RAM_ACPI_SHM_SIZE_CHOICE
|
||||
prompt "H2RAM space for ACPI shared memory region"
|
||||
default IT8XXX2_H2RAM_ACPI_SHM_SIZE_256
|
||||
depends on ESPI_PERIPHERAL_ACPI_SHM_REGION
|
||||
|
||||
config IT8XXX2_H2RAM_ACPI_SHM_SIZE_16
|
||||
bool "16"
|
||||
|
||||
config IT8XXX2_H2RAM_ACPI_SHM_SIZE_32
|
||||
bool "32"
|
||||
|
||||
config IT8XXX2_H2RAM_ACPI_SHM_SIZE_64
|
||||
bool "64"
|
||||
|
||||
config IT8XXX2_H2RAM_ACPI_SHM_SIZE_128
|
||||
bool "128"
|
||||
|
||||
config IT8XXX2_H2RAM_ACPI_SHM_SIZE_256
|
||||
bool "256"
|
||||
|
||||
config IT8XXX2_H2RAM_ACPI_SHM_SIZE_512
|
||||
bool "512"
|
||||
|
||||
config IT8XXX2_H2RAM_ACPI_SHM_SIZE_1024
|
||||
bool "1024"
|
||||
|
||||
config IT8XXX2_H2RAM_ACPI_SHM_SIZE_2048
|
||||
bool "2048"
|
||||
|
||||
endchoice
|
||||
|
||||
config ESPI_IT8XXX2_ACPI_SHM_H2RAM_SIZE
|
||||
int
|
||||
depends on ESPI_PERIPHERAL_ACPI_SHM_REGION
|
||||
default 16 if IT8XXX2_H2RAM_ACPI_SHM_SIZE_16
|
||||
default 32 if IT8XXX2_H2RAM_ACPI_SHM_SIZE_32
|
||||
default 64 if IT8XXX2_H2RAM_ACPI_SHM_SIZE_64
|
||||
default 128 if IT8XXX2_H2RAM_ACPI_SHM_SIZE_128
|
||||
default 256 if IT8XXX2_H2RAM_ACPI_SHM_SIZE_256
|
||||
default 512 if IT8XXX2_H2RAM_ACPI_SHM_SIZE_512
|
||||
default 1024 if IT8XXX2_H2RAM_ACPI_SHM_SIZE_1024
|
||||
default 2048 if IT8XXX2_H2RAM_ACPI_SHM_SIZE_2048
|
||||
|
||||
config ESPI_PERIPHERAL_CUSTOM_OPCODE
|
||||
default y
|
||||
|
||||
config ESPI_FLASH_CHANNEL
|
||||
default y
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL);
|
|||
#define IT8XXX2_KBC_OBE_IRQ DT_INST_IRQ_BY_IDX(0, 3, irq)
|
||||
#define IT8XXX2_PMC1_IBF_IRQ DT_INST_IRQ_BY_IDX(0, 4, irq)
|
||||
#define IT8XXX2_PORT_80_IRQ DT_INST_IRQ_BY_IDX(0, 5, irq)
|
||||
#define IT8XXX2_PMC2_IBF_IRQ DT_INST_IRQ_BY_IDX(0, 6, irq)
|
||||
|
||||
/* General Capabilities and Configuration 1 */
|
||||
#define IT8XXX2_ESPI_MAX_FREQ_MASK GENMASK(2, 0)
|
||||
|
@ -72,6 +73,7 @@ struct espi_it8xxx2_config {
|
|||
uintptr_t base_ec2i;
|
||||
uintptr_t base_kbc;
|
||||
uintptr_t base_pmc;
|
||||
uintptr_t base_smfi;
|
||||
};
|
||||
|
||||
struct espi_it8xxx2_data {
|
||||
|
@ -153,6 +155,125 @@ static const struct ec2i_t pmc1_settings[] = {
|
|||
{HOST_INDEX_LDA, 0x01},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD
|
||||
#define IT8XXX2_ESPI_HC_DATA_PORT_MSB \
|
||||
((CONFIG_ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM >> 8) & 0xff)
|
||||
#define IT8XXX2_ESPI_HC_DATA_PORT_LSB \
|
||||
(CONFIG_ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM & 0xff)
|
||||
#define IT8XXX2_ESPI_HC_CMD_PORT_MSB \
|
||||
(((CONFIG_ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM + 4) >> 8) & 0xff)
|
||||
#define IT8XXX2_ESPI_HC_CMD_PORT_LSB \
|
||||
((CONFIG_ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM + 4) & 0xff)
|
||||
static const struct ec2i_t pmc2_settings[] = {
|
||||
/* Select logical device 12h(PM2 host command) */
|
||||
{HOST_INDEX_LDN, LDN_PMC2},
|
||||
/* I/O Port Base Address (data/command ports) */
|
||||
{HOST_INDEX_IOBAD0_MSB, IT8XXX2_ESPI_HC_DATA_PORT_MSB},
|
||||
{HOST_INDEX_IOBAD0_LSB, IT8XXX2_ESPI_HC_DATA_PORT_LSB},
|
||||
{HOST_INDEX_IOBAD1_MSB, IT8XXX2_ESPI_HC_CMD_PORT_MSB},
|
||||
{HOST_INDEX_IOBAD1_LSB, IT8XXX2_ESPI_HC_CMD_PORT_LSB},
|
||||
/* Set IRQ=00h for logical device */
|
||||
{HOST_INDEX_IRQNUMX, 0x00},
|
||||
/* Enable logical device */
|
||||
{HOST_INDEX_LDA, 0x01},
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) || \
|
||||
defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
|
||||
/*
|
||||
* Host to RAM (H2RAM) memory mapping.
|
||||
* This feature allows host access EC's memory directly by eSPI I/O cycles.
|
||||
* Mapping range is 4K bytes and base address is adjustable.
|
||||
* Eg. the I/O cycle 800h~8ffh from host can be mapped to x800h~x8ffh.
|
||||
* Linker script of h2ram.ld will make the pool 4K aligned.
|
||||
*/
|
||||
#define IT8XXX2_ESPI_H2RAM_POOL_SIZE 0x1000
|
||||
static uint8_t h2ram_pool[IT8XXX2_ESPI_H2RAM_POOL_SIZE]
|
||||
__attribute__((section(".h2ram_pool")));
|
||||
|
||||
#if defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
|
||||
#define H2RAM_ACPI_SHM_MAX ((CONFIG_ESPI_IT8XXX2_ACPI_SHM_H2RAM_SIZE) + \
|
||||
(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION_PORT_NUM))
|
||||
#if (H2RAM_ACPI_SHM_MAX > IT8XXX2_ESPI_H2RAM_POOL_SIZE)
|
||||
#error "ACPI shared memory region out of h2ram"
|
||||
#endif
|
||||
#endif /* CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION */
|
||||
|
||||
#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD)
|
||||
#define H2RAM_EC_HOST_CMD_MAX ((CONFIG_ESPI_IT8XXX2_HC_H2RAM_SIZE) + \
|
||||
(CONFIG_ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM))
|
||||
#if (H2RAM_EC_HOST_CMD_MAX > IT8XXX2_ESPI_H2RAM_POOL_SIZE)
|
||||
#error "EC host command parameters out of h2ram"
|
||||
#endif
|
||||
#endif /* CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD */
|
||||
|
||||
#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) && \
|
||||
defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
|
||||
#if (MIN(H2RAM_ACPI_SHM_MAX, H2RAM_EC_HOST_CMD_MAX) > \
|
||||
MAX(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION_PORT_NUM, \
|
||||
CONFIG_ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM))
|
||||
#error "ACPI and HC sections of h2ram overlap"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define H2RAM_WINDOW_SIZE(ram_size) ((find_msb_set((ram_size) / 16) - 1) & 0x7)
|
||||
|
||||
static const struct ec2i_t smfi_settings[] = {
|
||||
/* Select logical device 0Fh(SMFI) */
|
||||
{HOST_INDEX_LDN, LDN_SMFI},
|
||||
/* Internal RAM base address on eSPI I/O space */
|
||||
{HOST_INDEX_DSLDC6, 0x00},
|
||||
/* Enable H2RAM eSPI I/O cycle */
|
||||
{HOST_INDEX_DSLDC7, 0x01},
|
||||
/* Enable logical device */
|
||||
{HOST_INDEX_LDA, 0x01},
|
||||
};
|
||||
|
||||
static void smfi_it8xxx2_init(const struct device *dev)
|
||||
{
|
||||
const struct espi_it8xxx2_config *const config = dev->config;
|
||||
struct flash_it8xxx2_regs *const smfi_reg =
|
||||
(struct flash_it8xxx2_regs *)config->base_smfi;
|
||||
struct gctrl_it8xxx2_regs *const gctrl = ESPI_IT8XXX2_GET_GCTRL_BASE;
|
||||
uint8_t h2ram_offset;
|
||||
|
||||
/* Set the host to RAM cycle address offset */
|
||||
h2ram_offset = ((uint32_t)h2ram_pool & 0xffff) /
|
||||
IT8XXX2_ESPI_H2RAM_POOL_SIZE;
|
||||
gctrl->GCTRL_H2ROFSR |= h2ram_offset;
|
||||
|
||||
#ifdef CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD
|
||||
memset(&h2ram_pool[CONFIG_ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM], 0,
|
||||
CONFIG_ESPI_IT8XXX2_HC_H2RAM_SIZE);
|
||||
/* Set host RAM window 0 base address */
|
||||
smfi_reg->SMFI_HRAMW0BA =
|
||||
(CONFIG_ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM >> 4) & 0xff;
|
||||
/* Set host RAM window 0 size. (allow R/W) */
|
||||
smfi_reg->SMFI_HRAMW0AAS =
|
||||
H2RAM_WINDOW_SIZE(CONFIG_ESPI_IT8XXX2_HC_H2RAM_SIZE);
|
||||
/* Enable window 0, H2RAM through IO cycle */
|
||||
smfi_reg->SMFI_HRAMWC |= (SMFI_H2RAMPS | SMFI_H2RAMW0E);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
|
||||
memset(&h2ram_pool[CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION_PORT_NUM], 0,
|
||||
CONFIG_ESPI_IT8XXX2_ACPI_SHM_H2RAM_SIZE);
|
||||
/* Set host RAM window 1 base address */
|
||||
smfi_reg->SMFI_HRAMW1BA =
|
||||
(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION_PORT_NUM >> 4) & 0xff;
|
||||
/* Set host RAM window 1 size. (read-only) */
|
||||
smfi_reg->SMFI_HRAMW1AAS =
|
||||
H2RAM_WINDOW_SIZE(CONFIG_ESPI_IT8XXX2_ACPI_SHM_H2RAM_SIZE) |
|
||||
SMFI_HRAMWXWPE_ALL;
|
||||
/* Enable window 1, H2RAM through IO cycle */
|
||||
smfi_reg->SMFI_HRAMWC |= (SMFI_H2RAMPS | SMFI_H2RAMW1E);
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD ||
|
||||
* CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
|
||||
*/
|
||||
|
||||
static void ec2i_it8xxx2_wait_status_cleared(const struct device *dev,
|
||||
uint8_t mask)
|
||||
{
|
||||
|
@ -230,6 +351,13 @@ static void pnpcfg_it8xxx2_init(const struct device *dev)
|
|||
if (IS_ENABLED(CONFIG_ESPI_PERIPHERAL_HOST_IO)) {
|
||||
PNPCFG(pmc1);
|
||||
}
|
||||
#ifdef CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD
|
||||
PNPCFG(pmc2);
|
||||
#endif
|
||||
#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) || \
|
||||
defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
|
||||
PNPCFG(smfi);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* KBC (port 60h/64h) */
|
||||
|
@ -387,6 +515,41 @@ static void port80_it8xxx2_init(const struct device *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD
|
||||
/* PMC 2 (Host command port CONFIG_ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM) */
|
||||
static void pmc2_it8xxx2_ibf_isr(const struct device *dev)
|
||||
{
|
||||
const struct espi_it8xxx2_config *const config = dev->config;
|
||||
struct espi_it8xxx2_data *const data = dev->data;
|
||||
struct pmc_regs *const pmc_reg = (struct pmc_regs *)config->base_pmc;
|
||||
struct espi_event evt = {
|
||||
ESPI_BUS_PERIPHERAL_NOTIFICATION,
|
||||
ESPI_PERIPHERAL_EC_HOST_CMD,
|
||||
ESPI_PERIPHERAL_NODATA
|
||||
};
|
||||
|
||||
/* Set processing flag before reading command byte */
|
||||
pmc_reg->PM2STS |= PMC_PM2STS_GPF;
|
||||
evt.evt_data = pmc_reg->PM2DI;
|
||||
|
||||
espi_send_callbacks(&data->callbacks, dev, evt);
|
||||
}
|
||||
|
||||
static void pmc2_it8xxx2_init(const struct device *dev)
|
||||
{
|
||||
const struct espi_it8xxx2_config *const config = dev->config;
|
||||
struct pmc_regs *const pmc_reg = (struct pmc_regs *)config->base_pmc;
|
||||
|
||||
/* Dedicated interrupt for PMC2 */
|
||||
pmc_reg->MBXCTRL |= PMC_MBXCTRL_DINT;
|
||||
/* Enable pmc2 input buffer full interrupt */
|
||||
pmc_reg->PM2CTL |= PMC_PM2CTL_IBFIE;
|
||||
IRQ_CONNECT(IT8XXX2_PMC2_IBF_IRQ, 0, pmc2_it8xxx2_ibf_isr,
|
||||
DEVICE_DT_INST_GET(0), 0);
|
||||
irq_enable(IT8XXX2_PMC2_IBF_IRQ);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* eSPI api functions */
|
||||
#define VW_CHAN(signal, index, level, valid) \
|
||||
[signal] = {.vw_index = index, .level_mask = level, .valid_mask = valid}
|
||||
|
@ -616,10 +779,30 @@ static int espi_it8xxx2_read_lpc_request(const struct device *dev,
|
|||
case EACPI_READ_STS:
|
||||
*data = pmc_reg->PM1STS;
|
||||
break;
|
||||
#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
|
||||
case EACPI_GET_SHARED_MEMORY:
|
||||
*data = (uint32_t)&h2ram_pool[
|
||||
CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION_PORT_NUM];
|
||||
break;
|
||||
#endif /* CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION */
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
#ifdef CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE
|
||||
else if (op >= ECUSTOM_START_OPCODE && op <= ECUSTOM_MAX_OPCODE) {
|
||||
|
||||
switch (op) {
|
||||
case ECUSTOM_HOST_CMD_GET_PARAM_MEMORY:
|
||||
*data = (uint32_t)&h2ram_pool[
|
||||
CONFIG_ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM];
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE */
|
||||
else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
|
@ -695,7 +878,33 @@ static int espi_it8xxx2_write_lpc_request(const struct device *dev,
|
|||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
#ifdef CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE
|
||||
else if (op >= ECUSTOM_START_OPCODE && op <= ECUSTOM_MAX_OPCODE) {
|
||||
struct pmc_regs *const pmc_reg =
|
||||
(struct pmc_regs *)config->base_pmc;
|
||||
|
||||
switch (op) {
|
||||
/* Enable/Disable PMC1 (port 62h/66h) interrupt */
|
||||
case ECUSTOM_HOST_SUBS_INTERRUPT_EN:
|
||||
if (*data) {
|
||||
pmc_reg->PM1CTL |= PMC_PM1CTL_IBFIE;
|
||||
} else {
|
||||
pmc_reg->PM1CTL &= ~PMC_PM1CTL_IBFIE;
|
||||
}
|
||||
break;
|
||||
case ECUSTOM_HOST_CMD_SEND_RESULT:
|
||||
/* Write result to data output port (set OBF status) */
|
||||
pmc_reg->PM2DO = (*data & 0xff);
|
||||
/* Clear processing flag */
|
||||
pmc_reg->PM2STS &= ~PMC_PM2STS_GPF;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE */
|
||||
else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
|
@ -1606,6 +1815,7 @@ static const struct espi_it8xxx2_config espi_it8xxx2_config_0 = {
|
|||
.base_ec2i = DT_INST_REG_ADDR_BY_IDX(0, 4),
|
||||
.base_kbc = DT_INST_REG_ADDR_BY_IDX(0, 5),
|
||||
.base_pmc = DT_INST_REG_ADDR_BY_IDX(0, 6),
|
||||
.base_smfi = DT_INST_REG_ADDR_BY_IDX(0, 7),
|
||||
};
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0, &espi_it8xxx2_init, NULL,
|
||||
|
@ -1642,6 +1852,14 @@ static int espi_it8xxx2_init(const struct device *dev)
|
|||
/* Accept Port 80h Cycle */
|
||||
port80_it8xxx2_init(dev);
|
||||
#endif
|
||||
#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) || \
|
||||
defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
|
||||
smfi_it8xxx2_init(dev);
|
||||
#endif
|
||||
#ifdef CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD
|
||||
/* enable pmc2 for host command port */
|
||||
pmc2_it8xxx2_init(dev);
|
||||
#endif
|
||||
|
||||
/* Reset vwidx_cached_flag[] at initialization */
|
||||
espi_it8xxx2_reset_vwidx_cache(dev);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue