From 70d4559fdfb4a16f2958a32acc717c895f84e897 Mon Sep 17 00:00:00 2001 From: Jay Vasanth Date: Mon, 1 Nov 2021 14:58:49 -0400 Subject: [PATCH] Microchip: MEC172x: eSPI driver Updates to MEC172x eSPI driver to support ACPI shared memory region and EC Host Command Subsystem through ACPI_EC1 and Embedded Memory Interface (EMI). Signed-off-by: Jay Vasanth --- .../mec172xevb_assy6906.dts | 4 + drivers/espi/Kconfig.xec_v2 | 16 +++ drivers/espi/espi_mchp_xec_host_v2.c | 135 +++++++++++++++++- .../microchip_mec/mec172x/reg/mec172x_emi.h | 50 +++++++ soc/arm/microchip_mec/mec172x/soc.h | 1 + 5 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 soc/arm/microchip_mec/mec172x/reg/mec172x_emi.h diff --git a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.dts b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.dts index c81159ad450..468bfbe18a8 100644 --- a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.dts +++ b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.dts @@ -97,6 +97,10 @@ status = "okay"; }; +&emi0 { + status = "okay"; +}; + &p80bd0 { status = "okay"; }; diff --git a/drivers/espi/Kconfig.xec_v2 b/drivers/espi/Kconfig.xec_v2 index 25a3c88a2c3..351f90c852f 100644 --- a/drivers/espi/Kconfig.xec_v2 +++ b/drivers/espi/Kconfig.xec_v2 @@ -10,6 +10,22 @@ config ESPI_XEC_V2 help Enable the Microchip XEC ESPI driver for MEC172x series. +config ESPI_XEC_PERIPHERAL_ACPI_SHD_MEM_SIZE + int "Host I/O peripheral port size for shared memory in MEC172X series" + depends on ESPI_XEC_V2 || 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. + +config ESPI_XEC_PERIPHERAL_HOST_CMD_PARAM_SIZE + int "Host I/O peripheral port size for ec host command in MEC172X series" + depends on ESPI_XEC_V2 || 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. + if ESPI_XEC_V2 config ESPI_OOB_CHANNEL diff --git a/drivers/espi/espi_mchp_xec_host_v2.c b/drivers/espi/espi_mchp_xec_host_v2.c index a00e7f86d33..1ab30f17531 100644 --- a/drivers/espi/espi_mchp_xec_host_v2.c +++ b/drivers/espi/espi_mchp_xec_host_v2.c @@ -448,7 +448,8 @@ static int init_acpi_ec0(const struct device *dev) #endif /* CONFIG_ESPI_PERIPHERAL_HOST_IO */ -#ifdef CONFIG_ESPI_PERIPHERAL_HOST_IO_PVT +#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) || \ + defined(CONFIG_ESPI_PERIPHERAL_HOST_IO_PVT) static const struct xec_acpi_ec_config xec_acpi_ec1_cfg = { .regbase = DT_REG_ADDR(DT_NODELABEL(acpi_ec1)), @@ -462,7 +463,11 @@ static void acpi_ec1_ibf_isr(const struct device *dev) (struct espi_xec_data *const)dev->data; struct espi_event evt = { .evt_type = ESPI_BUS_PERIPHERAL_NOTIFICATION, +#ifdef CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD + .evt_details = ESPI_PERIPHERAL_EC_HOST_CMD, +#else .evt_details = ESPI_PERIPHERAL_HOST_IO_PVT, +#endif .evt_data = ESPI_PERIPHERAL_NODATA }; @@ -509,11 +514,17 @@ static int init_acpi_ec1(const struct device *dev) struct espi_xec_config *const cfg = ESPI_XEC_CONFIG(dev); struct espi_iom_regs *regs = (struct espi_iom_regs *)cfg->base_addr; +#ifdef CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD + regs->IOHBAR[IOB_ACPI_EC1] = + (CONFIG_ESPI_PERIPHERAL_HOST_CMD_DATA_PORT_NUM << 16) | + MCHP_ESPI_IO_BAR_HOST_VALID; +#else regs->IOHBAR[IOB_ACPI_EC1] = CONFIG_ESPI_PERIPHERAL_HOST_IO_PVT_PORT_NUM | MCHP_ESPI_IO_BAR_HOST_VALID; regs->IOHBAR[IOB_MBOX] = ESPI_XEC_MBOX_BAR_ADDRESS | MCHP_ESPI_IO_BAR_HOST_VALID; +#endif return 0; } @@ -523,7 +534,123 @@ static int init_acpi_ec1(const struct device *dev) #undef INIT_ACPI_EC1 #define INIT_ACPI_EC1 init_acpi_ec1 -#endif /* CONFIG_ESPI_PERIPHERAL_HOST_IO_PVT */ +#endif /* CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD || CONFIG_ESPI_PERIPHERAL_HOST_IO_PVT */ + +#ifdef CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD + +BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(emi0), okay), + "XEC EMI0 DT node is disabled!"); + +struct xec_emi_config { + uintptr_t regbase; +}; + +static const struct xec_emi_config xec_emi0_cfg = { + .regbase = DT_REG_ADDR(DT_NODELABEL(emi0)), +}; + +#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION +static uint8_t ec_host_cmd_sram[CONFIG_ESPI_XEC_PERIPHERAL_HOST_CMD_PARAM_SIZE + + CONFIG_ESPI_XEC_PERIPHERAL_ACPI_SHD_MEM_SIZE]; +#else +static uint8_t ec_host_cmd_sram[CONFIG_ESPI_XEC_PERIPHERAL_HOST_CMD_PARAM_SIZE]; +#endif + +static int init_emi0(const struct device *dev) +{ + struct espi_xec_config *const cfg = ESPI_XEC_CONFIG(dev); + struct espi_iom_regs *regs = (struct espi_iom_regs *)cfg->base_addr; + struct emi_regs *emi_hw = + (struct emi_regs *)xec_emi0_cfg.regbase; + + regs->IOHBAR[IOB_EMI0] = + (CONFIG_ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM << 16) | + MCHP_ESPI_IO_BAR_HOST_VALID; + + emi_hw->MEM_BA_0 = (uint32_t)ec_host_cmd_sram; +#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION + emi_hw->MEM_RL_0 = CONFIG_ESPI_XEC_PERIPHERAL_HOST_CMD_PARAM_SIZE + + CONFIG_ESPI_XEC_PERIPHERAL_ACPI_SHD_MEM_SIZE; +#else + emi_hw->MEM_RL_0 = CONFIG_ESPI_XEC_PERIPHERAL_HOST_CMD_PARAM_SIZE; +#endif + emi_hw->MEM_WL_0 = CONFIG_ESPI_XEC_PERIPHERAL_HOST_CMD_PARAM_SIZE; + + return 0; +} + +#undef INIT_EMI0 +#define INIT_EMI0 init_emi0 + +#endif /* CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD */ + +#ifdef CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE + +static int ecust_rd_req(const struct device *dev, + enum lpc_peripheral_opcode op, + uint32_t *data) +{ + ARG_UNUSED(dev); + + switch (op) { +#ifdef CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD + case ECUSTOM_HOST_CMD_GET_PARAM_MEMORY: + *data = (uint32_t)ec_host_cmd_sram; + break; +#endif + default: + return -EINVAL; + } + + return 0; +} + +static int ecust_wr_req(const struct device *dev, + enum lpc_peripheral_opcode op, + uint32_t *data) +{ + ARG_UNUSED(dev); + ARG_UNUSED(op); + ARG_UNUSED(data); + + return -EINVAL; +} + +#endif /* CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE */ + +#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) && \ + defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION) + +static int eacpi_shm_rd_req(const struct device *dev, + enum lpc_peripheral_opcode op, + uint32_t *data) +{ + ARG_UNUSED(dev); + + switch (op) { + case EACPI_GET_SHARED_MEMORY: + *data = (uint32_t)&ec_host_cmd_sram[CONFIG_ESPI_XEC_PERIPHERAL_HOST_CMD_PARAM_SIZE]; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int eacpi_shm_wr_req(const struct device *dev, + enum lpc_peripheral_opcode op, + uint32_t *data) +{ + ARG_UNUSED(dev); + ARG_UNUSED(op); + ARG_UNUSED(data); + + return -EINVAL; +} + +#endif /* CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION */ + #ifdef CONFIG_ESPI_PERIPHERAL_DEBUG_PORT_80 @@ -754,6 +881,10 @@ static const struct espi_lpc_req espi_lpc_req_tbl[] = { #ifdef CONFIG_ESPI_PERIPHERAL_HOST_IO { EACPI_START_OPCODE, EACPI_MAX_OPCODE, eacpi_rd_req, eacpi_wr_req }, #endif +#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) && \ + defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION) + { EACPI_GET_SHARED_MEMORY, EACPI_GET_SHARED_MEMORY, eacpi_shm_rd_req, eacpi_shm_wr_req}, +#endif #ifdef CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE { ECUSTOM_START_OPCODE, ECUSTOM_MAX_OPCODE, ecust_rd_req, ecust_wr_req}, #endif diff --git a/soc/arm/microchip_mec/mec172x/reg/mec172x_emi.h b/soc/arm/microchip_mec/mec172x/reg/mec172x_emi.h new file mode 100644 index 00000000000..5f4d3748c8f --- /dev/null +++ b/soc/arm/microchip_mec/mec172x/reg/mec172x_emi.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _MEC172X_EMI_H +#define _MEC172X_EMI_H + +#include +#include + +/** @brief Embedded Memory Interface (EMI) Registers */ +struct emi_regs { + volatile uint8_t RT_HOST_TO_EC; + volatile uint8_t RT_EC_TO_HOST; + volatile uint8_t EC_ADDR_LSB; + volatile uint8_t EC_ADDR_MSB; + volatile uint8_t EC_DATA_0; /* +0x04 */ + volatile uint8_t EC_DATA_1; + volatile uint8_t EC_DATA_2; + volatile uint8_t EC_DATA_3; + volatile uint8_t INTR_SRC_LSB; /* +0x08 */ + volatile uint8_t INTR_SRC_MSB; + volatile uint8_t INTR_MSK_LSB; + volatile uint8_t INTR_MSK_MSB; + volatile uint8_t APPID; /* +0x0C */ + uint16_t RSVD1[3]; + volatile uint8_t APPID_ASSGN; /* +0x10 */ + uint16_t RSVD2[3]; + uint32_t RSVD3[(0x100 - 0x14) / 4]; + volatile uint8_t HOST_TO_EC; /* +0x100 */ + volatile uint8_t EC_TO_HOST; + uint16_t RSVD4[1]; + volatile uint32_t MEM_BA_0; /* +0x104 */ + volatile uint16_t MEM_RL_0; /* +0x108 */ + volatile uint16_t MEM_WL_0; + volatile uint32_t MEM_BA_1; /* +0x10C */ + volatile uint16_t MEM_RL_1; /* +0x110 */ + volatile uint16_t MEM_WL_1; + volatile uint16_t INTR_SET; /* +0x114 */ + volatile uint16_t HOST_CLR_EN; /* +0x116 */ + uint32_t RSVD5[2]; + volatile uint32_t APPID_STS_1; /* +0x120 */ + volatile uint32_t APPID_STS_2; + volatile uint32_t APPID_STS_3; + volatile uint32_t APPID_STS_4; +}; + +#endif /* #ifndef _MEC172X_EMI_H */ diff --git a/soc/arm/microchip_mec/mec172x/soc.h b/soc/arm/microchip_mec/mec172x/soc.h index a9bbbee1a3b..b8ea715a9dc 100644 --- a/soc/arm/microchip_mec/mec172x/soc.h +++ b/soc/arm/microchip_mec/mec172x/soc.h @@ -39,6 +39,7 @@ #include "reg/mec172x_pcr.h" #include "reg/mec172x_qspi.h" #include "reg/mec172x_vbat.h" +#include "reg/mec172x_emi.h" /* common peripheral register defines */ #include "../common/reg/mec_acpi_ec.h"