Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mbox mailbox driver support #68303

Merged
merged 2 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/mbox/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ zephyr_library_sources_ifdef(CONFIG_USERSPACE mbox_handlers.c)
zephyr_library_sources_ifdef(CONFIG_MBOX_NRFX_IPC mbox_nrfx_ipc.c)
zephyr_library_sources_ifdef(CONFIG_MBOX_NXP_S32_MRU mbox_nxp_s32_mru.c)
zephyr_library_sources_ifdef(CONFIG_MBOX_NXP_IMX_MU mbox_nxp_imx_mu.c)
zephyr_library_sources_ifdef(CONFIG_MBOX_NXP_MAILBOX mbox_nxp_mailbox.c)
zephyr_library_sources_ifdef(CONFIG_MBOX_ANDES_PLIC_SW mbox_andes_plic_sw.c)
2 changes: 2 additions & 0 deletions drivers/mbox/Kconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright (c) 2021 Carlo Caione <[email protected]>
# Copyright 2024 NXP
# SPDX-License-Identifier: Apache-2.0

menuconfig MBOX
Expand All @@ -14,6 +15,7 @@ if MBOX
source "drivers/mbox/Kconfig.nrfx"
source "drivers/mbox/Kconfig.nxp_s32"
source "drivers/mbox/Kconfig.nxp_imx"
source "drivers/mbox/Kconfig.nxp_mailbox"
source "drivers/mbox/Kconfig.andes"

config MBOX_INIT_PRIORITY
Expand Down
9 changes: 9 additions & 0 deletions drivers/mbox/Kconfig.nxp_mailbox
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright 2024 NXP
# SPDX-License-Identifier: Apache-2.0

config MBOX_NXP_MAILBOX
bool "NXP Mailbox driver for MBOX"
default y
depends on DT_HAS_NXP_LPC_MAILBOX_ENABLED
help
Driver for NXP Mailbox Unit around MBOX.
210 changes: 210 additions & 0 deletions drivers/mbox/mbox_nxp_mailbox.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: Apache-2.0
*
* Wrapper of NXP Mailbox driver for Zephyr's MBOX model.
*/

#include <zephyr/devicetree.h>
TomasGalbickaNXP marked this conversation as resolved.
Show resolved Hide resolved
#include <zephyr/drivers/mbox.h>
#include <zephyr/sys/util_macro.h>
#include <fsl_mailbox.h>

#define LOG_LEVEL CONFIG_MBOX_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(nxp_mbox_mailbox);

#define DT_DRV_COMPAT nxp_mbox_mailbox

#define MAILBOX_MAX_CHANNELS 4
#define MAILBOX_MBOX_SIZE 3

#if (defined(LPC55S69_cm33_core0_SERIES) || defined(LPC55S69_cm33_core1_SERIES))
#ifdef LPC55S69_cm33_core0_SERIES
#define MAILBOX_ID_THIS_CPU kMAILBOX_CM33_Core0
#define MAILBOX_ID_OTHER_CPU kMAILBOX_CM33_Core1
#else
#define MAILBOX_ID_THIS_CPU kMAILBOX_CM33_Core1
#define MAILBOX_ID_OTHER_CPU kMAILBOX_CM33_Core0
#endif
#else
#if defined(__CM4_CMSIS_VERSION)
#define MAILBOX_ID_THIS_CPU kMAILBOX_CM4
#define MAILBOX_ID_OTHER_CPU kMAILBOX_CM0Plus
#else
#define MAILBOX_ID_THIS_CPU kMAILBOX_CM0Plus
#define MAILBOX_ID_OTHER_CPU kMAILBOX_CM4
#endif
#endif

#define GENIRQ_SHIFT (28U)
#define GEN0_IRQ_TRIGGER BIT(GENIRQ_SHIFT + 3U) /*!< General interrupt 3. */
#define GEN1_IRQ_TRIGGER BIT(GENIRQ_SHIFT + 2U) /*!< General interrupt 2. */
#define GEN2_IRQ_TRIGGER BIT(GENIRQ_SHIFT + 1U) /*!< General interrupt 1. */
#define GEN3_IRQ_TRIGGER BIT(GENIRQ_SHIFT + 0U) /*!< General interrupt 0. */

#define DATA_MASK BIT_MASK(24U)
#define DATAIRQ_SHIFT (24U)
#define DATA0_IRQ_TRIGGER BIT(DATAIRQ_SHIFT + 3U) /*!< Data interrupt 3. */
#define DATA1_IRQ_TRIGGER BIT(DATAIRQ_SHIFT + 2U) /*!< Data interrupt 2. */
#define DATA2_IRQ_TRIGGER BIT(DATAIRQ_SHIFT + 1U) /*!< Data interrupt 1. */
#define DATA3_IRQ_TRIGGER BIT(DATAIRQ_SHIFT + 0U) /*!< Data interrupt 0. */

struct nxp_mailbox_data {
mbox_callback_t cb[MAILBOX_MAX_CHANNELS];
void *user_data[MAILBOX_MAX_CHANNELS];
bool channel_enable[MAILBOX_MAX_CHANNELS];
uint32_t received_data;
};

struct nxp_mailbox_config {
MAILBOX_Type *base;
};

static void mailbox_isr(const struct device *dev)
{
struct nxp_mailbox_data *data = dev->data;
const struct nxp_mailbox_config *config = dev->config;
mailbox_cpu_id_t cpu_id;

cpu_id = MAILBOX_ID_THIS_CPU;

volatile uint32_t mailbox_value = MAILBOX_GetValue(config->base, cpu_id);
uint32_t flags = mailbox_value & (~DATA_MASK);

/* Clear or the interrupt gets called intermittently */
MAILBOX_ClearValueBits(config->base, cpu_id, mailbox_value);

for (int i_channel = 0; i_channel < MAILBOX_MAX_CHANNELS; i_channel++) {
/* Continue to next channel if channel is not enabled */
if (!data->channel_enable[i_channel]) {
continue;
}

if ((flags & (DATA0_IRQ_TRIGGER >> i_channel))) {
data->received_data = mailbox_value & DATA_MASK;
struct mbox_msg msg = {(const void *)&data->received_data,
MAILBOX_MBOX_SIZE};

if (data->cb[i_channel]) {
data->cb[i_channel](dev, i_channel, data->user_data[i_channel],
&msg);
}
} else if ((flags & (GEN0_IRQ_TRIGGER >> i_channel))) {
if (data->cb[i_channel]) {
data->cb[i_channel](dev, i_channel, data->user_data[i_channel],
NULL);
}
}
}

/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F
* Store immediate overlapping exception return operation
* might vector to incorrect interrupt
*/
#if defined __CORTEX_M && (__CORTEX_M == 4U)
barrier_dsync_fence_full();
#endif
}

static int nxp_mailbox_send(const struct device *dev, uint32_t channel, const struct mbox_msg *msg)
{
uint32_t __aligned(4) data32;
const struct nxp_mailbox_config *cfg = dev->config;

if (channel >= MAILBOX_MAX_CHANNELS) {
return -EINVAL;
}

/* Signalling mode. */
if (msg == NULL) {
MAILBOX_SetValueBits(cfg->base, MAILBOX_ID_OTHER_CPU, GEN0_IRQ_TRIGGER >> channel);
return 0;
}

/* Data transfer mode. */
if (msg->size != MAILBOX_MBOX_SIZE) {
/* We can only send this many bytes at a time. */
return -EMSGSIZE;
}

/* memcpy to avoid issues when msg->data is not word-aligned. */
memcpy(&data32, msg->data, msg->size);

MAILBOX_SetValueBits(cfg->base, MAILBOX_ID_OTHER_CPU,
(DATA0_IRQ_TRIGGER >> channel) | (data32 & DATA_MASK));

return 0;
}

static int nxp_mailbox_register_callback(const struct device *dev, uint32_t channel,
mbox_callback_t cb, void *user_data)
{
struct nxp_mailbox_data *data = dev->data;

if (channel >= MAILBOX_MAX_CHANNELS) {
return -EINVAL;
}

data->cb[channel] = cb;
data->user_data[channel] = user_data;

return 0;
}

static int nxp_mailbox_mtu_get(const struct device *dev)
{
ARG_UNUSED(dev);

return MAILBOX_MBOX_SIZE;
}

static uint32_t nxp_mailbox_max_channels_get(const struct device *dev)
{
ARG_UNUSED(dev);
return MAILBOX_MAX_CHANNELS;
}

static int nxp_mailbox_set_enabled(const struct device *dev, uint32_t channel, bool enable)
{
struct nxp_mailbox_data *data = dev->data;

if (channel >= MAILBOX_MAX_CHANNELS) {
return -EINVAL;
}

data->channel_enable[channel] = enable;

return 0;
}

static const struct mbox_driver_api nxp_mailbox_driver_api = {
.send = nxp_mailbox_send,
.register_callback = nxp_mailbox_register_callback,
.mtu_get = nxp_mailbox_mtu_get,
.max_channels_get = nxp_mailbox_max_channels_get,
.set_enabled = nxp_mailbox_set_enabled,
};

#define MAILBOX_INSTANCE_DEFINE(idx) \
static struct nxp_mailbox_data nxp_mailbox_##idx##_data; \
const static struct nxp_mailbox_config nxp_mailbox_##idx##_config = { \
.base = (MAILBOX_Type *)DT_INST_REG_ADDR(idx), \
}; \
static int nxp_mailbox_##idx##_init(const struct device *dev) \
{ \
ARG_UNUSED(dev); \
MAILBOX_Init(nxp_mailbox_##idx##_config.base); \
IRQ_CONNECT(DT_INST_IRQN(idx), DT_INST_IRQ(idx, priority), mailbox_isr, \
DEVICE_DT_INST_GET(idx), 0); \
irq_enable(DT_INST_IRQN(idx)); \
return 0; \
} \
DEVICE_DT_INST_DEFINE(idx, nxp_mailbox_##idx##_init, NULL, &nxp_mailbox_##idx##_data, \
&nxp_mailbox_##idx##_config, POST_KERNEL, CONFIG_MBOX_INIT_PRIORITY, \
&nxp_mailbox_driver_api)

#define MAILBOX_INST(idx) MAILBOX_INSTANCE_DEFINE(idx);

DT_INST_FOREACH_STATUS_OKAY(MAILBOX_INST)
37 changes: 37 additions & 0 deletions dts/bindings/mbox/nxp,mbox-mailbox.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
description: |
NXP Mailbox Unit as Zephyr MBOX.

This NXP Mailbox driver implements Multi-Channel Inter-Processor Mailbox (MBOX) API
around NXP Inter-CPU Mailbox peripheral IP block.

The NXP Inter-CPU Mailbox provides up to thirty-two user defined interrupts.
This driver uses 4 interrupts for mbox signalling mode per each channel,
4 interrupts for mxbox data transfer mode per each channel and 24 as 3 bytes
for data.

compatible: "nxp,mbox-mailbox"

include: [base.yaml, mailbox-controller.yaml]

properties:
interrupts:
required: true

rx-channels:
type: int
enum: [1, 2, 3, 4]
description: |
Number of receive channels enabled on this instance.
Setting this value to N, will enable channels 0 to N-1, consecutively.
It should be set by the receiver core coupled with this Mailbox instance.

For example, if receiver A wants to Rx on channels 0 to 3, then A must
set rx-channels of mailbox as follows:

mbox {
rx-channels = <4>;
status = "okay";
};

mbox-cells:
- channel
5 changes: 3 additions & 2 deletions samples/drivers/mbox/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# Copyright (c) 2021 Carlo Caione <[email protected]>
# Copyright 2023 NXP
# Copyright 2023-2024 NXP
#
# SPDX-License-Identifier: Apache-2.0
#
Expand All @@ -17,7 +17,8 @@ if(("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") OR
("${BOARD}" STREQUAL "mimxrt1170_evkb_cm7") OR
("${BOARD}" STREQUAL "mimxrt1170_evk_cm7") OR
("${BOARD}" STREQUAL "mimxrt1160_evk_cm7") OR
("${BOARD}" STREQUAL "mimxrt595_evk_cm33"))
("${BOARD}" STREQUAL "mimxrt595_evk_cm33") OR
("${BOARD}" STREQUAL "lpcxpresso55s69_cpu0"))
message(STATUS "${BOARD} compile as Main in this sample")
else()
message(FATAL_ERROR "${BOARD} is not supported for this sample")
Expand Down
3 changes: 2 additions & 1 deletion samples/drivers/mbox/Kconfig.sysbuild
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Copyright 2023 Nordic Semiconductor ASA
# Copyright 2023 NXP
# Copyright 2023-2024 NXP
#
# SPDX-License-Identifier: Apache-2.0

Expand All @@ -14,3 +14,4 @@ string
default "mimxrt1170_evkb_cm4" if $(BOARD) = "mimxrt1170_evkb_cm7"
default "mimxrt1170_evk_cm4" if $(BOARD) = "mimxrt1170_evk_cm7"
default "mimxrt1160_evk_cm4" if $(BOARD) = "mimxrt1160_evk_cm7"
default "lpcxpresso55s69_cpu1" if $(BOARD) = "lpcxpresso55s69_cpu0"
3 changes: 3 additions & 0 deletions samples/drivers/mbox/boards/lpcxpresso55s69_cpu0.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CONFIG_SECOND_CORE_MCUX=y
CONFIG_MBOX_NXP_MAILBOX=y
CONFIG_BUILD_OUTPUT_HEX=y
29 changes: 29 additions & 0 deletions samples/drivers/mbox/boards/lpcxpresso55s69_cpu0.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
chosen {
/* Delete ipc chosen property where old IPM mailbox driver bellow is
* configured.
*/
/delete-property/ zephyr,ipc;
};

soc {
/* Delete IPM Driver node nxp,lpc-mailbox */
/delete-node/ mailbox@8b000;

/* Attach MBOX driver to Mailbox Unit */
mbox:mailbox0@5008b000 {
compatible = "nxp,mbox-mailbox";
reg = <0x5008b000 0xEC>;
interrupts = <31 0>;
rx-channels = <4>;
#mbox-cells = <1>;
status = "okay";
};
};
};
3 changes: 2 additions & 1 deletion samples/drivers/mbox/remote/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# Copyright (c) 2021 Carlo Caione <[email protected]>
# Copyright 2023 NXP
# Copyright 2023-2024 NXP
#
# SPDX-License-Identifier: Apache-2.0
#
Expand All @@ -14,6 +14,7 @@ if(("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpunet") OR
("${BOARD}" STREQUAL "mimxrt1170_evkb_cm4") OR
("${BOARD}" STREQUAL "mimxrt1170_evk_cm4") OR
("${BOARD}" STREQUAL "mimxrt1160_evk_cm4") OR
("${BOARD}" STREQUAL "lpcxpresso55s69_cpu1") OR
("${BOARD}" STREQUAL "adp_xc7k_ae350"))
message(STATUS "${BOARD} compile as remote in this sample")
else()
Expand Down
10 changes: 10 additions & 0 deletions samples/drivers/mbox/remote/boards/lpcxpresso55s69_cpu1.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CONFIG_SECOND_CORE_MCUX=y
CONFIG_BUILD_OUTPUT_HEX=y
CONFIG_MBOX_NXP_MAILBOX=y

# For purpose of sample enable UART Console on CPU1
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_CLOCK_CONTROL=y
Loading
Loading