/*
 * Copyright (c) 2018 Google LLC.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT atmel_sam0_dmac

#include <zephyr/device.h>
#include <soc.h>
#include <zephyr/drivers/dma.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(dma_sam0, CONFIG_DMA_LOG_LEVEL);

#define DMA_REGS	((Dmac *)DT_INST_REG_ADDR(0))

struct dma_sam0_channel {
	dma_callback_t cb;
	void *user_data;
};

struct dma_sam0_data {
	__aligned(16) DmacDescriptor descriptors[DMAC_CH_NUM];
	__aligned(16) DmacDescriptor descriptors_wb[DMAC_CH_NUM];
	struct dma_sam0_channel channels[DMAC_CH_NUM];
};

/* Handles DMA interrupts and dispatches to the individual channel */
static void dma_sam0_isr(const struct device *dev)
{
	struct dma_sam0_data *data = dev->data;
	struct dma_sam0_channel *chdata;
	uint16_t pend = DMA_REGS->INTPEND.reg;
	uint32_t channel;

	/* Acknowledge all interrupts for the channel in pend */
	DMA_REGS->INTPEND.reg = pend;

	channel = (pend & DMAC_INTPEND_ID_Msk) >> DMAC_INTPEND_ID_Pos;
	chdata = &data->channels[channel];

	if (pend & DMAC_INTPEND_TERR) {
		if (chdata->cb) {
			chdata->cb(dev, chdata->user_data,
				   channel, -DMAC_INTPEND_TERR);
		}
	} else if (pend & DMAC_INTPEND_TCMPL) {
		if (chdata->cb) {
			chdata->cb(dev, chdata->user_data, channel, 0);
		}
	}

	/*
	 * If more than one channel is pending, we'll just immediately
	 * interrupt again and handle it through a different INTPEND value.
	 */
}

/* Configure a channel */
static int dma_sam0_config(const struct device *dev, uint32_t channel,
			   struct dma_config *config)
{
	struct dma_sam0_data *data = dev->data;
	DmacDescriptor *desc = &data->descriptors[channel];
	struct dma_block_config *block = config->head_block;
	struct dma_sam0_channel *channel_control;
	DMAC_BTCTRL_Type btctrl = { .reg = 0 };
	int key;

	if (channel >= DMAC_CH_NUM) {
		LOG_ERR("Unsupported channel");
		return -EINVAL;
	}

	if (config->block_count > 1) {
		LOG_ERR("Chained transfers not supported");
		/* TODO: add support for chained transfers. */
		return -ENOTSUP;
	}

	if (config->dma_slot >= DMAC_TRIG_NUM) {
		LOG_ERR("Invalid trigger number");
		return -EINVAL;
	}

	/* Lock and page in the channel configuration */
	key = irq_lock();

	/*
	 * The "bigger" DMAC on some SAM0 chips (e.g. SAMD5x) has
	 * independently accessible registers for each channel, while
	 * the other ones require an indirect channel selection before
	 * accessing shared registers.  The simplest way to detect the
	 * difference is the presence of the DMAC_CHID_ID macro from the
	 * ASF HAL (i.e. it's only defined if indirect access is required).
	 */
#ifdef DMAC_CHID_ID
	/* Select the channel for configuration */
	DMA_REGS->CHID.reg = DMAC_CHID_ID(channel);
	DMA_REGS->CHCTRLA.reg = 0;

	/* Connect the peripheral trigger */
	if (config->channel_direction == MEMORY_TO_MEMORY) {
		/*
		 * A single software trigger will start the
		 * transfer
		 */
		DMA_REGS->CHCTRLB.reg = DMAC_CHCTRLB_TRIGACT_TRANSACTION |
				    DMAC_CHCTRLB_TRIGSRC(config->dma_slot);
	} else {
		/* One peripheral trigger per beat */
		DMA_REGS->CHCTRLB.reg = DMAC_CHCTRLB_TRIGACT_BEAT |
				    DMAC_CHCTRLB_TRIGSRC(config->dma_slot);
	}

	/* Set the priority */
	if (config->channel_priority >= DMAC_LVL_NUM) {
		LOG_ERR("Invalid priority");
		goto inval;
	}

	DMA_REGS->CHCTRLB.bit.LVL = config->channel_priority;

	/* Enable the interrupts */
	DMA_REGS->CHINTENSET.reg = DMAC_CHINTENSET_TCMPL;
	if (!config->error_callback_en) {
		DMA_REGS->CHINTENSET.reg = DMAC_CHINTENSET_TERR;
	} else {
		DMA_REGS->CHINTENCLR.reg = DMAC_CHINTENSET_TERR;
	}

	DMA_REGS->CHINTFLAG.reg = DMAC_CHINTFLAG_TERR | DMAC_CHINTFLAG_TCMPL;
#else
	/* Channels have separate configuration registers */
	DmacChannel * chcfg = &DMA_REGS->Channel[channel];

	if (config->channel_direction == MEMORY_TO_MEMORY) {
		/*
		 * A single software trigger will start the
		 * transfer
		 */
		chcfg->CHCTRLA.reg = DMAC_CHCTRLA_TRIGACT_TRANSACTION |
				     DMAC_CHCTRLA_TRIGSRC(config->dma_slot);
	} else if ((config->channel_direction == MEMORY_TO_PERIPHERAL) ||
		(config->channel_direction == PERIPHERAL_TO_MEMORY)) {
		/* One peripheral trigger per beat */
		chcfg->CHCTRLA.reg = DMAC_CHCTRLA_TRIGACT_BURST |
				     DMAC_CHCTRLA_TRIGSRC(config->dma_slot);
	} else {
		LOG_ERR("Direction error. %d", config->channel_direction);
		goto inval;
	}

	/* Set the priority */
	if (config->channel_priority >= DMAC_LVL_NUM) {
		LOG_ERR("Invalid priority");
		goto inval;
	}

	chcfg->CHPRILVL.bit.PRILVL = config->channel_priority;

	/* Set the burst length */
	if (config->source_burst_length != config->dest_burst_length) {
		LOG_ERR("Source and destination burst lengths must be equal");
		goto inval;
	}

	if (config->source_burst_length > 16U) {
		LOG_ERR("Invalid burst length");
		goto inval;
	}

	if (config->source_burst_length > 0U) {
		chcfg->CHCTRLA.reg |= DMAC_CHCTRLA_BURSTLEN(
			config->source_burst_length - 1U);
	}

	/* Enable the interrupts */
	chcfg->CHINTENSET.reg = DMAC_CHINTENSET_TCMPL;
	if (!config->error_callback_en) {
		chcfg->CHINTENSET.reg = DMAC_CHINTENSET_TERR;
	} else {
		chcfg->CHINTENCLR.reg = DMAC_CHINTENSET_TERR;
	}

	chcfg->CHINTFLAG.reg = DMAC_CHINTFLAG_TERR | DMAC_CHINTFLAG_TCMPL;
#endif

	/* Set the beat (single transfer) size */
	if (config->source_data_size != config->dest_data_size) {
		LOG_ERR("Source and destination data sizes must be equal");
		goto inval;
	}

	switch (config->source_data_size) {
	case 1:
		btctrl.bit.BEATSIZE = DMAC_BTCTRL_BEATSIZE_BYTE_Val;
		break;
	case 2:
		btctrl.bit.BEATSIZE = DMAC_BTCTRL_BEATSIZE_HWORD_Val;
		break;
	case 4:
		btctrl.bit.BEATSIZE = DMAC_BTCTRL_BEATSIZE_WORD_Val;
		break;
	default:
		LOG_ERR("Invalid data size");
		goto inval;
	}

	/* Set up the one and only block */
	desc->BTCNT.reg = block->block_size / config->source_data_size;
	desc->DESCADDR.reg = 0;

	/* Set the automatic source / dest increment */
	switch (block->source_addr_adj) {
	case DMA_ADDR_ADJ_INCREMENT:
		desc->SRCADDR.reg = block->source_address + block->block_size;
		btctrl.bit.SRCINC = 1;
		break;
	case DMA_ADDR_ADJ_NO_CHANGE:
		desc->SRCADDR.reg = block->source_address;
		break;
	default:
		LOG_ERR("Invalid source increment");
		goto inval;
	}

	switch (block->dest_addr_adj) {
	case DMA_ADDR_ADJ_INCREMENT:
		desc->DSTADDR.reg = block->dest_address + block->block_size;
		btctrl.bit.DSTINC = 1;
		break;
	case DMA_ADDR_ADJ_NO_CHANGE:
		desc->DSTADDR.reg = block->dest_address;
		break;
	default:
		LOG_ERR("Invalid destination increment");
		goto inval;
	}

	btctrl.bit.VALID = 1;
	desc->BTCTRL = btctrl;

	channel_control = &data->channels[channel];
	channel_control->cb = config->dma_callback;
	channel_control->user_data = config->user_data;

	LOG_DBG("Configured channel %d for %08X to %08X (%u)",
		channel,
		block->source_address,
		block->dest_address,
		block->block_size);

	irq_unlock(key);
	return 0;

inval:
	irq_unlock(key);
	return -EINVAL;
}

static int dma_sam0_start(const struct device *dev, uint32_t channel)
{
	int key = irq_lock();

	ARG_UNUSED(dev);

#ifdef DMAC_CHID_ID
	DMA_REGS->CHID.reg = channel;
	DMA_REGS->CHCTRLA.reg = DMAC_CHCTRLA_ENABLE;

	if (DMA_REGS->CHCTRLB.bit.TRIGSRC == 0) {
		/* Trigger via software */
		DMA_REGS->SWTRIGCTRL.reg = 1U << channel;
	}

#else
	DmacChannel * chcfg = &DMA_REGS->Channel[channel];

	chcfg->CHCTRLA.bit.ENABLE = 1;

	if (chcfg->CHCTRLA.bit.TRIGSRC == 0) {
		/* Trigger via software */
		DMA_REGS->SWTRIGCTRL.reg = 1U << channel;
	}
#endif

	irq_unlock(key);

	return 0;
}

static int dma_sam0_stop(const struct device *dev, uint32_t channel)
{
	int key = irq_lock();

	ARG_UNUSED(dev);

#ifdef DMAC_CHID_ID
	DMA_REGS->CHID.reg = channel;
	DMA_REGS->CHCTRLA.reg = 0;
#else
	DmacChannel * chcfg = &DMA_REGS->Channel[channel];

	chcfg->CHCTRLA.bit.ENABLE = 0;
#endif

	irq_unlock(key);

	return 0;
}

static int dma_sam0_reload(const struct device *dev, uint32_t channel,
			   uint32_t src, uint32_t dst, size_t size)
{
	struct dma_sam0_data *data = dev->data;
	DmacDescriptor *desc = &data->descriptors[channel];
	int key = irq_lock();

	switch (desc->BTCTRL.bit.BEATSIZE) {
	case DMAC_BTCTRL_BEATSIZE_BYTE_Val:
		desc->BTCNT.reg = size;
		break;
	case DMAC_BTCTRL_BEATSIZE_HWORD_Val:
		desc->BTCNT.reg = size / 2U;
		break;
	case DMAC_BTCTRL_BEATSIZE_WORD_Val:
		desc->BTCNT.reg = size / 4U;
		break;
	default:
		goto inval;
	}

	if (desc->BTCTRL.bit.SRCINC) {
		desc->SRCADDR.reg = src + size;
	} else {
		desc->SRCADDR.reg = src;
	}

	if (desc->BTCTRL.bit.DSTINC) {
		desc->DSTADDR.reg = dst + size;
	} else {
		desc->DSTADDR.reg = dst;
	}

	LOG_DBG("Reloaded channel %d for %08X to %08X (%u)",
		channel, src, dst, size);

	irq_unlock(key);
	return 0;

inval:
	irq_unlock(key);
	return -EINVAL;
}

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

	if (channel >= DMAC_CH_NUM || stat == NULL) {
		return -EINVAL;
	}

	act = DMA_REGS->ACTIVE.reg;
	if ((act & DMAC_ACTIVE_ABUSY) &&
	    ((act & DMAC_ACTIVE_ID_Msk) >> DMAC_ACTIVE_ID_Pos) == channel) {
		stat->busy = true;
		stat->pending_length = (act & DMAC_ACTIVE_BTCNT_Msk) >>
				       DMAC_ACTIVE_BTCNT_Pos;
	} else {
		stat->busy = false;
		stat->pending_length = data->descriptors_wb[channel].BTCNT.reg;
	}

	switch (data->descriptors[channel].BTCTRL.bit.BEATSIZE) {
	case DMAC_BTCTRL_BEATSIZE_BYTE_Val:
		break;
	case DMAC_BTCTRL_BEATSIZE_HWORD_Val:
		stat->pending_length *= 2U;
		break;
	case DMAC_BTCTRL_BEATSIZE_WORD_Val:
		stat->pending_length *= 4U;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

#define DMA_SAM0_IRQ_CONNECT(n)						 \
	do {								 \
		IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, n, irq),		 \
			    DT_INST_IRQ_BY_IDX(0, n, priority),		 \
			    dma_sam0_isr, DEVICE_DT_INST_GET(0), 0);	 \
		irq_enable(DT_INST_IRQ_BY_IDX(0, n, irq));		 \
	} while (0)

static int dma_sam0_init(const struct device *dev)
{
	struct dma_sam0_data *data = dev->data;

	/* Enable clocks. */
#ifdef MCLK
	MCLK->AHBMASK.bit.DMAC_ = 1;
#else
	PM->AHBMASK.bit.DMAC_ = 1;
	PM->APBBMASK.bit.DMAC_ = 1;
#endif

	/* Set up the descriptor and write back addresses */
	DMA_REGS->BASEADDR.reg = (uintptr_t)&data->descriptors;
	DMA_REGS->WRBADDR.reg = (uintptr_t)&data->descriptors_wb;

	/* Statically map each level to the same numeric priority */
	DMA_REGS->PRICTRL0.reg =
		DMAC_PRICTRL0_LVLPRI0(0) | DMAC_PRICTRL0_LVLPRI1(1) |
		DMAC_PRICTRL0_LVLPRI2(2) | DMAC_PRICTRL0_LVLPRI3(3);

	/* Enable the unit and enable all priorities */
	DMA_REGS->CTRL.reg = DMAC_CTRL_DMAENABLE | DMAC_CTRL_LVLEN(0x0F);

#if DT_INST_IRQ_HAS_CELL(0, irq)
	DMA_SAM0_IRQ_CONNECT(0);
#endif
#if DT_INST_IRQ_HAS_IDX(0, 1)
	DMA_SAM0_IRQ_CONNECT(1);
#endif
#if DT_INST_IRQ_HAS_IDX(0, 2)
	DMA_SAM0_IRQ_CONNECT(2);
#endif
#if DT_INST_IRQ_HAS_IDX(0, 3)
	DMA_SAM0_IRQ_CONNECT(3);
#endif
#if DT_INST_IRQ_HAS_IDX(0, 4)
	DMA_SAM0_IRQ_CONNECT(4);
#endif

	return 0;
}

static struct dma_sam0_data dmac_data;

static const struct dma_driver_api dma_sam0_api = {
	.config = dma_sam0_config,
	.start = dma_sam0_start,
	.stop = dma_sam0_stop,
	.reload = dma_sam0_reload,
	.get_status = dma_sam0_get_status,
};

DEVICE_DT_INST_DEFINE(0, &dma_sam0_init, NULL,
		    &dmac_data, NULL, PRE_KERNEL_1,
		    CONFIG_DMA_INIT_PRIORITY, &dma_sam0_api);
