diff --git a/boards/amd/versal2_rpu/versal2_rpu.yaml b/boards/amd/versal2_rpu/versal2_rpu.yaml index 91753bea822c..c45fe1827908 100644 --- a/boards/amd/versal2_rpu/versal2_rpu.yaml +++ b/boards/amd/versal2_rpu/versal2_rpu.yaml @@ -6,6 +6,7 @@ toolchain: supported: - scsi - ufs + - mbox testing: ignore_tags: - net diff --git a/boards/amd/versalnet_rpu/versalnet_rpu.yaml b/boards/amd/versalnet_rpu/versalnet_rpu.yaml index 21f19ea6cced..222c68f5308f 100644 --- a/boards/amd/versalnet_rpu/versalnet_rpu.yaml +++ b/boards/amd/versalnet_rpu/versalnet_rpu.yaml @@ -10,3 +10,4 @@ testing: vendor: amd supported: - sdhc + - mbox diff --git a/drivers/mbox/CMakeLists.txt b/drivers/mbox/CMakeLists.txt index 6a45598684fe..f70d0c3a6730 100644 --- a/drivers/mbox/CMakeLists.txt +++ b/drivers/mbox/CMakeLists.txt @@ -23,3 +23,4 @@ zephyr_library_sources_ifdef(CONFIG_MBOX_TI_OMAP_MAILBOX mbox_ti_omap.c) zephyr_library_sources_ifdef(CONFIG_MBOX_RENESAS_RZ_MHU mbox_renesas_rz_mhu.c) zephyr_library_sources_ifdef(CONFIG_MBOX_MHUV3 mbox_mhuv3.c) zephyr_library_sources_ifdef(CONFIG_MBOX_TI_SECURE_PROXY mbox_ti_secproxy.c) +zephyr_library_sources_ifdef(CONFIG_MBOX_XLNX_IPI_MAILBOX mbox_xlnx_ipi_mailbox.c) diff --git a/drivers/mbox/Kconfig b/drivers/mbox/Kconfig index 8649df680819..a69c2c3a3114 100644 --- a/drivers/mbox/Kconfig +++ b/drivers/mbox/Kconfig @@ -27,6 +27,7 @@ source "drivers/mbox/Kconfig.ti_omap" source "drivers/mbox/Kconfig.renesas_rz" source "drivers/mbox/Kconfig.mhuv3" source "drivers/mbox/Kconfig.ti_secproxy" +source "drivers/mbox/Kconfig.xlnx" config MBOX_INIT_PRIORITY int "MBOX init priority" diff --git a/drivers/mbox/Kconfig.xlnx b/drivers/mbox/Kconfig.xlnx new file mode 100644 index 000000000000..3268219b4d12 --- /dev/null +++ b/drivers/mbox/Kconfig.xlnx @@ -0,0 +1,10 @@ +# Copyright 2025 Advanced Micro Devices, Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +config MBOX_XLNX_IPI_MAILBOX + bool "MBOX XLNX IPI MAILBOX driver" + default y + depends on DT_HAS_XLNX_MBOX_VERSAL_IPI_MAILBOX_ENABLED + help + Enables the MBOX Driver for AMD-Xilinx IPI Mailbox peripheral. diff --git a/drivers/mbox/mbox_xlnx_ipi_mailbox.c b/drivers/mbox/mbox_xlnx_ipi_mailbox.c new file mode 100644 index 000000000000..e4f1730efa25 --- /dev/null +++ b/drivers/mbox/mbox_xlnx_ipi_mailbox.c @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2025 Advanced Micro Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(mbox_xlnx_ipi_mailbox, CONFIG_MBOX_LOG_LEVEL); + +/* Register offsets of IPI */ +#define IPI_REG_TRIG_OFFSET 0x00U /* Offset for Trigger Register */ +#define IPI_REG_OBS_OFFSET 0x04U /* Offset for Observation Register */ +#define IPI_REG_ISR_OFFSET 0x10U /* Offset for ISR Register */ +#define IPI_REG_IMR_OFFSET 0x14U /* Offset for Interrupt Mask Register */ +#define IPI_REG_IER_OFFSET 0x18U /* Offset for Interrupt Enable Register */ +#define IPI_REG_IDR_OFFSET 0x1CU /* Offset for Interrupt Disable Register */ + +/* Mask of all valid IPI bits in above registers */ +#define IPI_ALL_MASK GENMASK(31, 0) + +/* IPI mailbox channels */ +#define IPI_MB_MAX_CHNLS 2U /* One Tx, One Rx */ +#define IPI_MB_CHNL_TX 0U /* IPI mailbox TX channel */ +#define IPI_MB_CHNL_RX 1U /* IPI mailbox RX channel */ + +/* IPI Message Buffer Information */ +#define IPI_MAX_MSG_BYTES (32U) +#define IPI_MAX_MSG_WORDS (8U) +#define IPI_MEM_STRIDE (0x200U) +#define IPI_REQ_OFF (0x00U) +#define IPI_RESP_OFF (0x20U) +#define IPI_BUF_STRIDE (0x40U) + +/** + * @brief Configuration for the Xilinx IPI host mailbox + */ +struct mbox_xlnx_ipi_parent_config { + mem_addr_t reg_base; /**< Host Control register base address */ + uint8_t *msg_base; /**< Pointer to Host message buffer */ + uint32_t ipi_id; /**< Host IPI ID */ + uint32_t ipi_bitmask; /**< Host IPI Bitmask */ + void (*irq_config_func)(void); /**< IRQ configuration API pointer */ + const struct device **cdev_list; /**< Array of pointers to child devices */ + int num_cdev; /**< Number of child devices */ +}; + +/** + * @brief Configuration for the Xilinx IPI destination mailbox + */ +struct mbox_xlnx_ipi_child_config { + mem_addr_t reg_base; /**< Remote Control register base address */ + uint8_t *msg_base; /**< Pointer to the Remote message buffer */ + uint32_t remote_ipi_id; /**< Remote IPI ID */ + uint32_t remote_ipi_bitmask; /**< Remote IPI Bitmask */ + mem_addr_t parent_ipi_reg; /**< Host Control register base address */ + uint8_t *parent_ipi_msg; /**< Pointer to Host message buffer */ +}; + +/** + * @brief Runtime data for the Xilinx IPI destination mailbox + */ +struct mbox_xlnx_ipi_child_data { + bool enabled; /**< Channel enable status */ + mbox_callback_t mb_callback; /**< Callback function */ + void *user_data; /**< Application specific data pointer */ +}; + +/** + * @brief Interrupt Service Routine (ISR) for the Xilinx IPI mailbox + * + * Handles interrupts, processes messages and invokes registered callbacks + */ +static void mbox_xlnx_ipi_isr(const struct device *pdev) +{ + const struct mbox_xlnx_ipi_parent_config *pcfg = pdev->config; + const struct mbox_xlnx_ipi_child_config *cdev_conf; + const struct mbox_xlnx_ipi_child_data *cdev_data; + uint32_t ipi_msg_buf[IPI_MAX_MSG_WORDS]; + const struct device **cdev_list; + struct mbox_msg *msgptr = NULL; + const struct device *cdev; + uint32_t ipi_src_mask; + struct mbox_msg msg; + uint8_t *buf_ptr; + mem_addr_t off; + int num_cdev; + int cdev_idx; + int buf_idx; + + cdev_list = pcfg->cdev_list; + num_cdev = pcfg->num_cdev; + + /* Read interrupt status */ + ipi_src_mask = sys_read32(pcfg->reg_base + IPI_REG_ISR_OFFSET); + + for (cdev_idx = 0; cdev_idx < num_cdev; cdev_idx++) { + cdev = cdev_list[cdev_idx]; + cdev_conf = cdev->config; + cdev_data = cdev->data; + + if (cdev_data->enabled == false) { + continue; /* channel is disabled */ + } + + if ((ipi_src_mask & (cdev_conf->remote_ipi_bitmask)) == 0U) { + continue; /* interrupt is not for this channel */ + } + + if (cdev_data->mb_callback == NULL) { + continue; /* callback is not registered */ + } + + /* Read the message if buffered IPI */ + if ((pcfg->msg_base != NULL) && (cdev_conf->msg_base != NULL)) { + off = (mem_addr_t)pcfg->msg_base + IPI_REQ_OFF; + off += (cdev_conf->remote_ipi_id) * IPI_BUF_STRIDE; + buf_ptr = (uint8_t *)ipi_msg_buf; + for (buf_idx = 0; buf_idx < IPI_MAX_MSG_BYTES; buf_idx += 4) { + *(uint32_t *)(buf_ptr + buf_idx) = sys_read32(off + buf_idx); + } + msg.size = IPI_MAX_MSG_BYTES; + msg.data = (void *)buf_ptr; + msgptr = &msg; + } + /* Call registered callback */ + cdev_data->mb_callback(cdev, IPI_MB_CHNL_RX, cdev_data->user_data, msgptr); + } + + /* Clear the interrupt status */ + sys_write32(ipi_src_mask, pcfg->reg_base + IPI_REG_ISR_OFFSET); +} + +/** + * @brief Send a message/signal over the MBOX device. + */ +static int mbox_xlnx_ipi_send(const struct device *cdev, uint32_t channel, + const struct mbox_msg *msg) +{ + uint32_t __aligned(4) data32; + const struct mbox_xlnx_ipi_child_config *cfg = cdev->config; + uint32_t *data; + mem_addr_t off; + int obs_bit; + size_t len; + + /* Validate outbound channel */ + if (channel != IPI_MB_CHNL_TX) { + LOG_ERR("Invalid MBOX Tx channel number: %u", channel); + return -EINVAL; + } + + /* Check if Remote has read the previous message */ + obs_bit = sys_test_bit(cfg->parent_ipi_reg + IPI_REG_OBS_OFFSET, cfg->remote_ipi_id); + if (obs_bit != 0) { + LOG_DBG("Remote IPI-ID:%u is busy", cfg->remote_ipi_id); + return -EBUSY; + } + + /* Signalling mode: trigger interrupt without message */ + if ((msg == NULL) || (cfg->parent_ipi_msg == NULL) || (cfg->msg_base == NULL)) { + sys_set_bit(cfg->parent_ipi_reg + IPI_REG_TRIG_OFFSET, cfg->remote_ipi_id); + return 0; + } + + /* Data transfer mode: write message and then trigger interrupt */ + if (msg->size > IPI_MAX_MSG_BYTES) { + /* we can only send max this many bytes at a time */ + LOG_ERR("size: %u is invalid, Max size is %u bytes", msg->size, IPI_MAX_MSG_BYTES); + return -EMSGSIZE; + } + + data = (uint32_t *)msg->data; + len = msg->size; + off = (mem_addr_t)(cfg->parent_ipi_msg) + IPI_REQ_OFF; + off += (cfg->remote_ipi_id * IPI_BUF_STRIDE); + + /* send msg data in 4-byte chunks */ + while (len >= 4U) { + /* memcpy to avoid issues when msg->data is not word-aligned */ + (void)memcpy(&data32, data, sizeof(data32)); + sys_write32(data32, off); + + data++; + len -= 4U; + off += 4U; + } + + /* Handle any leftover bytes */ + if (len > 0U) { + data32 = 0U; + (void)memcpy(&data32, data, len); + sys_write32(data32, off); + } + + /* Trigger IPI to the target */ + sys_set_bit(cfg->parent_ipi_reg + IPI_REG_TRIG_OFFSET, cfg->remote_ipi_id); + + return 0; +} + +/** + * @brief Register a callback function on a channel for incoming messages. + */ +static int mbox_xlnx_ipi_register_callback(const struct device *cdev, uint32_t channel, + mbox_callback_t cb, void *user_data) +{ + struct mbox_xlnx_ipi_child_data *cdev_data = cdev->data; + + /* Validate inbound channel */ + if (channel != IPI_MB_CHNL_RX) { + LOG_ERR("Invalid MBOX Rx channel number: %u", channel); + return -EINVAL; + } + + /* Set the callback and user data */ + cdev_data->mb_callback = cb; + cdev_data->user_data = user_data; + + return 0; +} + +/** + * @brief Return the maximum number of bytes possible in an outbound message. + */ +static int mbox_xlnx_ipi_mtu_get(const struct device *cdev) +{ + const struct mbox_xlnx_ipi_child_config *cfg = cdev->config; + + /* Signalling mode: buffer-less IPI */ + if ((cfg->parent_ipi_msg == NULL) || (cfg->msg_base == NULL)) { + return 0; + } + + return IPI_MAX_MSG_BYTES; +} + +/** + * @brief Return the maximum number of channels supported by MBOX device instance. + */ +static uint32_t mbox_xlnx_ipi_max_channels_get(const struct device *cdev) +{ + ARG_UNUSED(cdev); + + return IPI_MB_MAX_CHNLS; +} + +/** + * @brief Enable (disable) interrupts and callbacks for inbound channels. + */ +static int mbox_xlnx_ipi_set_enabled(const struct device *cdev, uint32_t channel, bool enable) +{ + struct mbox_xlnx_ipi_child_data *cdev_data = cdev->data; + const struct mbox_xlnx_ipi_child_config *cfg = cdev->config; + + /* Validate inbound channel */ + if (channel != IPI_MB_CHNL_RX) { + LOG_ERR("Invalid MBOX Rx channel number: %u", channel); + return -EINVAL; + } + + /* check if already */ + if (cdev_data->enabled == enable) { + return -EALREADY; + } + + if (enable) { + if (cdev_data->mb_callback == NULL) { + LOG_WRN("Enabling channel:%u, without a registered callback", channel); + } + + /* Enable the interrupt for the specified channel */ + sys_set_bit(cfg->parent_ipi_reg + IPI_REG_IER_OFFSET, cfg->remote_ipi_id); + } else { + /* Disable the interrupt for the specified channel */ + sys_set_bit(cfg->parent_ipi_reg + IPI_REG_IDR_OFFSET, cfg->remote_ipi_id); + } + + cdev_data->enabled = enable; + + return 0; +} + +/** + * @brief Initialize the IPI mailbox module. + */ +static int mbox_xlnx_ipi_init(const struct device *pdev) +{ + const struct mbox_xlnx_ipi_parent_config *pcfg = pdev->config; + + /* Disable all the interrupts */ + sys_write32(IPI_ALL_MASK, pcfg->reg_base + IPI_REG_IDR_OFFSET); + + /* Clear status of any previous interrupts */ + sys_write32(IPI_ALL_MASK, pcfg->reg_base + IPI_REG_ISR_OFFSET); + + /* Configure IRQ */ + pcfg->irq_config_func(); + + return 0; +} + +static DEVICE_API(mbox, mbox_xlnx_ipi_driver_api) = { + .send = mbox_xlnx_ipi_send, + .register_callback = mbox_xlnx_ipi_register_callback, + .mtu_get = mbox_xlnx_ipi_mtu_get, + .max_channels_get = mbox_xlnx_ipi_max_channels_get, + .set_enabled = mbox_xlnx_ipi_set_enabled, +}; + +/* + * ************************* DRIVER REGISTER SECTION *************************** + */ + +/* Child node is used for MBOX driver */ +#define MBOX_XLNX_VERSAL_IPI_CHILD(ch_node)\ + struct mbox_xlnx_ipi_child_data mbox_xlnx_ipi_child_data##ch_node = {\ + .enabled = false,\ + .mb_callback = NULL,\ + .user_data = NULL,\ + };\ + struct mbox_xlnx_ipi_child_config mbox_xlnx_ipi_child_config##ch_node = {\ + .reg_base = DT_REG_ADDR_BY_NAME(ch_node, ctrl),\ + .msg_base = (uint8_t *)DT_REG_ADDR_BY_NAME_OR(ch_node, msg, NULL),\ + .remote_ipi_id = DT_PROP(ch_node, xlnx_ipi_id),\ + .remote_ipi_bitmask = BIT(DT_PROP(ch_node, xlnx_ipi_id)),\ + .parent_ipi_reg = DT_REG_ADDR_BY_NAME(DT_PARENT(ch_node), ctrl),\ + .parent_ipi_msg = (uint8_t *)DT_REG_ADDR_BY_NAME_OR(DT_PARENT(ch_node), msg, NULL),\ + };\ + DEVICE_DT_DEFINE(ch_node, NULL, NULL, &mbox_xlnx_ipi_child_data##ch_node,\ + &mbox_xlnx_ipi_child_config##ch_node, POST_KERNEL,\ + CONFIG_MBOX_INIT_PRIORITY, &mbox_xlnx_ipi_driver_api); + +/* Parent node for ISR and initialization */ +#define MBOX_XLNX_VERSAL_IPI_INSTANCE_DEFINE(idx)\ + DT_INST_FOREACH_CHILD_STATUS_OKAY(idx, MBOX_XLNX_VERSAL_IPI_CHILD);\ + static const struct device *cdev##idx[] = {\ + DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(idx, DEVICE_DT_GET, (,))\ + };\ + static void mbox_xlnx_ipi_##idx##_irq_config_func(void);\ + const static struct mbox_xlnx_ipi_parent_config mbox_xlnx_ipi_##idx##_pconfig = {\ + .reg_base = DT_REG_ADDR_BY_NAME(DT_DRV_INST(idx), ctrl),\ + .msg_base = (uint8_t *)DT_REG_ADDR_BY_NAME_OR(DT_DRV_INST(idx), msg, NULL),\ + .ipi_id = DT_INST_PROP(idx, xlnx_ipi_id),\ + .ipi_bitmask = BIT(DT_INST_PROP(idx, xlnx_ipi_id)),\ + .irq_config_func = mbox_xlnx_ipi_##idx##_irq_config_func,\ + .cdev_list = cdev##idx,\ + .num_cdev = ARRAY_SIZE(cdev##idx),\ + };\ + static void mbox_xlnx_ipi_##idx##_irq_config_func(void)\ + {\ + IRQ_CONNECT(DT_INST_IRQN(idx), DT_INST_IRQ(idx, priority),\ + mbox_xlnx_ipi_isr, DEVICE_DT_INST_GET(idx), 0);\ + irq_enable(DT_INST_IRQN(idx));\ + } \ + DEVICE_DT_INST_DEFINE(idx, mbox_xlnx_ipi_init, NULL, NULL,\ + &mbox_xlnx_ipi_##idx##_pconfig, POST_KERNEL,\ + CONFIG_MBOX_INIT_PRIORITY, NULL); + +#define DT_DRV_COMPAT xlnx_mbox_versal_ipi_mailbox +DT_INST_FOREACH_STATUS_OKAY(MBOX_XLNX_VERSAL_IPI_INSTANCE_DEFINE) diff --git a/dts/bindings/mbox/xlnx,mbox-versal-ipi-mailbox.yaml b/dts/bindings/mbox/xlnx,mbox-versal-ipi-mailbox.yaml new file mode 100644 index 000000000000..e6bb1b9fe48a --- /dev/null +++ b/dts/bindings/mbox/xlnx,mbox-versal-ipi-mailbox.yaml @@ -0,0 +1,95 @@ +# Copyright (c) 2025 Advanced Micro Devices, Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +description: | + AMD-Xilinx IPI (Inter Processor Interrupt) Mailbox Controller. + + It manages messaging and interrupt handling between two IPI agents (processors). + Each IPI agent owns registers used for notification and may include buffers for message. + + Example definition: + + mailbox@ff300000 { + compatible = "xlnx,versal-ipi-mailbox"; + interrupts = ; + reg = <0x0 0xff300000 0x0 0x1000>, + <0x0 0xff990000 0x0 0x1ff>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <0>; + #address-cells = <2>; + #size-cells = <2>; + + /* buffered IPI */ + child_1: mailbox@ff340000 { + compatible = "xlnx,versal-ipi-dest-mailbox"; + reg = <0x0 0xff340000 0x0 0x1000>, + <0x0 0xff990400 0x0 0x1ff>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <4>; + #mbox-cells = <1>; + }; + + /* bufferless IPI */ + child_2: mailbox@ff370000 { + compatible = "xlnx,versal-ipi-dest-mailbox"; + reg = <0x0 0xff370000 0x0 0x1000>; + reg-names = "ctrl"; + xlnx,ipi-id = <7>; + #mbox-cells = <1>; + }; + }; + + Example usage: + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&child_1 0>, <&child_1 1>; + mbox-names = "tx", "rx"; + }; + +compatible: "xlnx,mbox-versal-ipi-mailbox" + +include: [base.yaml] + +properties: + reg: + required: true + description: Host IPI agent control and message register space + + reg-names: + required: true + description: Identifiers for register spaces with "ctrl" for control and "msg" for message + + interrupts: + required: true + + xlnx,ipi-id: + type: int + required: true + description: Host IPI Agent ID associated with the mailbox + +child-binding: + description: AMD-Xilinx IPI agent child node + + compatible: "xlnx,mbox-versal-ipi-dest-mailbox" + + include: + - name: base.yaml + - name: mailbox-controller.yaml + + properties: + reg: + required: true + description: Remote IPI agent control and message register space + + reg-names: + required: true + description: Identifiers for register spaces with "ctrl" for control and "msg" for message + + xlnx,ipi-id: + required: true + type: int + description: Remote IPI Agent ID associated with the mailbox + + mbox-cells: + - channel diff --git a/dts/vendor/amd/versal2.dtsi b/dts/vendor/amd/versal2.dtsi index e5ab51ad59f8..d576fc34f20b 100644 --- a/dts/vendor/amd/versal2.dtsi +++ b/dts/vendor/amd/versal2.dtsi @@ -28,5 +28,181 @@ interrupt-names = "irq_1"; interrupts = ; }; + + ipi0: mailbox@eb330000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb330000 0x20>, <0xeb3f0400 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <2>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi1: mailbox@eb340000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb340000 0x20>, <0xeb3f0600 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <3>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi2: mailbox@eb350000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb350000 0x20>, <0xeb3f0800 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <4>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi3: mailbox@eb360000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb360000 0x20>, <0xeb3f0a00 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <5>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi4: mailbox@eb370000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb370000 0x20>, <0xeb3f0c00 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <6>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi5: mailbox@eb380000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb380000 0x20>, <0xeb3f0e00 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <7>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi6: mailbox@eb3a0000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3a0000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <9>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_nobuf1: mailbox@eb3b0000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3b0000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <10>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_nobuf2: mailbox@eb3b1000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3b1000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <11>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_nobuf3: mailbox@eb3b2000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3b2000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <12>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_nobuf4: mailbox@eb3b3000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3b3000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <13>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_nobuf5: mailbox@eb3b4000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3b4000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <14>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_nobuf6: mailbox@eb3b5000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3b5000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <15>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_asu: mailbox@eb310000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb310000 0x20>, <0xeb3f0000 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <0>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_pmc: mailbox@eb320000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb320000 0x20>, <0xeb3f0200 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <1>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_pmc_nobuf: mailbox@eb390000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb390000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <8>; + #address-cells = <1>; + #size-cells = <1>; + }; }; }; diff --git a/dts/vendor/amd/versalnet.dtsi b/dts/vendor/amd/versalnet.dtsi index dc2f4c4d50b6..e90fdd549b30 100644 --- a/dts/vendor/amd/versalnet.dtsi +++ b/dts/vendor/amd/versalnet.dtsi @@ -51,5 +51,181 @@ disk-name = "mmc0"; }; }; + + ipi0: mailbox@eb330000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb330000 0x20>, <0xeb3f0400 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <2>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi1: mailbox@eb340000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb340000 0x20>, <0xeb3f0600 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <3>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi2: mailbox@eb350000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb350000 0x20>, <0xeb3f0800 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <4>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi3: mailbox@eb360000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb360000 0x20>, <0xeb3f0a00 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <5>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi4: mailbox@eb370000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb370000 0x20>, <0xeb3f0c00 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <6>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi5: mailbox@eb380000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb380000 0x20>, <0xeb3f0e00 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <7>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi6: mailbox@eb3a0000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3a0000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <9>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_nobuf1: mailbox@eb3b0000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3b0000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <10>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_nobuf2: mailbox@eb3b1000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3b1000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <11>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_nobuf3: mailbox@eb3b2000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3b2000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <12>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_nobuf4: mailbox@eb3b3000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3b3000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <13>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_nobuf5: mailbox@eb3b4000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3b4000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <14>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_nobuf6: mailbox@eb3b5000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb3b5000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <15>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_psm: mailbox@eb310000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb310000 0x20>, <0xeb3f0000 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <0>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_pmc: mailbox@eb320000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb320000 0x20>, <0xeb3f0200 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <1>; + #address-cells = <1>; + #size-cells = <1>; + }; + + ipi_pmc_nobuf: mailbox@eb390000 { + compatible = "xlnx,mbox-versal-ipi-mailbox"; + status = "disabled"; + interrupts = ; + reg = <0xeb390000 0x20>; + reg-names = "ctrl"; + xlnx,ipi-id = <8>; + #address-cells = <1>; + #size-cells = <1>; + }; }; }; diff --git a/samples/drivers/mbox/CMakeLists.txt b/samples/drivers/mbox/CMakeLists.txt index 696b2317aa7c..2a871c83b6ad 100644 --- a/samples/drivers/mbox/CMakeLists.txt +++ b/samples/drivers/mbox/CMakeLists.txt @@ -31,7 +31,9 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP OR CONFIG_BOARD_NRF54LM20DK_NRF54LM20A_CPUAPP OR CONFIG_BOARD_STM32H747I_DISCO_STM32H747XX_M7 OR CONFIG_BOARD_BL54L15_DVK_NRF54L15_CPUAPP OR - CONFIG_BOARD_BL54L15U_DVK_NRF54L15_CPUAPP) + CONFIG_BOARD_BL54L15U_DVK_NRF54L15_CPUAPP OR + CONFIG_BOARD_VERSALNET_RPU OR + CONFIG_BOARD_VERSAL2_RPU) message(STATUS "${BOARD}${BOARD_QUALIFIERS} compile as Main in this sample") else() message(FATAL_ERROR "${BOARD}${BOARD_QUALIFIERS} is not supported for this sample") diff --git a/samples/drivers/mbox/Kconfig.sysbuild b/samples/drivers/mbox/Kconfig.sysbuild index 97402056c14e..4fc5d342212f 100644 --- a/samples/drivers/mbox/Kconfig.sysbuild +++ b/samples/drivers/mbox/Kconfig.sysbuild @@ -29,3 +29,5 @@ config REMOTE_BOARD default "esp32s3_devkitm/esp32s3/appcpu" if "$(BOARD)${BOARD_QUALIFIERS}" = "esp32s3_devkitm/esp32s3/procpu" default "bl54l15_dvk/nrf54l15/cpuflpr" if "$(BOARD)${BOARD_QUALIFIERS}" = "bl54l15_dvk/nrf54l15/cpuapp" default "bl54l15u_dvk/nrf54l15/cpuflpr" if $(BOARD) = "bl54l15u_dvk" + default "versalnet_rpu" if $(BOARD) = "versalnet_rpu" + default "versal2_rpu" if $(BOARD) = "versal2_rpu" diff --git a/samples/drivers/mbox/boards/versal2_rpu.overlay b/samples/drivers/mbox/boards/versal2_rpu.overlay new file mode 100644 index 000000000000..a93d2c8184b7 --- /dev/null +++ b/samples/drivers/mbox/boards/versal2_rpu.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Advanced Micro Devices, Inc. (AMD) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&ipi1 { + status = "okay"; + + rpu0_rpu0_mailbox: mailbox@eb340000 { + compatible = "xlnx,mbox-versal-ipi-dest-mailbox"; + status = "okay"; + reg = <0xeb340000 0x20>, <0xeb3f0600 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <3>; + #mbox-cells = <1>; + }; +}; + +/ { + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&rpu0_rpu0_mailbox 0>, <&rpu0_rpu0_mailbox 1>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/drivers/mbox/boards/versalnet_rpu.overlay b/samples/drivers/mbox/boards/versalnet_rpu.overlay new file mode 100644 index 000000000000..41ec41097f3b --- /dev/null +++ b/samples/drivers/mbox/boards/versalnet_rpu.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Advanced Micro Devices, Inc. (AMD) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&ipi5 { + status = "okay"; + + rpu0_rpu0_mailbox: mailbox@eb380000 { + compatible = "xlnx,mbox-versal-ipi-dest-mailbox"; + status = "okay"; + reg = <0xeb380000 0x20>, <0xeb3f0e00 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <7>; + #mbox-cells = <1>; + }; +}; + +/ { + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&rpu0_rpu0_mailbox 0>, <&rpu0_rpu0_mailbox 1>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/drivers/mbox/remote/CMakeLists.txt b/samples/drivers/mbox/remote/CMakeLists.txt index 48df8f0cb5b2..28e01f70a6aa 100644 --- a/samples/drivers/mbox/remote/CMakeLists.txt +++ b/samples/drivers/mbox/remote/CMakeLists.txt @@ -30,7 +30,9 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUNET OR CONFIG_BOARD_NRF54LM20DK_NRF54LM20A_CPUFLPR OR CONFIG_BOARD_STM32H747I_DISCO_STM32H747XX_M4 OR CONFIG_BOARD_BL54L15_DVK_NRF54L15_CPUFLPR OR - CONFIG_BOARD_BL54L15U_DVK_NRF54L15_CPUFLPR) + CONFIG_BOARD_BL54L15U_DVK_NRF54L15_CPUFLPR OR + CONFIG_BOARD_VERSALNET_RPU OR + CONFIG_BOARD_VERSAL2_RPU) message(STATUS "${BOARD}${BOARD_QUALIFIERS} compile as remote in this sample") else() message(FATAL_ERROR "${BOARD}${BOARD_QUALIFIERS} is not supported for this sample") diff --git a/samples/drivers/mbox/remote/boards/versal2_rpu.overlay b/samples/drivers/mbox/remote/boards/versal2_rpu.overlay new file mode 100644 index 000000000000..a93d2c8184b7 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/versal2_rpu.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Advanced Micro Devices, Inc. (AMD) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&ipi1 { + status = "okay"; + + rpu0_rpu0_mailbox: mailbox@eb340000 { + compatible = "xlnx,mbox-versal-ipi-dest-mailbox"; + status = "okay"; + reg = <0xeb340000 0x20>, <0xeb3f0600 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <3>; + #mbox-cells = <1>; + }; +}; + +/ { + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&rpu0_rpu0_mailbox 0>, <&rpu0_rpu0_mailbox 1>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/drivers/mbox/remote/boards/versalnet_rpu.overlay b/samples/drivers/mbox/remote/boards/versalnet_rpu.overlay new file mode 100644 index 000000000000..41ec41097f3b --- /dev/null +++ b/samples/drivers/mbox/remote/boards/versalnet_rpu.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Advanced Micro Devices, Inc. (AMD) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&ipi5 { + status = "okay"; + + rpu0_rpu0_mailbox: mailbox@eb380000 { + compatible = "xlnx,mbox-versal-ipi-dest-mailbox"; + status = "okay"; + reg = <0xeb380000 0x20>, <0xeb3f0e00 0x1000>; + reg-names = "ctrl", "msg"; + xlnx,ipi-id = <7>; + #mbox-cells = <1>; + }; +}; + +/ { + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&rpu0_rpu0_mailbox 0>, <&rpu0_rpu0_mailbox 1>; + mbox-names = "tx", "rx"; + }; +};