/*
 * Copyright 2024 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Wrapper of NXP Mailbox driver for Zephyr's MBOX model.
 */

#include <zephyr/devicetree.h>
#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)
