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

#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <asm/dma.h>
#include <hwregs/reg_map.h>
#include <hwregs/reg_rdwr.h>
#include <hwregs/marb_defs.h>
#include <hwregs/config_defs.h>
#include <hwregs/strmux_defs.h>
#include <linux/errno.h>
#include <mach/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_config_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!");
		return -EBUSY;
	}
	clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
	strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);

	switch (dmanr) {
	case 0:
	case 1:
		clk_ctrl.dma01_eth0 = 1;
		break;
	case 2:
	case 3:
		clk_ctrl.dma23 = 1;
		break;
	case 4:
	case 5:
		clk_ctrl.dma45 = 1;
		break;
	case 6:
	case 7:
		clk_ctrl.dma67 = 1;
		break;
	case 8:
	case 9:
		clk_ctrl.dma89_strcop = 1;
		break;
#if MAX_DMA_CHANNELS-1 != 9
#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_eth0:
		if (dmanr == 0)
			strmux_cfg.dma0 = regk_strmux_eth0;
		else if (dmanr == 1)
			strmux_cfg.dma1 = regk_strmux_eth0;
		else
			panic("Invalid DMA channel for eth0\n");
		break;
	case dma_eth1:
		if (dmanr == 6)
			strmux_cfg.dma6 = regk_strmux_eth1;
		else if (dmanr == 7)
			strmux_cfg.dma7 = regk_strmux_eth1;
		else
			panic("Invalid DMA channel for eth1\n");
		break;
	case dma_iop0:
		if (dmanr == 2)
			strmux_cfg.dma2 = regk_strmux_iop0;
		else if (dmanr == 3)
			strmux_cfg.dma3 = regk_strmux_iop0;
		else
			panic("Invalid DMA channel for iop0\n");
		break;
	case dma_iop1:
		if (dmanr == 4)
			strmux_cfg.dma4 = regk_strmux_iop1;
		else if (dmanr == 5)
			strmux_cfg.dma5 = regk_strmux_iop1;
		else
			panic("Invalid DMA channel for iop1\n");
		break;
	case dma_ser0:
		if (dmanr == 6)
			strmux_cfg.dma6 = regk_strmux_ser0;
		else if (dmanr == 7)
			strmux_cfg.dma7 = regk_strmux_ser0;
		else
			panic("Invalid DMA channel for ser0\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_ser2:
		if (dmanr == 2)
			strmux_cfg.dma2 = regk_strmux_ser2;
		else if (dmanr == 3)
			strmux_cfg.dma3 = regk_strmux_ser2;
		else
			panic("Invalid DMA channel for ser2\n");
		break;
	case dma_ser3:
		if (dmanr == 8)
			strmux_cfg.dma8 = regk_strmux_ser3;
		else if (dmanr == 9)
			strmux_cfg.dma9 = regk_strmux_ser3;
		else
			panic("Invalid DMA channel for ser3\n");
		break;
	case dma_sser0:
		if (dmanr == 4)
			strmux_cfg.dma4 = regk_strmux_sser0;
		else if (dmanr == 5)
			strmux_cfg.dma5 = regk_strmux_sser0;
		else
			panic("Invalid DMA channel for sser0\n");
		break;
	case dma_sser1:
		if (dmanr == 6)
			strmux_cfg.dma6 = regk_strmux_sser1;
		else if (dmanr == 7)
			strmux_cfg.dma7 = regk_strmux_sser1;
		else
			panic("Invalid DMA channel for sser1\n");
		break;
	case dma_ata:
		if (dmanr == 2)
			strmux_cfg.dma2 = regk_strmux_ata;
		else if (dmanr == 3)
			strmux_cfg.dma3 = regk_strmux_ata;
		else
			panic("Invalid DMA channel for ata\n");
		break;
	case dma_strp:
		if (dmanr == 8)
			strmux_cfg.dma8 = regk_strmux_strcop;
		else if (dmanr == 9)
			strmux_cfg.dma9 = regk_strmux_strcop;
		else
			panic("Invalid DMA channel for strp\n");
		break;
	case dma_ext0:
		if (dmanr == 6)
			strmux_cfg.dma6 = regk_strmux_ext0;
		else
			panic("Invalid DMA channel for ext0\n");
		break;
	case dma_ext1:
		if (dmanr == 7)
			strmux_cfg.dma7 = regk_strmux_ext1;
		else
			panic("Invalid DMA channel for ext1\n");
		break;
	case dma_ext2:
		if (dmanr == 2)
			strmux_cfg.dma2 = regk_strmux_ext2;
		else if (dmanr == 8)
			strmux_cfg.dma8 = regk_strmux_ext2;
		else
			panic("Invalid DMA channel for ext2\n");
		break;
	case dma_ext3:
		if (dmanr == 3)
			strmux_cfg.dma3 = regk_strmux_ext3;
		else if (dmanr == 9)
			strmux_cfg.dma9 = regk_strmux_ext2;
		else
			panic("Invalid DMA channel for ext2\n");
		break;
	}

	used_dma_channels[dmanr] = 1;
	used_dma_channels_users[dmanr] = device_id;
	REG_WR(config, regi_config, 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);
}
