/*
 * Copyright (C) 2008 by NXP Semiconductors
 * @Author: Kevin Wells
 * @Descr: LPC3250 DMA controller interface support functions
 *
 * Copyright (c) 2015 Tyco Fire Protection Products.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <errno.h>
#include <asm/arch/dma.h>
#include <asm/arch/cpu.h>
#include <asm/arch/clk.h>
#include <asm/arch/sys_proto.h>
#include <asm/io.h>

/* DMA controller channel register structure */
struct dmac_chan_reg {
	u32 src_addr;
	u32 dest_addr;
	u32 lli;
	u32 control;
	u32 config_ch;
	u32 reserved[3];
};

/* DMA controller register structures */
struct dma_reg {
	u32 int_stat;
	u32 int_tc_stat;
	u32 int_tc_clear;
	u32 int_err_stat;
	u32 int_err_clear;
	u32 raw_tc_stat;
	u32 raw_err_stat;
	u32 chan_enable;
	u32 sw_burst_req;
	u32 sw_single_req;
	u32 sw_last_burst_req;
	u32 sw_last_single_req;
	u32 config;
	u32 sync;
	u32 reserved[50];
	struct dmac_chan_reg dma_chan[8];
};

#define DMA_NO_OF_CHANNELS	8

/* config register definitions */
#define DMAC_CTRL_ENABLE	(1 << 0) /* For enabling the DMA controller */

static u32 alloc_ch;

static struct dma_reg *dma = (struct dma_reg *)DMA_BASE;

int lpc32xx_dma_get_channel(void)
{
	int i;

	if (!alloc_ch) { /* First time caller */
		/*
		 * DMA clock are enable by "lpc32xx_dma_init()" and should
		 * be call by board "board_early_init_f()" function.
		 */

		/*
		 * Make sure DMA controller and all channels are disabled.
		 * Controller is in little-endian mode. Disable sync signals.
		 */
		writel(0, &dma->config);
		writel(0, &dma->sync);

		/* Clear interrupt and error statuses */
		writel(0xFF, &dma->int_tc_clear);
		writel(0xFF, &dma->raw_tc_stat);
		writel(0xFF, &dma->int_err_clear);
		writel(0xFF, &dma->raw_err_stat);

		/* Enable DMA controller */
		writel(DMAC_CTRL_ENABLE, &dma->config);
	}

	i = ffz(alloc_ch);

	/* Check if all the available channels are busy */
	if (unlikely(i == DMA_NO_OF_CHANNELS))
		return -1;
	alloc_ch |= BIT_MASK(i);
	return i;
}

int lpc32xx_dma_start_xfer(unsigned int channel,
			   const struct lpc32xx_dmac_ll *desc, u32 config)
{
	if (unlikely(((BIT_MASK(channel) & alloc_ch) == 0) ||
		     (channel >= DMA_NO_OF_CHANNELS))) {
		error("Request for xfer on unallocated channel %d", channel);
		return -1;
	}
	writel(BIT_MASK(channel), &dma->int_tc_clear);
	writel(BIT_MASK(channel), &dma->int_err_clear);
	writel(desc->dma_src, &dma->dma_chan[channel].src_addr);
	writel(desc->dma_dest, &dma->dma_chan[channel].dest_addr);
	writel(desc->next_lli, &dma->dma_chan[channel].lli);
	writel(desc->next_ctrl, &dma->dma_chan[channel].control);
	writel(config, &dma->dma_chan[channel].config_ch);

	return 0;
}

int lpc32xx_dma_wait_status(unsigned int channel)
{
	unsigned long start;
	u32 reg;

	/* Check if given channel is valid */
	if (unlikely(channel >= DMA_NO_OF_CHANNELS)) {
		error("Request for status on unallocated channel %d", channel);
		return -1;
	}

	start = get_timer(0);
	while (1) {
		reg = readl(&dma->raw_tc_stat);
		reg |= readl(dma->raw_err_stat);
		if (reg & BIT_MASK(channel))
			break;

		if (get_timer(start) > CONFIG_SYS_HZ) {
			error("DMA status timeout channel %d\n", channel);
			return -ETIMEDOUT;
		}
		udelay(1);
	}

	if (unlikely(readl(&dma->raw_err_stat) & BIT_MASK(channel))) {
		setbits_le32(&dma->int_err_clear, BIT_MASK(channel));
		setbits_le32(&dma->raw_err_stat, BIT_MASK(channel));
		error("DMA error on channel %d\n", channel);
		return -1;
	}
	setbits_le32(&dma->int_tc_clear, BIT_MASK(channel));
	setbits_le32(&dma->raw_tc_stat, BIT_MASK(channel));
	return 0;
}
