Microchip: MEC172x: eSPI driver

MEC172x eSPI driver, eSPI pin programming, interrupt updates related
to eSPI and other updates for MEC172x eSPI driver.

Signed-off-by: Jay Vasanth <jay.vasanth@microchip.com>
This commit is contained in:
Jay Vasanth 2021-10-18 16:44:45 -04:00 committed by Christopher Friedt
parent bf68b670f1
commit c214c59548
24 changed files with 3291 additions and 79 deletions

View file

@ -54,6 +54,15 @@
status = "okay";
};
/* Enable aggregated GIRQ24 and GIRQ25 for eSPI virtual wires interrupts */
&girq24 {
status = "okay";
};
&girq25 {
status = "okay";
};
&rtimer {
status = "okay";
};
@ -71,6 +80,27 @@
status = "okay";
};
&espi0 {
status = "okay";
};
/* enable various eSPI child devices (host facing) */
&kbc0 {
status = "okay";
};
&acpi_ec0 {
status = "okay";
};
&acpi_ec1 {
status = "okay";
};
&p80bd0 {
status = "okay";
};
&i2c_smb_0 {
status = "okay";
label = "I2C0";

View file

@ -17,3 +17,4 @@ CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_ADC=y
CONFIG_I2C=y
CONFIG_ESPI=y

View file

@ -7,10 +7,27 @@
#include <device.h>
#include <init.h>
#include <kernel.h>
#include <drivers/clock_control/mchp_xec_clock_control.h>
#include <drivers/pinmux.h>
#include <soc.h>
enum gpio_ports {
port_000_036 = 0,
port_040_076,
port_100_136,
port_140_176,
port_200_236,
port_240_276,
port_max,
};
struct pin_info {
enum gpio_ports port_num;
uint8_t pin;
uint32_t flags;
};
struct pinmux_ports_t {
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_000_036), okay)
const struct device *porta;
@ -32,6 +49,31 @@ struct pinmux_ports_t {
#endif
};
const struct pin_info uart_pin_table[] = {
#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay)
{ port_100_136, MCHP_GPIO_104, MCHP_GPIO_CTRL_MUX_F1 },
{ port_100_136, MCHP_GPIO_105, MCHP_GPIO_CTRL_MUX_F1 },
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay)
{ port_140_176, MCHP_GPIO_170, MCHP_GPIO_CTRL_MUX_F1 },
{ port_140_176, MCHP_GPIO_171, MCHP_GPIO_CTRL_MUX_F1 },
#endif
};
/* eSPI: Reset#, Alert#, CS#, CLK, IO0 - IO4 */
const struct pin_info espi_pin_table[] = {
#if defined(CONFIG_ESPI_XEC_V2) && DT_NODE_HAS_STATUS(DT_NODELABEL(espi0), okay)
{ port_040_076, MCHP_GPIO_061, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_063, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_066, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_065, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_070, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_071, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_072, MCHP_GPIO_CTRL_MUX_F1 },
{ port_040_076, MCHP_GPIO_073, MCHP_GPIO_CTRL_MUX_F1 },
#endif
};
static void brd_init_pinmux_ports(struct pinmux_ports_t *pp)
{
ARG_UNUSED(pp);
@ -68,16 +110,52 @@ static void brd_init_pinmux_ports(struct pinmux_ports_t *pp)
#endif
}
static void brd_cfg_uart(struct pinmux_ports_t *pp)
const struct device *get_port_device(struct pinmux_ports_t *pp,
uint8_t port_num)
{
#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay)
pinmux_pin_set(pp->portc, MCHP_GPIO_104, MCHP_GPIO_CTRL_MUX_F1);
pinmux_pin_set(pp->portc, MCHP_GPIO_105, MCHP_GPIO_CTRL_MUX_F1);
switch (port_num) {
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_000_036), okay)
case port_000_036:
return pp->porta;
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay)
pinmux_pin_set(pp->portd, MCHP_GPIO_170, MCHP_GPIO_CTRL_MUX_F1);
pinmux_pin_set(pp->portd, MCHP_GPIO_171, MCHP_GPIO_CTRL_MUX_F1);
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_040_076), okay)
case port_040_076:
return pp->portb;
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_100_136), okay)
case port_100_136:
return pp->portc;
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_140_176), okay)
case port_140_176:
return pp->portd;
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_200_236), okay)
case port_200_236:
return pp->porte;
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_240_276), okay)
case port_240_276:
return pp->portf;
#endif
default:
return NULL;
}
}
static void brd_pin_table_init(struct pinmux_ports_t *pp,
const struct pin_info *table, size_t nentries)
{
for (size_t n = 0; n < nentries; n++) {
const struct device *dev =
get_port_device(pp, table[n].port_num);
if (!dev) {
continue;
}
pinmux_pin_set(dev, table[n].pin, table[n].flags);
}
}
/* caller passes dev = NULL */
@ -87,7 +165,8 @@ static int board_pinmux_init(const struct device *dev)
struct pinmux_ports_t pp;
brd_init_pinmux_ports(&pp);
brd_cfg_uart(&pp);
brd_pin_table_init(&pp, uart_pin_table, ARRAY_SIZE(uart_pin_table));
brd_pin_table_init(&pp, espi_pin_table, ARRAY_SIZE(espi_pin_table));
return 0;
}

View file

@ -8,3 +8,5 @@ zephyr_library_sources_ifdef(CONFIG_ESPI_NPCX host_subs_npcx.c)
zephyr_library_sources_ifdef(CONFIG_USERSPACE espi_handlers.c)
zephyr_library_sources_ifdef(CONFIG_ESPI_EMUL espi_emul.c)
zephyr_library_sources_ifdef(CONFIG_ESPI_SAF espi_saf_mchp_xec.c)
zephyr_library_sources_ifdef(CONFIG_ESPI_XEC_V2 espi_mchp_xec_v2.c)
zephyr_library_sources_ifdef(CONFIG_ESPI_XEC_V2 espi_mchp_xec_host_v2.c)

View file

@ -12,6 +12,8 @@ if ESPI
source "drivers/espi/Kconfig.xec"
source "drivers/espi/Kconfig.xec_v2"
source "drivers/espi/Kconfig.npcx"
source "drivers/espi/Kconfig.espi_emul"

View file

@ -5,9 +5,9 @@
config ESPI_XEC
bool "XEC Microchip ESPI driver"
depends on SOC_FAMILY_MEC
depends on SOC_SERIES_MEC1501X
help
Enable the Microchip XEC ESPI driver.
Enable the Microchip XEC ESPI driver for MEC15xx family.
if ESPI_XEC

132
drivers/espi/Kconfig.xec_v2 Normal file
View file

@ -0,0 +1,132 @@
# Microchip XEC ESPI configuration options
# Copyright (c) 2019 Intel Corporation
# Copyright (c) 2021 Microchip Technology Inc.
# SPDX-License-Identifier: Apache-2.0
config ESPI_XEC_V2
bool "XEC Microchip ESPI V2 driver"
depends on SOC_SERIES_MEC172X
help
Enable the Microchip XEC ESPI driver for MEC172x series.
if ESPI_XEC_V2
config ESPI_OOB_CHANNEL
default y
config ESPI_FLASH_CHANNEL
default y
config ESPI_PERIPHERAL_HOST_IO
default y
config ESPI_PERIPHERAL_HOST_IO_PVT
default y
config ESPI_PERIPHERAL_DEBUG_PORT_80
default y
config ESPI_PERIPHERAL_8042_KBC
default y
config ESPI_PERIPHERAL_UART
default y
config ESPI_PERIPHERAL_UART_SOC_MAPPING
int "SoC port exposed as logical eSPI UART"
default 1
depends on ESPI_PERIPHERAL_UART
help
This tells the driver to which SoC UART to direct the UART traffic
send over eSPI from host. MEC172x implements two UARTs.
config ESPI_PERIPHERAL_XEC_MAILBOX
bool "SoC Mailbox over eSPI"
depends on ESPI_PERIPHERAL_CHANNEL
help
Enable a 32 byte mailbox interface accessible via Host I/O over the
ESPI Peripheral Channel.
config ESPI_PERIPHERAL_XEC_ACPI_EC2
bool "SoC ACPI EC 2 over eSPI"
depends on ESPI_PERIPHERAL_CHANNEL
help
Enable ACPI EC2 interface accessible via Host I/O over the
ESPI Peripheral Channel.
config ESPI_PERIPHERAL_XEC_ACPI_EC3
bool "SoC ACPI EC 3 over eSPI"
depends on ESPI_PERIPHERAL_CHANNEL
help
Enable ACPI EC3 interface accessible via Host I/O over the
ESPI Peripheral Channel.
config ESPI_PERIPHERAL_XEC_ACPI_EC4
bool "SoC ACPI EC 4 over eSPI"
depends on ESPI_PERIPHERAL_CHANNEL
help
Enable ACPI EC4 interface accessible via Host I/O over the
ESPI Peripheral Channel.
config ESPI_PERIPHERAL_XEC_ACPI_PM1
bool "SoC ACPI PM1 over eSPI"
depends on ESPI_PERIPHERAL_CHANNEL
help
Enable ACPI PM1 interface accessible via Host I/O over the
ESPI Peripheral Channel.
config ESPI_PERIPHERAL_XEC_EMI0
bool "SoC EMI 0 over eSPI"
depends on ESPI_PERIPHERAL_CHANNEL
help
Enable EMI 0 interface accessible via Host I/O over the
ESPI Peripheral Channel.
config ESPI_PERIPHERAL_XEC_EMI1
bool "SoC EMI 1 over eSPI"
depends on ESPI_PERIPHERAL_CHANNEL
help
Enable EMI 1 interface accessible via Host I/O over the
ESPI Peripheral Channel.
config ESPI_PERIPHERAL_XEC_EMI2
bool "SoC EMI 2 over eSPI"
depends on ESPI_PERIPHERAL_CHANNEL
help
Enable EMI 2 interface accessible via Host I/O over the
ESPI Peripheral Channel.
config ESPI_OOB_BUFFER_SIZE
int "eSPI OOB channel buffer size in bytes"
default 128
depends on ESPI_OOB_CHANNEL
help
Use minimum RAM buffer size by default but allow applications to
override the value.
Maximum OOB payload is 73 bytes.
config ESPI_FLASH_BUFFER_SIZE
int "eSPI Flash channel buffer size in bytes"
default 256
depends on ESPI_FLASH_CHANNEL
help
Use maximum RAM buffer size defined by spec but allow applications
to override if eSPI host doesn't support it.
config ESPI_SAF
bool "XEC Microchip ESPI SAF driver"
depends on ESPI_FLASH_CHANNEL
default n
help
Enable Slave Attached Flash eSPI driver. SAF depends upon ESPI XEC driver
and flash channel.
config ESPI_SAF_INIT_PRIORITY
int "ESPI SAF driver initialization priority"
depends on ESPI_SAF
default 4
help
Driver initialization priority for eSPI SAF driver.
endif #ESPI_XEC_V2

View file

@ -0,0 +1,819 @@
/*
* Copyright (c) 2019 Intel Corporation
* Copyright (c) 2021 Microchip Technology Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT microchip_xec_espi_host_dev
#include <kernel.h>
#include <soc.h>
#include <errno.h>
#include <drivers/espi.h>
#include <drivers/clock_control/mchp_xec_clock_control.h>
#include <drivers/interrupt_controller/intc_mchp_xec_ecia.h>
#include <dt-bindings/interrupt-controller/mchp-xec-ecia.h>
#include <logging/log.h>
#include <sys/sys_io.h>
#include <sys/util.h>
#include "espi_utils.h"
#include "espi_mchp_xec_v2.h"
#define CONNECT_IRQ_MBOX0 NULL
#define CONNECT_IRQ_KBC0 NULL
#define CONNECT_IRQ_ACPI_EC0 NULL
#define CONNECT_IRQ_ACPI_EC1 NULL
#define CONNECT_IRQ_ACPI_EC2 NULL
#define CONNECT_IRQ_ACPI_EC3 NULL
#define CONNECT_IRQ_ACPI_EC4 NULL
#define CONNECT_IRQ_ACPI_PM1 NULL
#define CONNECT_IRQ_EMI0 NULL
#define CONNECT_IRQ_EMI1 NULL
#define CONNECT_IRQ_EMI2 NULL
#define CONNECT_IRQ_RTC0 NULL
#define CONNECT_IRQ_P80BD0 NULL
#define INIT_MBOX0 NULL
#define INIT_KBC0 NULL
#define INIT_ACPI_EC0 NULL
#define INIT_ACPI_EC1 NULL
#define INIT_ACPI_EC2 NULL
#define INIT_ACPI_EC3 NULL
#define INIT_ACPI_EC4 NULL
#define INIT_ACPI_PM1 NULL
#define INIT_EMI0 NULL
#define INIT_EMI1 NULL
#define INIT_EMI2 NULL
#define INIT_RTC0 NULL
#define INIT_P80BD0 NULL
#define INIT_UART0 NULL
#define INIT_UART1 NULL
/* BARs as defined in LPC spec chapter 11 */
#define ESPI_XEC_KBC_BAR_ADDRESS 0x00600000
#define ESPI_XEC_UART0_BAR_ADDRESS 0x03F80000
#define ESPI_XEC_MBOX_BAR_ADDRESS 0x03600000
#define ESPI_XEC_PORT80_BAR_ADDRESS 0x00800000
#define ESPI_XEC_PORT81_BAR_ADDRESS 0x00810000
#define ESPI_XEC_ACPI_EC0_BAR_ADDRESS 0x00620000
/* Espi peripheral has 3 uart ports */
#define ESPI_PERIPHERAL_UART_PORT0 0
#define ESPI_PERIPHERAL_UART_PORT1 1
#define UART_DEFAULT_IRQ_POS 2u
#define UART_DEFAULT_IRQ BIT(UART_DEFAULT_IRQ_POS)
/* PCR */
#define XEC_PCR_REG_BASE \
((struct pcr_regs *)(DT_REG_ADDR(DT_NODELABEL(pcr))))
struct xec_espi_host_sram_config {
uint32_t host_sram1_base;
uint32_t host_sram2_base;
uint16_t ec_sram1_ofs;
uint16_t ec_sram2_ofs;
uint8_t sram1_acc_size;
uint8_t sram2_acc_size;
};
struct xec_espi_host_dev_config {
const struct device *parent;
uint32_t reg_base; /* logical device registers */
uint32_t host_mem_base; /* 32-bit host memory address */
uint16_t host_io_base; /* 16-bit host I/O address */
uint8_t ldn; /* Logical device number */
uint8_t num_ecia;
uint32_t *girqs;
};
struct xec_acpi_ec_config {
uintptr_t regbase;
uint32_t ibf_ecia_info;
uint32_t obe_ecia_info;
};
#ifdef CONFIG_ESPI_PERIPHERAL_XEC_MAILBOX
BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(mbox0), okay),
"XEC mbox0 DT node is disabled!");
static struct xec_mbox_config {
uintptr_t regbase;
uint32_t ecia_info;
};
static const struct xec_mbox0_config xec_mbox0_cfg = {
.regbase = DT_REG_ADDR(DT_NODELABEL(mbox0)),
.ecia_info = DT_PROP_BY_IDX(DT_NODELABEL(mbox0), girqs, 0),
};
/* dev is a pointer to espi0 (parent) device */
static void mbox0_isr(const struct device *dev)
{
uint8_t girq = MCHP_XEC_ECIA_GIRQ(xec_mbox0_cfg.ecia_info);
uint8_t bitpos = MCHP_XEC_ECIA_GIRQ_POS(xec_mbox0_cfg.ecia_info);
/* clear GIRQ source, inline version */
mchp_soc_ecia_girq_src_clr(girq, bitpos);
}
static int connect_irq_mbox0(const struct device *dev)
{
/* clear GIRQ source */
mchp_xec_ecia_info_girq_src_clr(xec_mbox0_cfg.ecia_info);
IRQ_CONNECT(DT_IRQN(DT_NODELABLE(mbox0)),
DT_IRQ(DT_NODELABLE(mbox0), priority),
acpi_ec0_isr,
DEVICE_DT_GET(DT_NODELABEL(espi0)),
0);
irq_enable(DT_IRQN(DT_NODELABLE(mbox0)));
/* enable GIRQ source */
mchp_xec_ecia_info_girq_src_en(xec_mbox0_cfg.ecia_info);
return 0;
}
/* Called by eSPI Bus init, eSPI reset de-assertion, and eSPI Platform Reset
* de-assertion.
*/
static int init_mbox0(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;
regs->IOHBAR[IOB_MBOX] = ESPI_XEC_MBOX_BAR_ADDRESS |
MCHP_ESPI_IO_BAR_HOST_VALID;
return 0;
}
#undef CONNECT_IRQ_MBOX0
#define CONNECT_IRQ_MBOX0 connect_irq_mbox0
#undef INIT_MBOX0
#define INIT_MBOX0 init_mbox0
#endif /* CONFIG_ESPI_PERIPHERAL_XEC_MAILBOX */
#ifdef CONFIG_ESPI_PERIPHERAL_8042_KBC
BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(kbc0), okay),
"XEC kbc0 DT node is disabled!");
struct xec_kbc0_config {
uintptr_t regbase;
uint32_t ibf_ecia_info;
uint32_t obe_ecia_info;
};
static const struct xec_kbc0_config xec_kbc0_cfg = {
.regbase = DT_REG_ADDR(DT_NODELABEL(kbc0)),
.ibf_ecia_info = DT_PROP_BY_IDX(DT_NODELABEL(kbc0), girqs, 1),
.obe_ecia_info = DT_PROP_BY_IDX(DT_NODELABEL(kbc0), girqs, 0),
};
static void kbc0_ibf_isr(const struct device *dev)
{
struct kbc_regs *kbc_hw = (struct kbc_regs *)xec_kbc0_cfg.regbase;
struct espi_xec_data *const data =
(struct espi_xec_data *const)dev->data;
/* The high byte contains information from the host,
* and the lower byte speficies if the host sent
* a command or data. 1 = Command.
*/
uint32_t isr_data = ((kbc_hw->EC_DATA & 0xFF) << E8042_ISR_DATA_POS) |
((kbc_hw->EC_KBC_STS & MCHP_KBC_STS_CD) <<
E8042_ISR_CMD_DATA_POS);
struct espi_event evt = {
.evt_type = ESPI_BUS_PERIPHERAL_NOTIFICATION,
.evt_details = ESPI_PERIPHERAL_8042_KBC,
.evt_data = isr_data
};
espi_send_callbacks(&data->callbacks, dev, evt);
mchp_xec_ecia_info_girq_src_clr(xec_kbc0_cfg.ibf_ecia_info);
}
static void kbc0_obe_isr(const struct device *dev)
{
/* disable and clear GIRQ interrupt and status */
mchp_xec_ecia_info_girq_src_dis(xec_kbc0_cfg.obe_ecia_info);
mchp_xec_ecia_info_girq_src_clr(xec_kbc0_cfg.obe_ecia_info);
}
/* dev is a pointer to espi0 device */
static int kbc0_rd_req(const struct device *dev, enum lpc_peripheral_opcode op,
uint32_t *data)
{
struct kbc_regs *kbc_hw = (struct kbc_regs *)xec_kbc0_cfg.regbase;
ARG_UNUSED(dev);
if (op >= E8042_START_OPCODE && op <= E8042_MAX_OPCODE) {
/* Make sure kbc 8042 is on */
if (!(kbc_hw->KBC_CTRL & MCHP_KBC_CTRL_OBFEN)) {
return -ENOTSUP;
}
switch (op) {
case E8042_OBF_HAS_CHAR:
/* EC has written data back to host. OBF is
* automatically cleared after host reads
* the data
*/
*data = kbc_hw->EC_KBC_STS & MCHP_KBC_STS_OBF ? 1 : 0;
break;
case E8042_IBF_HAS_CHAR:
*data = kbc_hw->EC_KBC_STS & MCHP_KBC_STS_IBF ? 1 : 0;
break;
case E8042_READ_KB_STS:
*data = kbc_hw->EC_KBC_STS;
break;
default:
return -EINVAL;
}
} else {
return -ENOTSUP;
}
return 0;
}
/* dev is a pointer to espi0 device */
static int kbc0_wr_req(const struct device *dev, enum lpc_peripheral_opcode op,
uint32_t *data)
{
struct kbc_regs *kbc_hw = (struct kbc_regs *)xec_kbc0_cfg.regbase;
volatile uint32_t __attribute__((unused)) dummy;
ARG_UNUSED(dev);
if (op >= E8042_START_OPCODE && op <= E8042_MAX_OPCODE) {
/* Make sure kbc 8042 is on */
if (!(kbc_hw->KBC_CTRL & MCHP_KBC_CTRL_OBFEN)) {
return -ENOTSUP;
}
switch (op) {
case E8042_WRITE_KB_CHAR:
kbc_hw->EC_DATA = *data & 0xff;
break;
case E8042_WRITE_MB_CHAR:
kbc_hw->EC_AUX_DATA = *data & 0xff;
break;
case E8042_RESUME_IRQ:
mchp_xec_ecia_info_girq_src_clr(
xec_kbc0_cfg.ibf_ecia_info);
mchp_xec_ecia_info_girq_src_en(
xec_kbc0_cfg.ibf_ecia_info);
break;
case E8042_PAUSE_IRQ:
mchp_xec_ecia_info_girq_src_dis(
xec_kbc0_cfg.ibf_ecia_info);
break;
case E8042_CLEAR_OBF:
dummy = kbc_hw->HOST_AUX_DATA;
break;
case E8042_SET_FLAG:
/* FW shouldn't modify these flags directly */
*data &= ~(MCHP_KBC_STS_OBF | MCHP_KBC_STS_IBF |
MCHP_KBC_STS_AUXOBF);
kbc_hw->EC_KBC_STS |= *data;
break;
case E8042_CLEAR_FLAG:
/* FW shouldn't modify these flags directly */
*data |= (MCHP_KBC_STS_OBF | MCHP_KBC_STS_IBF |
MCHP_KBC_STS_AUXOBF);
kbc_hw->EC_KBC_STS &= ~(*data);
break;
default:
return -EINVAL;
}
} else {
return -ENOTSUP;
}
return 0;
}
static int connect_irq_kbc0(const struct device *dev)
{
/* clear GIRQ source */
mchp_xec_ecia_info_girq_src_clr(xec_kbc0_cfg.ibf_ecia_info);
mchp_xec_ecia_info_girq_src_clr(xec_kbc0_cfg.obe_ecia_info);
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_NODELABEL(kbc0), kbc_ibf, irq),
DT_IRQ_BY_NAME(DT_NODELABEL(kbc0), kbc_ibf, priority),
kbc0_ibf_isr,
DEVICE_DT_GET(DT_NODELABEL(espi0)),
0);
irq_enable(DT_IRQ_BY_NAME(DT_NODELABEL(kbc0), kbc_ibf, irq));
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_NODELABEL(kbc0), kbc_obe, irq),
DT_IRQ_BY_NAME(DT_NODELABEL(kbc0), kbc_obe, priority),
kbc0_obe_isr,
DEVICE_DT_GET(DT_NODELABEL(espi0)),
0);
irq_enable(DT_IRQ_BY_NAME(DT_NODELABEL(kbc0), kbc_obe, irq));
/* enable GIRQ sources */
mchp_xec_ecia_info_girq_src_en(xec_kbc0_cfg.ibf_ecia_info);
mchp_xec_ecia_info_girq_src_en(xec_kbc0_cfg.obe_ecia_info);
return 0;
}
static int init_kbc0(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 kbc_regs *kbc_hw = (struct kbc_regs *)xec_kbc0_cfg.regbase;
kbc_hw->KBC_CTRL |= MCHP_KBC_CTRL_AUXH;
kbc_hw->KBC_CTRL |= MCHP_KBC_CTRL_OBFEN;
/* This is the activate register, but the HAL has a funny name */
kbc_hw->KBC_PORT92_EN = MCHP_KBC_PORT92_EN;
regs->IOHBAR[IOB_KBC] = ESPI_XEC_KBC_BAR_ADDRESS |
MCHP_ESPI_IO_BAR_HOST_VALID;
return 0;
}
#undef CONNECT_IRQ_KBC0
#define CONNECT_IRQ_KBC0 connect_irq_kbc0
#undef INIT_KBC0
#define INIT_KBC0 init_kbc0
#endif /* CONFIG_ESPI_PERIPHERAL_8042_KBC */
#ifdef CONFIG_ESPI_PERIPHERAL_HOST_IO
static const struct xec_acpi_ec_config xec_acpi_ec0_cfg = {
.regbase = DT_REG_ADDR(DT_NODELABEL(acpi_ec0)),
.ibf_ecia_info = DT_PROP_BY_IDX(DT_NODELABEL(acpi_ec0), girqs, 0),
.obe_ecia_info = DT_PROP_BY_IDX(DT_NODELABEL(acpi_ec0), girqs, 1),
};
static void acpi_ec0_ibf_isr(const struct device *dev)
{
struct espi_xec_data *const data =
(struct espi_xec_data *const)dev->data;
struct espi_event evt = { ESPI_BUS_PERIPHERAL_NOTIFICATION,
ESPI_PERIPHERAL_HOST_IO, ESPI_PERIPHERAL_NODATA
};
espi_send_callbacks(&data->callbacks, dev, evt);
/* clear GIRQ status */
mchp_xec_ecia_info_girq_src_clr(xec_acpi_ec0_cfg.ibf_ecia_info);
}
static void acpi_ec0_obe_isr(const struct device *dev)
{
/* disable and clear GIRQ status */
mchp_xec_ecia_info_girq_src_dis(xec_acpi_ec0_cfg.obe_ecia_info);
mchp_xec_ecia_info_girq_src_clr(xec_acpi_ec0_cfg.obe_ecia_info);
}
static int eacpi_rd_req(const struct device *dev,
enum lpc_peripheral_opcode op,
uint32_t *data)
{
ARG_UNUSED(dev);
ARG_UNUSED(op);
ARG_UNUSED(data);
return -EINVAL;
}
static int eacpi_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;
}
static int connect_irq_acpi_ec0(const struct device *dev)
{
mchp_xec_ecia_info_girq_src_clr(xec_acpi_ec0_cfg.ibf_ecia_info);
mchp_xec_ecia_info_girq_src_clr(xec_acpi_ec0_cfg.obe_ecia_info);
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_NODELABEL(acpi_ec0), acpi_ibf, irq),
DT_IRQ_BY_NAME(DT_NODELABEL(acpi_ec0), acpi_ibf, priority),
acpi_ec0_ibf_isr,
DEVICE_DT_GET(DT_NODELABEL(espi0)),
0);
irq_enable(DT_IRQ_BY_NAME(DT_NODELABEL(acpi_ec0), acpi_ibf, irq));
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_NODELABEL(acpi_ec0), acpi_obe, irq),
DT_IRQ_BY_NAME(DT_NODELABEL(acpi_ec0), acpi_obe, priority),
acpi_ec0_obe_isr,
DEVICE_DT_GET(DT_NODELABEL(espi0)),
0);
irq_enable(DT_IRQ_BY_NAME(DT_NODELABEL(acpi_ec0), acpi_obe, irq));
mchp_xec_ecia_info_girq_src_en(xec_acpi_ec0_cfg.ibf_ecia_info);
mchp_xec_ecia_info_girq_src_en(xec_acpi_ec0_cfg.obe_ecia_info);
return 0;
}
static int init_acpi_ec0(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;
regs->IOHBAR[IOB_ACPI_EC0] = ESPI_XEC_ACPI_EC0_BAR_ADDRESS |
MCHP_ESPI_IO_BAR_HOST_VALID;
return 0;
}
#undef CONNECT_IRQ_ACPI_EC0
#define CONNECT_IRQ_ACPI_EC0 connect_irq_acpi_ec0
#undef INIT_ACPI_EC0
#define INIT_ACPI_EC0 init_acpi_ec0
#endif /* CONFIG_ESPI_PERIPHERAL_HOST_IO */
#ifdef 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)),
.ibf_ecia_info = DT_PROP_BY_IDX(DT_NODELABEL(acpi_ec1), girqs, 0),
.obe_ecia_info = DT_PROP_BY_IDX(DT_NODELABEL(acpi_ec1), girqs, 1),
};
static void acpi_ec1_ibf_isr(const struct device *dev)
{
struct espi_xec_data *const data =
(struct espi_xec_data *const)dev->data;
struct espi_event evt = {
.evt_type = ESPI_BUS_PERIPHERAL_NOTIFICATION,
.evt_details = ESPI_PERIPHERAL_HOST_IO_PVT,
.evt_data = ESPI_PERIPHERAL_NODATA
};
espi_send_callbacks(&data->callbacks, dev, evt);
/* clear GIRQ status */
mchp_xec_ecia_info_girq_src_clr(xec_acpi_ec1_cfg.ibf_ecia_info);
}
static void acpi_ec1_obe_isr(const struct device *dev)
{
/* disable and clear GIRQ status */
mchp_xec_ecia_info_girq_src_dis(xec_acpi_ec1_cfg.obe_ecia_info);
mchp_xec_ecia_info_girq_src_clr(xec_acpi_ec1_cfg.obe_ecia_info);
}
static int connect_irq_acpi_ec1(const struct device *dev)
{
mchp_xec_ecia_info_girq_src_clr(xec_acpi_ec1_cfg.ibf_ecia_info);
mchp_xec_ecia_info_girq_src_clr(xec_acpi_ec1_cfg.obe_ecia_info);
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_NODELABEL(acpi_ec1), acpi_ibf, irq),
DT_IRQ_BY_NAME(DT_NODELABEL(acpi_ec1), acpi_ibf, priority),
acpi_ec1_ibf_isr,
DEVICE_DT_GET(DT_NODELABEL(espi0)),
0);
irq_enable(DT_IRQ_BY_NAME(DT_NODELABEL(acpi_ec1), acpi_ibf, irq));
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_NODELABEL(acpi_ec1), acpi_obe, irq),
DT_IRQ_BY_NAME(DT_NODELABEL(acpi_ec1), acpi_obe, priority),
acpi_ec1_obe_isr,
DEVICE_DT_GET(DT_NODELABEL(espi0)),
0);
irq_enable(DT_IRQ_BY_NAME(DT_NODELABEL(acpi_ec1), acpi_obe, irq));
mchp_xec_ecia_info_girq_src_en(xec_acpi_ec1_cfg.ibf_ecia_info);
mchp_xec_ecia_info_girq_src_en(xec_acpi_ec1_cfg.obe_ecia_info);
return 0;
}
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;
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;
return 0;
}
#undef CONNECT_IRQ_ACPI_EC1
#define CONNECT_IRQ_ACPI_EC1 connect_irq_acpi_ec1
#undef INIT_ACPI_EC1
#define INIT_ACPI_EC1 init_acpi_ec1
#endif /* CONFIG_ESPI_PERIPHERAL_HOST_IO_PVT */
#ifdef CONFIG_ESPI_PERIPHERAL_DEBUG_PORT_80
struct xec_p80bd_config {
uintptr_t regbase;
uint32_t ecia_info;
};
static const struct xec_p80bd_config xec_p80bd0_cfg = {
.regbase = DT_REG_ADDR(DT_NODELABEL(p80bd0)),
.ecia_info = DT_PROP_BY_IDX(DT_NODELABEL(p80bd0), girqs, 0),
};
/*
* MEC172x P80 BIOS Debug Port hardware captures writes to its 4-byte I/O range
* Hardware provides status indicating byte lane(s) of each write.
* We must decode the byte lane information and produce one or more
* notification packets.
*/
static void p80bd0_isr(const struct device *dev)
{
struct espi_xec_data *const data =
(struct espi_xec_data *const)dev->data;
struct p80bd_regs *p80regs =
(struct p80bd_regs *)xec_p80bd0_cfg.regbase;
struct espi_event evt = { ESPI_BUS_PERIPHERAL_NOTIFICATION, 0,
ESPI_PERIPHERAL_NODATA };
int count = 8; /* limit ISR to 8 bytes */
uint32_t dattr = p80regs->EC_DA;
/* b[7:0]=8-bit value written, b[15:8]=attributes */
while ((dattr & MCHP_P80BD_ECDA_NE) && (count--)) { /* Not empty? */
/* espi_event protocol No Data value is 0 so pick a bit and
* set it. This depends on the application.
*/
evt.evt_data = (dattr & 0xffu) | BIT(16);
switch (dattr & MCHP_P80BD_ECDA_LANE_MSK) {
case MCHP_P80BD_ECDA_LANE_0:
evt.evt_details |= (ESPI_PERIPHERAL_INDEX_0 << 16) |
ESPI_PERIPHERAL_DEBUG_PORT80;
break;
case MCHP_P80BD_ECDA_LANE_1:
evt.evt_details |= (ESPI_PERIPHERAL_INDEX_1 << 16) |
ESPI_PERIPHERAL_DEBUG_PORT80;
break;
case MCHP_P80BD_ECDA_LANE_2:
break;
case MCHP_P80BD_ECDA_LANE_3:
break;
default:
break;
}
if (evt.evt_details) {
espi_send_callbacks(&data->callbacks, dev, evt);
evt.evt_details = 0;
}
}
/* clear GIRQ status */
mchp_xec_ecia_info_girq_src_clr(xec_p80bd0_cfg.ecia_info);
}
static int connect_irq_p80bd0(const struct device *dev)
{
mchp_xec_ecia_info_girq_src_clr(xec_p80bd0_cfg.ecia_info);
IRQ_CONNECT(DT_IRQN(DT_NODELABEL(p80bd0)),
DT_IRQ(DT_NODELABEL(acpi_ec1), priority),
p80bd0_isr,
DEVICE_DT_GET(DT_NODELABEL(espi0)),
0);
irq_enable(DT_IRQN(DT_NODELABEL(p80bd0)));
mchp_xec_ecia_info_girq_src_en(xec_p80bd0_cfg.ecia_info);
return 0;
}
static int init_p80bd0(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 p80bd_regs *p80bd_hw =
(struct p80bd_regs *)xec_p80bd0_cfg.regbase;
regs->IOHBAR[IOB_P80BD] = ESPI_XEC_PORT80_BAR_ADDRESS |
MCHP_ESPI_IO_BAR_HOST_VALID;
p80bd_hw->ACTV = 1;
p80bd_hw->STS_IEN = MCHP_P80BD_SI_THR_IEN;
return 0;
}
#undef CONNECT_IRQ_P80BD0
#define CONNECT_IRQ_P80BD0 connect_irq_p80bd0
#undef INIT_P80BD0
#define INIT_P80BD0 init_p80bd0
#endif /* CONFIG_ESPI_PERIPHERAL_DEBUG_PORT_80 */
#ifdef CONFIG_ESPI_PERIPHERAL_UART
#if CONFIG_ESPI_PERIPHERAL_UART_SOC_MAPPING == 0
int init_uart0(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;
regs->IOHBAR[IOB_UART0] = ESPI_XEC_UART0_BAR_ADDRESS |
MCHP_ESPI_IO_BAR_HOST_VALID;
return 0;
}
#undef INIT_UART0
#define INIT_UART0 init_uart0
#elif CONFIG_ESPI_PERIPHERAL_UART_SOC_MAPPING == 1
int init_uart1(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;
regs->IOHBAR[IOB_UART1] = ESPI_XEC_UART0_BAR_ADDRESS |
MCHP_ESPI_IO_BAR_HOST_VALID;
return 0;
}
#undef INIT_UART1
#define INIT_UART1 init_uart1
#endif /* CONFIG_ESPI_PERIPHERAL_UART_SOC_MAPPING */
#endif /* CONFIG_ESPI_PERIPHERAL_UART */
typedef int (*host_dev_irq_connect)(const struct device *dev);
static const host_dev_irq_connect hdic_tbl[] = {
CONNECT_IRQ_MBOX0,
CONNECT_IRQ_KBC0,
CONNECT_IRQ_ACPI_EC0,
CONNECT_IRQ_ACPI_EC1,
CONNECT_IRQ_ACPI_EC2,
CONNECT_IRQ_ACPI_EC3,
CONNECT_IRQ_ACPI_EC4,
CONNECT_IRQ_ACPI_PM1,
CONNECT_IRQ_EMI0,
CONNECT_IRQ_EMI1,
CONNECT_IRQ_EMI2,
CONNECT_IRQ_RTC0,
CONNECT_IRQ_P80BD0,
};
typedef int (*host_dev_init)(const struct device *dev);
static const host_dev_init hd_init_tbl[] = {
INIT_MBOX0,
INIT_KBC0,
INIT_ACPI_EC0,
INIT_ACPI_EC1,
INIT_ACPI_EC2,
INIT_ACPI_EC3,
INIT_ACPI_EC4,
INIT_ACPI_PM1,
INIT_EMI0,
INIT_EMI1,
INIT_EMI2,
INIT_RTC0,
INIT_P80BD0,
INIT_UART0,
INIT_UART1,
};
int xec_host_dev_connect_irqs(const struct device *dev)
{
int ret = 0;
for (int i = 0; i < ARRAY_SIZE(hdic_tbl); i++) {
if (hdic_tbl[i] == NULL) {
continue;
}
ret = hdic_tbl[i](dev);
if (ret < 0) {
break;
}
}
return ret;
}
int xec_host_dev_init(const struct device *dev)
{
int ret = 0;
for (int i = 0; i < ARRAY_SIZE(hd_init_tbl); i++) {
if (hd_init_tbl[i] == NULL) {
continue;
}
ret = hd_init_tbl[i](dev);
if (ret < 0) {
break;
}
}
return ret;
}
#ifdef CONFIG_ESPI_PERIPHERAL_CHANNEL
typedef int (*xec_lpc_req)(const struct device *,
enum lpc_peripheral_opcode,
uint32_t *);
struct espi_lpc_req {
uint16_t opcode_start;
uint16_t opcode_max;
xec_lpc_req rd_req;
xec_lpc_req wr_req;
};
static const struct espi_lpc_req espi_lpc_req_tbl[] = {
#ifdef CONFIG_ESPI_PERIPHERAL_8042_KBC
{ E8042_START_OPCODE, E8042_MAX_OPCODE, kbc0_rd_req, kbc0_wr_req },
#endif
#ifdef CONFIG_ESPI_PERIPHERAL_HOST_IO
{ EACPI_START_OPCODE, EACPI_MAX_OPCODE, eacpi_rd_req, eacpi_wr_req },
#endif
#ifdef CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE
{ ECUSTOM_START_OPCODE, ECUSTOM_MAX_OPCODE, ecust_rd_req, ecust_wr_req},
#endif
};
static int espi_xec_lpc_req(const struct device *dev,
enum lpc_peripheral_opcode op,
uint32_t *data, uint8_t write)
{
ARG_UNUSED(dev);
for (int i = 0; i < ARRAY_SIZE(espi_lpc_req_tbl); i++) {
const struct espi_lpc_req *req = &espi_lpc_req_tbl[i];
if ((op >= req->opcode_start) && (op <= req->opcode_max)) {
if (write) {
return req->wr_req(dev, op, data);
} else {
return req->rd_req(dev, op, data);
}
}
}
return -ENOTSUP;
}
/* dev = pointer to espi0 device */
int espi_xec_read_lpc_request(const struct device *dev,
enum lpc_peripheral_opcode op,
uint32_t *data)
{
return espi_xec_lpc_req(dev, op, data, 0);
}
int espi_xec_write_lpc_request(const struct device *dev,
enum lpc_peripheral_opcode op,
uint32_t *data)
{
return espi_xec_lpc_req(dev, op, data, 1);
}
#else
int espi_xec_write_lpc_request(const struct device *dev,
enum lpc_peripheral_opcode op,
uint32_t *data)
{
ARG_UNUSED(dev);
ARG_UNUSED(op);
ARG_UNUSED(data);
return -ENOTSUP;
}
int espi_xec_read_lpc_request(const struct device *dev,
enum lpc_peripheral_opcode op,
uint32_t *data)
{
ARG_UNUSED(dev);
ARG_UNUSED(op);
ARG_UNUSED(data);
return -ENOTSUP;
}
#endif /* CONFIG_ESPI_PERIPHERAL_CHANNEL */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 2021 Microchip Technology Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_DRIVERS_ESPI_MCHP_XEC_ESPI_V2_H_
#define ZEPHYR_DRIVERS_ESPI_MCHP_XEC_ESPI_V2_H_
#include <stdint.h>
#include <device.h>
#include <drivers/espi.h>
#define ESPI_XEC_V2_DEBUG 1
struct espi_isr {
uint8_t girq_id;
uint8_t girq_pos;
void (*the_isr)(const struct device *dev);
};
struct espi_vw_isr {
uint8_t signal;
uint8_t girq_id;
uint8_t girq_pos;
void (*the_isr)(int girq, int bpos, void *dev);
};
struct espi_xec_irq_info {
uint8_t gid; /* GIRQ id [8, 26] */
uint8_t gpos; /* bit position in GIRQ [0, 31] */
uint8_t anid; /* Aggregated GIRQ NVIC number */
uint8_t dnid; /* Direct GIRQ NVIC number */
};
struct espi_xec_config {
uint32_t base_addr;
uint32_t vw_base_addr;
uint8_t pcr_idx;
uint8_t pcr_bitpos;
const struct espi_xec_irq_info *irq_info_list;
uint8_t irq_info_size;
};
#define ESPI_XEC_CONFIG(dev) \
((struct espi_xec_config * const)(dev)->config)
struct espi_xec_data {
sys_slist_t callbacks;
struct k_sem tx_lock;
struct k_sem rx_lock;
struct k_sem flash_lock;
uint8_t plt_rst_asserted;
uint8_t espi_rst_asserted;
uint8_t sx_state;
#ifdef ESPI_XEC_V2_DEBUG
uint32_t espi_rst_count;
#endif
};
#define ESPI_XEC_DATA(dev) \
((struct espi_xec_data * const)(dev)->data)
struct xec_signal {
uint8_t xec_reg_idx;
uint8_t bit;
uint8_t dir;
};
enum mchp_msvw_regs {
MCHP_MSVW00,
MCHP_MSVW01,
MCHP_MSVW02,
MCHP_MSVW03,
MCHP_MSVW04,
MCHP_MSVW05,
MCHP_MSVW06,
MCHP_MSVW07,
MCHP_MSVW08,
};
enum mchp_smvw_regs {
MCHP_SMVW00,
MCHP_SMVW01,
MCHP_SMVW02,
MCHP_SMVW03,
MCHP_SMVW04,
MCHP_SMVW05,
MCHP_SMVW06,
MCHP_SMVW07,
MCHP_SMVW08,
};
enum xec_espi_girq_idx {
pc_girq_idx = 0,
bm1_girq_idx,
bm2_girq_idx,
ltr_girq_idx,
oob_up_girq_idx,
oob_dn_girq_idx,
fc_girq_idx,
rst_girq_idx,
vw_ch_en_girq_idx,
max_girq_idx,
};
int xec_host_dev_init(const struct device *dev);
int xec_host_dev_connect_irqs(const struct device *dev);
int espi_xec_read_lpc_request(const struct device *dev,
enum lpc_peripheral_opcode op,
uint32_t *data);
int espi_xec_write_lpc_request(const struct device *dev,
enum lpc_peripheral_opcode op,
uint32_t *data);
#endif /* ZEPHYR_DRIVERS_ESPI_MCHP_XEC_ESPI_V2_H_ */

View file

@ -19,6 +19,7 @@
#include <sys/__assert.h>
#include <drivers/clock_control/mchp_xec_clock_control.h>
#include <drivers/interrupt_controller/intc_mchp_xec_ecia.h>
#include <dt-bindings/interrupt-controller/mchp-xec-ecia.h>
/* defined at the SoC layer */
#define MCHP_FIRST_GIRQ MCHP_FIRST_GIRQ_NOS
@ -186,6 +187,58 @@ void mchp_xec_ecia_nvic_clr_pend(uint32_t nvic_num)
NVIC_ClearPendingIRQ(nvic_num);
}
/* API taking input encoded with MCHP_XEC_ECIA(g, gb, na, nd) macro */
void mchp_xec_ecia_info_girq_aggr_en(int ecia_info, uint8_t enable)
{
uint8_t girq_num = MCHP_XEC_ECIA_GIRQ(ecia_info);
mchp_xec_ecia_girq_aggr_en(girq_num, enable);
}
void mchp_xec_ecia_info_girq_src_clr(int ecia_info)
{
uint8_t girq_num = MCHP_XEC_ECIA_GIRQ(ecia_info);
uint8_t bitpos = MCHP_XEC_ECIA_GIRQ_POS(ecia_info);
mchp_xec_ecia_girq_src_clr(girq_num, bitpos);
}
void mchp_xec_ecia_info_girq_src_en(int ecia_info)
{
uint8_t girq_num = MCHP_XEC_ECIA_GIRQ(ecia_info);
uint8_t bitpos = MCHP_XEC_ECIA_GIRQ_POS(ecia_info);
mchp_xec_ecia_girq_src_en(girq_num, bitpos);
}
void mchp_xec_ecia_info_girq_src_dis(int ecia_info)
{
uint8_t girq_num = MCHP_XEC_ECIA_GIRQ(ecia_info);
uint8_t bitpos = MCHP_XEC_ECIA_GIRQ_POS(ecia_info);
mchp_xec_ecia_girq_src_dis(girq_num, bitpos);
}
uint32_t mchp_xec_ecia_info_girq_result(int ecia_info)
{
uint8_t girq_num = MCHP_XEC_ECIA_GIRQ(ecia_info);
return mchp_xec_ecia_girq_result(girq_num);
}
/*
* Clear NVIC pending status given GIRQ source information encoded by macro
* MCHP_XEC_ECIA. For aggregated only sources the ecoding sets direct NVIC
* number equal to aggregated NVIC number.
*/
void mchp_xec_ecia_info_nvic_clr_pend(int ecia_info)
{
uint8_t nvic_num = MCHP_XEC_ECIA_NVIC_DIRECT(ecia_info);
mchp_xec_ecia_nvic_clr_pend(nvic_num);
}
/**
* @brief enable GIRQn interrupt for specific source
*
@ -207,6 +260,20 @@ int mchp_xec_ecia_enable(int girq, int src)
return 0;
}
/**
* @brief enable EXTI interrupt for specific line specified by parameter
* encoded with MCHP_XEC_ECIA macro.
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
*/
int mchp_xec_ecia_info_enable(int ecia_info)
{
uint8_t girq = (uint8_t)MCHP_XEC_ECIA_GIRQ(ecia_info);
uint8_t src = (uint8_t)MCHP_XEC_ECIA_GIRQ_POS(ecia_info);
return mchp_xec_ecia_enable(girq, src);
}
/**
* @brief disable EXTI interrupt for specific line
*
@ -228,6 +295,20 @@ int mchp_xec_ecia_disable(int girq, int src)
return 0;
}
/**
* @brief disable EXTI interrupt for specific line specified by parameter
* encoded with MCHP_XEC_ECIA macro.
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
*/
int mchp_xec_ecia_info_disable(int ecia_info)
{
uint8_t girq = (uint8_t)MCHP_XEC_ECIA_GIRQ(ecia_info);
uint8_t src = (uint8_t)MCHP_XEC_ECIA_GIRQ_POS(ecia_info);
return mchp_xec_ecia_disable(girq, src);
}
/* forward reference */
static const struct device *get_girq_dev(int girq_num);
@ -279,6 +360,22 @@ int mchp_xec_ecia_set_callback(int girq_num, int src,
return mchp_xec_ecia_set_callback_by_dev(dev, src, cb, data);
}
/**
* @brief set GIRQn interrupt source callback
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
* @param cb user callback
* @param data user data
*/
int mchp_xec_ecia_info_set_callback(int ecia_info, mchp_xec_ecia_callback_t cb,
void *data)
{
const struct device *dev = get_girq_dev(MCHP_XEC_ECIA_GIRQ(ecia_info));
uint8_t src = MCHP_XEC_ECIA_GIRQ_POS(ecia_info);
return mchp_xec_ecia_set_callback_by_dev(dev, src, cb, data);
}
/**
* @brief unset GIRQn interrupt source callback by device handle
*
@ -321,6 +418,20 @@ int mchp_ecia_unset_callback(int girq_num, int src)
return mchp_ecia_unset_callback_by_dev(dev, src);
}
/**
* @brief unset GIRQn interrupt source callback
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
*/
int mchp_ecia_info_unset_callback(int ecia_info)
{
const struct device *dev = get_girq_dev(MCHP_XEC_ECIA_GIRQ(ecia_info));
uint8_t src = MCHP_XEC_ECIA_GIRQ_POS(ecia_info);
return mchp_ecia_unset_callback_by_dev(dev, src);
}
/*
* Create a build time flag to know if any aggregated GIRQ has been enabled.
* We make use of DT FOREACH macro to check GIRQ node status.

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2021 Microchip Technology Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#define MSVW 0
#define SMVW 1
/ {
mchp-xec-espi-vw-routing {
compatible = "microchip,xec-espi-vw-routing";
/* eSPI Virtual Vire (VW) routing */
vw-slp-s3-n {
/* Host-index MSVW/SMVW MSVW/SMVW-index source */
vw-reg = <0x02 MSVW 0 0>;
vw-girq = <24 0>;
};
vw-slp-s4-n {
vw-reg = <0x02 MSVW 0 1>;
vw-girq = <24 1>;
};
vw-slp-s5-n {
vw-reg = <0x02 MSVW 0 2>;
vw-girq = <24 2>;
};
vw-sus-stat-n {
vw-reg = <0x03 MSVW 1 0>;
vw-girq = <24 4>;
};
vw-pltrst-n {
vw-reg = <0x03 MSVW 1 1>;
vw-girq = <24 5>;
};
vw-oob-rst-warn {
vw-reg = <0x03 MSVW 1 2>;
vw-girq = <24 6>;
};
vw-host-rst-warn {
vw-reg = <0x07 MSVW 2 0>;
vw-girq = <24 8>;
};
vw-sus-warn-n {
vw-reg = <0x41 MSVW 3 0>;
vw-girq = <24 12>;
};
vw-sus-pwrdn-ack {
vw-reg = <0x41 MSVW 3 1>;
vw-girq = <24 13>;
};
vw-slp-a-n {
vw-reg = <0x41 MSVW 3 3>;
vw-girq = <24 15>;
};
vw-slp-lan-n {
vw-reg = <0x42 MSVW 4 0>;
vw-girq = <24 16>;
};
vw-slp-wlen-n {
vw-reg = <0x42 MSVW 4 1>;
vw-girq = <24 17>;
};
vw-host-c10 {
vw-reg = <0x47 MSVW 7 0>;
vw-girq = <25 0>;
};
vw-dnx-warn {
vw-reg = <0x4a MSVW 8 1>;
vw-girq = <25 5>;
};
/* Device to Host (SMVW) do not have SoC interrupts */
vw-oob-rst-ack {
vw-reg = <0x04 SMVW 0 0>;
};
vw-wake-n {
vw-reg = <0x04 SMVW 0 2>;
};
vw-pme-n {
vw-reg = <0x04 SMVW 0 3>;
};
vw-slave-boot-load-done {
vw-reg = <0x05 SMVW 1 0>;
};
vw-error-fatal {
vw-reg = <0x05 SMVW 1 1>;
};
vw-error-non-fatal {
vw-reg = <0x05 SMVW 1 2>;
};
vw-slave-boot-load-status {
vw-reg = <0x05 SMVW 1 3>;
};
vw-sci-n {
vw-reg = <0x06 SMVW 2 0>;
};
vw-smi-n {
vw-reg = <0x06 SMVW 2 1>;
};
vw-rcin-n {
vw-reg = <0x06 SMVW 2 2>;
};
vw-host-rst-ack {
vw-reg = <0x06 SMVW 2 3>;
};
vw-sus-ack-n {
vw-reg = <0x40 SMVW 3 0>;
};
vw-dnx-ack {
vw-reg = <0x40 SMVW 3 1>;
};
};
};

View file

@ -11,6 +11,8 @@
#include <dt-bindings/clock/mchp_xec_pcr.h>
#include <dt-bindings/interrupt-controller/mchp-xec-ecia.h>
#include "mec172x/mec172x-vw-routing.dtsi"
/ {
cpus {
#address-cells = <1>;
@ -592,28 +594,7 @@
#size-cells = <0>;
status = "disabled";
};
uart0: uart@400f2400 {
compatible = "microchip,xec-uart";
reg = <0x400f2400 0x400>;
interrupts = <40 0>;
clock-frequency = <1843200>;
current-speed = <38400>;
label = "UART_0";
girqs = <15 0>;
pcrs = <2 1>;
status = "disabled";
};
uart1: uart@400f2800 {
compatible = "microchip,xec-uart";
reg = <0x400f2800 0x400>;
interrupts = <41 0>;
clock-frequency = <1843200>;
current-speed = <38400>;
label = "UART_1";
girqs = <15 1>;
pcrs = <2 2>;
status = "disabled";
};
/* uarts were here */
ps2_0: ps2@40009000 {
reg = <0x40009000 0x40>;
interrupts = <100 1>;
@ -888,51 +869,6 @@
label = "BCLINK_0";
status = "disabled";
};
mbox0: mbox@400f0000 {
reg = <0x400f0000 0x200>;
interrupts = <60 0>;
girqs = <15 20>;
pcrs = <2 17>;
label = "MBOX_0";
status = "disabled";
};
emi0: emi@400f4000 {
reg = <0x400f4000 0x400>;
interrupts = <42 0>;
girqs = <15 2>;
label = "EMI_0";
status = "disabled";
};
emi1: emi@400f4400 {
reg = <0x400f4400 0x400>;
interrupts = <43 0>;
girqs = <15 3>;
label = "EMI_1";
status = "disabled";
};
emi2: emi@400f4800 {
reg = <0x400f4800 0x400>;
interrupts = <44 0>;
girqs = <15 4>;
label = "EMI_2";
status = "disabled";
};
rtc0: rtc@400f5000 {
reg = <0x400f5000 0x100>;
interrupts = <119 0>, <120 0>;
girqs = <21 8>, <21 9>;
pcrs = <2 18>;
label = "RTC_0";
status = "disabled";
};
p80bd0: p80bd@400f8000 {
reg = <0x400f8000 0x800>;
interrupts = <62 0>;
girqs = <15 22>;
pcrs = <2 25>;
label = "P80BD_0";
status = "disabled";
};
tfdp0: tfdp@40008c00 {
reg = <0x40008c00 0x10>;
pcrs = <1 7>;
@ -945,6 +881,212 @@
label = "GLBLCFG_0";
status = "disabled";
};
espi0: espi@400f3400 {
compatible = "microchip,xec-espi-v2";
reg = < 0x400f3400 0x400
0x400f3800 0x400
0x400f9c00 0x400>;
reg-names = "io", "mem", "vw";
interrupts = <103 3>, <104 3>, <105 3>, <106 3>,
<107 3>, <108 3>, <109 3>, <110 3>,
<156 3>;
interrupt-names = "pc", "bm1", "bm2", "ltr", "oob_up",
"oob_dn", "fc", "rst", "vw_chan_en";
girqs = < MCHP_XEC_ECIA(19, 0, 11, 103)
MCHP_XEC_ECIA(19, 1, 11, 104)
MCHP_XEC_ECIA(19, 2, 11, 105)
MCHP_XEC_ECIA(19, 3, 11, 106)
MCHP_XEC_ECIA(19, 4, 11, 107)
MCHP_XEC_ECIA(19, 5, 11, 108)
MCHP_XEC_ECIA(19, 6, 11, 109)
MCHP_XEC_ECIA(19, 7, 11, 110)
MCHP_XEC_ECIA(19, 8, 11, 156) >;
pcrs = <2 19>;
label = "ESPI_0";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
mbox0: mbox@400f0000 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f0000 0x200>;
interrupts = <60 0>;
girqs = < MCHP_XEC_ECIA(15, 20, 7, 60) >;
pcrs = <2 17>;
ldn = <0>;
label = "MBOX_0";
status = "disabled";
};
kbc0: kbc@400f0400 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f0400 0x400>;
interrupts = <58 3>, <59 3>;
interrupt-names = "kbc_obe", "kbc_ibf";
girqs = < MCHP_XEC_ECIA(15, 18, 7, 58)
MCHP_XEC_ECIA(15, 19, 7, 58) >;
ldn = <1>;
label = "KBC_0";
status = "disabled";
};
acpi_ec0: acpi_ec@400f0800 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f0800 0x400>;
interrupts = <45 3>, <46 3>;
interrupt-names = "acpi_ibf", "acpi_obe";
girqs = < MCHP_XEC_ECIA(15, 5, 7, 45)
MCHP_XEC_ECIA(15, 6, 7, 46) >;
ldn = <2>;
label = "ACPI_EC_0";
status = "disabled";
};
acpi_ec1: acpi_ec@400f0c00 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f0c00 0x400>;
interrupts = <47 3>, <48 3>;
interrupt-names = "acpi_ibf", "acpi_obe";
girqs = < MCHP_XEC_ECIA(15, 7, 7, 58)
MCHP_XEC_ECIA(15, 8, 7, 58) >;
ldn = <3>;
label = "ACPI_EC_1";
status = "disabled";
};
acpi_ec2: acpi_ec@400f1000 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f1000 0x400>;
interrupts = <49 3>, <50 3>;
interrupt-names = "acpi_ibf", "acpi_obe";
girqs = < MCHP_XEC_ECIA(15, 9, 7, 58)
MCHP_XEC_ECIA(15, 10, 7, 58) >;
ldn = <4>;
label = "ACPI_EC_2";
status = "disabled";
};
acpi_ec3: acpi_ec@400f1400 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f1400 0x400>;
interrupts = <51 3>, <52 3>;
interrupt-names = "acpi_ibf", "acpi_obe";
girqs = < MCHP_XEC_ECIA(15, 11, 7, 58)
MCHP_XEC_ECIA(15, 12, 7, 58) >;
ldn = <5>;
label = "ACPI_EC_3";
status = "disabled";
};
acpi_ec4: acpi_ec@400f1800 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f1800 0x400>;
interrupts = <53 3>, <54 3>;
interrupt-names = "acpi_ibf", "acpi_obe";
girqs = < MCHP_XEC_ECIA(15, 13, 7, 58)
MCHP_XEC_ECIA(15, 14, 7, 58) >;
ldn = <6>;
label = "ACPI_EC_4";
status = "disabled";
};
acpi_pm1: acpi_pm1@400f1c00 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f1c00 0x400>;
interrupts = <55 3>, <56 3>, <57 3>;
interrupt-names = "pm1_ctl", "pm1_en", "pm1_sts";
girqs = < MCHP_XEC_ECIA(15, 15, 7, 58)
MCHP_XEC_ECIA(15, 16, 7, 58)
MCHP_XEC_ECIA(15, 17, 7, 58) >;
ldn = <7>;
label = "ACPI_PM1";
status = "disabled";
};
port92: port92@400f2000 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f2000 0x400>;
label = "PORT92";
ldn = <8>;
status = "disabled";
};
uart0: uart@400f2400 {
compatible = "microchip,xec-uart";
reg = <0x400f2400 0x400>;
interrupts = <40 0>;
clock-frequency = <1843200>;
current-speed = <38400>;
label = "UART_0";
girqs = <15 0>;
pcrs = <2 1>;
ldn = <9>;
status = "disabled";
};
uart1: uart@400f2800 {
compatible = "microchip,xec-uart";
reg = <0x400f2800 0x400>;
interrupts = <41 0>;
clock-frequency = <1843200>;
current-speed = <38400>;
label = "UART_1";
girqs = <15 1>;
pcrs = <2 2>;
ldn = <10>;
status = "disabled";
};
emi0: emi@400f4000 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f4000 0x400>;
interrupts = <42 0>;
girqs = < MCHP_XEC_ECIA(15, 2, 7, 42) >;
label = "EMI_0";
ldn = <16>;
status = "disabled";
};
emi1: emi@400f4400 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f4400 0x400>;
interrupts = <43 0>;
girqs = < MCHP_XEC_ECIA(15, 3, 7, 43) >;
label = "EMI_1";
ldn = <17>;
status = "disabled";
};
emi2: emi@400f4800 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f4800 0x400>;
interrupts = <44 0>;
girqs = < MCHP_XEC_ECIA(15, 4, 7, 44) >;
label = "EMI_2";
ldn = <18>;
status = "disabled";
};
rtc0: rtc@400f5000 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f5000 0x100>;
interrupts = <119 0>, <120 0>;
girqs = < MCHP_XEC_ECIA(21, 8, 13, 119)
MCHP_XEC_ECIA(21, 9, 13, 120) >;
pcrs = <2 18>;
label = "RTC_0";
ldn = <20>;
status = "disabled";
};
/* Capture writes to host I/O 0x80 - 0x83 */
p80bd0: p80bd@400f8000 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f8000 0x400>;
interrupts = <62 0>;
girqs = < MCHP_XEC_ECIA(15, 22, 7, 58) >;
pcrs = <2 25>;
ldn = <32>;
label = "P80BD_0";
status = "disabled";
};
/* Capture writes to an 8-bit I/O and map to one of 0x80 to 0x83 */
p80bd0_alias: p80bd@400f8400 {
compatible = "microchip,xec-espi-host-dev";
reg = <0x400f8400 0x400>;
label = "P80BD_0_ALIAS";
ldn = <33>;
host-io = <0x90>;
/* map 0x90 to 0x80 */
host-io-addr-mask = <0x01>;
status = "disabled";
};
};
};
};

View file

@ -0,0 +1,95 @@
# Copyright (c) 2021, Microchip Technology Inc.
# SPDX-License-Identifier: Apache-2.0
description: Microchip XEC eSPI Host devices
compatible: "microchip,xec-espi-host-dev"
include: [base.yaml]
on-bus: espi
properties:
reg:
required: true
interrupts:
required: false
interrupt-names:
required: false
ldn:
type: int
required: true
description: logical device number
girqs:
type: array
required: false
description: array of GIRQ and bit positions
pcrs:
type: array
required: false
description: PCR sleep register index and bit position
# optional properties application to different host facing devices
host-io:
type: int
required: false
description: |
Logical device Host I/O (x86) base. Refer to SoC documentation for the
number of I/O decoders implemented by a device (1 or 2) and the fixed
I/O masks.
host-io-addr-mask:
type: int
required: false
description: |
Host I/O address mask. This value is fixed for all HW and is only
used by Port80 BIOS debug alias device to specify the byte lane the
alias address is mapped to in the 80h to 83h I/O range.
host-mem:
type: int
required: false
description: |
Logical device Host memory (x86) base address. Refer to SoC
documentation for which logical devices implement a memory decoder
and the fixed memory address masking.
emi-mems:
type: array
required: false
description: |
Each EMI host device supports Host access to two SoC data memory
regions. Each region requires three configuration parameters:
Base address in the SoC data memory, read limit, and write limit.
If bits[14:2] of the address written by the Host to the EC address
register is less than the limit value the access is allowed. Bit[15]
of the EC address selects which of the two memory regions is accessed.
"emi-mem-cells":
type: int
const: 3
"#girq-cells":
type: int
const: 1
"#pcr-cells":
type: int
const: 2
emi-mem-cells:
- base
- rdlimit
- wrlimit
girq-cells:
- girqinfo
pcr-cells:
- reg_idx
- bitpos

View file

@ -0,0 +1,44 @@
# Copyright (c) 2019 Intel Corporation
# Copyright (c) 2021 Microchip Technology Inc.
# SPDX-License-Identifier: Apache-2.0
description: Microchip ESPI V2 controller
compatible: "microchip,xec-espi-v2"
include: espi-controller.yaml
properties:
reg:
description: mmio register space
required: true
reg-names:
required: true
description: Name of each register space
girqs:
type: array
required: true
description: |
Array of encoded interrupt information
pcrs:
type: array
required: true
description: eSPI PCR register index and bit position
"#girq-cells":
type: int
const: 1
"#pcr-cells":
type: int
const: 2
girq-cells:
- girqinfo
pcr-cells:
- regidx
- bitpos

View file

@ -0,0 +1,25 @@
# Copyright (c) 2021 Microchip Technology Inc.
# SPDX-License-Identifier: Apache-2.0
description: Microchip XEC eSPI Virtual Wire routing
compatible: "microchip,xec-espi-vw-routing"
child-binding:
description: |
Child node containing the routing of an eSPI virtual wire to the SoC
VW registers and ECIA GIRQ registers.
properties:
vw-reg:
type: array
required: true
description: vw signal's register index and vw bitmask.
vw-girq:
type: array
required: false
description: |
Routing of MSVW source to aggregated GIRQs
Example: OOB_RST_WARN is source 2 of MSVW01 routed to GIRQ24 b[5]
vw-girq = <24 5>;

View file

@ -37,7 +37,7 @@ properties:
required: true
description: PCR sleep enable register index and bit position.
"girq-cells":
"#girq-cells":
type: int
const: 2

View file

@ -11,6 +11,11 @@ properties:
interrupts:
required: true
ldn:
type: int
required: true
description: logical device number
girqs:
type: array
required: true

View file

@ -22,7 +22,7 @@ properties:
required: true
description: Array of GIRQ numbers [8:26] and bit positions [0:31].
"girq-cells":
"#girq-cells":
type: int
const: 2

View file

@ -28,6 +28,14 @@
*/
int mchp_xec_ecia_enable(int girq_id, int src);
/**
* @brief enable EXTI interrupt for specific line specified by parameter
* encoded with MCHP_XEC_ECIA macro.
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
*/
int mchp_xec_ecia_info_enable(int ecia_info);
/**
* @brief disable EXTI interrupt for specific line
*
@ -36,6 +44,14 @@ int mchp_xec_ecia_enable(int girq_id, int src);
*/
int mchp_xec_ecia_disable(int girq_id, int src);
/**
* @brief disable EXTI interrupt for specific line specified by parameter
* encoded with MCHP_XEC_ECIA macro.
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
*/
int mchp_xec_ecia_info_disable(int ecia_info);
/* callback for ECIA GIRQ interrupt source */
typedef void (*mchp_xec_ecia_callback_t) (int girq_id, int src, void *user);
@ -51,6 +67,16 @@ typedef void (*mchp_xec_ecia_callback_t) (int girq_id, int src, void *user);
int mchp_xec_ecia_set_callback(int girq_id, int src,
mchp_xec_ecia_callback_t cb, void *data);
/**
* @brief set GIRQn interrupt source callback
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
* @param cb user callback
* @param data user data
*/
int mchp_xec_ecia_info_set_callback(int ecia_info, mchp_xec_ecia_callback_t cb,
void *data);
/**
* @brief set GIRQn interrupt source callback
*
@ -141,4 +167,44 @@ uint32_t mchp_xec_ecia_girq_result(uint8_t girq_id);
*/
void mchp_xec_ecia_nvic_clr_pend(uint32_t nvic_num);
/* API using GIRQ parameters encoded with MCHP_XEC_ECIA */
/** @brief enable or disable aggregated GIRQ output
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
* @param enable is flag to indicate enable(1) or disable(0)
*/
void mchp_xec_ecia_info_girq_aggr_en(int ecia_info, uint8_t enable);
/** @brief clear GIRQ latched source status bit
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
*/
void mchp_xec_ecia_info_girq_src_clr(int ecia_info);
/** @brief enable a source in a GIRQ
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
*/
void mchp_xec_ecia_info_girq_src_en(int ecia_info);
/** @brief disable a source in a GIRQ
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
*/
void mchp_xec_ecia_info_girq_src_dis(int ecia_info);
/** @brief Read GIRQ result register (bit-wise OR of enable and source)
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
* @return 32-bit unsigned result register value
*/
uint32_t mchp_xec_ecia_info_girq_result(int ecia_info);
/** @brief Clear external NVIC input pending status given encoded ECIA info.
*
* @param ecia_info is GIRQ connection encoded with MCHP_XEC_ECIA
*/
void mchp_xec_ecia_info_nvic_clr_pend(int ecia_info);
#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_MCHP_XEC_ECIA_H_ */

View file

@ -0,0 +1,22 @@
/*
* Copyright (c) 2019 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _SOC_ESPI_V2_H_
#define _SOC_ESPI_V2_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <device.h>
int mchp_xec_espi_host_dev_init(const struct device *dev);
#ifdef __cplusplus
}
#endif
#endif /* _SOC_ESPI_V2_H_ */

View file

@ -31,4 +31,8 @@ config I2C_XEC_V2
default y
depends on I2C
config ESPI_XEC_V2
default y
depends on ESPI
endif # SOC_MEC172X_NSZ

View file

@ -1078,6 +1078,18 @@ enum MCHP_GIRQ_INDEX {
#define MCHP_GIRQ25_NVIC_AGGR 16u
#define MCHP_MSVW00_GIRQ 24
#define MCHP_MSVW01_GIRQ 24
#define MCHP_MSVW02_GIRQ 24
#define MCHP_MSVW03_GIRQ 24
#define MCHP_MSVW04_GIRQ 24
#define MCHP_MSVW05_GIRQ 24
#define MCHP_MSVW06_GIRQ 24
#define MCHP_MSVW07_GIRQ 25
#define MCHP_MSVW08_GIRQ 25
#define MCHP_MSVW09_GIRQ 25
#define MCHP_MSVW10_GIRQ 25
/* GIRQ26 Source, Enable_Set/Clr, Result registers bit positions */
#define MCHP_GPIO_0240_GIRQ_POS 0
#define MCHP_GPIO_0241_GIRQ_POS 1

View file

@ -62,6 +62,7 @@
#include "../common/soc_pins.h"
#include "../common/soc_espi_channels.h"
#include "../common/soc_espi_saf.h"
#include "../common/soc_espi_v2.h"
#endif