The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* Re: [PATCH 3/7] soc: aspeed: Add AST2600 peripheral channel port I/O support
       [not found] ` <20260313-upstream_espi-v1-3-9504428e1f43@aspeedtech.com>
@ 2026-05-07 14:03   ` Shulzhenko, Oleksandr
  0 siblings, 0 replies; 4+ messages in thread
From: Shulzhenko, Oleksandr @ 2026-05-07 14:03 UTC (permalink / raw)
  To: aspeedyh, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Joel Stanley, Andrew Jeffery, Ryan Chen, Philipp Zabel
  Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel, openbmc,
	maciej.lawniczak

On 3/13/2026 11:07 AM, aspeedyh wrote:
> Add initial support for the AST2600 eSPI peripheral channel handling of
> port I/O transactions used for LPC-style accesses.
>
> This patch does not yet implement peripheral memory read or write
> cycles. Support for those transactions will be added in a follow-up
> patch once the remaining transport and buffer handling pieces are in
> place.
>
> Signed-off-by: aspeedyh <yh_chung@aspeedtech.com>
> ---
>   drivers/soc/aspeed/espi/Makefile       |   2 +-
>   drivers/soc/aspeed/espi/aspeed-espi.c  |  24 +++
>   drivers/soc/aspeed/espi/ast2600-espi.c | 139 ++++++++++++++++
>   drivers/soc/aspeed/espi/ast2600-espi.h | 291 +++++++++++++++++++++++++++++++++
>   4 files changed, 455 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/soc/aspeed/espi/Makefile b/drivers/soc/aspeed/espi/Makefile
> index d96dc030e23b..30f9dbf92a0f 100644
> --- a/drivers/soc/aspeed/espi/Makefile
> +++ b/drivers/soc/aspeed/espi/Makefile
> @@ -1 +1 @@
> -obj-y += aspeed-espi.o
> +obj-y += aspeed-espi.o ast2600-espi.o
> diff --git a/drivers/soc/aspeed/espi/aspeed-espi.c b/drivers/soc/aspeed/espi/aspeed-espi.c
> index 15d58b38bbe4..e369738119bc 100644
> --- a/drivers/soc/aspeed/espi/aspeed-espi.c
> +++ b/drivers/soc/aspeed/espi/aspeed-espi.c
> @@ -13,15 +13,28 @@
>   #include <linux/reset.h>
>   
>   #include "aspeed-espi.h"
> +#include "ast2600-espi.h"
>   
>   struct aspeed_espi_ops {
>   	void (*espi_pre_init)(struct aspeed_espi *espi);
>   	void (*espi_post_init)(struct aspeed_espi *espi);
>   	void (*espi_deinit)(struct aspeed_espi *espi);
> +	int (*espi_perif_probe)(struct aspeed_espi *espi);
> +	int (*espi_perif_remove)(struct aspeed_espi *espi);
Should it be int? I don't see any error condition returned
>   	irqreturn_t (*espi_isr)(int irq, void *espi);
>   };
>   
> +static const struct aspeed_espi_ops aspeed_espi_ast2600_ops = {
> +	.espi_pre_init = ast2600_espi_pre_init,
> +	.espi_post_init = ast2600_espi_post_init,
> +	.espi_deinit = ast2600_espi_deinit,
> +	.espi_perif_probe = ast2600_espi_perif_probe,
> +	.espi_perif_remove = ast2600_espi_perif_remove,
> +	.espi_isr = ast2600_espi_isr,
> +};
> +
>   static const struct of_device_id aspeed_espi_of_matches[] = {
> +	{ .compatible = "aspeed,ast2600-espi", .data = &aspeed_espi_ast2600_ops },
>   	{ }
>   };
>   MODULE_DEVICE_TABLE(of, aspeed_espi_of_matches);
> @@ -88,6 +101,14 @@ static int aspeed_espi_probe(struct platform_device *pdev)
>   	if (espi->ops->espi_pre_init)
>   		espi->ops->espi_pre_init(espi);
>   
> +	if (espi->ops->espi_perif_probe) {
> +		rc = espi->ops->espi_perif_probe(espi);
> +		if (rc) {
> +			dev_err(dev, "cannot init peripheral channel, rc=%d\n", rc);
> +			goto err_deinit;
> +		}
> +	}
> +
>   	rc = devm_request_irq(dev, espi->irq, espi->ops->espi_isr, 0,
>   			      dev_name(dev), espi);
>   	if (rc) {
> @@ -121,6 +142,9 @@ static void aspeed_espi_remove(struct platform_device *pdev)
>   	if (!espi)
>   		return;
>   
> +	if (espi->ops->espi_perif_remove)
> +		espi->ops->espi_perif_remove(espi);
> +
>   	if (espi->ops->espi_deinit)
>   		espi->ops->espi_deinit(espi);
>   
> diff --git a/drivers/soc/aspeed/espi/ast2600-espi.c b/drivers/soc/aspeed/espi/ast2600-espi.c
> new file mode 100644
> index 000000000000..8effd0404d1f
> --- /dev/null
> +++ b/drivers/soc/aspeed/espi/ast2600-espi.c
> @@ -0,0 +1,139 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright Aspeed Technology Inc.
> + */
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/reset.h>
> +
> +#include "aspeed-espi.h"
> +#include "ast2600-espi.h"
> +
> +static void ast2600_espi_perif_isr(struct aspeed_espi *espi)
> +{
> +	u32 sts;
> +
> +	sts = readl(espi->regs + ESPI_INT_STS);
> +
> +	if (sts & ESPI_INT_STS_PERIF_PC_RX_CMPLT)
> +		writel(ESPI_INT_STS_PERIF_PC_RX_CMPLT, espi->regs + ESPI_INT_STS);
> +}
> +
> +static void ast2600_espi_perif_sw_reset(struct aspeed_espi *espi)
> +{
> +	u32 reg;
> +
> +	reg = readl(espi->regs + ESPI_CTRL);
> +	reg &= ~(ESPI_CTRL_PERIF_NP_TX_SW_RST
> +		 | ESPI_CTRL_PERIF_NP_RX_SW_RST
> +		 | ESPI_CTRL_PERIF_PC_TX_SW_RST
> +		 | ESPI_CTRL_PERIF_PC_RX_SW_RST
> +		 | ESPI_CTRL_PERIF_NP_TX_DMA_EN
> +		 | ESPI_CTRL_PERIF_PC_TX_DMA_EN
> +		 | ESPI_CTRL_PERIF_PC_RX_DMA_EN
> +		 | ESPI_CTRL_PERIF_SW_RDY);
> +	writel(reg, espi->regs + ESPI_CTRL);
> +
> +	udelay(1);
> +
> +	reg |= (ESPI_CTRL_PERIF_NP_TX_SW_RST
> +		| ESPI_CTRL_PERIF_NP_RX_SW_RST
> +		| ESPI_CTRL_PERIF_PC_TX_SW_RST
> +		| ESPI_CTRL_PERIF_PC_RX_SW_RST);
> +	writel(reg, espi->regs + ESPI_CTRL);
> +}
> +
> +static void ast2600_espi_perif_reset(struct aspeed_espi *espi)
> +{
> +	u32 reg;
> +
> +	writel(ESPI_INT_EN_PERIF, espi->regs + ESPI_INT_EN_CLR);
> +	writel(ESPI_INT_STS_PERIF, espi->regs + ESPI_INT_STS);
> +
> +	writel(0x0, espi->regs + ESPI_MMBI_INT_EN);
> +	writel(0xffffffff, espi->regs + ESPI_MMBI_INT_STS);
> +
> +	reg = readl(espi->regs + ESPI_CTRL2);
> +	reg &= ~(ESPI_CTRL2_MCYC_RD_DIS_WDT | ESPI_CTRL2_MCYC_WR_DIS_WDT);
> +	writel(reg, espi->regs + ESPI_CTRL2);
> +
> +	reg = readl(espi->regs + ESPI_CTRL);
> +	reg &= ~(ESPI_CTRL_PERIF_NP_TX_DMA_EN
> +		 | ESPI_CTRL_PERIF_PC_TX_DMA_EN
> +		 | ESPI_CTRL_PERIF_PC_RX_DMA_EN
> +		 | ESPI_CTRL_PERIF_SW_RDY);
> +	writel(reg, espi->regs + ESPI_CTRL);
> +
> +	reg = readl(espi->regs + ESPI_CTRL) | ESPI_CTRL_PERIF_SW_RDY;
> +	writel(reg, espi->regs + ESPI_CTRL);
> +}
> +
> +int ast2600_espi_perif_probe(struct aspeed_espi *espi)
> +{
> +	ast2600_espi_perif_reset(espi);
> +	return 0;
> +}
> +
> +int ast2600_espi_perif_remove(struct aspeed_espi *espi)
> +{
> +	u32 reg;
> +
> +	writel(ESPI_INT_EN_PERIF, espi->regs + ESPI_INT_EN_CLR);
> +
> +	reg = readl(espi->regs + ESPI_CTRL2);
> +	reg |= (ESPI_CTRL2_MCYC_RD_DIS | ESPI_CTRL2_MCYC_WR_DIS);
> +	writel(reg, espi->regs + ESPI_CTRL2);
> +
> +	reg = readl(espi->regs + ESPI_CTRL);
> +	reg &= ~(ESPI_CTRL_PERIF_NP_TX_DMA_EN
> +		 | ESPI_CTRL_PERIF_PC_TX_DMA_EN
> +		 | ESPI_CTRL_PERIF_PC_RX_DMA_EN
> +		 | ESPI_CTRL_PERIF_SW_RDY);
> +	writel(reg, espi->regs + ESPI_CTRL);
> +	return 0;
> +}
> +
> +/* global control */
> +irqreturn_t ast2600_espi_isr(int irq, void *arg)
> +{
> +	struct aspeed_espi *espi;
> +	u32 sts;
> +
> +	espi = (struct aspeed_espi *)arg;
> +	sts = readl(espi->regs + ESPI_INT_STS);
> +
> +	if (!sts)
> +		return IRQ_NONE;
> +
> +	if (sts & ESPI_INT_STS_PERIF)
> +		ast2600_espi_perif_isr(espi);
> +
> +	if (sts & ESPI_INT_STS_RST_DEASSERT) {
> +		/* this will clear all interrupt enable and status */
> +		reset_control_assert(espi->rst);
> +		reset_control_deassert(espi->rst);
> +
> +		ast2600_espi_perif_sw_reset(espi);
> +		ast2600_espi_perif_reset(espi);
> +
> +		/* re-enable eSPI_RESET# interrupt */
> +		writel(ESPI_INT_EN_RST_DEASSERT, espi->regs + ESPI_INT_EN);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +void ast2600_espi_pre_init(struct aspeed_espi *espi)
> +{
> +	writel(ESPI_INT_EN_RST_DEASSERT, espi->regs + ESPI_INT_EN_CLR);
> +}
> +
> +void ast2600_espi_post_init(struct aspeed_espi *espi)
> +{
> +	writel(ESPI_INT_EN_RST_DEASSERT, espi->regs + ESPI_INT_EN);
> +}
> +
> +void ast2600_espi_deinit(struct aspeed_espi *espi)
> +{
> +	writel(ESPI_INT_EN_RST_DEASSERT, espi->regs + ESPI_INT_EN_CLR);
> +}
> diff --git a/drivers/soc/aspeed/espi/ast2600-espi.h b/drivers/soc/aspeed/espi/ast2600-espi.h
> new file mode 100644
> index 000000000000..309479ee1187
> --- /dev/null
> +++ b/drivers/soc/aspeed/espi/ast2600-espi.h
> @@ -0,0 +1,291 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Register definitions for Aspeed AST2600 eSPI controller
> + * Copyright 2026 Aspeed Technology Inc.
> + */
> +#ifndef AST2600_ESPI_H
> +#define AST2600_ESPI_H
> +
> +#include <linux/bits.h>
> +#include <linux/irqreturn.h>
> +#include "aspeed-espi.h"
> +
> +/* registers */
> +#define ESPI_CTRL				0x000
> +#define   ESPI_CTRL_FLASH_TX_SW_RST		BIT(31)
> +#define   ESPI_CTRL_FLASH_RX_SW_RST		BIT(30)
> +#define   ESPI_CTRL_OOB_TX_SW_RST		BIT(29)
> +#define   ESPI_CTRL_OOB_RX_SW_RST		BIT(28)
> +#define   ESPI_CTRL_PERIF_NP_TX_SW_RST		BIT(27)
> +#define   ESPI_CTRL_PERIF_NP_RX_SW_RST		BIT(26)
> +#define   ESPI_CTRL_PERIF_PC_TX_SW_RST		BIT(25)
> +#define   ESPI_CTRL_PERIF_PC_RX_SW_RST		BIT(24)
> +#define   ESPI_CTRL_FLASH_TX_DMA_EN		BIT(23)
> +#define   ESPI_CTRL_FLASH_RX_DMA_EN		BIT(22)
> +#define   ESPI_CTRL_OOB_TX_DMA_EN		BIT(21)
> +#define   ESPI_CTRL_OOB_RX_DMA_EN		BIT(20)
> +#define   ESPI_CTRL_PERIF_NP_TX_DMA_EN		BIT(19)
> +#define   ESPI_CTRL_PERIF_PC_TX_DMA_EN		BIT(17)
> +#define   ESPI_CTRL_PERIF_PC_RX_DMA_EN		BIT(16)
> +#define   ESPI_CTRL_FLASH_EDAF_MODE		GENMASK(11, 10)
> +#define   ESPI_CTRL_VW_GPIO_SW			BIT(9)
> +#define   ESPI_CTRL_FLASH_SW_RDY		BIT(7)
> +#define   ESPI_CTRL_OOB_SW_RDY			BIT(4)
> +#define   ESPI_CTRL_VW_SW_RDY			BIT(3)
> +#define   ESPI_CTRL_PERIF_SW_RDY		BIT(1)
> +#define ESPI_STS				0x004
> +#define ESPI_INT_STS				0x008
> +#define   ESPI_INT_STS_RST_DEASSERT		BIT(31)
> +#define   ESPI_INT_STS_OOB_RX_TMOUT		BIT(23)
> +#define   ESPI_INT_STS_VW_SYSEVT1		BIT(22)
> +#define   ESPI_INT_STS_FLASH_TX_ERR		BIT(21)
> +#define   ESPI_INT_STS_OOB_TX_ERR		BIT(20)
> +#define   ESPI_INT_STS_FLASH_TX_ABT		BIT(19)
> +#define   ESPI_INT_STS_OOB_TX_ABT		BIT(18)
> +#define   ESPI_INT_STS_PERIF_NP_TX_ABT		BIT(17)
> +#define   ESPI_INT_STS_PERIF_PC_TX_ABT		BIT(16)
> +#define   ESPI_INT_STS_FLASH_RX_ABT		BIT(15)
> +#define   ESPI_INT_STS_OOB_RX_ABT		BIT(14)
> +#define   ESPI_INT_STS_PERIF_NP_RX_ABT		BIT(13)
> +#define   ESPI_INT_STS_PERIF_PC_RX_ABT		BIT(12)
> +#define   ESPI_INT_STS_PERIF_NP_TX_ERR		BIT(11)
> +#define   ESPI_INT_STS_PERIF_PC_TX_ERR		BIT(10)
> +#define   ESPI_INT_STS_VW_GPIO			BIT(9)
> +#define   ESPI_INT_STS_VW_SYSEVT		BIT(8)
> +#define   ESPI_INT_STS_FLASH_TX_CMPLT		BIT(7)
> +#define   ESPI_INT_STS_FLASH_RX_CMPLT		BIT(6)
> +#define   ESPI_INT_STS_OOB_TX_CMPLT		BIT(5)
> +#define   ESPI_INT_STS_OOB_RX_CMPLT		BIT(4)
> +#define   ESPI_INT_STS_PERIF_NP_TX_CMPLT	BIT(3)
> +#define   ESPI_INT_STS_PERIF_PC_TX_CMPLT	BIT(1)
> +#define   ESPI_INT_STS_PERIF_PC_RX_CMPLT	BIT(0)
> +#define ESPI_INT_EN				0x00c
> +#define   ESPI_INT_EN_RST_DEASSERT		BIT(31)
> +#define   ESPI_INT_EN_OOB_RX_TMOUT		BIT(23)
> +#define   ESPI_INT_EN_VW_SYSEVT1		BIT(22)
> +#define   ESPI_INT_EN_FLASH_TX_ERR		BIT(21)
> +#define   ESPI_INT_EN_OOB_TX_ERR		BIT(20)
> +#define   ESPI_INT_EN_FLASH_TX_ABT		BIT(19)
> +#define   ESPI_INT_EN_OOB_TX_ABT		BIT(18)
> +#define   ESPI_INT_EN_PERIF_NP_TX_ABT		BIT(17)
> +#define   ESPI_INT_EN_PERIF_PC_TX_ABT		BIT(16)
> +#define   ESPI_INT_EN_FLASH_RX_ABT		BIT(15)
> +#define   ESPI_INT_EN_OOB_RX_ABT		BIT(14)
> +#define   ESPI_INT_EN_PERIF_NP_RX_ABT		BIT(13)
> +#define   ESPI_INT_EN_PERIF_PC_RX_ABT		BIT(12)
> +#define   ESPI_INT_EN_PERIF_NP_TX_ERR		BIT(11)
> +#define   ESPI_INT_EN_PERIF_PC_TX_ERR		BIT(10)
> +#define   ESPI_INT_EN_VW_GPIO			BIT(9)
> +#define   ESPI_INT_EN_VW_SYSEVT			BIT(8)
> +#define   ESPI_INT_EN_FLASH_TX_CMPLT		BIT(7)
> +#define   ESPI_INT_EN_FLASH_RX_CMPLT		BIT(6)
> +#define   ESPI_INT_EN_OOB_TX_CMPLT		BIT(5)
> +#define   ESPI_INT_EN_OOB_RX_CMPLT		BIT(4)
> +#define   ESPI_INT_EN_PERIF_NP_TX_CMPLT		BIT(3)
> +#define   ESPI_INT_EN_PERIF_PC_TX_CMPLT		BIT(1)
> +#define   ESPI_INT_EN_PERIF_PC_RX_CMPLT		BIT(0)
> +#define ESPI_PERIF_PC_RX_DMA			0x010
> +#define ESPI_PERIF_PC_RX_CTRL			0x014
> +#define   ESPI_PERIF_PC_RX_CTRL_SERV_PEND	BIT(31)
> +#define   ESPI_PERIF_PC_RX_CTRL_LEN		GENMASK(23, 12)
> +#define   ESPI_PERIF_PC_RX_CTRL_TAG		GENMASK(11, 8)
> +#define   ESPI_PERIF_PC_RX_CTRL_CYC		GENMASK(7, 0)
> +#define ESPI_PERIF_PC_RX_DATA			0x018
> +#define ESPI_PERIF_PC_TX_DMA			0x020
> +#define ESPI_PERIF_PC_TX_CTRL			0x024
> +#define	  ESPI_PERIF_PC_TX_CTRL_TRIG_PEND	BIT(31)
> +#define	  ESPI_PERIF_PC_TX_CTRL_LEN		GENMASK(23, 12)
> +#define	  ESPI_PERIF_PC_TX_CTRL_TAG		GENMASK(11, 8)
> +#define	  ESPI_PERIF_PC_TX_CTRL_CYC		GENMASK(7, 0)
> +#define ESPI_PERIF_PC_TX_DATA			0x028
> +#define ESPI_PERIF_NP_TX_DMA			0x030
> +#define ESPI_PERIF_NP_TX_CTRL			0x034
> +#define   ESPI_PERIF_NP_TX_CTRL_TRIG_PEND	BIT(31)
> +#define	  ESPI_PERIF_NP_TX_CTRL_LEN		GENMASK(23, 12)
> +#define	  ESPI_PERIF_NP_TX_CTRL_TAG		GENMASK(11, 8)
> +#define	  ESPI_PERIF_NP_TX_CTRL_CYC		GENMASK(7, 0)
> +#define ESPI_PERIF_NP_TX_DATA			0x038
> +#define ESPI_OOB_RX_DMA				0x040
> +#define ESPI_OOB_RX_CTRL			0x044
> +#define	  ESPI_OOB_RX_CTRL_SERV_PEND		BIT(31)
> +#define	  ESPI_OOB_RX_CTRL_LEN			GENMASK(23, 12)
> +#define	  ESPI_OOB_RX_CTRL_TAG			GENMASK(11, 8)
> +#define	  ESPI_OOB_RX_CTRL_CYC			GENMASK(7, 0)
> +#define ESPI_OOB_RX_DATA			0x048
> +#define ESPI_OOB_TX_DMA				0x050
> +#define ESPI_OOB_TX_CTRL			0x054
> +#define	  ESPI_OOB_TX_CTRL_TRIG_PEND		BIT(31)
> +#define	  ESPI_OOB_TX_CTRL_LEN			GENMASK(23, 12)
> +#define	  ESPI_OOB_TX_CTRL_TAG			GENMASK(11, 8)
> +#define	  ESPI_OOB_TX_CTRL_CYC			GENMASK(7, 0)
> +#define ESPI_OOB_TX_DATA			0x058
> +#define ESPI_FLASH_RX_DMA			0x060
> +#define ESPI_FLASH_RX_CTRL			0x064
> +#define	  ESPI_FLASH_RX_CTRL_SERV_PEND		BIT(31)
> +#define	  ESPI_FLASH_RX_CTRL_LEN		GENMASK(23, 12)
> +#define	  ESPI_FLASH_RX_CTRL_TAG		GENMASK(11, 8)
> +#define	  ESPI_FLASH_RX_CTRL_CYC		GENMASK(7, 0)
> +#define ESPI_FLASH_RX_DATA			0x068
> +#define ESPI_FLASH_TX_DMA			0x070
> +#define ESPI_FLASH_TX_CTRL			0x074
> +#define	  ESPI_FLASH_TX_CTRL_TRIG_PEND		BIT(31)
> +#define	  ESPI_FLASH_TX_CTRL_LEN		GENMASK(23, 12)
> +#define	  ESPI_FLASH_TX_CTRL_TAG		GENMASK(11, 8)
> +#define	  ESPI_FLASH_TX_CTRL_CYC		GENMASK(7, 0)
> +#define ESPI_FLASH_TX_DATA			0x078
> +#define ESPI_CTRL2				0x080
> +#define   ESPI_CTRL2_VW_TX_SORT			BIT(30)
> +#define   ESPI_CTRL2_MCYC_RD_DIS_WDT		BIT(11)
> +#define   ESPI_CTRL2_MCYC_WR_DIS_WDT		BIT(10)
> +#define   ESPI_CTRL2_MCYC_RD_DIS		BIT(6)
> +#define   ESPI_CTRL2_MMBI_RD_DIS		ESPI_CTRL2_MCYC_RD_DIS
> +#define   ESPI_CTRL2_MCYC_WR_DIS		BIT(4)
> +#define   ESPI_CTRL2_MMBI_WR_DIS		ESPI_CTRL2_MCYC_WR_DIS
> +#define ESPI_PERIF_MCYC_SADDR			0x084
> +#define ESPI_PERIF_MMBI_SADDR			ESPI_PERIF_MCYC_SADDR
> +#define ESPI_PERIF_MCYC_TADDR			0x088
> +#define ESPI_PERIF_MMBI_TADDR			ESPI_PERIF_MCYC_TADDR
> +#define ESPI_PERIF_MCYC_MASK			0x08c
> +#define ESPI_PERIF_MMBI_MASK			ESPI_PERIF_MCYC_MASK
> +#define ESPI_FLASH_EDAF_TADDR			0x090
> +#define   ESPI_FLASH_EDAF_TADDR_BASE		GENMASK(31, 24)
> +#define   ESPI_FLASH_EDAF_TADDR_MASK		GENMASK(15, 8)
> +#define ESPI_VW_SYSEVT_INT_EN			0x094
> +#define ESPI_VW_SYSEVT				0x098
> +#define   ESPI_VW_SYSEVT_HOST_RST_ACK		BIT(27)
> +#define   ESPI_VW_SYSEVT_RST_CPU_INIT		BIT(26)
> +#define   ESPI_VW_SYSEVT_SLV_BOOT_STS		BIT(23)
> +#define   ESPI_VW_SYSEVT_NON_FATAL_ERR		BIT(22)
> +#define   ESPI_VW_SYSEVT_FATAL_ERR		BIT(21)
> +#define   ESPI_VW_SYSEVT_SLV_BOOT_DONE		BIT(20)
> +#define   ESPI_VW_SYSEVT_OOB_RST_ACK		BIT(16)
> +#define   ESPI_VW_SYSEVT_NMI_OUT		BIT(10)
> +#define   ESPI_VW_SYSEVT_SMI_OUT		BIT(9)
> +#define   ESPI_VW_SYSEVT_HOST_RST_WARN		BIT(8)
> +#define   ESPI_VW_SYSEVT_OOB_RST_WARN		BIT(6)
> +#define   ESPI_VW_SYSEVT_PLTRSTN		BIT(5)
> +#define   ESPI_VW_SYSEVT_SUSPEND		BIT(4)
> +#define   ESPI_VW_SYSEVT_S5_SLEEP		BIT(2)
> +#define   ESPI_VW_SYSEVT_S4_SLEEP		BIT(1)
> +#define   ESPI_VW_SYSEVT_S3_SLEEP		BIT(0)
> +#define ESPI_VW_GPIO_VAL			0x09c
> +#define ESPI_GEN_CAP_N_CONF			0x0a0
> +#define ESPI_CH0_CAP_N_CONF			0x0a4
> +#define ESPI_CH1_CAP_N_CONF			0x0a8
> +#define ESPI_CH2_CAP_N_CONF			0x0ac
> +#define ESPI_CH3_CAP_N_CONF			0x0b0
> +#define ESPI_CH3_CAP_N_CONF2			0x0b4
> +#define ESPI_VW_GPIO_DIR			0x0c0
> +#define ESPI_VW_GPIO_GRP			0x0c4
> +#define ESPI_INT_EN_CLR				0x0fc
> +#define ESPI_VW_SYSEVT1_INT_EN			0x100
> +#define ESPI_VW_SYSEVT1				0x104
> +#define   ESPI_VW_SYSEVT1_SUSPEND_ACK		BIT(20)
> +#define   ESPI_VW_SYSEVT1_SUSPEND_WARN		BIT(0)
> +#define ESPI_VW_SYSEVT_INT_T0			0x110
> +#define ESPI_VW_SYSEVT_INT_T1			0x114
> +#define ESPI_VW_SYSEVT_INT_T2			0x118
> +#define ESPI_VW_SYSEVT_INT_STS			0x11c
> +#define ESPI_VW_SYSEVT1_INT_T0			0x120
> +#define ESPI_VW_SYSEVT1_INT_T1			0x124
> +#define ESPI_VW_SYSEVT1_INT_T2			0x128
> +#define ESPI_VW_SYSEVT1_INT_STS			0x12c
> +#define ESPI_OOB_RX_DESC_NUM			0x130
> +#define ESPI_OOB_RX_DESC_RPTR			0x134
> +#define	  ESPI_OOB_RX_DESC_RPTR_UPDATE		BIT(31)
> +#define   ESPI_OOB_RX_DESC_RPTR_RP		GENMASK(11, 0)
> +#define ESPI_OOB_RX_DESC_WPTR			0x138
> +#define   ESPI_OOB_RX_DESC_WPTR_RECV_EN		BIT(31)
> +#define   ESPI_OOB_RX_DESC_WPTR_SP		GENMASK(27, 16)
> +#define   ESPI_OOB_RX_DESC_WPTR_WP		GENMASK(11, 0)
> +#define ESPI_OOB_TX_DESC_NUM			0x140
> +#define ESPI_OOB_TX_DESC_RPTR			0x144
> +#define	  ESPI_OOB_TX_DESC_RPTR_UPDATE		BIT(31)
> +#define ESPI_OOB_TX_DESC_WPTR			0x148
> +#define	  ESPI_OOB_TX_DESC_WPTR_SEND_EN		BIT(31)
> +#define ESPI_MMBI_CTRL				0x800
> +#define   ESPI_MMBI_CTRL_INST_SZ		GENMASK(10, 8)
> +#define   ESPI_MMBI_CTRL_TOTAL_SZ		GENMASK(6, 4)
> +#define   ESPI_MMBI_CTRL_EN			BIT(0)
> +#define ESPI_MMBI_INT_STS			0x808
> +#define ESPI_MMBI_INT_EN			0x80c
> +#define ESPI_MMBI_HOST_RWP(x)			(0x810 + ((x) << 3))
> +
> +/* collect ESPI_INT_EN bits for convenience */
> +#define ESPI_INT_EN_PERIF			\
> +	(ESPI_INT_EN_PERIF_NP_TX_ABT |		\
> +	 ESPI_INT_EN_PERIF_PC_TX_ABT |		\
> +	 ESPI_INT_EN_PERIF_NP_RX_ABT |		\
> +	 ESPI_INT_EN_PERIF_PC_RX_ABT |		\
> +	 ESPI_INT_EN_PERIF_NP_TX_ERR |		\
> +	 ESPI_INT_EN_PERIF_PC_TX_ERR |		\
> +	 ESPI_INT_EN_PERIF_NP_TX_CMPLT |	\
> +	 ESPI_INT_EN_PERIF_PC_TX_CMPLT |	\
> +	 ESPI_INT_EN_PERIF_PC_RX_CMPLT)
> +
> +#define ESPI_INT_EN_VW			\
> +	(ESPI_INT_EN_VW_SYSEVT1 |	\
> +	 ESPI_INT_EN_VW_GPIO    |	\
> +	 ESPI_INT_EN_VW_SYSEVT)
> +
> +#define ESPI_INT_EN_OOB		\
> +	(ESPI_INT_EN_OOB_RX_TMOUT |	\
> +	 ESPI_INT_EN_OOB_TX_ERR |	\
> +	 ESPI_INT_EN_OOB_TX_ABT |	\
> +	 ESPI_INT_EN_OOB_RX_ABT |	\
> +	 ESPI_INT_EN_OOB_TX_CMPLT |	\
> +	 ESPI_INT_EN_OOB_RX_CMPLT)
> +
> +#define ESPI_INT_EN_FLASH		\
> +	(ESPI_INT_EN_FLASH_TX_ERR |	\
> +	 ESPI_INT_EN_FLASH_TX_ABT |	\
> +	 ESPI_INT_EN_FLASH_RX_ABT |	\
> +	 ESPI_INT_EN_FLASH_TX_CMPLT |	\
> +	 ESPI_INT_EN_FLASH_RX_CMPLT)
> +
> +/* collect ESPI_INT_STS bits for convenience */
> +#define ESPI_INT_STS_PERIF			\
> +	(ESPI_INT_STS_PERIF_NP_TX_ABT |		\
> +	 ESPI_INT_STS_PERIF_PC_TX_ABT |		\
> +	 ESPI_INT_STS_PERIF_NP_RX_ABT |		\
> +	 ESPI_INT_STS_PERIF_PC_RX_ABT |		\
> +	 ESPI_INT_STS_PERIF_NP_TX_ERR |		\
> +	 ESPI_INT_STS_PERIF_PC_TX_ERR |		\
> +	 ESPI_INT_STS_PERIF_NP_TX_CMPLT |	\
> +	 ESPI_INT_STS_PERIF_PC_TX_CMPLT |	\
> +	 ESPI_INT_STS_PERIF_PC_RX_CMPLT)
> +
> +#define ESPI_INT_STS_VW			\
> +	(ESPI_INT_STS_VW_SYSEVT1 |	\
> +	 ESPI_INT_STS_VW_GPIO    |	\
> +	 ESPI_INT_STS_VW_SYSEVT)
> +
> +#define ESPI_INT_STS_OOB		\
> +	(ESPI_INT_STS_OOB_RX_TMOUT |	\
> +	 ESPI_INT_STS_OOB_TX_ERR |	\
> +	 ESPI_INT_STS_OOB_TX_ABT |	\
> +	 ESPI_INT_STS_OOB_RX_ABT |	\
> +	 ESPI_INT_STS_OOB_TX_CMPLT |	\
> +	 ESPI_INT_STS_OOB_RX_CMPLT)
> +
> +#define ESPI_INT_STS_FLASH		\
> +	(ESPI_INT_STS_FLASH_TX_ERR |	\
> +	 ESPI_INT_STS_FLASH_TX_ABT |	\
> +	 ESPI_INT_STS_FLASH_RX_ABT |	\
> +	 ESPI_INT_STS_FLASH_TX_CMPLT |	\
> +	 ESPI_INT_STS_FLASH_RX_CMPLT)
> +
> +/* function operators */
> +void ast2600_espi_pre_init(struct aspeed_espi *espi);
> +void ast2600_espi_post_init(struct aspeed_espi *espi);
> +void ast2600_espi_deinit(struct aspeed_espi *espi);
> +int ast2600_espi_perif_probe(struct aspeed_espi *espi);
> +int ast2600_espi_perif_remove(struct aspeed_espi *espi);
> +int ast2600_espi_vw_probe(struct aspeed_espi *espi);
> +int ast2600_espi_vw_remove(struct aspeed_espi *espi);
> +int ast2600_espi_oob_probe(struct aspeed_espi *espi);
> +int ast2600_espi_oob_remove(struct aspeed_espi *espi);
> +int ast2600_espi_flash_probe(struct aspeed_espi *espi);
> +int ast2600_espi_flash_remove(struct aspeed_espi *espi);
> +irqreturn_t ast2600_espi_isr(int irq, void *arg);
> +#endif
>


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/7] soc: aspeed: Add AST2600 eSPI controller support
       [not found]                 ` <KL1PR0601MB427603A6A5768D6A537CAFCB905AA@KL1PR0601MB4276.apcprd06.prod.outlook.com>
@ 2026-05-07 16:00                   ` Shulzhenko, Oleksandr
  2026-05-12  7:08                     ` YH Chung
  0 siblings, 1 reply; 4+ messages in thread
From: Shulzhenko, Oleksandr @ 2026-05-07 16:00 UTC (permalink / raw)
  To: YH Chung, Arnd Bergmann, Andrew Jeffery, Conor Dooley
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Ryan Chen, Philipp Zabel, devicetree@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org,
	openbmc@lists.ozlabs.org, maciej.lawniczak@intel.com, Mark Brown

On 4/7/2026 11:36 AM, YH Chung wrote:
> Hi Arnd,
>
> Thanks for the comments and questions.
>
>> These all seem to be viable options, but I still think we should focus on
>> agreeing on a design for the low-level hardware interface and whether this
>> can or should be abstracted between SoC vendor specific drivers before
>> trying to solve the user interface side.
>   
> Could you share your thoughts on whether it would make sense to accept our
> eSPI driver as is, and whether it should live under the SoC vendor-specific
> directories? Any comment would be greatly appreciated.
>
> Thanks,
> YunHsuan

Hi YunHsuan,

Let me add my 5 cents on this matter.

Integrating this driver into the SPI subsystem may allow reusing some 
existing definitions, e.g.|spi_controller|,|spi_message|, and perhaps 
parts related to single/dual/quad I/O handling. At the same time, parts 
such as the Flash channel (included in the current series), and OOB / 
Virtual Wire support (I would expect to come later), appear to be 
specific to the Intel eSPI protocol. Modeling all of that as just 
another SPI IP driver may introduce some awkward layering and overhead.

Also, the current series already seems to separate common eSPI logic 
from AST2600-specific pieces, assuming that 2700 driver is also coming 
at some point.

This makes me wonder whether a dedicated eSPI layer/subsystem could be a 
better fit — either under the SPI or as something separate (but not SoC 
driver).

Given my limited experience with SPI/eSPI, could you help clarify a few 
points for me (and probably others as well)?

  * How much of the SPI subsystem can be reused for this implementation,
    both for the current patchset and for likely future extensions?
  * Are there any pitfalls or abstraction mismatches in trying to reuse
    the SPI core here?

I think this would help make the subsystem placement discussion much 
clearer.



^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [PATCH 0/7] soc: aspeed: Add AST2600 eSPI controller support
  2026-05-07 16:00                   ` [PATCH 0/7] soc: aspeed: Add AST2600 eSPI controller support Shulzhenko, Oleksandr
@ 2026-05-12  7:08                     ` YH Chung
  2026-05-12  8:45                       ` Shulzhenko, Oleksandr
  0 siblings, 1 reply; 4+ messages in thread
From: YH Chung @ 2026-05-12  7:08 UTC (permalink / raw)
  To: Shulzhenko, Oleksandr, Arnd Bergmann, Andrew Jeffery,
	Conor Dooley
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Ryan Chen, Philipp Zabel, devicetree@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org,
	openbmc@lists.ozlabs.org, maciej.lawniczak@intel.com, Mark Brown

Hi Shulzhenko, 

Thanks for the follow-up. 

> Integrating this driver into the SPI subsystem may allow reusing some existing 
> definitions, e.g.|spi_controller|,|spi_message|, and perhaps parts related to 
> single/dual/quad I/O handling. At the same time, parts such as the Flash channel 
> (included in the current series), and OOB / Virtual Wire support (I would expect 
> to come later), appear to be specific to the Intel eSPI protocol. Modeling all of 
> that as just another SPI IP driver may introduce some awkward layering and 
> overhead. 

Agreed. eSPI introduces two additional pins, RESET# and ALERT#, beyond the
standard SPI signals. More importantly, eSPI functionality is described
primarily in terms of four logical channels, rather than generic low-level
bus signaling or pure data transfers.

> Also, the current series already seems to separate common eSPI logic from 
> AST2600-specific pieces, assuming that 2700 driver is also coming at some point. 
>
> This makes me wonder whether a dedicated eSPI layer/subsystem could be a 
> better fit — either under the SPI or as something separate (but not SoC driver). 
>
> Given my limited experience with SPI/eSPI, could you help clarify a few points for 
> me (and probably others as well)? 
> 
> * How much of the SPI subsystem can be reused for this implementation, 
> both for the current patchset and for likely future extensions? 

I believe only a limited portion of the SPI subsystem can be reused. Some
generic framework elements, such as controller registration and basic
scaffolding, may be useful initially. But this reuse appears to be mostly
mechanical rather than semantic. Once eSPI-specific features like Flash
channels, OOB messaging, and Virtual Wire semantics are involved, the SPI
transaction model does not seem to map very naturally. 

> * Are there any pitfalls or abstraction mismatches in trying to reuse 
> the SPI core here? 

Our main concern is an abstraction mismatch. SPI is designed as a generic
peripheral bus, while eSPI is more of a system-management interface with
explicit host-BMC-specific semantics. Reusing the SPI core would likely
require treating eSPI packets as generic bus-level transfers in the kernel.

However, some eSPI transactions and protocol handling, such as LPC bridge
accesses, are performed autonomously by the hardware rather than being fully
driven as low-level bus operations by the driver. This makes the eSPI driver
somewhat different from a conventional serial bus controller driver
maintained under the SPI core.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/7] soc: aspeed: Add AST2600 eSPI controller support
  2026-05-12  7:08                     ` YH Chung
@ 2026-05-12  8:45                       ` Shulzhenko, Oleksandr
  0 siblings, 0 replies; 4+ messages in thread
From: Shulzhenko, Oleksandr @ 2026-05-12  8:45 UTC (permalink / raw)
  To: YH Chung, Arnd Bergmann, Andrew Jeffery, Conor Dooley
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Ryan Chen, Philipp Zabel, devicetree@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org,
	openbmc@lists.ozlabs.org, maciej.lawniczak@intel.com, Mark Brown

On 5/12/2026 9:08 AM, YH Chung wrote:
> Hi Shulzhenko,
>
> Thanks for the follow-up.
>
>> Integrating this driver into the SPI subsystem may allow reusing some existing
>> definitions, e.g.|spi_controller|,|spi_message|, and perhaps parts related to
>> single/dual/quad I/O handling. At the same time, parts such as the Flash channel
>> (included in the current series), and OOB / Virtual Wire support (I would expect
>> to come later), appear to be specific to the Intel eSPI protocol. Modeling all of
>> that as just another SPI IP driver may introduce some awkward layering and
>> overhead.
> Agreed. eSPI introduces two additional pins, RESET# and ALERT#, beyond the
> standard SPI signals. More importantly, eSPI functionality is described
> primarily in terms of four logical channels, rather than generic low-level
> bus signaling or pure data transfers.
>
>> Also, the current series already seems to separate common eSPI logic from
>> AST2600-specific pieces, assuming that 2700 driver is also coming at some point.
>>
>> This makes me wonder whether a dedicated eSPI layer/subsystem could be a
>> better fit — either under the SPI or as something separate (but not SoC driver).
>>
>> Given my limited experience with SPI/eSPI, could you help clarify a few points for
>> me (and probably others as well)?
>>
>> * How much of the SPI subsystem can be reused for this implementation,
>> both for the current patchset and for likely future extensions?
> I believe only a limited portion of the SPI subsystem can be reused. Some
> generic framework elements, such as controller registration and basic
> scaffolding, may be useful initially. But this reuse appears to be mostly
> mechanical rather than semantic. Once eSPI-specific features like Flash
> channels, OOB messaging, and Virtual Wire semantics are involved, the SPI
> transaction model does not seem to map very naturally.
>
>> * Are there any pitfalls or abstraction mismatches in trying to reuse
>> the SPI core here?
> Our main concern is an abstraction mismatch. SPI is designed as a generic
> peripheral bus, while eSPI is more of a system-management interface with
> explicit host-BMC-specific semantics. Reusing the SPI core would likely
> require treating eSPI packets as generic bus-level transfers in the kernel.
>
> However, some eSPI transactions and protocol handling, such as LPC bridge
> accesses, are performed autonomously by the hardware rather than being fully
> driven as low-level bus operations by the driver. This makes the eSPI driver
> somewhat different from a conventional serial bus controller driver
> maintained under the SPI core.
>
Hi YH,

My main concern is trying to understand whether it is completely 
impossible (or introduces too much effort that we'd better not to take) 
integrating this to SPI subsystem.

 From your reply I understand there are two potential blockers:

a) Treating eSPI transfers as bus-level transfers (meaning that it will 
be necessary probably making separate driver for OOB/VW/Flash channels 
as they essentially use eSPI as a transport);

b) Some logic being done by the hardware (i.e. LPC bridge).

Please confirm my understanding:

(a) is feasible, but requires many effort to re-define architecture

(b) If something is done by the hardware - what is the driver impact? I 
recall eDAF use case when the driver wasn't involved at all - and flash 
access was fully done by the hardware (unless the controller is 
configured to handle it in SW mode).


P.S. I guess we can talk about host-BMC communication only when talking 
about hardware-dependent stuff (i.e. ast2600-espi files). eSPI core 
should be (it seems to be already is) at least BMC agnostic and this is 
the reason not having it under SOC/aspeed (ast2600-espi.* may stay here 
though).


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-05-12  8:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20260313-upstream_espi-v1-0-9504428e1f43@aspeedtech.com>
     [not found] ` <20260313-upstream_espi-v1-3-9504428e1f43@aspeedtech.com>
2026-05-07 14:03   ` [PATCH 3/7] soc: aspeed: Add AST2600 peripheral channel port I/O support Shulzhenko, Oleksandr
     [not found] ` <20260313-energy-casket-ca8adc1f1fd1@spud>
     [not found]   ` <23909400-4e7f-49c9-a982-14036372af98@app.fastmail.com>
     [not found]     ` <c3b28ee92fa46700887d0c68b23045b2418358a7.camel@codeconstruct.com.au>
     [not found]       ` <KL1PR0601MB4276ED93723F0B1F42349AD89041A@KL1PR0601MB4276.apcprd06.prod.outlook.com>
     [not found]         ` <0f7f0f96-a918-47d5-a0bd-bbde494c8fed@app.fastmail.com>
     [not found]           ` <KL1PR0601MB4276B5BE3B96C18E3A66AD709049A@KL1PR0601MB4276.apcprd06.prod.outlook.com>
     [not found]             ` <14870d17-2471-4522-b8b5-03cb9002a4f7@app.fastmail.com>
     [not found]               ` <KL1PR0601MB42763DAD359305DEBA4B769D9057A@KL1PR0601MB4276.apcprd06.prod.outlook.com>
     [not found]                 ` <KL1PR0601MB427603A6A5768D6A537CAFCB905AA@KL1PR0601MB4276.apcprd06.prod.outlook.com>
2026-05-07 16:00                   ` [PATCH 0/7] soc: aspeed: Add AST2600 eSPI controller support Shulzhenko, Oleksandr
2026-05-12  7:08                     ` YH Chung
2026-05-12  8:45                       ` Shulzhenko, Oleksandr

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox