/*
 * Copyright (c) 2023 Andes Technology Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <errno.h>

#include <stdio.h>
#include <string.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/drivers/dma.h>

#define DT_DRV_COMPAT andestech_atcdmac300

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

#define ATCDMAC100_MAX_CHAN	8

#define DMA_ABORT(dev)		(((struct dma_atcdmac300_cfg *)dev->config)->base + 0x24)
#define DMA_INT_STATUS(dev)		\
		(((struct dma_atcdmac300_cfg *)dev->config)->base + 0x30)

#define DMA_CH_OFFSET(ch)	(ch * 0x20)
#define DMA_CH_CTRL(dev, ch)		\
		(((struct dma_atcdmac300_cfg *)dev->config)->base + 0x40 + DMA_CH_OFFSET(ch))
#define DMA_CH_TRANSIZE(dev, ch)	\
		(((struct dma_atcdmac300_cfg *)dev->config)->base + 0x44 + DMA_CH_OFFSET(ch))
#define DMA_CH_SRC_ADDR_L(dev, ch)	\
		(((struct dma_atcdmac300_cfg *)dev->config)->base + 0x48 + DMA_CH_OFFSET(ch))
#define DMA_CH_SRC_ADDR_H(dev, ch)	\
		(((struct dma_atcdmac300_cfg *)dev->config)->base + 0x4C + DMA_CH_OFFSET(ch))
#define DMA_CH_DST_ADDR_L(dev, ch)	\
		(((struct dma_atcdmac300_cfg *)dev->config)->base + 0x50 + DMA_CH_OFFSET(ch))
#define DMA_CH_DST_ADDR_H(dev, ch)	\
		(((struct dma_atcdmac300_cfg *)dev->config)->base + 0x54 + DMA_CH_OFFSET(ch))
#define DMA_CH_LL_PTR_L(dev, ch)	\
		(((struct dma_atcdmac300_cfg *)dev->config)->base + 0x58 + DMA_CH_OFFSET(ch))
#define DMA_CH_LL_PTR_H(dev, ch)	\
		(((struct dma_atcdmac300_cfg *)dev->config)->base + 0x5C + DMA_CH_OFFSET(ch))

/* Source burst size options */
#define DMA_BSIZE_1		(0)
#define DMA_BSIZE_2		(1)
#define DMA_BSIZE_4		(2)
#define DMA_BSIZE_8		(3)
#define DMA_BSIZE_16		(4)
#define DMA_BSIZE_32		(5)
#define DMA_BSIZE_64		(6)
#define DMA_BSIZE_128		(7)
#define DMA_BSIZE_256		(8)
#define DMA_BSIZE_512		(9)
#define DMA_BSIZE_1024		(10)

/* Source/Destination transfer width options */
#define DMA_WIDTH_BYTE		(0)
#define DMA_WIDTH_HALFWORD	(1)
#define DMA_WIDTH_WORD		(2)
#define DMA_WIDTH_DWORD		(3)
#define DMA_WIDTH_QWORD		(4)
#define DMA_WIDTH_EWORD		(5)

/* Bus interface index */
#define DMA_INF_IDX0		(0)
#define DMA_INF_IDX1		(1)

/* DMA Channel Control Register Definition */
#define DMA_CH_CTRL_SBINF_MASK		BIT(31)
#define DMA_CH_CTRL_DBINF_MASK		BIT(30)
#define DMA_CH_CTRL_PRIORITY_HIGH	BIT(29)
#define DMA_CH_CTRL_SBSIZE_MASK		GENMASK(27, 24)
#define DMA_CH_CTRL_SBSIZE(n)		FIELD_PREP(DMA_CH_CTRL_SBSIZE_MASK, (n))
#define DMA_CH_CTRL_SWIDTH_MASK		GENMASK(23, 21)
#define DMA_CH_CTRL_SWIDTH(n)		FIELD_PREP(DMA_CH_CTRL_SWIDTH_MASK, (n))
#define DMA_CH_CTRL_DWIDTH_MASK		GENMASK(20, 18)
#define DMA_CH_CTRL_DWIDTH(n)		FIELD_PREP(DMA_CH_CTRL_DWIDTH_MASK, (n))
#define DMA_CH_CTRL_SMODE_HANDSHAKE	BIT(17)
#define DMA_CH_CTRL_DMODE_HANDSHAKE	BIT(16)
#define DMA_CH_CTRL_SRCADDRCTRL_MASK	GENMASK(15, 14)
#define DMA_CH_CTRL_SRCADDR_INC		FIELD_PREP(DMA_CH_CTRL_SRCADDRCTRL_MASK, (0))
#define DMA_CH_CTRL_SRCADDR_DEC		FIELD_PREP(DMA_CH_CTRL_SRCADDRCTRL_MASK, (1))
#define DMA_CH_CTRL_SRCADDR_FIX		FIELD_PREP(DMA_CH_CTRL_SRCADDRCTRL_MASK, (2))
#define DMA_CH_CTRL_DSTADDRCTRL_MASK	GENMASK(13, 12)
#define DMA_CH_CTRL_DSTADDR_INC		FIELD_PREP(DMA_CH_CTRL_DSTADDRCTRL_MASK, (0))
#define DMA_CH_CTRL_DSTADDR_DEC		FIELD_PREP(DMA_CH_CTRL_DSTADDRCTRL_MASK, (1))
#define DMA_CH_CTRL_DSTADDR_FIX		FIELD_PREP(DMA_CH_CTRL_DSTADDRCTRL_MASK, (2))
#define DMA_CH_CTRL_SRCREQ_MASK		GENMASK(11, 8)
#define DMA_CH_CTRL_SRCREQ(n)		FIELD_PREP(DMA_CH_CTRL_SRCREQ_MASK, (n))
#define DMA_CH_CTRL_DSTREQ_MASK		GENMASK(7, 4)
#define DMA_CH_CTRL_DSTREQ(n)		FIELD_PREP(DMA_CH_CTRL_DSTREQ_MASK, (n))
#define DMA_CH_CTRL_INTABT		BIT(3)
#define DMA_CH_CTRL_INTERR		BIT(2)
#define DMA_CH_CTRL_INTTC		BIT(1)
#define DMA_CH_CTRL_ENABLE		BIT(0)

/* DMA Interrupt Status Register Definition */
#define	DMA_INT_STATUS_TC_MASK		GENMASK(23, 16)
#define	DMA_INT_STATUS_ABORT_MASK	GENMASK(15, 8)
#define	DMA_INT_STATUS_ERROR_MASK	GENMASK(7, 0)
#define DMA_INT_STATUS_TC_VAL(x)	FIELD_GET(DMA_INT_STATUS_TC_MASK, (x))
#define DMA_INT_STATUS_ABORT_VAL(x)	FIELD_GET(DMA_INT_STATUS_ABORT_MASK, (x))
#define DMA_INT_STATUS_ERROR_VAL(x)	FIELD_GET(DMA_INT_STATUS_ERROR_MASK, (x))
#define DMA_INT_STATUS_CH_MSK(ch)	(0x111 << ch)

typedef void (*atcdmac300_cfg_func_t)(void);

struct chain_block {
	uint32_t ctrl;
	uint32_t transize;
	uint32_t srcaddrl;
	uint32_t srcaddrh;
	uint32_t dstaddrl;
	uint32_t dstaddrh;
	uint32_t llpointerl;
	uint32_t llpointerh;
#if __riscv_xlen == 32
	uint32_t reserved;
#endif
	struct chain_block *next_block;
};

/* data for each DMA channel */
struct dma_chan_data {
	void *blkuser_data;
	dma_callback_t blkcallback;
	struct chain_block *head_block;
	struct dma_status status;
};

/* Device run time data */
struct dma_atcdmac300_data {
	struct dma_chan_data chan[ATCDMAC100_MAX_CHAN];
	struct k_spinlock lock;
};

/* Device constant configuration parameters */
struct dma_atcdmac300_cfg {
	atcdmac300_cfg_func_t irq_config;
	uint32_t base;
	uint32_t irq_num;
};

static struct __aligned(64)
	chain_block dma_chain[ATCDMAC100_MAX_CHAN][sizeof(struct chain_block) * 16];

static void dma_atcdmac300_isr(const struct device *dev)
{
	uint32_t int_status, int_ch_status, channel;
	struct dma_atcdmac300_data *const data = dev->data;
	struct dma_chan_data *ch_data;
	k_spinlock_key_t key;

	key = k_spin_lock(&data->lock);
	int_status = sys_read32(DMA_INT_STATUS(dev));
	/* Clear interrupt*/
	sys_write32(int_status, DMA_INT_STATUS(dev));

	k_spin_unlock(&data->lock, key);

	/* Handle terminal count status */
	int_ch_status = DMA_INT_STATUS_TC_VAL(int_status);
	while (int_ch_status) {
		channel = find_msb_set(int_ch_status) - 1;
		int_ch_status &= ~(BIT(channel));

		ch_data = &data->chan[channel];
		if (ch_data->blkcallback) {
			ch_data->blkcallback(dev, ch_data->blkuser_data, channel, 0);
		}
		data->chan[channel].status.busy = false;
	}

	/* Handle error status */
	int_ch_status = DMA_INT_STATUS_ERROR_VAL(int_status);
	while (int_ch_status) {
		channel = find_msb_set(int_ch_status) - 1;
		int_ch_status &= ~(BIT(channel));

		ch_data = &data->chan[channel];
		if (ch_data->blkcallback) {
			ch_data->blkcallback(dev, ch_data->blkuser_data, channel, -EIO);
		}
	}
}

static int dma_atcdmac300_config(const struct device *dev, uint32_t channel,
				 struct dma_config *cfg)
{
	struct dma_atcdmac300_data *const data = dev->data;
	uint32_t src_width, dst_width, src_burst_size, ch_ctrl, tfr_size;
	int32_t ret = 0;
	struct dma_block_config *cfg_blocks;
	k_spinlock_key_t key;

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

	__ASSERT_NO_MSG(cfg->source_data_size == cfg->dest_data_size);
	__ASSERT_NO_MSG(cfg->source_burst_length == cfg->dest_burst_length);

	if (cfg->source_data_size != 1 && cfg->source_data_size != 2 &&
	    cfg->source_data_size != 4) {
		LOG_ERR("Invalid 'source_data_size' value");
		ret = -EINVAL;
		goto end;
	}

	cfg_blocks = cfg->head_block;
	if (cfg_blocks == NULL) {
		ret = -EINVAL;
		goto end;
	}

	tfr_size = cfg_blocks->block_size/cfg->source_data_size;
	if (tfr_size == 0) {
		ret = -EINVAL;
		goto end;
	}

	ch_ctrl = 0;

	switch (cfg->channel_direction) {
	case MEMORY_TO_MEMORY:
		break;
	case MEMORY_TO_PERIPHERAL:
		ch_ctrl |= DMA_CH_CTRL_DSTREQ(cfg->dma_slot);
		ch_ctrl |= DMA_CH_CTRL_DMODE_HANDSHAKE;
		break;
	case PERIPHERAL_TO_MEMORY:
		ch_ctrl |= DMA_CH_CTRL_SRCREQ(cfg->dma_slot);
		ch_ctrl |= DMA_CH_CTRL_SMODE_HANDSHAKE;
		break;
	default:
		ret = -EINVAL;
		goto end;
	}


	switch (cfg_blocks->source_addr_adj) {
	case DMA_ADDR_ADJ_INCREMENT:
		ch_ctrl |= DMA_CH_CTRL_SRCADDR_INC;
		break;
	case DMA_ADDR_ADJ_DECREMENT:
		ch_ctrl |= DMA_CH_CTRL_SRCADDR_DEC;
		break;
	case DMA_ADDR_ADJ_NO_CHANGE:
		ch_ctrl |= DMA_CH_CTRL_SRCADDR_FIX;
		break;
	default:
		ret = -EINVAL;
		goto end;
	}

	switch (cfg_blocks->dest_addr_adj) {
	case DMA_ADDR_ADJ_INCREMENT:
		ch_ctrl |= DMA_CH_CTRL_DSTADDR_INC;
		break;
	case DMA_ADDR_ADJ_DECREMENT:
		ch_ctrl |= DMA_CH_CTRL_DSTADDR_DEC;
		break;
	case DMA_ADDR_ADJ_NO_CHANGE:
		ch_ctrl |= DMA_CH_CTRL_DSTADDR_FIX;
		break;
	default:
		ret = -EINVAL;
		goto end;
	}

	ch_ctrl |= DMA_CH_CTRL_INTABT;

	/* Disable the error callback */
	if (!cfg->error_callback_en) {
		ch_ctrl |= DMA_CH_CTRL_INTERR;
	}

	src_width = find_msb_set(cfg->source_data_size) - 1;
	dst_width = find_msb_set(cfg->dest_data_size) - 1;
	src_burst_size = find_msb_set(cfg->source_burst_length) - 1;

	ch_ctrl |=  DMA_CH_CTRL_SWIDTH(src_width)	|
		    DMA_CH_CTRL_DWIDTH(dst_width)	|
		    DMA_CH_CTRL_SBSIZE(src_burst_size);


	/* Reset DMA channel configuration */
	sys_write32(0, DMA_CH_CTRL(dev, channel));

	key = k_spin_lock(&data->lock);
	/* Clear DMA interrupts status */
	sys_write32(DMA_INT_STATUS_CH_MSK(channel), DMA_INT_STATUS(dev));
	k_spin_unlock(&data->lock, key);

	/* Set transfer size */
	sys_write32(tfr_size, DMA_CH_TRANSIZE(dev, channel));

	/* Update the status of channel */
	data->chan[channel].status.dir = cfg->channel_direction;
	data->chan[channel].status.pending_length = cfg->source_data_size;

	/* Configure a callback appropriately depending on whether the
	 * interrupt is requested at the end of transaction completion or
	 * at the end of each block.
	 */
	data->chan[channel].blkcallback = cfg->dma_callback;
	data->chan[channel].blkuser_data = cfg->user_data;

	sys_write32(ch_ctrl, DMA_CH_CTRL(dev, channel));

	/* Set source and destination address */
	sys_write32(cfg_blocks->source_address,
					DMA_CH_SRC_ADDR_L(dev, channel));
	sys_write32(0, DMA_CH_SRC_ADDR_H(dev, channel));
	sys_write32(cfg_blocks->dest_address,
					DMA_CH_DST_ADDR_L(dev, channel));
	sys_write32(0, DMA_CH_DST_ADDR_H(dev, channel));

	if (cfg->dest_chaining_en == 1 && cfg_blocks->next_block) {
		uint32_t current_block_idx = 0;

		sys_write32((uint32_t)((long)&dma_chain[channel][current_block_idx]),
							DMA_CH_LL_PTR_L(dev, channel));
		sys_write32(0, DMA_CH_LL_PTR_H(dev, channel));

		for (cfg_blocks = cfg_blocks->next_block; cfg_blocks != NULL;
				cfg_blocks = cfg_blocks->next_block) {

			ch_ctrl &= ~(DMA_CH_CTRL_SRCADDRCTRL_MASK |
					DMA_CH_CTRL_DSTADDRCTRL_MASK);

			switch (cfg_blocks->source_addr_adj) {
			case DMA_ADDR_ADJ_INCREMENT:
				ch_ctrl |= DMA_CH_CTRL_SRCADDR_INC;
				break;
			case DMA_ADDR_ADJ_DECREMENT:
				ch_ctrl |= DMA_CH_CTRL_SRCADDR_DEC;
				break;
			case DMA_ADDR_ADJ_NO_CHANGE:
				ch_ctrl |= DMA_CH_CTRL_SRCADDR_FIX;
				break;
			default:
				ret = -EINVAL;
				goto end;
			}

			switch (cfg_blocks->dest_addr_adj) {
			case DMA_ADDR_ADJ_INCREMENT:
				ch_ctrl |= DMA_CH_CTRL_DSTADDR_INC;
				break;
			case DMA_ADDR_ADJ_DECREMENT:
				ch_ctrl |= DMA_CH_CTRL_DSTADDR_DEC;
				break;
			case DMA_ADDR_ADJ_NO_CHANGE:
				ch_ctrl |= DMA_CH_CTRL_DSTADDR_FIX;
				break;
			default:
				ret = -EINVAL;
				goto end;
			}
			dma_chain[channel][current_block_idx].ctrl = ch_ctrl;
			dma_chain[channel][current_block_idx].transize =
						cfg_blocks->block_size/cfg->source_data_size;

			dma_chain[channel][current_block_idx].srcaddrl =
						(uint32_t)cfg_blocks->source_address;
			dma_chain[channel][current_block_idx].srcaddrh = 0x0;

			dma_chain[channel][current_block_idx].dstaddrl =
						(uint32_t)((long)cfg_blocks->dest_address);
			dma_chain[channel][current_block_idx].dstaddrh = 0x0;

			if (cfg_blocks->next_block) {
				dma_chain[channel][current_block_idx].llpointerl =
					(uint32_t)&dma_chain[channel][current_block_idx + 1];
				dma_chain[channel][current_block_idx].llpointerh = 0x0;

				current_block_idx = current_block_idx + 1;

			} else {
				dma_chain[channel][current_block_idx].llpointerl = 0x0;
				dma_chain[channel][current_block_idx].llpointerh = 0x0;
				dma_chain[channel][current_block_idx].next_block = NULL;
			}
		}
	} else {
		/* Single transfer is supported, but Chain transfer is still
		 * not supported. Therefore, set LLPointer to zero
		 */
		sys_write32(0, DMA_CH_LL_PTR_L(dev, channel));
		sys_write32(0, DMA_CH_LL_PTR_H(dev, channel));
	}

end:
	return ret;
}

static int dma_atcdmac300_reload(const struct device *dev, uint32_t channel,
				 uint32_t src, uint32_t dst, size_t size)
{
	uint32_t src_width;

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

	/* Set source and destination address */
	sys_write32(src, DMA_CH_SRC_ADDR_L(dev, channel));
	sys_write32(0, DMA_CH_SRC_ADDR_H(dev, channel));
	sys_write32(dst, DMA_CH_DST_ADDR_L(dev, channel));
	sys_write32(0, DMA_CH_DST_ADDR_H(dev, channel));

	src_width = FIELD_GET(DMA_CH_CTRL_SWIDTH_MASK, sys_read32(DMA_CH_CTRL(dev, channel)));
	src_width = BIT(src_width);

	/* Set transfer size */
	sys_write32(size/src_width, DMA_CH_TRANSIZE(dev, channel));

	return 0;
}

static int dma_atcdmac300_transfer_start(const struct device *dev,
					 uint32_t channel)
{
	struct dma_atcdmac300_data *const data = dev->data;

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

	sys_write32(sys_read32(DMA_CH_CTRL(dev, channel)) | DMA_CH_CTRL_ENABLE,
						DMA_CH_CTRL(dev, channel));

	data->chan[channel].status.busy = true;

	return 0;
}

static int dma_atcdmac300_transfer_stop(const struct device *dev,
					uint32_t channel)
{
	struct dma_atcdmac300_data *const data = dev->data;
	k_spinlock_key_t key;

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

	key = k_spin_lock(&data->lock);

	sys_write32(BIT(channel), DMA_ABORT(dev));
	sys_write32(0, DMA_CH_CTRL(dev, channel));
	sys_write32(FIELD_GET(DMA_INT_STATUS_ABORT_MASK, (channel)), DMA_INT_STATUS(dev));
	data->chan[channel].status.busy = false;

	k_spin_unlock(&data->lock, key);

	return 0;
}

static int dma_atcdmac300_init(const struct device *dev)
{
	const struct dma_atcdmac300_cfg *const config = (struct dma_atcdmac300_cfg *)dev->config;
	uint32_t ch_num;

	/* Disable all channels and Channel interrupts */
	for (ch_num = 0; ch_num < ATCDMAC100_MAX_CHAN; ch_num++) {
		sys_write32(0, DMA_CH_CTRL(dev, ch_num));
	}

	sys_write32(0xFFFFFF, DMA_INT_STATUS(dev));

	/* Configure interrupts */
	config->irq_config();

	irq_enable(config->irq_num);

	return 0;
}

static int dma_atcdmac300_get_status(const struct device *dev,
				     uint32_t channel,
				     struct dma_status *stat)
{
	struct dma_atcdmac300_data *const data = dev->data;

	stat->busy = data->chan[channel].status.busy;
	stat->dir = data->chan[channel].status.dir;
	stat->pending_length = data->chan[channel].status.pending_length;

	return 0;
}

static const struct dma_driver_api dma_atcdmac300_api = {
	.config = dma_atcdmac300_config,
	.reload = dma_atcdmac300_reload,
	.start = dma_atcdmac300_transfer_start,
	.stop = dma_atcdmac300_transfer_stop,
	.get_status = dma_atcdmac300_get_status
};

#define ATCDMAC300_INIT(n)						\
									\
	static void dma_atcdmac300_irq_config_##n(void);		\
									\
	static const struct dma_atcdmac300_cfg dma_config_##n = {	\
		.irq_config = dma_atcdmac300_irq_config_##n,		\
		.base = DT_INST_REG_ADDR(n),				\
		.irq_num = DT_INST_IRQN(n),				\
	};								\
									\
	static struct dma_atcdmac300_data dma_data_##n;			\
									\
	DEVICE_DT_INST_DEFINE(0,					\
		dma_atcdmac300_init,					\
		NULL,							\
		&dma_data_##n,						\
		&dma_config_##n,					\
		POST_KERNEL,						\
		CONFIG_KERNEL_INIT_PRIORITY_DEVICE,			\
		&dma_atcdmac300_api);					\
									\
	static void dma_atcdmac300_irq_config_##n(void)			\
	{								\
		IRQ_CONNECT(DT_INST_IRQN(n),				\
			    1,						\
			    dma_atcdmac300_isr,				\
			    DEVICE_DT_INST_GET(n),			\
			    0);						\
	}


DT_INST_FOREACH_STATUS_OKAY(ATCDMAC300_INIT)
