/*
 * 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_dis) {
		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)
