/* Wrapper for DMA channel allocator that starts clocks etc */

#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <mach/dma.h>
#include <hwregs/reg_map.h>
#include <hwregs/reg_rdwr.h>
#include <hwregs/marb_defs.h>
#include <hwregs/clkgen_defs.h>
#include <hwregs/strmux_defs.h>
#include <linux/errno.h>
#include <arbiter.h>

static char used_dma_channels[MAX_DMA_CHANNELS];
static const char *used_dma_channels_users[MAX_DMA_CHANNELS];

static DEFINE_SPINLOCK(dma_lock);

int crisv32_request_dma(unsigned int dmanr, const char *device_id,
	unsigned options, unsigned int bandwidth, enum dma_owner owner)
{
	unsigned long flags;
	reg_clkgen_rw_clk_ctrl clk_ctrl;
	reg_strmux_rw_cfg strmux_cfg;

	if (crisv32_arbiter_allocate_bandwidth(dmanr,
			options & DMA_INT_MEM ? INT_REGION : EXT_REGION,
			bandwidth))
		return -ENOMEM;

	spin_lock_irqsave(&dma_lock, flags);

	if (used_dma_channels[dmanr]) {
		spin_unlock_irqrestore(&dma_lock, flags);
		if (options & DMA_VERBOSE_ON_ERROR)
			printk(KERN_ERR "Failed to request DMA %i for %s, "
				"already allocated by %s\n",
				dmanr,
				device_id,
				used_dma_channels_users[dmanr]);

		if (options & DMA_PANIC_ON_ERROR)
			panic("request_dma error!");
		spin_unlock_irqrestore(&dma_lock, flags);
		return -EBUSY;
	}
	clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
	strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);

	switch (dmanr) {
	case 0:
	case 1:
		clk_ctrl.dma0_1_eth = 1;
		break;
	case 2:
	case 3:
		clk_ctrl.dma2_3_strcop = 1;
		break;
	case 4:
	case 5:
		clk_ctrl.dma4_5_iop = 1;
		break;
	case 6:
	case 7:
		clk_ctrl.sser_ser_dma6_7 = 1;
		break;
	case 9:
	case 11:
		clk_ctrl.dma9_11 = 1;
		break;
#if MAX_DMA_CHANNELS-1 != 11
#error Check dma.c
#endif
	default:
		spin_unlock_irqrestore(&dma_lock, flags);
		if (options & DMA_VERBOSE_ON_ERROR)
			printk(KERN_ERR "Failed to request DMA %i for %s, "
				"only 0-%i valid)\n",
				dmanr, device_id, MAX_DMA_CHANNELS-1);

		if (options & DMA_PANIC_ON_ERROR)
			panic("request_dma error!");
		return -EINVAL;
	}

	switch (owner) {
	case dma_eth:
		if (dmanr == 0)
			strmux_cfg.dma0 = regk_strmux_eth;
		else if (dmanr == 1)
			strmux_cfg.dma1 = regk_strmux_eth;
		else
			panic("Invalid DMA channel for eth\n");
		break;
	case dma_ser0:
		if (dmanr == 0)
			strmux_cfg.dma0 = regk_strmux_ser0;
		else if (dmanr == 1)
			strmux_cfg.dma1 = regk_strmux_ser0;
		else
			panic("Invalid DMA channel for ser0\n");
		break;
	case dma_ser3:
		if (dmanr == 2)
			strmux_cfg.dma2 = regk_strmux_ser3;
		else if (dmanr == 3)
			strmux_cfg.dma3 = regk_strmux_ser3;
		else
			panic("Invalid DMA channel for ser3\n");
		break;
	case dma_strp:
		if (dmanr == 2)
			strmux_cfg.dma2 = regk_strmux_strcop;
		else if (dmanr == 3)
			strmux_cfg.dma3 = regk_strmux_strcop;
		else
			panic("Invalid DMA channel for strp\n");
		break;
	case dma_ser1:
		if (dmanr == 4)
			strmux_cfg.dma4 = regk_strmux_ser1;
		else if (dmanr == 5)
			strmux_cfg.dma5 = regk_strmux_ser1;
		else
			panic("Invalid DMA channel for ser1\n");
		break;
	case dma_iop:
		if (dmanr == 4)
			strmux_cfg.dma4 = regk_strmux_iop;
		else if (dmanr == 5)
			strmux_cfg.dma5 = regk_strmux_iop;
		else
			panic("Invalid DMA channel for iop\n");
		break;
	case dma_ser2:
		if (dmanr == 6)
			strmux_cfg.dma6 = regk_strmux_ser2;
		else if (dmanr == 7)
			strmux_cfg.dma7 = regk_strmux_ser2;
		else
			panic("Invalid DMA channel for ser2\n");
		break;
	case dma_sser:
		if (dmanr == 6)
			strmux_cfg.dma6 = regk_strmux_sser;
		else if (dmanr == 7)
			strmux_cfg.dma7 = regk_strmux_sser;
		else
			panic("Invalid DMA channel for sser\n");
		break;
	case dma_ser4:
		if (dmanr == 9)
			strmux_cfg.dma9 = regk_strmux_ser4;
		else
			panic("Invalid DMA channel for ser4\n");
		break;
	case dma_jpeg:
		if (dmanr == 9)
			strmux_cfg.dma9 = regk_strmux_jpeg;
		else
			panic("Invalid DMA channel for JPEG\n");
		break;
	case dma_h264:
		if (dmanr == 11)
			strmux_cfg.dma11 = regk_strmux_h264;
		else
			panic("Invalid DMA channel for H264\n");
		break;
	}

	used_dma_channels[dmanr] = 1;
	used_dma_channels_users[dmanr] = device_id;
	REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
	REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
	spin_unlock_irqrestore(&dma_lock, flags);
	return 0;
}

void crisv32_free_dma(unsigned int dmanr)
{
	spin_lock(&dma_lock);
	used_dma_channels[dmanr] = 0;
	spin_unlock(&dma_lock);
}
