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:
parent
bf68b670f1
commit
c214c59548
|
@ -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";
|
||||
|
|
|
@ -17,3 +17,4 @@ CONFIG_CONSOLE=y
|
|||
CONFIG_UART_CONSOLE=y
|
||||
CONFIG_ADC=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_ESPI=y
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
132
drivers/espi/Kconfig.xec_v2
Normal 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
|
819
drivers/espi/espi_mchp_xec_host_v2.c
Normal file
819
drivers/espi/espi_mchp_xec_host_v2.c
Normal 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 */
|
1387
drivers/espi/espi_mchp_xec_v2.c
Normal file
1387
drivers/espi/espi_mchp_xec_v2.c
Normal file
File diff suppressed because it is too large
Load diff
119
drivers/espi/espi_mchp_xec_v2.h
Normal file
119
drivers/espi/espi_mchp_xec_v2.h
Normal 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_ */
|
|
@ -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.
|
||||
|
|
114
dts/arm/microchip/mec172x/mec172x-vw-routing.dtsi
Normal file
114
dts/arm/microchip/mec172x/mec172x-vw-routing.dtsi
Normal 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>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
95
dts/bindings/espi/microchip,xec-espi-host-dev.yaml
Normal file
95
dts/bindings/espi/microchip,xec-espi-host-dev.yaml
Normal 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
|
44
dts/bindings/espi/microchip,xec-espi-v2.yaml
Normal file
44
dts/bindings/espi/microchip,xec-espi-v2.yaml
Normal 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
|
25
dts/bindings/espi/microchip,xec-espi-vw-routing.yaml
Normal file
25
dts/bindings/espi/microchip,xec-espi-vw-routing.yaml
Normal 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>;
|
|
@ -37,7 +37,7 @@ properties:
|
|||
required: true
|
||||
description: PCR sleep enable register index and bit position.
|
||||
|
||||
"girq-cells":
|
||||
"#girq-cells":
|
||||
type: int
|
||||
const: 2
|
||||
|
||||
|
|
|
@ -11,6 +11,11 @@ properties:
|
|||
interrupts:
|
||||
required: true
|
||||
|
||||
ldn:
|
||||
type: int
|
||||
required: true
|
||||
description: logical device number
|
||||
|
||||
girqs:
|
||||
type: array
|
||||
required: true
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
22
soc/arm/microchip_mec/common/soc_espi_v2.h
Normal file
22
soc/arm/microchip_mec/common/soc_espi_v2.h
Normal 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_ */
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue