* [PATCH v5 0/2] ASPEED: Add mailbox driver for AST2700 series @ 2025-06-25 7:34 Jammy Huang 2025-06-25 7:34 ` [PATCH v5 1/2] dt-bindings: mailbox: Add ASPEED AST2700 series SoC Jammy Huang 2025-06-25 7:34 ` [PATCH v5 2/2] mailbox: aspeed: add mailbox driver for AST27XX " Jammy Huang 0 siblings, 2 replies; 9+ messages in thread From: Jammy Huang @ 2025-06-25 7:34 UTC (permalink / raw) To: jassisinghbrar, robh, krzk+dt, conor+dt, joel, andrew, linux-kernel, devicetree, linux-arm-kernel, linux-aspeed Add mailbox controller driver for AST27XX SoCs, which provides independent tx/rx mailbox between different processors. There are 4 channels for each tx/rx mailbox and each channel has an 32-byte FIFO. v5 changes: - Update document 1. Separate reg from 1 to 2. 1st is tx controller; 2nd is rx. 2. Remove 'Reviewed-by' since the patch has changed. - Update driver, no functional changes. 1. Update since there is 2 reg base now. 2. Refine reg definitions 3. Add spinlock to protect registers 4. Use bool as return value for ast2700_mbox_tx_done 5. Rename variable from drv_data to dev_data. v4 changes: - Update driver, no functional changes. 1. Remove unused variable, rx_buff, in struct ast2700_mbox. 2. Remove unneeded cast on device_get_match_data. 3. Remove the usage of writel/readl_relaxed. 4. Improve readability. v3 changes: - Correct document 1. Use 32-bit addressing in dts example property, reg. v2 changes: - Update document 1. Correct error in dts example. 2. Drop description for mbox-cell per suggestion previously. Jammy Huang (2): dt-bindings: mailbox: Add ASPEED AST2700 series SoC mailbox: aspeed: add mailbox driver for AST27XX series SoC .../mailbox/aspeed,ast2700-mailbox.yaml | 60 +++++ drivers/mailbox/Kconfig | 8 + drivers/mailbox/Makefile | 2 + drivers/mailbox/ast2700-mailbox.c | 240 ++++++++++++++++++ 4 files changed, 310 insertions(+) create mode 100644 Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox.yaml create mode 100644 drivers/mailbox/ast2700-mailbox.c base-commit: ec7714e4947909190ffb3041a03311a975350fe0 -- 2.25.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v5 1/2] dt-bindings: mailbox: Add ASPEED AST2700 series SoC 2025-06-25 7:34 [PATCH v5 0/2] ASPEED: Add mailbox driver for AST2700 series Jammy Huang @ 2025-06-25 7:34 ` Jammy Huang 2025-06-25 15:50 ` Rob Herring 2025-06-25 7:34 ` [PATCH v5 2/2] mailbox: aspeed: add mailbox driver for AST27XX " Jammy Huang 1 sibling, 1 reply; 9+ messages in thread From: Jammy Huang @ 2025-06-25 7:34 UTC (permalink / raw) To: jassisinghbrar, robh, krzk+dt, conor+dt, joel, andrew, linux-kernel, devicetree, linux-arm-kernel, linux-aspeed Introduce the mailbox module for AST27XX series SoC, which is responsible for interchanging messages between asymmetric processors. Signed-off-by: Jammy Huang <jammy_huang@aspeedtech.com> --- .../mailbox/aspeed,ast2700-mailbox.yaml | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox.yaml diff --git a/Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox.yaml new file mode 100644 index 000000000000..0a5f43de5f28 --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mailbox/aspeed,ast2700-mailbox.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ASPEED AST2700 mailbox controller + +maintainers: + - Jammy Huang <jammy_huang@aspeedtech.com> + +description: + ASPEED AST2700 has multiple processors that need to communicate with each + other. The mailbox controller provides a way for these processors to send + messages to each other. It is a hardware-based inter-processor communication + mechanism that allows processors to send and receive messages through + dedicated channels. + The mailbox's tx/rx are independent, meaning that one processor can send a + message while another processor is receiving a message simultaneously. + There are 4 channels available for both tx and rx operations. Each channel + has a FIFO buffer that can hold messages of a fixed size (32 bytes in this + case). + The mailbox controller also supports interrupt generation, allowing + processors to notify each other when a message is available or when an event + occurs. + +properties: + compatible: + const: aspeed,ast2700-mailbox + + reg: + maxItems: 2 + description: + Contains the base addresses and sizes of the mailbox controller. 1st one + is for TX control register; 2nd one is for RX control register. + + interrupts: + maxItems: 1 + + "#mbox-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - "#mbox-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + + mailbox@12c1c200 { + compatible = "aspeed,ast2700-mailbox"; + reg = <0x12c1c200 0x100>, <0x12c1c300 0x100>; + interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; + #mbox-cells = <1>; + }; -- 2.25.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/2] dt-bindings: mailbox: Add ASPEED AST2700 series SoC 2025-06-25 7:34 ` [PATCH v5 1/2] dt-bindings: mailbox: Add ASPEED AST2700 series SoC Jammy Huang @ 2025-06-25 15:50 ` Rob Herring 2025-06-26 3:41 ` Jammy Huang 2025-06-27 1:52 ` Andrew Jeffery 0 siblings, 2 replies; 9+ messages in thread From: Rob Herring @ 2025-06-25 15:50 UTC (permalink / raw) To: Jammy Huang Cc: jassisinghbrar, krzk+dt, conor+dt, joel, andrew, linux-kernel, devicetree, linux-arm-kernel, linux-aspeed On Wed, Jun 25, 2025 at 03:34:16PM +0800, Jammy Huang wrote: > Introduce the mailbox module for AST27XX series SoC, which is responsible > for interchanging messages between asymmetric processors. > > Signed-off-by: Jammy Huang <jammy_huang@aspeedtech.com> You didn't add Krzysztof's Reviewed-by... > --- > .../mailbox/aspeed,ast2700-mailbox.yaml | 60 +++++++++++++++++++ > 1 file changed, 60 insertions(+) > create mode 100644 Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox.yaml > > diff --git a/Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox.yaml > new file mode 100644 > index 000000000000..0a5f43de5f28 > --- /dev/null > +++ b/Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox.yaml > @@ -0,0 +1,60 @@ > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/mailbox/aspeed,ast2700-mailbox.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: ASPEED AST2700 mailbox controller > + > +maintainers: > + - Jammy Huang <jammy_huang@aspeedtech.com> > + > +description: You need '>' to preserve paragraphs. > + ASPEED AST2700 has multiple processors that need to communicate with each > + other. The mailbox controller provides a way for these processors to send > + messages to each other. It is a hardware-based inter-processor communication > + mechanism that allows processors to send and receive messages through > + dedicated channels. And a blank line between paragraphs. > + The mailbox's tx/rx are independent, meaning that one processor can send a > + message while another processor is receiving a message simultaneously. > + There are 4 channels available for both tx and rx operations. Each channel > + has a FIFO buffer that can hold messages of a fixed size (32 bytes in this > + case). And here. > + The mailbox controller also supports interrupt generation, allowing > + processors to notify each other when a message is available or when an event > + occurs. > + > +properties: > + compatible: > + const: aspeed,ast2700-mailbox > + > + reg: > + maxItems: 2 > + description: > + Contains the base addresses and sizes of the mailbox controller. 1st one > + is for TX control register; 2nd one is for RX control register. Instead, just: items: - description: TX control register - description: RX control register > + > + interrupts: > + maxItems: 1 > + > + "#mbox-cells": > + const: 1 > + > +required: > + - compatible > + - reg > + - interrupts > + - "#mbox-cells" > + > +additionalProperties: false > + > +examples: > + - | > + #include <dt-bindings/interrupt-controller/arm-gic.h> > + > + mailbox@12c1c200 { > + compatible = "aspeed,ast2700-mailbox"; > + reg = <0x12c1c200 0x100>, <0x12c1c300 0x100>; > + interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; > + #mbox-cells = <1>; > + }; > -- > 2.25.1 > ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH v5 1/2] dt-bindings: mailbox: Add ASPEED AST2700 series SoC 2025-06-25 15:50 ` Rob Herring @ 2025-06-26 3:41 ` Jammy Huang 2025-06-27 1:52 ` Andrew Jeffery 1 sibling, 0 replies; 9+ messages in thread From: Jammy Huang @ 2025-06-26 3:41 UTC (permalink / raw) To: Rob Herring Cc: jassisinghbrar@gmail.com, krzk+dt@kernel.org, conor+dt@kernel.org, joel@jms.id.au, andrew@codeconstruct.com.au, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org > On Wed, Jun 25, 2025 at 03:34:16PM +0800, Jammy Huang wrote: > > Introduce the mailbox module for AST27XX series SoC, which is > > responsible for interchanging messages between asymmetric processors. > > > > Signed-off-by: Jammy Huang <jammy_huang@aspeedtech.com> > > You didn't add Krzysztof's Reviewed-by... Hi Rob, I checked submitting patches' guide, and it says that if the patch has changed substantially in following version, these tags might not be applicable anymore and thus should be removed. I also mentioned this in changelog on the cover. I am not sure about this, so may I keep Krzk's Reviewed-by tag? If it's OK, I will add it back on next patch. > > > --- > > .../mailbox/aspeed,ast2700-mailbox.yaml | 60 > +++++++++++++++++++ > > 1 file changed, 60 insertions(+) > > create mode 100644 > > Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox.yaml > > > > diff --git > > a/Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox.yam > > l > > b/Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox.yam > > l > > new file mode 100644 > > index 000000000000..0a5f43de5f28 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/mailbox/aspeed,ast2700-mailbox > > +++ .yaml > > @@ -0,0 +1,60 @@ > > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2 > > +--- > > +$id: > > +http://devicetree.org/schemas/mailbox/aspeed,ast2700-mailbox.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: ASPEED AST2700 mailbox controller > > + > > +maintainers: > > + - Jammy Huang <jammy_huang@aspeedtech.com> > > + > > +description: > > You need '>' to preserve paragraphs. OK > > > + ASPEED AST2700 has multiple processors that need to communicate > > + with each other. The mailbox controller provides a way for these > > + processors to send messages to each other. It is a hardware-based > > + inter-processor communication mechanism that allows processors to > > + send and receive messages through dedicated channels. > > And a blank line between paragraphs. > OK > > + The mailbox's tx/rx are independent, meaning that one processor can > > + send a message while another processor is receiving a message > simultaneously. > > + There are 4 channels available for both tx and rx operations. Each > > + channel has a FIFO buffer that can hold messages of a fixed size > > + (32 bytes in this case). > > And here. > Sure. > > + The mailbox controller also supports interrupt generation, allowing > > + processors to notify each other when a message is available or when > > + an event occurs. > > + > > +properties: > > + compatible: > > + const: aspeed,ast2700-mailbox > > + > > + reg: > > + maxItems: 2 > > + description: > > + Contains the base addresses and sizes of the mailbox controller. 1st > one > > + is for TX control register; 2nd one is for RX control register. > > Instead, just: > > items: > - description: TX control register > - description: RX control register > Agree. > > + > > + interrupts: > > + maxItems: 1 > > + > > + "#mbox-cells": > > + const: 1 > > + > > +required: > > + - compatible > > + - reg > > + - interrupts > > + - "#mbox-cells" > > + > > +additionalProperties: false > > + > > +examples: > > + - | > > + #include <dt-bindings/interrupt-controller/arm-gic.h> > > + > > + mailbox@12c1c200 { > > + compatible = "aspeed,ast2700-mailbox"; > > + reg = <0x12c1c200 0x100>, <0x12c1c300 0x100>; > > + interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; > > + #mbox-cells = <1>; > > + }; > > -- > > 2.25.1 > > Thanks for your help. Regards Jammy ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/2] dt-bindings: mailbox: Add ASPEED AST2700 series SoC 2025-06-25 15:50 ` Rob Herring 2025-06-26 3:41 ` Jammy Huang @ 2025-06-27 1:52 ` Andrew Jeffery 2025-06-27 2:22 ` Jammy Huang 1 sibling, 1 reply; 9+ messages in thread From: Andrew Jeffery @ 2025-06-27 1:52 UTC (permalink / raw) To: Rob Herring, Jammy Huang Cc: jassisinghbrar, krzk+dt, conor+dt, joel, linux-kernel, devicetree, linux-arm-kernel, linux-aspeed On Wed, 2025-06-25 at 10:50 -0500, Rob Herring wrote: > On Wed, Jun 25, 2025 at 03:34:16PM +0800, Jammy Huang wrote: > > Introduce the mailbox module for AST27XX series SoC, which is responsible > > for interchanging messages between asymmetric processors. > > > > Signed-off-by: Jammy Huang <jammy_huang@aspeedtech.com> > *snip* > > +properties: > > + compatible: > > + const: aspeed,ast2700-mailbox > > + > > + reg: > > + maxItems: 2 > > + description: > > + Contains the base addresses and sizes of the mailbox controller. 1st one > > + is for TX control register; 2nd one is for RX control register. > > Instead, just: > > items: > - description: TX control register > - description: RX control register Maybe also specify reg-names with "tx" and "rx"? That way we can use devm_platform_ioremap_resource_byname() in the linux driver implementation, which should look tidier. Andrew ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH v5 1/2] dt-bindings: mailbox: Add ASPEED AST2700 series SoC 2025-06-27 1:52 ` Andrew Jeffery @ 2025-06-27 2:22 ` Jammy Huang 0 siblings, 0 replies; 9+ messages in thread From: Jammy Huang @ 2025-06-27 2:22 UTC (permalink / raw) To: Andrew Jeffery, Rob Herring Cc: jassisinghbrar@gmail.com, krzk+dt@kernel.org, conor+dt@kernel.org, joel@jms.id.au, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org > On Wed, 2025-06-25 at 10:50 -0500, Rob Herring wrote: > > On Wed, Jun 25, 2025 at 03:34:16PM +0800, Jammy Huang wrote: > > > Introduce the mailbox module for AST27XX series SoC, which is > > > responsible for interchanging messages between asymmetric processors. > > > > > > Signed-off-by: Jammy Huang <jammy_huang@aspeedtech.com> > > > > *snip* > > > > +properties: > > > + compatible: > > > + const: aspeed,ast2700-mailbox > > > + > > > + reg: > > > + maxItems: 2 > > > + description: > > > + Contains the base addresses and sizes of the mailbox > > > +controller. 1st one > > > + is for TX control register; 2nd one is for RX control register. > > > > Instead, just: > > > > items: > > - description: TX control register > > - description: RX control register > > Maybe also specify reg-names with "tx" and "rx"? That way we can use > devm_platform_ioremap_resource_byname() in the linux driver > implementation, which should look tidier. Sounds good. I will do it. > > Andrew Regards Jammy ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v5 2/2] mailbox: aspeed: add mailbox driver for AST27XX series SoC 2025-06-25 7:34 [PATCH v5 0/2] ASPEED: Add mailbox driver for AST2700 series Jammy Huang 2025-06-25 7:34 ` [PATCH v5 1/2] dt-bindings: mailbox: Add ASPEED AST2700 series SoC Jammy Huang @ 2025-06-25 7:34 ` Jammy Huang 2025-06-27 1:54 ` Andrew Jeffery 1 sibling, 1 reply; 9+ messages in thread From: Jammy Huang @ 2025-06-25 7:34 UTC (permalink / raw) To: jassisinghbrar, robh, krzk+dt, conor+dt, joel, andrew, linux-kernel, devicetree, linux-arm-kernel, linux-aspeed Add mailbox controller driver for AST27XX SoCs, which provides independent tx/rx mailbox between different processors. There are 4 channels for each tx/rx mailbox and each channel has an 32-byte FIFO. Signed-off-by: Jammy Huang <jammy_huang@aspeedtech.com> --- drivers/mailbox/Kconfig | 8 + drivers/mailbox/Makefile | 2 + drivers/mailbox/ast2700-mailbox.c | 240 ++++++++++++++++++++++++++++++ 3 files changed, 250 insertions(+) create mode 100644 drivers/mailbox/ast2700-mailbox.c diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index 68eeed660a4a..1c38cd570091 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -340,4 +340,12 @@ config THEAD_TH1520_MBOX kernel is running, and E902 core used for power management among other things. +config AST2700_MBOX + tristate "ASPEED AST2700 IPC driver" + depends on ARCH_ASPEED || COMPILE_TEST + help + Mailbox driver implementation for ASPEED AST27XX SoCs. This driver + can be used to send message between different processors in SoC. + The driver provides mailbox support for sending interrupts to the + clients. Say Y here if you want to build this driver. endif diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index 13a3448b3271..9a9add9a7548 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -72,3 +72,5 @@ obj-$(CONFIG_QCOM_CPUCP_MBOX) += qcom-cpucp-mbox.o obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o obj-$(CONFIG_THEAD_TH1520_MBOX) += mailbox-th1520.o + +obj-$(CONFIG_AST2700_MBOX) += ast2700-mailbox.o diff --git a/drivers/mailbox/ast2700-mailbox.c b/drivers/mailbox/ast2700-mailbox.c new file mode 100644 index 000000000000..5470053f8139 --- /dev/null +++ b/drivers/mailbox/ast2700-mailbox.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright Aspeed Technology Inc. (C) 2025. All rights reserved + */ + +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/kernel.h> +#include <linux/mailbox_controller.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +/* Each bit in the register represents an IPC ID */ +#define IPCR_TX_TRIG 0x00 +#define IPCR_ENABLE 0x04 +#define IPCR_STATUS 0x08 +#define RX_IRQ(n) BIT(n) +#define RX_IRQ_MASK 0xf +#define IPCR_DATA 0x10 + +struct ast2700_mbox_data { + u8 num_chans; + u8 msg_size; +}; + +struct ast2700_mbox { + struct mbox_controller mbox; + u8 msg_size; + void __iomem *tx_regs; + void __iomem *rx_regs; + spinlock_t lock; +}; + +static inline int ch_num(struct mbox_chan *chan) +{ + return chan - chan->mbox->chans; +} + +static inline bool ast2700_mbox_tx_done(struct ast2700_mbox *mb, int idx) +{ + return !(readl(mb->tx_regs + IPCR_STATUS) & BIT(idx)); +} + +static irqreturn_t ast2700_mbox_irq(int irq, void *p) +{ + struct ast2700_mbox *mb = p; + void __iomem *data_reg; + int num_words; + u32 *word_data; + u32 status; + int n; + + /* Only examine channels that are currently enabled. */ + status = readl(mb->rx_regs + IPCR_ENABLE) & + readl(mb->rx_regs + IPCR_STATUS); + + if (!(status & RX_IRQ_MASK)) + return IRQ_NONE; + + for (n = 0; n < mb->mbox.num_chans; ++n) { + struct mbox_chan *chan = &mb->mbox.chans[n]; + + if (!(status & RX_IRQ(n))) + continue; + + /* Read the message data */ + for (data_reg = mb->rx_regs + IPCR_DATA + mb->msg_size * n, + word_data = chan->con_priv, + num_words = (mb->msg_size / sizeof(u32)); + num_words; + num_words--, data_reg += sizeof(u32), word_data++) + *word_data = readl(data_reg); + + mbox_chan_received_data(chan, chan->con_priv); + + /* The IRQ can be cleared only once the FIFO is empty. */ + writel(RX_IRQ(n), mb->rx_regs + IPCR_STATUS); + } + + return IRQ_HANDLED; +} + +static int ast2700_mbox_send_data(struct mbox_chan *chan, void *data) +{ + struct ast2700_mbox *mb = dev_get_drvdata(chan->mbox->dev); + void __iomem *data_reg; + u32 *word_data; + int num_words; + int idx = ch_num(chan); + + if (!(readl(mb->tx_regs + IPCR_ENABLE) & BIT(idx))) { + dev_warn(mb->mbox.dev, "%s: Ch-%d not enabled yet\n", __func__, idx); + return -EBUSY; + } + + if (!(ast2700_mbox_tx_done(mb, idx))) { + dev_warn(mb->mbox.dev, "%s: Ch-%d last data has not finished\n", __func__, idx); + return -EBUSY; + } + + /* Write the message data */ + for (data_reg = mb->tx_regs + IPCR_DATA + mb->msg_size * idx, + word_data = (u32 *)data, + num_words = (mb->msg_size / sizeof(u32)); + num_words; + num_words--, data_reg += sizeof(u32), word_data++) + writel(*word_data, data_reg); + + writel(BIT(idx), mb->tx_regs + IPCR_TX_TRIG); + dev_dbg(mb->mbox.dev, "%s: Ch-%d sent\n", __func__, idx); + + return 0; +} + +static int ast2700_mbox_startup(struct mbox_chan *chan) +{ + struct ast2700_mbox *mb = dev_get_drvdata(chan->mbox->dev); + int idx = ch_num(chan); + void __iomem *reg = mb->rx_regs + IPCR_ENABLE; + unsigned long flags; + + spin_lock_irqsave(&mb->lock, flags); + writel(readl(reg) | BIT(idx), reg); + spin_unlock_irqrestore(&mb->lock, flags); + + return 0; +} + +static void ast2700_mbox_shutdown(struct mbox_chan *chan) +{ + struct ast2700_mbox *mb = dev_get_drvdata(chan->mbox->dev); + int idx = ch_num(chan); + void __iomem *reg = mb->rx_regs + IPCR_ENABLE; + unsigned long flags; + + spin_lock_irqsave(&mb->lock, flags); + writel(readl(reg) & ~BIT(idx), reg); + spin_unlock_irqrestore(&mb->lock, flags); +} + +static bool ast2700_mbox_last_tx_done(struct mbox_chan *chan) +{ + struct ast2700_mbox *mb = dev_get_drvdata(chan->mbox->dev); + int idx = ch_num(chan); + + return ast2700_mbox_tx_done(mb, idx); +} + +static const struct mbox_chan_ops ast2700_mbox_chan_ops = { + .send_data = ast2700_mbox_send_data, + .startup = ast2700_mbox_startup, + .shutdown = ast2700_mbox_shutdown, + .last_tx_done = ast2700_mbox_last_tx_done, +}; + +static int ast2700_mbox_probe(struct platform_device *pdev) +{ + struct ast2700_mbox *mb; + const struct ast2700_mbox_data *dev_data; + struct device *dev = &pdev->dev; + int irq, ret; + + if (!pdev->dev.of_node) + return -ENODEV; + + dev_data = device_get_match_data(&pdev->dev); + + mb = devm_kzalloc(dev, sizeof(*mb), GFP_KERNEL); + if (!mb) + return -ENOMEM; + + mb->mbox.chans = devm_kcalloc(&pdev->dev, dev_data->num_chans, + sizeof(*mb->mbox.chans), GFP_KERNEL); + if (!mb->mbox.chans) + return -ENOMEM; + + /* con_priv of each channel is used to store the message received */ + for (int i = 0; i < dev_data->num_chans; i++) { + mb->mbox.chans[i].con_priv = devm_kcalloc(dev, dev_data->msg_size, + sizeof(u8), GFP_KERNEL); + if (!mb->mbox.chans[i].con_priv) + return -ENOMEM; + } + + platform_set_drvdata(pdev, mb); + + mb->tx_regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(mb->tx_regs)) + return PTR_ERR(mb->tx_regs); + + mb->rx_regs = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(mb->rx_regs)) + return PTR_ERR(mb->rx_regs); + + mb->msg_size = dev_data->msg_size; + mb->mbox.dev = dev; + mb->mbox.num_chans = dev_data->num_chans; + mb->mbox.ops = &ast2700_mbox_chan_ops; + mb->mbox.txdone_irq = false; + mb->mbox.txdone_poll = true; + mb->mbox.txpoll_period = 5; + spin_lock_init(&mb->lock); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + ret = devm_request_irq(dev, irq, ast2700_mbox_irq, 0, dev_name(dev), mb); + if (ret) + return ret; + + return devm_mbox_controller_register(dev, &mb->mbox); +} + +static const struct ast2700_mbox_data ast2700_dev_data = { + .num_chans = 4, + .msg_size = 0x20, +}; + +static const struct of_device_id ast2700_mbox_of_match[] = { + { .compatible = "aspeed,ast2700-mailbox", .data = &ast2700_dev_data }, + {} +}; +MODULE_DEVICE_TABLE(of, ast2700_mbox_of_match); + +static struct platform_driver ast2700_mbox_driver = { + .driver = { + .name = "ast2700-mailbox", + .of_match_table = ast2700_mbox_of_match, + }, + .probe = ast2700_mbox_probe, +}; +module_platform_driver(ast2700_mbox_driver); + +MODULE_AUTHOR("Jammy Huang <jammy_huang@aspeedtech.com>"); +MODULE_DESCRIPTION("ASPEED AST2700 IPC driver"); +MODULE_LICENSE("GPL"); -- 2.25.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v5 2/2] mailbox: aspeed: add mailbox driver for AST27XX series SoC 2025-06-25 7:34 ` [PATCH v5 2/2] mailbox: aspeed: add mailbox driver for AST27XX " Jammy Huang @ 2025-06-27 1:54 ` Andrew Jeffery 2025-06-27 2:21 ` Jammy Huang 0 siblings, 1 reply; 9+ messages in thread From: Andrew Jeffery @ 2025-06-27 1:54 UTC (permalink / raw) To: Jammy Huang, jassisinghbrar, robh, krzk+dt, conor+dt, joel, linux-kernel, devicetree, linux-arm-kernel, linux-aspeed On Wed, 2025-06-25 at 15:34 +0800, Jammy Huang wrote: > Add mailbox controller driver for AST27XX SoCs, which provides > independent tx/rx mailbox between different processors. There are 4 > channels for each tx/rx mailbox and each channel has an 32-byte FIFO. > > Signed-off-by: Jammy Huang <jammy_huang@aspeedtech.com> > --- > drivers/mailbox/Kconfig | 8 + > drivers/mailbox/Makefile | 2 + > drivers/mailbox/ast2700-mailbox.c | 240 ++++++++++++++++++++++++++++++ > 3 files changed, 250 insertions(+) > create mode 100644 drivers/mailbox/ast2700-mailbox.c > > diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig > index 68eeed660a4a..1c38cd570091 100644 > --- a/drivers/mailbox/Kconfig > +++ b/drivers/mailbox/Kconfig > @@ -340,4 +340,12 @@ config THEAD_TH1520_MBOX > kernel is running, and E902 core used for power management among other > things. > > +config AST2700_MBOX > + tristate "ASPEED AST2700 IPC driver" > + depends on ARCH_ASPEED || COMPILE_TEST > + help > + Mailbox driver implementation for ASPEED AST27XX SoCs. This driver > + can be used to send message between different processors in SoC. > + The driver provides mailbox support for sending interrupts to the > + clients. Say Y here if you want to build this driver. > endif > diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile > index 13a3448b3271..9a9add9a7548 100644 > --- a/drivers/mailbox/Makefile > +++ b/drivers/mailbox/Makefile > @@ -72,3 +72,5 @@ obj-$(CONFIG_QCOM_CPUCP_MBOX) += qcom-cpucp-mbox.o > obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o > > obj-$(CONFIG_THEAD_TH1520_MBOX) += mailbox-th1520.o > + > +obj-$(CONFIG_AST2700_MBOX) += ast2700-mailbox.o > diff --git a/drivers/mailbox/ast2700-mailbox.c b/drivers/mailbox/ast2700-mailbox.c > new file mode 100644 > index 000000000000..5470053f8139 > --- /dev/null > +++ b/drivers/mailbox/ast2700-mailbox.c > @@ -0,0 +1,240 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright Aspeed Technology Inc. (C) 2025. All rights reserved > + */ > + > +#include <linux/interrupt.h> > +#include <linux/io.h> > +#include <linux/iopoll.h> > +#include <linux/kernel.h> > +#include <linux/mailbox_controller.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/platform_device.h> > +#include <linux/slab.h> > + > +/* Each bit in the register represents an IPC ID */ > +#define IPCR_TX_TRIG 0x00 > +#define IPCR_ENABLE 0x04 > +#define IPCR_STATUS 0x08 > +#define RX_IRQ(n) BIT(n) > +#define RX_IRQ_MASK 0xf > +#define IPCR_DATA 0x10 > + > +struct ast2700_mbox_data { > + u8 num_chans; > + u8 msg_size; > +}; > + > +struct ast2700_mbox { > + struct mbox_controller mbox; > + u8 msg_size; > + void __iomem *tx_regs; > + void __iomem *rx_regs; > + spinlock_t lock; > +}; > + > +static inline int ch_num(struct mbox_chan *chan) > +{ > + return chan - chan->mbox->chans; > +} > + > +static inline bool ast2700_mbox_tx_done(struct ast2700_mbox *mb, int idx) > +{ > + return !(readl(mb->tx_regs + IPCR_STATUS) & BIT(idx)); > +} > + > +static irqreturn_t ast2700_mbox_irq(int irq, void *p) > +{ > + struct ast2700_mbox *mb = p; > + void __iomem *data_reg; > + int num_words; > + u32 *word_data; > + u32 status; > + int n; > + > + /* Only examine channels that are currently enabled. */ > + status = readl(mb->rx_regs + IPCR_ENABLE) & > + readl(mb->rx_regs + IPCR_STATUS); Also need to lock over these reads to handle concurrent startup/shutdown? > + > + if (!(status & RX_IRQ_MASK)) > + return IRQ_NONE; > + > + for (n = 0; n < mb->mbox.num_chans; ++n) { > + struct mbox_chan *chan = &mb->mbox.chans[n]; > + > + if (!(status & RX_IRQ(n))) > + continue; > + > + /* Read the message data */ > + for (data_reg = mb->rx_regs + IPCR_DATA + mb->msg_size * n, > + word_data = chan->con_priv, > + num_words = (mb->msg_size / sizeof(u32)); > + num_words; > + num_words--, data_reg += sizeof(u32), word_data++) > + *word_data = readl(data_reg); > + > + mbox_chan_received_data(chan, chan->con_priv); > + > + /* The IRQ can be cleared only once the FIFO is empty. */ > + writel(RX_IRQ(n), mb->rx_regs + IPCR_STATUS); Can we rather clear the status once outside the loop immediately before return? writel(status, mb->rx_regs + IPCR_STATUS); > + } > + > + return IRQ_HANDLED; > +} > + > +static int ast2700_mbox_send_data(struct mbox_chan *chan, void *data) > +{ > + struct ast2700_mbox *mb = dev_get_drvdata(chan->mbox->dev); > + void __iomem *data_reg; > + u32 *word_data; > + int num_words; > + int idx = ch_num(chan); > + > + if (!(readl(mb->tx_regs + IPCR_ENABLE) & BIT(idx))) { > + dev_warn(mb->mbox.dev, "%s: Ch-%d not enabled yet\n", __func__, idx); > + return -EBUSY; -ENODEV? I wouldn't say it's busy here :) > + } > + > + if (!(ast2700_mbox_tx_done(mb, idx))) { > + dev_warn(mb->mbox.dev, "%s: Ch-%d last data has not finished\n", __func__, idx); > + return -EBUSY; > + } > + > + /* Write the message data */ > + for (data_reg = mb->tx_regs + IPCR_DATA + mb->msg_size * idx, > + word_data = (u32 *)data, > + num_words = (mb->msg_size / sizeof(u32)); > + num_words; > + num_words--, data_reg += sizeof(u32), word_data++) > + writel(*word_data, data_reg); > + > + writel(BIT(idx), mb->tx_regs + IPCR_TX_TRIG); > + dev_dbg(mb->mbox.dev, "%s: Ch-%d sent\n", __func__, idx); > + > + return 0; > +} > + *snip* > + > +static int ast2700_mbox_probe(struct platform_device *pdev) > +{ > + struct ast2700_mbox *mb; > + const struct ast2700_mbox_data *dev_data; > + struct device *dev = &pdev->dev; > + int irq, ret; > + > + if (!pdev->dev.of_node) > + return -ENODEV; > + > + dev_data = device_get_match_data(&pdev->dev); > + > + mb = devm_kzalloc(dev, sizeof(*mb), GFP_KERNEL); > + if (!mb) > + return -ENOMEM; > + > + mb->mbox.chans = devm_kcalloc(&pdev->dev, dev_data->num_chans, > + sizeof(*mb->mbox.chans), GFP_KERNEL); > + if (!mb->mbox.chans) > + return -ENOMEM; > + > + /* con_priv of each channel is used to store the message received */ > + for (int i = 0; i < dev_data->num_chans; i++) { > + mb->mbox.chans[i].con_priv = devm_kcalloc(dev, dev_data->msg_size, > + sizeof(u8), GFP_KERNEL); > + if (!mb->mbox.chans[i].con_priv) > + return -ENOMEM; > + } > + > + platform_set_drvdata(pdev, mb); > + > + mb->tx_regs = devm_platform_ioremap_resource(pdev, 0); See the thought about reg-names on the binding. Andrew ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH v5 2/2] mailbox: aspeed: add mailbox driver for AST27XX series SoC 2025-06-27 1:54 ` Andrew Jeffery @ 2025-06-27 2:21 ` Jammy Huang 0 siblings, 0 replies; 9+ messages in thread From: Jammy Huang @ 2025-06-27 2:21 UTC (permalink / raw) To: Andrew Jeffery, jassisinghbrar@gmail.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, joel@jms.id.au, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org > On Wed, 2025-06-25 at 15:34 +0800, Jammy Huang wrote: > > Add mailbox controller driver for AST27XX SoCs, which provides > > independent tx/rx mailbox between different processors. There are 4 > > channels for each tx/rx mailbox and each channel has an 32-byte FIFO. > > > > Signed-off-by: Jammy Huang <jammy_huang@aspeedtech.com> > > --- > > drivers/mailbox/Kconfig | 8 + > > drivers/mailbox/Makefile | 2 + > > drivers/mailbox/ast2700-mailbox.c | 240 > > ++++++++++++++++++++++++++++++ > > 3 files changed, 250 insertions(+) > > create mode 100644 drivers/mailbox/ast2700-mailbox.c > > > > diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index > > 68eeed660a4a..1c38cd570091 100644 > > --- a/drivers/mailbox/Kconfig > > +++ b/drivers/mailbox/Kconfig > > @@ -340,4 +340,12 @@ config THEAD_TH1520_MBOX > > kernel is running, and E902 core used for power > management > > among other > > things. > > > > +config AST2700_MBOX > > + tristate "ASPEED AST2700 IPC driver" > > + depends on ARCH_ASPEED || COMPILE_TEST > > + help > > + Mailbox driver implementation for ASPEED AST27XX SoCs. > This > > +driver > > + can be used to send message between different processors in > SoC. > > + The driver provides mailbox support for sending interrupts > > +to the > > + clients. Say Y here if you want to build this driver. > > endif > > diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index > > 13a3448b3271..9a9add9a7548 100644 > > --- a/drivers/mailbox/Makefile > > +++ b/drivers/mailbox/Makefile > > @@ -72,3 +72,5 @@ obj-$(CONFIG_QCOM_CPUCP_MBOX) += > qcom-cpucp-mbox.o > > obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o > > > > obj-$(CONFIG_THEAD_TH1520_MBOX) += mailbox-th1520.o > > + > > +obj-$(CONFIG_AST2700_MBOX) += ast2700-mailbox.o > > diff --git a/drivers/mailbox/ast2700-mailbox.c > > b/drivers/mailbox/ast2700-mailbox.c > > new file mode 100644 > > index 000000000000..5470053f8139 > > --- /dev/null > > +++ b/drivers/mailbox/ast2700-mailbox.c > > @@ -0,0 +1,240 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * Copyright Aspeed Technology Inc. (C) 2025. All rights reserved */ > > + > > +#include <linux/interrupt.h> > > +#include <linux/io.h> > > +#include <linux/iopoll.h> > > +#include <linux/kernel.h> > > +#include <linux/mailbox_controller.h> #include <linux/module.h> > > +#include <linux/of.h> #include <linux/platform_device.h> #include > > +<linux/slab.h> > > + > > +/* Each bit in the register represents an IPC ID */ #define > > +IPCR_TX_TRIG 0x00 #define > IPCR_ENABLE 0x04 > > +#define IPCR_STATUS 0x08 > #define RX_IRQ(n) > > +BIT(n) #define RX_IRQ_MASK 0xf #define > IPCR_DATA > > +0x10 > > + > > +struct ast2700_mbox_data { > > + u8 num_chans; > > + u8 msg_size; > > +}; > > + > > +struct ast2700_mbox { > > + struct mbox_controller mbox; > > + u8 msg_size; > > + void __iomem *tx_regs; > > + void __iomem *rx_regs; > > + spinlock_t lock; > > +}; > > + > > +static inline int ch_num(struct mbox_chan *chan) { > > + return chan - chan->mbox->chans; } > > + > > +static inline bool ast2700_mbox_tx_done(struct ast2700_mbox *mb, int > > +idx) { > > + return !(readl(mb->tx_regs + IPCR_STATUS) & BIT(idx)); } > > + > > +static irqreturn_t ast2700_mbox_irq(int irq, void *p) { > > + struct ast2700_mbox *mb = p; > > + void __iomem *data_reg; > > + int num_words; > > + u32 *word_data; > > + u32 status; > > + int n; > > + > > + /* Only examine channels that are currently enabled. */ > > + status = readl(mb->rx_regs + IPCR_ENABLE) & > > + readl(mb->rx_regs + IPCR_STATUS); > > Also need to lock over these reads to handle concurrent startup/shutdown? It read-only here. I think it's fine. > > > + > > + if (!(status & RX_IRQ_MASK)) > > + return IRQ_NONE; > > + > > + for (n = 0; n < mb->mbox.num_chans; ++n) { > > + struct mbox_chan *chan = &mb->mbox.chans[n]; > > + > > + if (!(status & RX_IRQ(n))) > > + continue; > > + > > + /* Read the message data */ > > + for (data_reg = mb->rx_regs + IPCR_DATA + > mb->msg_size > > +* n, > > + word_data = chan->con_priv, > > + num_words = (mb->msg_size / sizeof(u32)); > > + num_words; > > + num_words--, data_reg += sizeof(u32), > > +word_data++) > > + *word_data = readl(data_reg); > > + > > + mbox_chan_received_data(chan, chan->con_priv); > > + > > + /* The IRQ can be cleared only once the FIFO is > empty. > > +*/ > > + writel(RX_IRQ(n), mb->rx_regs + IPCR_STATUS); > > Can we rather clear the status once outside the loop immediately before > return? > > writel(status, mb->rx_regs + IPCR_STATUS); I think it's better to keep current way. Because tx side could polling check rx-status to know if tx is done. mbox_chan_received_data() here will invoke the callback registered by mailbox-client. It could take times depending on how the callback is implemented. Since we have 4 channels now, clear it earlier can have better performance. > > > + } > > + > > + return IRQ_HANDLED; > > +} > > + > > +static int ast2700_mbox_send_data(struct mbox_chan *chan, void *data) > > +{ > > + struct ast2700_mbox *mb = > dev_get_drvdata(chan->mbox->dev); > > + void __iomem *data_reg; > > + u32 *word_data; > > + int num_words; > > + int idx = ch_num(chan); > > + > > + if (!(readl(mb->tx_regs + IPCR_ENABLE) & BIT(idx))) { > > + dev_warn(mb->mbox.dev, "%s: Ch-%d not enabled > yet\n", > > +__func__, idx); > > + return -EBUSY; > > -ENODEV? I wouldn't say it's busy here :) > > > + } > > + > > + if (!(ast2700_mbox_tx_done(mb, idx))) { > > + dev_warn(mb->mbox.dev, "%s: Ch-%d last data has > not > > +finished\n", __func__, idx); > > + return -EBUSY; > > + } > > + > > + /* Write the message data */ > > + for (data_reg = mb->tx_regs + IPCR_DATA + mb->msg_size * idx, > > + word_data = (u32 *)data, > > + num_words = (mb->msg_size / sizeof(u32)); > > + num_words; > > + num_words--, data_reg += sizeof(u32), word_data++) > > + writel(*word_data, data_reg); > > + > > + writel(BIT(idx), mb->tx_regs + IPCR_TX_TRIG); > > + dev_dbg(mb->mbox.dev, "%s: Ch-%d sent\n", __func__, idx); > > + > > + return 0; > > +} > > + > > *snip* > > > + > > +static int ast2700_mbox_probe(struct platform_device *pdev) { > > + struct ast2700_mbox *mb; > > + const struct ast2700_mbox_data *dev_data; > > + struct device *dev = &pdev->dev; > > + int irq, ret; > > + > > + if (!pdev->dev.of_node) > > + return -ENODEV; > > + > > + dev_data = device_get_match_data(&pdev->dev); > > + > > + mb = devm_kzalloc(dev, sizeof(*mb), GFP_KERNEL); > > + if (!mb) > > + return -ENOMEM; > > + > > + mb->mbox.chans = devm_kcalloc(&pdev->dev, > dev_data->num_chans, > > > + sizeof(*mb->mbox.c > hans), > > +GFP_KERNEL); > > + if (!mb->mbox.chans) > > + return -ENOMEM; > > + > > + /* con_priv of each channel is used to store the message > > +received */ > > + for (int i = 0; i < dev_data->num_chans; i++) { > > + mb->mbox.chans[i].con_priv = devm_kcalloc(dev, > > +dev_data->msg_size, > > > + > sizeof(u8), > > +GFP_KERNEL); > > + if (!mb->mbox.chans[i].con_priv) > > + return -ENOMEM; > > + } > > + > > + platform_set_drvdata(pdev, mb); > > + > > + mb->tx_regs = devm_platform_ioremap_resource(pdev, 0); > > See the thought about reg-names on the binding. Agree. > > Andrew Regards Jammy ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-06-27 2:23 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-06-25 7:34 [PATCH v5 0/2] ASPEED: Add mailbox driver for AST2700 series Jammy Huang 2025-06-25 7:34 ` [PATCH v5 1/2] dt-bindings: mailbox: Add ASPEED AST2700 series SoC Jammy Huang 2025-06-25 15:50 ` Rob Herring 2025-06-26 3:41 ` Jammy Huang 2025-06-27 1:52 ` Andrew Jeffery 2025-06-27 2:22 ` Jammy Huang 2025-06-25 7:34 ` [PATCH v5 2/2] mailbox: aspeed: add mailbox driver for AST27XX " Jammy Huang 2025-06-27 1:54 ` Andrew Jeffery 2025-06-27 2:21 ` Jammy Huang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).