/*
 * Copyright (c) 2022 Intel 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>
#include <soc.h>
#include "dma_dw_common.h"

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

/* number of tries to wait for reset */
#define DW_DMA_CFG_TRIES	10000

void dw_dma_isr(const struct device *dev)
{
	const struct dw_dma_dev_cfg *const dev_cfg = dev->config;
	struct dw_dma_dev_data *const dev_data = dev->data;
	struct dw_dma_chan_data *chan_data;

	uint32_t status_tfr = 0U;
	uint32_t status_block = 0U;
	uint32_t status_err = 0U;
	uint32_t status_intr;
	uint32_t channel;

	status_intr = dw_read(dev_cfg->base, DW_INTR_STATUS);
	if (!status_intr) {
		LOG_ERR("status_intr = %d", status_intr);
	}

	/* get the source of our IRQ. */
	status_block = dw_read(dev_cfg->base, DW_STATUS_BLOCK);
	status_tfr = dw_read(dev_cfg->base, DW_STATUS_TFR);

	/* TODO: handle errors, just clear them atm */
	status_err = dw_read(dev_cfg->base, DW_STATUS_ERR);
	if (status_err) {
		LOG_ERR("status_err = %d\n", status_err);
		dw_write(dev_cfg->base, DW_CLEAR_ERR, status_err);
	}

	/* clear interrupts */
	dw_write(dev_cfg->base, DW_CLEAR_BLOCK, status_block);
	dw_write(dev_cfg->base, DW_CLEAR_TFR, status_tfr);

	/* Dispatch callbacks for channels depending upon the bit set */
	while (status_block) {
		channel = find_lsb_set(status_block) - 1;
		status_block &= ~(1 << channel);
		chan_data = &dev_data->chan[channel];

		if (chan_data->dma_blkcallback) {
			LOG_DBG("Dispatching block complete callback");

			/* Ensure the linked list (chan_data->lli) is
			 * freed in the user callback function once
			 * all the blocks are transferred.
			 */
			chan_data->dma_blkcallback(dev,
						   chan_data->blkuser_data,
						   channel, 0);
		}
	}

	while (status_tfr) {
		channel = find_lsb_set(status_tfr) - 1;
		status_tfr &= ~(1 << channel);
		chan_data = &dev_data->chan[channel];

		/* Transfer complete, channel now idle, a reload
		 * could safely occur in the callback via dma_config
		 * and dma_start
		 */
		chan_data->state = DW_DMA_IDLE;

		if (chan_data->dma_tfrcallback) {
			LOG_DBG("Dispatching transfer callback");
			chan_data->dma_tfrcallback(dev,
						   chan_data->tfruser_data,
						   channel, 0);
		}
	}
}


/* mask address for dma to identify memory space. */
static void dw_dma_mask_address(struct dma_block_config *block_cfg,
				struct dw_lli *lli_desc, uint32_t direction)
{
	lli_desc->sar = block_cfg->source_address;
	lli_desc->dar = block_cfg->dest_address;

	switch (direction) {
	case MEMORY_TO_PERIPHERAL:
		lli_desc->sar |= CONFIG_DMA_DW_HOST_MASK;
		break;
	case PERIPHERAL_TO_MEMORY:
		lli_desc->dar |= CONFIG_DMA_DW_HOST_MASK;
		break;
	case MEMORY_TO_MEMORY:
		lli_desc->sar |= CONFIG_DMA_DW_HOST_MASK;
		lli_desc->dar |= CONFIG_DMA_DW_HOST_MASK;
		break;
	default:
		break;
	}
}

int dw_dma_config(const struct device *dev, uint32_t channel,
			 struct dma_config *cfg)
{
	const struct dw_dma_dev_cfg *const dev_cfg = dev->config;
	struct dw_dma_dev_data *const dev_data = dev->data;
	struct dma_block_config *block_cfg;


	struct dw_lli *lli_desc;
	struct dw_lli *lli_desc_head;
	struct dw_lli *lli_desc_tail;
	uint32_t msize = 3;/* default msize, 8 bytes */
	int ret = 0;

	if (channel >= DW_MAX_CHAN) {
		LOG_ERR("%s: invalid dma channel %d", __func__, channel);
		ret = -EINVAL;
		goto out;
	}

	struct dw_dma_chan_data *chan_data = &dev_data->chan[channel];

	if (chan_data->state != DW_DMA_IDLE && chan_data->state != DW_DMA_PREPARED) {
		LOG_ERR("%s: dma %s channel %d must be inactive to "
			"reconfigure, currently %d", __func__, dev->name,
			channel, chan_data->state);
		ret = -EBUSY;
		goto out;
	}

	LOG_DBG("%s: dma %s channel %d config",
	       __func__, dev->name, channel);

	__ASSERT_NO_MSG(cfg->source_data_size == cfg->dest_data_size);
	__ASSERT_NO_MSG(cfg->source_burst_length == cfg->dest_burst_length);
	__ASSERT_NO_MSG(cfg->block_count > 0);
	__ASSERT_NO_MSG(cfg->head_block != NULL);

	if (cfg->source_data_size != 1 && cfg->source_data_size != 2 &&
	    cfg->source_data_size != 4 && cfg->source_data_size != 8 &&
	    cfg->source_data_size != 16) {
		LOG_ERR("%s: dma %s channel %d 'invalid source_data_size' value %d",
			__func__, dev->name, channel, cfg->source_data_size);
		ret = -EINVAL;
		goto out;
	}

	if (cfg->block_count > CONFIG_DMA_DW_LLI_POOL_SIZE) {
		LOG_ERR("%s: dma %s channel %d scatter gather list larger than"
			" descriptors in pool, consider increasing CONFIG_DMA_DW_LLI_POOL_SIZE",
			__func__, dev->name, channel);
		ret = -EINVAL;
		goto out;
	}

	/* burst_size = (2 ^ msize) */
	msize = find_msb_set(cfg->source_burst_length) - 1;
	LOG_DBG("%s: dma %s channel %d m_size=%d", __func__, dev->name, channel, msize);
	__ASSERT_NO_MSG(msize < 5);

	/* default channel config */
	chan_data->direction = cfg->channel_direction;


	/* setup a list of lli structs. we don't need to allocate */
	chan_data->lli = &dev_data->lli_pool[channel][0]; /* TODO allocate here */
	chan_data->lli_count = cfg->block_count;

	/* zero the scatter gather list */
	memset(chan_data->lli, 0, sizeof(struct dw_lli) * chan_data->lli_count);
	lli_desc = chan_data->lli;
	lli_desc_head = &chan_data->lli[0];
	lli_desc_tail = &chan_data->lli[chan_data->lli_count - 1];

	chan_data->ptr_data.buffer_bytes = 0;

	/* copy the scatter gather list from dma_cfg to dw_lli */
	block_cfg = cfg->head_block;
	for (int i = 0; i < cfg->block_count; i++) {
		__ASSERT_NO_MSG(block_cfg != NULL);
		LOG_DBG("copying block_cfg %p to lli_desc %p", block_cfg, lli_desc);

		/* write CTL_LO for each lli */
		switch (cfg->source_data_size) {
		case 1:
			/* byte at a time transfer */
			lli_desc->ctrl_lo |= DW_CTLL_SRC_WIDTH(0);
		case 2:
			/* non peripheral copies are optimal using words */
			switch (cfg->channel_direction) {
			case MEMORY_TO_MEMORY:
				/* config the src tr width for 32 bit words */
				lli_desc->ctrl_lo |= DW_CTLL_SRC_WIDTH(2);
				break;
			default:
				/* config the src width for 16 bit samples */
				lli_desc->ctrl_lo |= DW_CTLL_SRC_WIDTH(1);
				break;
			}
			break;
		case 4:
			/* config the src tr width for 24, 32 bit samples */
			lli_desc->ctrl_lo |= DW_CTLL_SRC_WIDTH(2);
			break;
		default:
			LOG_ERR("%s: dma %s channel %d invalid src width %d",
			       __func__, dev->name, channel, cfg->source_data_size);
			ret = -EINVAL;
			goto out;
		}

		LOG_DBG("source data size: lli_desc %p, ctrl_lo %x",
			lli_desc, lli_desc->ctrl_lo);

		switch (cfg->dest_data_size) {
		case 1:
			/* byte at a time transfer */
			lli_desc->ctrl_lo |= DW_CTLL_SRC_WIDTH(0);
		case 2:
			/* non peripheral copies are optimal using words */
			switch (cfg->channel_direction) {
			case MEMORY_TO_MEMORY:
				/* config the dest tr width for 32 bit words */
				lli_desc->ctrl_lo |= DW_CTLL_DST_WIDTH(2);
				break;
			default:
				/* config the dest width for 16 bit samples */
				lli_desc->ctrl_lo |= DW_CTLL_DST_WIDTH(1);
				break;
			}
			break;
		case 4:
			/* config the dest tr width for 24, 32 bit samples */
			lli_desc->ctrl_lo |= DW_CTLL_DST_WIDTH(2);
			break;
		default:
			LOG_ERR("%s: dma %s channel %d invalid dest width %d",
				__func__, dev->name, channel, cfg->dest_data_size);
			ret = -EINVAL;
			goto out;
		}

		LOG_DBG("dest data size: lli_desc %p, ctrl_lo %x", lli_desc, lli_desc->ctrl_lo);

		lli_desc->ctrl_lo |= DW_CTLL_SRC_MSIZE(msize) |
			DW_CTLL_DST_MSIZE(msize) |
			DW_CTLL_INT_EN; /* enable interrupt */

		LOG_DBG("msize, int_en: lli_desc %p, ctrl_lo %x", lli_desc, lli_desc->ctrl_lo);

		/* config the SINC and DINC fields of CTL_LO,
		 * SRC/DST_PER fields of CFG_HI
		 */
		switch (cfg->channel_direction) {
		case MEMORY_TO_MEMORY:
			lli_desc->ctrl_lo |= DW_CTLL_FC_M2M | DW_CTLL_SRC_INC |
				DW_CTLL_DST_INC;
#if CONFIG_DMA_DW_HW_LLI
			LOG_DBG("setting LLP_D_EN, LLP_S_EN in lli_desc->ctrl_lo %x",
				lli_desc->ctrl_lo);
			lli_desc->ctrl_lo |=
				DW_CTLL_LLP_S_EN | DW_CTLL_LLP_D_EN;
			LOG_DBG("lli_desc->ctrl_lo %x", lli_desc->ctrl_lo);
#endif
			break;
		case MEMORY_TO_PERIPHERAL:
			lli_desc->ctrl_lo |= DW_CTLL_FC_M2P | DW_CTLL_SRC_INC |
				DW_CTLL_DST_FIX;
#if CONFIG_DMA_DW_HW_LLI
			lli_desc->ctrl_lo |= DW_CTLL_LLP_S_EN;
			chan_data->cfg_lo |= DW_CFGL_RELOAD_DST;
#endif
			/* Assign a hardware handshake interface (0-15) to the
			 * destination of the channel
			 */
			chan_data->cfg_hi |= DW_CFGH_DST_PER(cfg->dma_slot);
			break;
		case PERIPHERAL_TO_MEMORY:
			lli_desc->ctrl_lo |= DW_CTLL_FC_P2M | DW_CTLL_SRC_FIX |
				DW_CTLL_DST_INC;
#if CONFIG_DMA_DW_HW_LLI
			if (!block_cfg->dest_scatter_en) {
				lli_desc->ctrl_lo |= DW_CTLL_LLP_D_EN;
			} else {
				/* Use contiguous auto-reload. Line 3 in
				 * table 3-3
				 */
				lli_desc->ctrl_lo |= DW_CTLL_D_SCAT_EN;
			}
			chan_data->cfg_lo |= DW_CFGL_RELOAD_SRC;
#endif
			/* Assign a hardware handshake interface (0-15) to the
			 * source of the channel
			 */
			chan_data->cfg_hi |= DW_CFGH_SRC_PER(cfg->dma_slot);
			break;
		default:
			LOG_ERR("%s: dma %s channel %d invalid direction %d",
			       __func__, dev->name, channel, cfg->channel_direction);
			ret = -EINVAL;
			goto out;
		}

		LOG_DBG("direction: lli_desc %p, ctrl_lo %x, cfg_hi %x, cfg_lo %x",
			lli_desc, lli_desc->ctrl_lo, chan_data->cfg_hi, chan_data->cfg_lo);

		dw_dma_mask_address(block_cfg, lli_desc, cfg->channel_direction);

		LOG_DBG("mask address: lli_desc %p, ctrl_lo %x, cfg_hi %x, cfg_lo %x",
			lli_desc, lli_desc->ctrl_lo, chan_data->cfg_hi, chan_data->cfg_lo);

		if (block_cfg->block_size > DW_CTLH_BLOCK_TS_MASK) {
			LOG_ERR("%s: dma %s channel %d block size too big %d",
			       __func__, dev->name, channel, block_cfg->block_size);
			ret = -EINVAL;
			goto out;
		}

		/* Set class and transfer size */
		lli_desc->ctrl_hi |= DW_CTLH_CLASS(dev_data->channel_data->chan[channel].class) |
			(block_cfg->block_size & DW_CTLH_BLOCK_TS_MASK);

		LOG_DBG("block_size, class: lli_desc %p, ctrl_lo %x, cfg_hi %x, cfg_lo %x",
			lli_desc, lli_desc->ctrl_lo, chan_data->cfg_hi, chan_data->cfg_lo);

		chan_data->ptr_data.buffer_bytes += block_cfg->block_size;

		/* set next descriptor in list */
		lli_desc->llp = (uint32_t)(lli_desc + 1);

		LOG_DBG("lli_desc llp %x", lli_desc->llp);

		/* next descriptor */
		lli_desc++;

		block_cfg = block_cfg->next_block;
	}

#if CONFIG_DMA_DW_HW_LLI
	chan_data->cfg_lo |= DW_CFGL_CTL_HI_UPD_EN;
#endif

	/* end of list or cyclic buffer */
	if (cfg->cyclic) {
		lli_desc_tail->llp = (uint32_t)lli_desc_head;
	} else {
		lli_desc_tail->llp = 0;
#if CONFIG_DMA_DW_HW_LLI
		LOG_DBG("Clearing LLP_S_EN, LLP_D_EN from tail LLI %x", lli_desc_tail->ctrl_lo);
		lli_desc_tail->ctrl_lo &= ~(DW_CTLL_LLP_S_EN | DW_CTLL_LLP_D_EN);
		LOG_DBG("ctrl_lo %x", lli_desc_tail->ctrl_lo);
#endif
	}

	/* set the initial lli, mark the channel as prepared (ready to be started) */
	chan_data->state = DW_DMA_PREPARED;
	chan_data->lli_current = chan_data->lli;

	/* initialize pointers */
	chan_data->ptr_data.start_ptr = DW_DMA_LLI_ADDRESS(chan_data->lli,
							 chan_data->direction);
	chan_data->ptr_data.end_ptr = chan_data->ptr_data.start_ptr +
				    chan_data->ptr_data.buffer_bytes;
	chan_data->ptr_data.current_ptr = chan_data->ptr_data.start_ptr;
	chan_data->ptr_data.hw_ptr = chan_data->ptr_data.start_ptr;

	/* Configure a callback appropriately depending on whether the
	 * interrupt is requested at the end of transaction completion or
	 * at the end of each block.
	 */
	if (cfg->complete_callback_en) {
		chan_data->dma_blkcallback = cfg->dma_callback;
		chan_data->blkuser_data = cfg->user_data;
		dw_write(dev_cfg->base, DW_MASK_BLOCK, DW_CHAN_UNMASK(channel));
	} else {
		chan_data->dma_tfrcallback = cfg->dma_callback;
		chan_data->tfruser_data = cfg->user_data;
		dw_write(dev_cfg->base, DW_MASK_TFR, DW_CHAN_UNMASK(channel));
	}

	dw_write(dev_cfg->base, DW_MASK_ERR, DW_CHAN_UNMASK(channel));

	/* write interrupt clear registers for the channel
	 * ClearTfr, ClearBlock, ClearSrcTran, ClearDstTran, ClearErr
	 */
	dw_write(dev_cfg->base, DW_CLEAR_TFR, 0x1 << channel);
	dw_write(dev_cfg->base, DW_CLEAR_BLOCK, 0x1 << channel);
	dw_write(dev_cfg->base, DW_CLEAR_SRC_TRAN, 0x1 << channel);
	dw_write(dev_cfg->base, DW_CLEAR_DST_TRAN, 0x1 << channel);
	dw_write(dev_cfg->base, DW_CLEAR_ERR, 0x1 << channel);


out:
	return ret;
}

int dw_dma_start(const struct device *dev, uint32_t channel)
{
	const struct dw_dma_dev_cfg *const dev_cfg = dev->config;
	struct dw_dma_dev_data *dev_data = dev->data;
	int ret = 0;

	/* validate channel */
	if (channel >= DW_MAX_CHAN) {
		ret = -EINVAL;
		goto out;
	}

	struct dw_dma_chan_data *chan_data = &dev_data->chan[channel];

	/* validate channel state */
	if (chan_data->state != DW_DMA_PREPARED) {
		LOG_ERR("%s: dma %s channel %d not ready ena 0x%x status 0x%x",
		       __func__, dev->name, channel,
		       dw_read(dev_cfg->base, DW_DMA_CHAN_EN),
		       chan_data->state);
		ret = -EBUSY;
		goto out;
	}

	/* is valid stream */
	if (!chan_data->lli) {
		LOG_ERR("%s: dma %s channel %d invalid stream",
		       __func__, dev->name, channel);
		ret = -EINVAL;
		goto out;
	}

	struct dw_lli *lli = chan_data->lli_current;

#ifdef CONFIG_DMA_DW_HW_LLI
	/* LLP mode - write LLP pointer */

	uint32_t masked_ctrl_lo = lli->ctrl_lo & (DW_CTLL_LLP_D_EN | DW_CTLL_LLP_S_EN);
	uint32_t llp = 0;

	if (masked_ctrl_lo) {
		llp = (uint32_t)lli;
		LOG_DBG("Setting llp");
	}
	dw_write(dev_cfg->base, DW_LLP(channel), llp);
	LOG_DBG("ctrl_lo %x, masked ctrl_lo %x, LLP %x",
		lli->ctrl_lo, masked_ctrl_lo, dw_read(dev_cfg->base, DW_LLP(channel)));
#endif /* CONFIG_DMA_DW_HW_LLI */

	/* channel needs to start from scratch, so write SAR and DAR */
	dw_write(dev_cfg->base, DW_SAR(channel), lli->sar);
	dw_write(dev_cfg->base, DW_DAR(channel), lli->dar);

	/* program CTL_LO and CTL_HI */
	dw_write(dev_cfg->base, DW_CTRL_LOW(channel), lli->ctrl_lo);
	dw_write(dev_cfg->base, DW_CTRL_HIGH(channel), lli->ctrl_hi);

	/* program CFG_LO and CFG_HI */
	dw_write(dev_cfg->base, DW_CFG_LOW(channel), chan_data->cfg_lo);
	dw_write(dev_cfg->base, DW_CFG_HIGH(channel), chan_data->cfg_hi);

	LOG_DBG("start: sar %x, dar %x, ctrl_lo %x, ctrl_hi %x, cfg_lo %x, cfg_hi %x, llp %x",
		lli->sar, lli->dar, lli->ctrl_lo, lli->ctrl_hi, chan_data->cfg_lo,
		chan_data->cfg_hi, dw_read(dev_cfg->base, DW_LLP(channel))
		);

#ifdef CONFIG_DMA_DW_HW_LLI
	if (lli->ctrl_lo & DW_CTLL_D_SCAT_EN) {
		LOG_DBG("configuring DW_DSR");
		uint32_t words_per_tfr = (lli->ctrl_hi & DW_CTLH_BLOCK_TS_MASK) >>
			((lli->ctrl_lo & DW_CTLL_DST_WIDTH_MASK) >> DW_CTLL_DST_WIDTH_SHIFT);
		dw_write(dev_cfg->base, DW_DSR(channel),
			 DW_DSR_DSC(words_per_tfr) | DW_DSR_DSI(words_per_tfr));
	}
#endif /* CONFIG_DMA_DW_HW_LLI */

	chan_data->state = DW_DMA_ACTIVE;

	/* enable the channel */
	dw_write(dev_cfg->base, DW_DMA_CHAN_EN, DW_CHAN_UNMASK(channel));

out:
	return ret;
}

int dw_dma_stop(const struct device *dev, uint32_t channel)
{
	const struct dw_dma_dev_cfg *const dev_cfg = dev->config;
	struct dw_dma_dev_data *dev_data = dev->data;
	int ret = 0;

	if (channel >= DW_MAX_CHAN) {
		ret = -EINVAL;
		goto out;
	}

#if defined(CONFIG_DMA_DW_HW_LLI) || defined(CONFIG_DMA_DW_SUSPEND_DRAIN)
	struct dw_dma_chan_data *chan_data = &dev_data->chan[channel];
#endif

#ifdef CONFIG_DMA_DW_HW_LLI
	struct dw_lli *lli = chan_data->lli;
	int i;
#endif

	LOG_DBG("%s: dma %s channel %d stop",
		__func__, dev->name, channel);

	/* Validate the channel state */
	if (chan_data->state != DW_DMA_ACTIVE &&
	    chan_data->state != DW_DMA_SUSPENDED) {
		ret = -EINVAL;
		goto out;
	}

#ifdef CONFIG_DMA_DW_SUSPEND_DRAIN
	/* channel cannot be disabled right away, so first we need to)
	 * suspend it and drain the FIFO
	 */
	dw_write(dev_cfg->base, DW_CFG_LOW(channel),
		 dw_chan->cfg_lo | DW_CFGL_SUSPEND | DW_CFGL_DRAIN);

	/* now we wait for FIFO to be empty */
	bool timeout = wait_for(dw_read(dev_cfg->base, DW_CFG_LOW(channel)) & DW_CFGL_FIFO_EMPTY,
				DW_DMA_TIMEOUT, k_busy_wait(DW_DMA_TIMEOUT/10));
	if (timeout) {
		LOG_ERR("%s: dma %s channel drain time out", __func__, channel);
	}
#endif

	dw_write(dev_cfg->base, DW_DMA_CHAN_EN, DW_CHAN_MASK(channel));

#if CONFIG_DMA_DW_HW_LLI
	for (i = 0; i < chan_data->lli_count; i++) {
		lli->ctrl_hi &= ~DW_CTLH_DONE(1);
		lli++;
	}
#endif
	chan_data->state = DW_DMA_IDLE;

out:
	return 0;
}

int dw_dma_resume(const struct device *dev, uint32_t channel)
{
	const struct dw_dma_dev_cfg *const dev_cfg = dev->config;
	struct dw_dma_dev_data *dev_data = dev->data;
	int ret = 0;

	/* Validate channel index */
	if (channel >= DW_MAX_CHAN) {
		ret = -EINVAL;
		goto out;
	}

	struct dw_dma_chan_data *chan_data = &dev_data->chan[channel];

	/* Validate channel state */
	if (chan_data->state != DW_DMA_SUSPENDED) {
		ret = -EINVAL;
		goto out;
	}

	LOG_DBG("%s: dma %s channel %d resume",
		__func__, dev->name, channel);

	dw_write(dev_cfg->base, DW_CFG_LOW(channel), chan_data->cfg_lo);

	/* Channel is now active */
	chan_data->state = DW_DMA_ACTIVE;

out:
	return ret;
}

int dw_dma_suspend(const struct device *dev, uint32_t channel)
{
	const struct dw_dma_dev_cfg *const dev_cfg = dev->config;
	struct dw_dma_dev_data *dev_data = dev->data;
	int ret = 0;

	/* Validate channel index */
	if (channel >= DW_MAX_CHAN) {
		ret = -EINVAL;
		goto out;
	}

	struct dw_dma_chan_data *chan_data = &dev_data->chan[channel];

	/* Validate channel state */
	if (chan_data->state != DW_DMA_ACTIVE) {
		ret = -EINVAL;
		goto out;
	}


	LOG_DBG("%s: dma %s channel %d suspend",
		__func__, dev->name, channel);

	dw_write(dev_cfg->base, DW_CFG_LOW(channel),
		      chan_data->cfg_lo | DW_CFGL_SUSPEND);

	/* Channel is now suspended */
	chan_data->state = DW_DMA_SUSPENDED;


out:
	return ret;
}


int dw_dma_setup(const struct device *dev)
{
	const struct dw_dma_dev_cfg *const dev_cfg = dev->config;
	struct dw_dma_dev_data *const dev_data = dev->data;

	int i, ret = 0;

	/* we cannot config DMAC if DMAC has been already enabled by host */
	if (dw_read(dev_cfg->base, DW_DMA_CFG) != 0) {
		dw_write(dev_cfg->base, DW_DMA_CFG, 0x0);
	}

	for (i = DW_DMA_CFG_TRIES; i > 0; i--) {
		if (!dw_read(dev_cfg->base, DW_DMA_CFG)) {
			break;
		}
	}

	if (!i) {
		LOG_ERR("%s: dma %s setup failed",
			__func__, dev->name);
		ret = -EIO;
		goto out;
	}

	LOG_DBG("%s: dma %s", __func__, dev->name);

	for (i = 0; i <  DW_MAX_CHAN; i++) {
		dw_read(dev_cfg->base, DW_DMA_CHAN_EN);
	}


	/* enable the DMA controller */
	dw_write(dev_cfg->base, DW_DMA_CFG, 1);

	/* mask all interrupts for all 8 channels */
	dw_write(dev_cfg->base, DW_MASK_TFR, DW_CHAN_MASK_ALL);
	dw_write(dev_cfg->base, DW_MASK_BLOCK, DW_CHAN_MASK_ALL);
	dw_write(dev_cfg->base, DW_MASK_SRC_TRAN, DW_CHAN_MASK_ALL);
	dw_write(dev_cfg->base, DW_MASK_DST_TRAN, DW_CHAN_MASK_ALL);
	dw_write(dev_cfg->base, DW_MASK_ERR, DW_CHAN_MASK_ALL);

#ifdef CONFIG_DMA_DW_FIFO_PARTITION
	/* allocate FIFO partitions for each channel */
	dw_write(dev_cfg->base, DW_FIFO_PART1_HI,
		      DW_FIFO_CHx(DW_FIFO_SIZE) | DW_FIFO_CHy(DW_FIFO_SIZE));
	dw_write(dev_cfg->base, DW_FIFO_PART1_LO,
		      DW_FIFO_CHx(DW_FIFO_SIZE) | DW_FIFO_CHy(DW_FIFO_SIZE));
	dw_write(dev_cfg->base, DW_FIFO_PART0_HI,
		      DW_FIFO_CHx(DW_FIFO_SIZE) | DW_FIFO_CHy(DW_FIFO_SIZE));
	dw_write(dev_cfg->base, DW_FIFO_PART0_LO,
		      DW_FIFO_CHx(DW_FIFO_SIZE) | DW_FIFO_CHy(DW_FIFO_SIZE) |
		 DW_FIFO_UPD);
#endif /* CONFIG_DMA_DW_FIFO_PARTITION */

	/* TODO add baytrail/cherrytrail workaround */


	/* Setup context and atomics for channels */
	dev_data->dma_ctx.magic = DMA_MAGIC;
	dev_data->dma_ctx.dma_channels = DW_MAX_CHAN;
	dev_data->dma_ctx.atomic = dev_data->channels_atomic;

out:
	return ret;
}

static int dw_dma_avail_data_size(uint32_t base,
				  struct dw_dma_chan_data *chan_data,
				  uint32_t channel)
{
	int32_t read_ptr = chan_data->ptr_data.current_ptr;
	int32_t write_ptr = dw_read(base, DW_DAR(channel));
	int32_t delta = write_ptr - chan_data->ptr_data.hw_ptr;
	int size;

	chan_data->ptr_data.hw_ptr = write_ptr;

	size = write_ptr - read_ptr;

	if (size < 0) {
		size += chan_data->ptr_data.buffer_bytes;
	} else if (!size) {
		/*
		 * Buffer is either full or empty. If the DMA pointer has
		 * changed, then the DMA has filled the buffer.
		 */
		if (delta) {
			size = chan_data->ptr_data.buffer_bytes;
		} else {
			LOG_INF("%s size is 0!", __func__);
		}
	}

	LOG_DBG("DAR %x reader 0x%x free 0x%x avail 0x%x", write_ptr, read_ptr,
		chan_data->ptr_data.buffer_bytes - size, size);

	return size;
}

static int dw_dma_free_data_size(uint32_t base,
				 struct dw_dma_chan_data *chan_data,
				 uint32_t channel)
{
	int32_t read_ptr = dw_read(base, DW_SAR(channel));
	int32_t write_ptr = chan_data->ptr_data.current_ptr;
	int32_t delta = read_ptr - chan_data->ptr_data.hw_ptr;
	int size;

	chan_data->ptr_data.hw_ptr = read_ptr;

	size = read_ptr - write_ptr;
	if (size < 0) {
		size += chan_data->ptr_data.buffer_bytes;
	} else if (!size) {
		/*
		 * Buffer is either full or empty. If the DMA pointer has
		 * changed, then the DMA has emptied the buffer.
		 */
		if (delta) {
			size = chan_data->ptr_data.buffer_bytes;
		} else {
			LOG_INF("%s size is 0!", __func__);
		}
	}

	LOG_DBG("SAR %x writer 0x%x free 0x%x avail 0x%x", read_ptr, write_ptr, size,
		chan_data->ptr_data.buffer_bytes - size);

	return size;
}

int dw_dma_get_status(const struct device *dev, uint32_t channel,
		      struct dma_status *stat)
{
	struct dw_dma_dev_data *const dev_data = dev->data;
	const struct dw_dma_dev_cfg *const dev_cfg = dev->config;
	struct dw_dma_chan_data *chan_data;

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

	chan_data = &dev_data->chan[channel];

	if (chan_data->direction == MEMORY_TO_MEMORY ||
	    chan_data->direction == PERIPHERAL_TO_MEMORY) {
		stat->pending_length = dw_dma_avail_data_size(dev_cfg->base, chan_data, channel);
		stat->free = chan_data->ptr_data.buffer_bytes - stat->pending_length;

	} else {
		stat->free = dw_dma_free_data_size(dev_cfg->base, chan_data, channel);
		stat->pending_length = chan_data->ptr_data.buffer_bytes - stat->free;
	}
#if CONFIG_DMA_DW_HW_LLI
	if (!(dw_read(dev_cfg->base, DW_DMA_CHAN_EN) & DW_CHAN(channel))) {
		LOG_ERR("xrun detected");
		return -ENODATA;
	}
#endif
	return 0;
}
