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 <jay.vasanth@microchip.com>
This commit is contained in:
Jay Vasanth 2021-11-01 14:58:49 -04:00 committed by Carles Cufí
commit 70d4559fdf
5 changed files with 204 additions and 2 deletions

View file

@ -97,6 +97,10 @@
status = "okay";
};
&emi0 {
status = "okay";
};
&p80bd0 {
status = "okay";
};

View file

@ -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

View file

@ -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

View file

@ -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 <stdint.h>
#include <stddef.h>
/** @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 */

View file

@ -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"