/*
 * Copyright 2024 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "dma_nxp_edma.h"

/* TODO list:
 * 1) Support for requesting a specific channel.
 * 2) Support for checking if DMA transfer is pending when attempting config. (?)
 * 3) Support for error interrupt.
 * 4) Support for error if buffer overflow/underrun.
 * 5) Ideally, HALFMAJOR should be set on a per-channel basis not through a
 * config. If not possible, this should be done through a DTS property. Also,
 * maybe do the same for INTMAJOR IRQ.
 */

static void edma_isr(const void *parameter)
{
	const struct edma_config *cfg;
	struct edma_data *data;
	struct edma_channel *chan;
	int ret;
	uint32_t update_size;

	chan = (struct edma_channel *)parameter;
	cfg = chan->dev->config;
	data = chan->dev->data;

	if (!EDMA_ChannelRegRead(data->hal_cfg, chan->id, EDMA_TCD_CH_INT)) {
		/* skip, interrupt was probably triggered by another channel */
		return;
	}

	/* clear interrupt */
	EDMA_ChannelRegUpdate(data->hal_cfg, chan->id,
			      EDMA_TCD_CH_INT, EDMA_TCD_CH_INT_MASK, 0);

	if (chan->cyclic_buffer) {
		update_size = chan->bsize;

		if (IS_ENABLED(CONFIG_DMA_NXP_EDMA_ENABLE_HALFMAJOR_IRQ)) {
			update_size = chan->bsize / 2;
		} else {
			update_size = chan->bsize;
		}

		/* TODO: add support for error handling here */
		ret = EDMA_CHAN_PRODUCE_CONSUME_A(chan, update_size);
		if (ret < 0) {
			LOG_ERR("chan %d buffer overflow/underrun", chan->id);
		}
	}

	/* TODO: are there any sanity checks we have to perform before invoking
	 * the registered callback?
	 */
	if (chan->cb) {
		chan->cb(chan->dev, chan->arg, chan->id, DMA_STATUS_COMPLETE);
	}
}

static struct edma_channel *lookup_channel(const struct device *dev,
					   uint32_t chan_id)
{
	struct edma_data *data;
	const struct edma_config *cfg;
	int i;

	data = dev->data;
	cfg = dev->config;


	/* optimization: if dma-channels property is present then
	 * the channel data associated with the passed channel ID
	 * can be found at index chan_id in the array of channels.
	 */
	if (cfg->contiguous_channels) {
		/* check for index out of bounds */
		if (chan_id >= data->ctx.dma_channels) {
			return NULL;
		}

		return &data->channels[chan_id];
	}

	/* channels are passed through the valid-channels property.
	 * As such, since some channels may be missing we need to
	 * look through the entire channels array for an ID match.
	 */
	for (i = 0; i < data->ctx.dma_channels; i++) {
		if (data->channels[i].id == chan_id) {
			return &data->channels[i];
		}
	}

	return NULL;
}

static int edma_config(const struct device *dev, uint32_t chan_id,
		       struct dma_config *dma_cfg)
{
	struct edma_data *data;
	const struct edma_config *cfg;
	struct edma_channel *chan;
	uint32_t transfer_type;
	int ret;

	data = dev->data;
	cfg = dev->config;

	if (!dma_cfg->head_block) {
		LOG_ERR("head block shouldn't be NULL");
		return -EINVAL;
	}

	/* validate source data size (SSIZE) */
	if (!EDMA_TransferWidthIsValid(data->hal_cfg, dma_cfg->source_data_size)) {
		LOG_ERR("invalid source data size: %d",
			dma_cfg->source_data_size);
		return -EINVAL;
	}

	/* validate destination data size (DSIZE) */
	if (!EDMA_TransferWidthIsValid(data->hal_cfg, dma_cfg->dest_data_size)) {
		LOG_ERR("invalid destination data size: %d",
			dma_cfg->dest_data_size);
		return -EINVAL;
	}

	/* validate configured alignment */
	if (!EDMA_TransferWidthIsValid(data->hal_cfg, CONFIG_DMA_NXP_EDMA_ALIGN)) {
		LOG_ERR("configured alignment %d is invalid",
			CONFIG_DMA_NXP_EDMA_ALIGN);
		return -EINVAL;
	}

	/* Scatter-Gather configurations currently not supported */
	if (dma_cfg->block_count != 1) {
		LOG_ERR("number of blocks %d not supported", dma_cfg->block_count);
		return -ENOTSUP;
	}

	/* source address shouldn't be NULL */
	if (!dma_cfg->head_block->source_address) {
		LOG_ERR("source address cannot be NULL");
		return -EINVAL;
	}

	/* destination address shouldn't be NULL */
	if (!dma_cfg->head_block->dest_address) {
		LOG_ERR("destination address cannot be NULL");
		return -EINVAL;
	}

	/* check source address's (SADDR) alignment with respect to the data size (SSIZE)
	 *
	 * Failing to meet this condition will lead to the assertion of the SAE
	 * bit (see CHn_ES register).
	 *
	 * TODO: this will also restrict scenarios such as the following:
	 *	SADDR is 8B aligned and SSIZE is 16B. I've tested this
	 *	scenario and seems to raise no hardware errors (I'm assuming
	 *	because this doesn't break the 8B boundary of the 64-bit system
	 *	I tested it on). Is there a need to allow such a scenario?
	 */
	if (dma_cfg->head_block->source_address % dma_cfg->source_data_size) {
		LOG_ERR("source address 0x%x alignment doesn't match data size %d",
			dma_cfg->head_block->source_address,
			dma_cfg->source_data_size);
		return -EINVAL;
	}

	/* check destination address's (DADDR) alignment with respect to the data size (DSIZE)
	 * Failing to meet this condition will lead to the assertion of the DAE
	 * bit (see CHn_ES register).
	 */
	if (dma_cfg->head_block->dest_address % dma_cfg->dest_data_size) {
		LOG_ERR("destination address 0x%x alignment doesn't match data size %d",
			dma_cfg->head_block->dest_address,
			dma_cfg->dest_data_size);
		return -EINVAL;
	}

	/* source burst length should match destination burst length.
	 * This is because the burst length is the equivalent of NBYTES which
	 * is used for both the destination and the source.
	 */
	if (dma_cfg->source_burst_length !=
	    dma_cfg->dest_burst_length) {
		LOG_ERR("source burst length %d doesn't match destination burst length %d",
			dma_cfg->source_burst_length,
			dma_cfg->dest_burst_length);
		return -EINVAL;
	}

	/* total number of bytes should be a multiple of NBYTES.
	 *
	 * This is needed because the EDMA engine performs transfers based
	 * on CITER (integer value) and NBYTES, thus it has no knowledge of
	 * the total transfer size. If the total transfer size is not a
	 * multiple of NBYTES then we'll end up with copying a wrong number
	 * of bytes (CITER = TOTAL_SIZE / BITER). This, of course, raises
	 * no error in the hardware but it's still wrong.
	 */
	if (dma_cfg->head_block->block_size % dma_cfg->source_burst_length) {
		LOG_ERR("block size %d should be a multiple of NBYTES %d",
			dma_cfg->head_block->block_size,
			dma_cfg->source_burst_length);
		return -EINVAL;
	}

	/* check if NBYTES is a multiple of MAX(SSIZE, DSIZE).
	 *
	 * This stems from the fact that NBYTES needs to be a multiple
	 * of SSIZE AND DSIZE. If NBYTES is a multiple of MAX(SSIZE, DSIZE)
	 * then it will for sure satisfy the aforementioned condition (since
	 * SSIZE and DSIZE are powers of 2).
	 *
	 * Failing to meet this condition will lead to the assertion of the
	 * NCE bit (see CHn_ES register).
	 */
	if (dma_cfg->source_burst_length %
	    MAX(dma_cfg->source_data_size, dma_cfg->dest_data_size)) {
		LOG_ERR("NBYTES %d should be a multiple of MAX(SSIZE(%d), DSIZE(%d))",
			dma_cfg->source_burst_length,
			dma_cfg->source_data_size,
			dma_cfg->dest_data_size);
		return -EINVAL;
	}

	/* fetch channel data */
	chan = lookup_channel(dev, chan_id);
	if (!chan) {
		LOG_ERR("channel ID %u is not valid", chan_id);
		return -EINVAL;
	}

	/* save the block size for later usage in edma_reload */
	chan->bsize = dma_cfg->head_block->block_size;

	if (dma_cfg->cyclic) {
		chan->cyclic_buffer = true;

		chan->stat.read_position = 0;
		chan->stat.write_position = 0;

		/* ASSUMPTION: for CONSUMER-type channels, the buffer from
		 * which the engine consumes should be full, while in the
		 * case of PRODUCER-type channels it should be empty.
		 */
		switch (dma_cfg->channel_direction) {
		case MEMORY_TO_PERIPHERAL:
			chan->type = CHAN_TYPE_CONSUMER;
			chan->stat.free = 0;
			chan->stat.pending_length = chan->bsize;
			break;
		case PERIPHERAL_TO_MEMORY:
			chan->type = CHAN_TYPE_PRODUCER;
			chan->stat.pending_length = 0;
			chan->stat.free = chan->bsize;
			break;
		default:
			LOG_ERR("unsupported transfer dir %d for cyclic mode",
				dma_cfg->channel_direction);
			return -ENOTSUP;
		}
	} else {
		chan->cyclic_buffer = false;
	}

	/* change channel's state to CONFIGURED */
	ret = channel_change_state(chan, CHAN_STATE_CONFIGURED);
	if (ret < 0) {
		LOG_ERR("failed to change channel %d state to CONFIGURED", chan_id);
		return ret;
	}

	ret = get_transfer_type(dma_cfg->channel_direction, &transfer_type);
	if (ret < 0) {
		return ret;
	}

	chan->cb = dma_cfg->dma_callback;
	chan->arg = dma_cfg->user_data;

	/* warning: this sets SOFF and DOFF to SSIZE and DSIZE which are POSITIVE. */
	ret = EDMA_ConfigureTransfer(data->hal_cfg, chan_id,
				     dma_cfg->head_block->source_address,
				     dma_cfg->head_block->dest_address,
				     dma_cfg->source_data_size,
				     dma_cfg->dest_data_size,
				     dma_cfg->source_burst_length,
				     dma_cfg->head_block->block_size,
				     transfer_type);
	if (ret < 0) {
		LOG_ERR("failed to configure transfer");
		return to_std_error(ret);
	}

	/* TODO: channel MUX should be forced to 0 based on the previous state */
	if (EDMA_HAS_MUX(data->hal_cfg)) {
		ret = EDMA_SetChannelMux(data->hal_cfg, chan_id, dma_cfg->dma_slot);
		if (ret < 0) {
			LOG_ERR("failed to set channel MUX");
			return to_std_error(ret);
		}
	}

	/* set SLAST and DLAST */
	ret = set_slast_dlast(dma_cfg, transfer_type, data, chan_id);
	if (ret < 0) {
		return ret;
	}

	/* allow interrupting the CPU when a major cycle is completed.
	 *
	 * interesting note: only 1 major loop is performed per slave peripheral
	 * DMA request. For instance, if block_size = 768 and burst_size = 192
	 * we're going to get 4 transfers of 192 bytes. Each of these transfers
	 * translates to a DMA request made by the slave peripheral.
	 */
	EDMA_ChannelRegUpdate(data->hal_cfg, chan_id,
			      EDMA_TCD_CSR, EDMA_TCD_CSR_INTMAJOR_MASK, 0);

	if (IS_ENABLED(CONFIG_DMA_NXP_EDMA_ENABLE_HALFMAJOR_IRQ)) {
		/* if enabled through the above configuration, also
		 * allow the CPU to be interrupted when CITER = BITER / 2.
		 */
		EDMA_ChannelRegUpdate(data->hal_cfg, chan_id, EDMA_TCD_CSR,
				      EDMA_TCD_CSR_INTHALF_MASK, 0);
	}

	/* enable channel interrupt */
	irq_enable(chan->irq);

	/* dump register status - for debugging purposes */
	edma_dump_channel_registers(data, chan_id);

	return 0;
}

static int edma_get_status(const struct device *dev, uint32_t chan_id,
			   struct dma_status *stat)
{
	struct edma_data *data;
	struct edma_channel *chan;
	uint32_t citer, biter, done;
	unsigned int key;

	data = dev->data;

	/* fetch channel data */
	chan = lookup_channel(dev, chan_id);
	if (!chan) {
		LOG_ERR("channel ID %u is not valid", chan_id);
		return -EINVAL;
	}

	if (chan->cyclic_buffer) {
		key = irq_lock();

		stat->free = chan->stat.free;
		stat->pending_length = chan->stat.pending_length;

		irq_unlock(key);
	} else {
		/* note: no locking required here. The DMA interrupts
		 * have no effect over CITER and BITER.
		 */
		citer = EDMA_ChannelRegRead(data->hal_cfg, chan_id, EDMA_TCD_CITER);
		biter = EDMA_ChannelRegRead(data->hal_cfg, chan_id, EDMA_TCD_BITER);
		done = EDMA_ChannelRegRead(data->hal_cfg, chan_id, EDMA_TCD_CH_CSR) &
			EDMA_TCD_CH_CSR_DONE_MASK;
		if (done) {
			stat->free = chan->bsize;
			stat->pending_length = 0;
		} else {
			stat->free = (biter - citer) * (chan->bsize / biter);
			stat->pending_length = chan->bsize - stat->free;
		}
	}

	LOG_DBG("free: %d, pending: %d", stat->free, stat->pending_length);

	return 0;
}

static int edma_suspend(const struct device *dev, uint32_t chan_id)
{
	struct edma_data *data;
	const struct edma_config *cfg;
	struct edma_channel *chan;
	int ret;

	data = dev->data;
	cfg = dev->config;

	/* fetch channel data */
	chan = lookup_channel(dev, chan_id);
	if (!chan) {
		LOG_ERR("channel ID %u is not valid", chan_id);
		return -EINVAL;
	}

	edma_dump_channel_registers(data, chan_id);

	/* change channel's state to SUSPENDED */
	ret = channel_change_state(chan, CHAN_STATE_SUSPENDED);
	if (ret < 0) {
		LOG_ERR("failed to change channel %d state to SUSPENDED", chan_id);
		return ret;
	}

	LOG_DBG("suspending channel %u", chan_id);

	/* disable HW requests */
	EDMA_ChannelRegUpdate(data->hal_cfg, chan_id,
			      EDMA_TCD_CH_CSR, 0, EDMA_TCD_CH_CSR_ERQ_MASK);

	return 0;
}

static int edma_stop(const struct device *dev, uint32_t chan_id)
{
	struct edma_data *data;
	const struct edma_config *cfg;
	struct edma_channel *chan;
	enum channel_state prev_state;
	int ret;

	data = dev->data;
	cfg = dev->config;

	/* fetch channel data */
	chan = lookup_channel(dev, chan_id);
	if (!chan) {
		LOG_ERR("channel ID %u is not valid", chan_id);
		return -EINVAL;
	}

	prev_state = chan->state;

	/* change channel's state to STOPPED */
	ret = channel_change_state(chan, CHAN_STATE_STOPPED);
	if (ret < 0) {
		LOG_ERR("failed to change channel %d state to STOPPED", chan_id);
		return ret;
	}

	LOG_DBG("stopping channel %u", chan_id);

	if (prev_state == CHAN_STATE_SUSPENDED) {
		/* if the channel has been suspended then there's
		 * no point in disabling the HW requests again. Just
		 * jump to the channel release operation.
		 */
		goto out_release_channel;
	}

	/* disable HW requests */
	EDMA_ChannelRegUpdate(data->hal_cfg, chan_id, EDMA_TCD_CH_CSR, 0,
			      EDMA_TCD_CH_CSR_ERQ_MASK);
out_release_channel:

	/* clear the channel MUX so that it can used by a different peripheral.
	 *
	 * note: because the channel is released during dma_stop() that means
	 * dma_start() can no longer be immediately called. This is because
	 * one needs to re-configure the channel MUX which can only be done
	 * through dma_config(). As such, if one intends to reuse the current
	 * configuration then please call dma_suspend() instead of dma_stop().
	 */
	if (EDMA_HAS_MUX(data->hal_cfg)) {
		ret = EDMA_SetChannelMux(data->hal_cfg, chan_id, 0);
		if (ret < 0) {
			LOG_ERR("failed to set channel MUX");
			return to_std_error(ret);
		}
	}

	edma_dump_channel_registers(data, chan_id);

	return 0;
}

static int edma_start(const struct device *dev, uint32_t chan_id)
{
	struct edma_data *data;
	const struct edma_config *cfg;
	struct edma_channel *chan;
	int ret;

	data = dev->data;
	cfg = dev->config;

	/* fetch channel data */
	chan = lookup_channel(dev, chan_id);
	if (!chan) {
		LOG_ERR("channel ID %u is not valid", chan_id);
		return -EINVAL;
	}

	/* change channel's state to STARTED */
	ret = channel_change_state(chan, CHAN_STATE_STARTED);
	if (ret < 0) {
		LOG_ERR("failed to change channel %d state to STARTED", chan_id);
		return ret;
	}

	LOG_DBG("starting channel %u", chan_id);

	/* enable HW requests */
	EDMA_ChannelRegUpdate(data->hal_cfg, chan_id,
			      EDMA_TCD_CH_CSR, EDMA_TCD_CH_CSR_ERQ_MASK, 0);

	return 0;
}

static int edma_reload(const struct device *dev, uint32_t chan_id, uint32_t src,
		       uint32_t dst, size_t size)
{
	struct edma_data *data;
	struct edma_channel *chan;
	int ret;
	unsigned int key;

	data = dev->data;

	/* fetch channel data */
	chan = lookup_channel(dev, chan_id);
	if (!chan) {
		LOG_ERR("channel ID %u is not valid", chan_id);
		return -EINVAL;
	}

	/* channel needs to be started to allow reloading */
	if (chan->state != CHAN_STATE_STARTED) {
		LOG_ERR("reload is only supported on started channels");
		return -EINVAL;
	}

	if (chan->cyclic_buffer) {
		key = irq_lock();
		ret = EDMA_CHAN_PRODUCE_CONSUME_B(chan, size);
		irq_unlock(key);
		if (ret < 0) {
			LOG_ERR("chan %d buffer overflow/underrun", chan_id);
			return ret;
		}
	}

	return 0;
}

static int edma_get_attribute(const struct device *dev, uint32_t type, uint32_t *val)
{
	switch (type) {
	case DMA_ATTR_BUFFER_SIZE_ALIGNMENT:
	case DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT:
		*val = CONFIG_DMA_NXP_EDMA_ALIGN;
		break;
	case DMA_ATTR_MAX_BLOCK_COUNT:
		/* this is restricted to 1 because SG configurations are not supported */
		*val = 1;
		break;
	default:
		LOG_ERR("invalid attribute type: %d", type);
		return -EINVAL;
	}

	return 0;
}

static bool edma_channel_filter(const struct device *dev, int chan_id, void *param)
{
	int *requested_channel;

	if (!param) {
		return false;
	}

	requested_channel = param;

	if (*requested_channel == chan_id && lookup_channel(dev, chan_id)) {
		return true;
	}

	return false;
}

static const struct dma_driver_api edma_api = {
	.reload = edma_reload,
	.config = edma_config,
	.start = edma_start,
	.stop = edma_stop,
	.suspend = edma_suspend,
	.resume = edma_start,
	.get_status = edma_get_status,
	.get_attribute = edma_get_attribute,
	.chan_filter = edma_channel_filter,
};

static int edma_init(const struct device *dev)
{
	const struct edma_config *cfg;
	struct edma_data *data;
	mm_reg_t regmap;

	data = dev->data;
	cfg = dev->config;

	/* map instance MMIO */
	device_map(&regmap, cfg->regmap_phys, cfg->regmap_size, K_MEM_CACHE_NONE);

	/* overwrite physical address set in the HAL configuration.
	 * We can down-cast the virtual address to a 32-bit address because
	 * we know we're working with 32-bit addresses only.
	 */
	data->hal_cfg->regmap = (uint32_t)POINTER_TO_UINT(regmap);

	cfg->irq_config();

	/* dma_request_channel() uses this variable to keep track of the
	 * available channels. As such, it needs to be initialized with NULL
	 * which signifies that all channels are initially available.
	 */
	data->channel_flags = ATOMIC_INIT(0);
	data->ctx.atomic = &data->channel_flags;
	data->ctx.dma_channels = data->hal_cfg->channels;

	return 0;
}

/* a few comments about the BUILD_ASSERT statements:
 *	1) dma-channels and valid-channels should be mutually exclusive.
 *	This means that you specify the one or the other. There's no real
 *	need to have both of them.
 *	2) Number of channels should match the number of interrupts for
 *	said channels (TODO: what about error interrupts?)
 *	3) The channel-mux property shouldn't be specified unless
 *	the eDMA is MUX-capable (signaled via the EDMA_HAS_CHAN_MUX
 *	configuration).
 */
#define EDMA_INIT(inst)								\
										\
BUILD_ASSERT(!DT_NODE_HAS_PROP(DT_INST(inst, DT_DRV_COMPAT), dma_channels) ||	\
	     !DT_NODE_HAS_PROP(DT_INST(inst, DT_DRV_COMPAT), valid_channels),	\
	     "dma_channels and valid_channels are mutually exclusive");		\
										\
BUILD_ASSERT(DT_INST_PROP_OR(inst, dma_channels, 0) ==				\
	     DT_NUM_IRQS(DT_INST(inst, DT_DRV_COMPAT)) ||			\
	     DT_INST_PROP_LEN_OR(inst, valid_channels, 0) ==			\
	     DT_NUM_IRQS(DT_INST(inst, DT_DRV_COMPAT)),				\
	     "number of interrupts needs to match number of channels");		\
										\
BUILD_ASSERT(DT_PROP_OR(DT_INST(inst, DT_DRV_COMPAT), hal_cfg_index, 0) <	\
	     ARRAY_SIZE(s_edmaConfigs),						\
	     "HAL configuration index out of bounds");				\
										\
static struct edma_channel channels_##inst[] = EDMA_CHANNEL_ARRAY_GET(inst);	\
										\
static void interrupt_config_function_##inst(void)				\
{										\
	EDMA_CONNECT_INTERRUPTS(inst);						\
}										\
										\
static struct edma_config edma_config_##inst = {				\
	.regmap_phys = DT_INST_REG_ADDR(inst),					\
	.regmap_size = DT_INST_REG_SIZE(inst),					\
	.irq_config = interrupt_config_function_##inst,				\
	.contiguous_channels = EDMA_CHANS_ARE_CONTIGUOUS(inst),			\
};										\
										\
static struct edma_data edma_data_##inst = {					\
	.channels = channels_##inst,						\
	.ctx.magic = DMA_MAGIC,							\
	.hal_cfg = &EDMA_HAL_CFG_GET(inst),					\
};										\
										\
DEVICE_DT_INST_DEFINE(inst, &edma_init, NULL,					\
		      &edma_data_##inst, &edma_config_##inst,			\
		      PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY,			\
		      &edma_api);						\

DT_INST_FOREACH_STATUS_OKAY(EDMA_INIT);
