#include <linux/init.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/sched.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <mach/c2k_dma.h>
#include <linux/dmaengine.h>
#include <linux/circ_buf.h>
#include <linux/delay.h>


#define XOR_MAX_SRC_CNT	6

#define virt_to_xor_dma(pbase, vbase, vaddr)		((pbase + ((unsigned long)vaddr - (unsigned long)vbase)))

struct comcerto_xor_device {
	struct dma_device        device;
};

struct comcerto_xor_chan {
	struct comcerto_xor_device        *device;
	struct dma_chan                 chan;
	struct tasklet_struct       irq_tasklet;
	spinlock_t                  lock;
	dma_cookie_t                completed_cookie;
};

struct comcerto_sw_xor_desc {
	struct dma_async_tx_descriptor async_tx;
	int src_cnt;
	size_t len;
	dma_addr_t dma_dest;
	dma_addr_t dma_src[XOR_MAX_SRC_CNT];
};

void *comcerto_xor_pool_virt;
dma_addr_t comcerto_xor_pool_phy;

spinlock_t	comcerto_xor_cleanup_lock;
static DECLARE_WAIT_QUEUE_HEAD(comcerto_xor_wait_queue);
static int comcerto_xor_sleeping = 0;

static int xor_rd_idx = 0;
static int xor_wr_idx = 0;
static int xor_dma_idx = 0;
static int xor_sw_rd_idx = 0;
static int xor_sw_wr_idx = 0;
static int xor_sw_wr_prev_idx = 0;
static int xor_current_batch_count = 0;

#define XOR_FDESC_COUNT 512
#if defined(CONFIG_COMCERTO_64K_PAGES)
#define XOR_SW_FDESC_COUNT 32
#else
#define XOR_SW_FDESC_COUNT XOR_FDESC_COUNT
#endif

struct timer_list comcerto_xor_timer;
#define COMPLETION_TIMEOUT      msecs_to_jiffies(100)
static int comerto_xor_timer_first = 1;

struct comcerto_xor_inbound_fdesc *xor_in_fdesc[XOR_FDESC_COUNT];
struct comcerto_xor_outbound_fdesc *xor_out_fdesc[XOR_FDESC_COUNT];
struct comcerto_sw_xor_desc     sw_xor_desc[XOR_SW_FDESC_COUNT];

struct comcerto_xor_device *comcerto_xor_dev;
struct comcerto_xor_chan   comcerto_xor_ch;
#define OWNER_XOR_FREE	1
#define OWNER_MEMCPY_FREE 2
#define OWNER_XOR_BUSY	3
#define OWNER_MEMCPY_BUSY	4
static int dma_owned = 0;
static int memcpy_processed_ongoing = 0;
static int memcpy_pending_count = 0;


//static int mdma_busy = 0;
static int mdma_done;
static spinlock_t mdma_lock;

static void *virtbase;

#define M2IO_CONTROL           (virtbase)
#define M2IO_HEAD              (virtbase + 0x4)
#define M2IO_BURST             (virtbase + 0x8)
#define M2IO_FLEN              (virtbase + 0xC)
#define M2IO_IRQ_ENABLE        (virtbase + 0x10)
#define M2IO_IRQ_STATUS        (virtbase + 0x14)
#define M2IO_RESET             (virtbase + 0x20)

#define IO2M_CONTROL           (virtbase + 0x80)
#define IO2M_HEAD              (virtbase + 0x84)
#define IO2M_BURST             (virtbase + 0x88)
#define IO2M_FLEN              (virtbase + 0x8C)
#define IO2M_IRQ_ENABLE        (virtbase + 0x90)
#define IO2M_IRQ_STATUS        (virtbase + 0x94)
#define IO2M_RESET             (virtbase + 0xA0)

#define FDONE_MASK	0x80000000

#define FLENEN          0x2

static DECLARE_WAIT_QUEUE_HEAD(mdma_memcpy_busy_queue);
static DECLARE_WAIT_QUEUE_HEAD(mdma_done_queue);

unsigned long mdma_in_desc_phy;
unsigned long mdma_out_desc_phy;

struct comcerto_memcpy_inbound_fdesc *mdma_in_desc;
struct comcerto_memcpy_outbound_fdesc *mdma_out_desc;

EXPORT_SYMBOL(mdma_in_desc);
EXPORT_SYMBOL(mdma_out_desc);

static inline void comcerto_xor_set_in_bdesc(u32 buf_idx, u32 bdesc_idx, u32 addr, u32 ctrl)
{
	xor_in_fdesc[buf_idx]->bdesc[bdesc_idx].bpointer = addr;
	xor_in_fdesc[buf_idx]->bdesc[bdesc_idx].bcontrol = ctrl;
}

static inline void comcerto_xor_set_out_bdesc(u32 buf_idx, u32 bdesc_idx, u32 addr, u32 ctrl)
{
	xor_out_fdesc[buf_idx]->bdesc[bdesc_idx].bpointer = addr;
	xor_out_fdesc[buf_idx]->bdesc[bdesc_idx].bcontrol = ctrl;
}

static void comcerto_xor_set_desc(sw_idx,  hw_idx)
{
	int i,split_no;
	u32 fstatus0 = 0;
	u32 addr;
	int split_size;
	dma_addr_t dest;
	dma_addr_t *srcs;	
	u32 block_size;
	int src_cnt;

	block_size = sw_xor_desc[sw_idx].len;
	src_cnt = sw_xor_desc[sw_idx].src_cnt;
	srcs = sw_xor_desc[sw_idx].dma_src;
	dest = sw_xor_desc[sw_idx].dma_dest;

	if(block_size != PAGE_SIZE)
		printk("%s: input buffers not %d len\n",__func__, (unsigned int)PAGE_SIZE);	

#if defined(CONFIG_COMCERTO_64K_PAGES)
	block_size = block_size/16; //to get 4K
	split_size = 16;
#else
	split_size = 1;
#endif

	for(split_no = 0 ; split_no < split_size; split_no++)
	{

		for(i = 0; i < src_cnt - 1; i++) {
			addr = (u32)sw_xor_desc[sw_idx].dma_src[i] + 4096 * split_no;
			comcerto_xor_set_in_bdesc(hw_idx, i, addr, block_size);
		}

		addr = (u32)sw_xor_desc[sw_idx].dma_src[src_cnt - 1] + 4096 * split_no;
		comcerto_xor_set_in_bdesc(hw_idx, src_cnt - 1, addr, block_size | BLAST);

		fstatus0 = 1; // New Req, reset block counter, block offset, clear scratchpad (overwrite existing data)
		fstatus0 |=  (1 << 1); // Read SP, return content of scratch pad after processing input data
		fstatus0 |=  (0 << 2); // Mode, Encode
		fstatus0 |=  (src_cnt << 4); // Number of blocks to be processed
		fstatus0 |=  (1 << 9); // Type, XOR
		fstatus0 |=  (XOR_BLOCK_SIZE_4096 << 11);

		xor_in_fdesc[hw_idx]->fcontrol = 0;
		xor_in_fdesc[hw_idx]->fstatus0 = fstatus0;
		xor_in_fdesc[hw_idx]->fstatus1 = 0;

		addr = (u32)sw_xor_desc[sw_idx].dma_dest + 4096 * split_no;
		comcerto_xor_set_out_bdesc(hw_idx, 0, addr, block_size | BLAST);

		xor_out_fdesc[hw_idx]->fcontrol = 0;
		xor_out_fdesc[hw_idx]->fstatus0 = 0;
		xor_out_fdesc[hw_idx]->fstatus1 = 0;

		hw_idx = (hw_idx + 1) % XOR_FDESC_COUNT;
	}

	xor_wr_idx = hw_idx;
}

static inline int comcerto_dma_busy(void)
{
	return (readl_relaxed(IO2M_CONTROL) & 0x1);
}

static void comcerto_xor_update_dma_head(int idx)
{
	u32 out_desc_head, in_desc_head;
	out_desc_head = virt_to_xor_dma(comcerto_xor_pool_phy, comcerto_xor_pool_virt, xor_out_fdesc[idx]);
	in_desc_head = virt_to_xor_dma(comcerto_xor_pool_phy, comcerto_xor_pool_virt, xor_in_fdesc[idx]);

	wmb();
	writel_relaxed(out_desc_head, IO2M_HEAD);
	writel_relaxed(in_desc_head, M2IO_HEAD);
}

static void comcerto_xor_update_dma_flen(int flen)
{
	wmb();
	writel_relaxed(flen, M2IO_FLEN);
	writel_relaxed(flen, IO2M_FLEN);
}

static int comcerto_xor_rb_full(void)
{
	if(CIRC_SPACE(xor_sw_wr_idx, xor_sw_rd_idx, XOR_SW_FDESC_COUNT) > 0)
		return 0;
	else
		return 1;
}

void comcerto_xor_request_wait(void)
{
	DEFINE_WAIT(wait);

	prepare_to_wait(&comcerto_xor_wait_queue, &wait, TASK_UNINTERRUPTIBLE);

	comcerto_xor_sleeping++;

	while (comcerto_xor_rb_full()) {
		spin_unlock_bh(&comcerto_xor_ch.lock);
		schedule();
		spin_lock_bh(&comcerto_xor_ch.lock);
		prepare_to_wait(&comcerto_xor_wait_queue, &wait, TASK_UNINTERRUPTIBLE);
	}

	finish_wait(&comcerto_xor_wait_queue, &wait);
	comcerto_xor_sleeping--;
}

static void comcerto_dma_process(void)
{
	unsigned long pending_count;

	if(!dma_owned || dma_owned==OWNER_XOR_FREE)
	{
		pending_count = CIRC_CNT(xor_wr_idx, xor_dma_idx, XOR_FDESC_COUNT);
		if(pending_count)
		{
			dma_owned = OWNER_XOR_BUSY;
			xor_current_batch_count = pending_count;
			comcerto_xor_update_dma_flen(pending_count);
			comcerto_xor_update_dma_head(xor_dma_idx);
		}
	}
}

static void comcerto_xor_cleanup(void)
{
	int i,j,k;
	int idx;
	int cleanup_count;
	unsigned long flags;
	int split_size;
	struct comcerto_sw_xor_desc *sw_desc;

	spin_lock_irqsave(&mdma_lock, flags);
	cleanup_count = CIRC_CNT(xor_dma_idx, xor_rd_idx, XOR_FDESC_COUNT);
	spin_unlock_irqrestore(&mdma_lock, flags);

#if defined(CONFIG_COMCERTO_64K_PAGES)
	split_size = 16;
#else
	split_size = 1;
#endif

	if(cleanup_count && (cleanup_count % split_size == 0))
	{
		for(i = 0 ; i < cleanup_count/split_size; i++)
		{
			struct dma_async_tx_descriptor *tx;

#if defined(CONFIG_COMCERTO_64K_PAGES)
			if(xor_rd_idx%16)
				printk("%s: xor_rd_idx %d not multiple of 16\n",__func__, xor_rd_idx);
#endif
			idx = xor_sw_rd_idx;
			tx = &sw_xor_desc[idx].async_tx;
			sw_desc = &sw_xor_desc[idx];

			for (j = 0; j < sw_desc->src_cnt; j++) {
				dma_unmap_page(NULL, sw_desc->dma_src[j], sw_desc->len, DMA_TO_DEVICE);
			}
			dma_unmap_page(NULL, sw_desc->dma_dest, sw_desc->len, DMA_BIDIRECTIONAL);

			comcerto_xor_ch.completed_cookie = tx->cookie;

			if (tx->callback) {
				tx->callback(tx->callback_param);
				tx->callback = NULL;
			}
			else
				printk("No Callback\n");

			smp_mb();		

			spin_lock_irqsave(&mdma_lock, flags);
			for(k = 0 ; k < split_size; k++)
			{
				xor_rd_idx = (xor_rd_idx + 1) % XOR_FDESC_COUNT;
			}
			spin_unlock_irqrestore(&mdma_lock, flags);

			xor_sw_rd_idx = (xor_sw_rd_idx + 1) % XOR_SW_FDESC_COUNT;
		}
	}
	else
	{
		if(cleanup_count)
			printk("%s: cleanup_count %d not multiple of 16\n",__func__, cleanup_count);
	}
}

static void comcerto_xor_tasklet(unsigned long data)
{
	spin_lock_bh(&comcerto_xor_ch.lock);

	comcerto_xor_cleanup();

	spin_unlock_bh(&comcerto_xor_ch.lock);
}

static void comcerto_xor_timer_fnc(unsigned long data)
{
	unsigned long           flags;

	spin_lock_irqsave(&mdma_lock, flags);

	if(comcerto_xor_sleeping)
		wake_up(&comcerto_xor_wait_queue);

	spin_unlock_irqrestore(&mdma_lock, flags);

	comcerto_xor_tasklet(0);

	mod_timer(&comcerto_xor_timer, jiffies + COMPLETION_TIMEOUT);

}


static void comcerto_xor_issue_pending(struct dma_chan *chan)
{
	unsigned long           flags;


	spin_lock_irqsave(&mdma_lock, flags);

	comcerto_dma_process();

	if(comcerto_xor_sleeping)
		wake_up(&comcerto_xor_wait_queue);

	spin_unlock_irqrestore(&mdma_lock, flags);

	comcerto_xor_tasklet(0);
}

static inline struct comcerto_sw_xor_desc *txd_to_comcerto_desc(struct dma_async_tx_descriptor *txd)
{
	return container_of(txd, struct comcerto_sw_xor_desc, async_tx);
}


static dma_cookie_t comcerto_xor_tx_submit(struct dma_async_tx_descriptor *tx)
{
	unsigned long flags;

	struct dma_chan *c = tx->chan;
	dma_cookie_t cookie;

	spin_lock_bh(&comcerto_xor_ch.lock);

	cookie = c->cookie;
	cookie++;
	if (cookie < 0)
		cookie = 1;
	tx->cookie = cookie;
	c->cookie = cookie;

	spin_lock_irqsave(&mdma_lock, flags);

	comcerto_xor_set_desc(xor_sw_wr_prev_idx, xor_wr_idx);
	xor_sw_wr_prev_idx = (xor_sw_wr_prev_idx + 1) % XOR_SW_FDESC_COUNT ;
	comcerto_dma_process();

	spin_unlock_irqrestore(&mdma_lock, flags);

	spin_unlock_bh(&comcerto_xor_ch.lock);

	if(comerto_xor_timer_first)
	{
		mod_timer(&comcerto_xor_timer, jiffies + COMPLETION_TIMEOUT);
		comerto_xor_timer_first = 0;
	}
	return cookie;
}

	struct dma_async_tx_descriptor *
comcerto_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *srcs,
		unsigned int src_cnt, size_t len, unsigned long xor_flags)
{
	int desc_idx;
	int i;

	spin_lock_bh(&comcerto_xor_ch.lock);
	if(comcerto_xor_rb_full())
	{
		comcerto_xor_request_wait();
	}

	desc_idx = xor_sw_wr_idx;
	xor_sw_wr_idx = (xor_sw_wr_idx + 1) % XOR_SW_FDESC_COUNT ;

	sw_xor_desc[desc_idx].async_tx.flags = xor_flags;
	sw_xor_desc[desc_idx].src_cnt = src_cnt;
	sw_xor_desc[desc_idx].len = len;
	sw_xor_desc[desc_idx].dma_dest = dest;
	for(i = 0; i < src_cnt; i++)
		sw_xor_desc[desc_idx].dma_src[i] = srcs[i];

	spin_unlock_bh(&comcerto_xor_ch.lock);

	return &sw_xor_desc[desc_idx].async_tx;

}


static int comcerto_xor_alloc_chan_resources(struct dma_chan *chan)
{
	int i;

	for(i = 0; i < XOR_SW_FDESC_COUNT; i++) {
		memset(&sw_xor_desc[i], 0, sizeof(struct comcerto_sw_xor_desc));
		sw_xor_desc[i].async_tx.tx_submit = comcerto_xor_tx_submit;
		sw_xor_desc[i].async_tx.cookie = 0;
		dma_async_tx_descriptor_init(&sw_xor_desc[i].async_tx, chan);
	}
	return XOR_SW_FDESC_COUNT;
}

static void comcerto_xor_free_chan_resources(struct dma_chan *chan)
{
	//TODO

	printk("*** %s ***\n",__func__);

	return;
}

static enum dma_status comcerto_xor_status(struct dma_chan *chan,
		dma_cookie_t cookie,
		struct dma_tx_state *txstate)
{
	dma_cookie_t last_used;
	dma_cookie_t last_complete;

	last_used = chan->cookie;
	last_complete = comcerto_xor_ch.completed_cookie;
	dma_set_tx_state(txstate, last_complete, last_used, 0);

	return dma_async_is_complete(cookie, last_complete, last_used);
}


#if defined(CONFIG_COMCERTO_MDMA_PROF)

unsigned int mdma_time_counter[256];
unsigned int mdma_reqtime_counter[256];
unsigned int mdma_data_counter[256];
static struct timeval last_mdma;
unsigned int init_mdma_prof = 0;
unsigned int enable_mdma_prof = 0;

void comcerto_dma_profiling_start(struct comcerto_dma_sg *sg, unsigned int len)
{
	long diff_time_us;

	if (enable_mdma_prof) {
		do_gettimeofday(&sg->start);

		if (init_mdma_prof) {
			diff_time_us = ((sg->start.tv_sec - last_mdma.tv_sec) * 1000000 + sg->start.tv_usec - last_mdma.tv_usec) >> 4;
			if (diff_time_us < 256) {
				mdma_time_counter[diff_time_us]++;
			}
			else {
				mdma_time_counter[255]++;
			}
		}

		len >>= 13;

		if (len < 256)
			mdma_data_counter[len]++;
		else
			mdma_data_counter[255]++;
	}
}

void comcerto_dma_profiling_end(struct comcerto_dma_sg *sg)
{
	long diff_time_us;

	if (enable_mdma_prof) {
		do_gettimeofday(&sg->end);

		diff_time_us = ((sg->end.tv_sec - sg->start.tv_sec) * 1000000 + sg->end.tv_usec - sg->start.tv_usec) >> 4;
		if (diff_time_us < 256) {
			mdma_reqtime_counter[diff_time_us]++;
		}
		else
			mdma_reqtime_counter[255]++;

		if (!init_mdma_prof)
			init_mdma_prof = 1;

		last_mdma = sg->end;
	}
}

#else
void comcerto_dma_profiling_start(struct comcerto_dma_sg *sg, unsigned int len) {}
void comcerto_dma_profiling_end(struct comcerto_dma_sg *sg) {}
#endif


static inline dma_addr_t dma_acp_map_page(struct comcerto_dma_sg *sg, void *p, unsigned int len, int dir, int use_acp)
{
	dma_addr_t phys_addr = virt_to_phys(p);
	dma_addr_t low, high;

	if (!use_acp)
		goto map;

	if ((phys_addr >= sg->low_phys_addr) && (phys_addr + len) < sg->high_phys_addr)
	{
		/* In range, skip mapping */
		return COMCERTO_AXI_ACP_BASE + phys_addr;
	}

	/* Try to grow window, if possible */
	if (phys_addr < sg->low_phys_addr)
		low = phys_addr & ~(COMCERTO_AXI_ACP_SIZE - 1);
	else
		low = sg->low_phys_addr;

	if ((phys_addr + len) > sg->high_phys_addr)
		high = (phys_addr + len + COMCERTO_AXI_ACP_SIZE - 1) & ~(COMCERTO_AXI_ACP_SIZE - 1);
	else
		high = sg->high_phys_addr;

	if ((high - low) <= COMCERTO_AXI_ACP_SIZE) {
		sg->low_phys_addr = low;
		sg->high_phys_addr = high;

		return COMCERTO_AXI_ACP_BASE + phys_addr;
	}

map:
	return dma_map_single(NULL, p, len, dir); //TODO add proper checks
}


int comcerto_dma_sg_add_input(struct comcerto_dma_sg *sg, void *p, unsigned int len, int use_acp)
{
	dma_addr_t phys_addr;

	if (unlikely(len > (MDMA_MAX_BUF_SIZE + 1))) {
		printk(KERN_ERR "%s: tried to add a page larger than %d kB.\n", __func__, MDMA_MAX_BUF_SIZE + 1);
		return -2;
	}

	if (len <= MDMA_MAX_BUF_SIZE) {
		if (sg->input_idx >= MDMA_INBOUND_BUF_DESC)
			return -1;

		phys_addr = dma_acp_map_page(sg, p, len, DMA_TO_DEVICE, use_acp);

		sg->in_bdesc[sg->input_idx].split = 0;
		sg->in_bdesc[sg->input_idx].phys_addr = phys_addr;
		sg->in_bdesc[sg->input_idx].len = len;
		sg->input_idx++;

		return 0;
	}
	else { /* len = MSPD_MDMA_MAX_BUF_SIZE +1, split it in 2 pieces */
		if (sg->input_idx >= (MDMA_INBOUND_BUF_DESC - 1))
			return -1;

		phys_addr = dma_acp_map_page(sg, p, len, DMA_TO_DEVICE, use_acp);

		sg->in_bdesc[sg->input_idx].split = 1;
		sg->in_bdesc[sg->input_idx].phys_addr = phys_addr;
		sg->in_bdesc[sg->input_idx].len = MDMA_SPLIT_BUF_SIZE;
		sg->input_idx++;
		sg->in_bdesc[sg->input_idx].split = 0;
		sg->in_bdesc[sg->input_idx].phys_addr = phys_addr + MDMA_SPLIT_BUF_SIZE;
		sg->in_bdesc[sg->input_idx].len = len - MDMA_SPLIT_BUF_SIZE;
		sg->input_idx++;

		return 0;
	}
}
EXPORT_SYMBOL(comcerto_dma_sg_add_input);

int comcerto_dma_sg_add_output(struct comcerto_dma_sg *sg, void *p, unsigned int len, int use_acp)
{
	dma_addr_t phys_addr;

	if (unlikely(len > (MDMA_MAX_BUF_SIZE + 1))) {
		printk(KERN_ERR "%s: tried to add a page larger than %d kB.\n", __func__, MDMA_MAX_BUF_SIZE + 1);
		return -2;
	}

	if (len <= MDMA_MAX_BUF_SIZE) {
		if (sg->output_idx >= MDMA_OUTBOUND_BUF_DESC)
			return -1;

		phys_addr = dma_acp_map_page(sg, p, len, DMA_FROM_DEVICE, use_acp);

		sg->out_bdesc[sg->output_idx].split = 0;
		sg->out_bdesc[sg->output_idx].phys_addr = phys_addr;
		sg->out_bdesc[sg->output_idx].len = len;
		sg->output_idx++;

		return 0;
	}
	else { /* len = MDMA_MAX_BUF_SIZE +1, split it in 2 pieces */
		if (sg->output_idx >= (MDMA_OUTBOUND_BUF_DESC - 1))
			return -1;

		phys_addr = dma_acp_map_page(sg, p, len, DMA_FROM_DEVICE, use_acp);

		sg->out_bdesc[sg->output_idx].split = 1;
		sg->out_bdesc[sg->output_idx].phys_addr = phys_addr;
		sg->out_bdesc[sg->output_idx].len = MDMA_SPLIT_BUF_SIZE;
		sg->output_idx++;
		sg->out_bdesc[sg->output_idx].split = 0;
		sg->out_bdesc[sg->output_idx].phys_addr = phys_addr + MDMA_SPLIT_BUF_SIZE;
		sg->out_bdesc[sg->output_idx].len = len - MDMA_SPLIT_BUF_SIZE;
		sg->output_idx++;

		return 0;
	}
}
EXPORT_SYMBOL(comcerto_dma_sg_add_output);

void comcerto_dma_sg_setup(struct comcerto_dma_sg *sg, unsigned int len)
{
	int i;
	unsigned int remaining;

	comcerto_dma_profiling_start(sg, len);

	writel_relaxed(sg->low_phys_addr |
			AWUSER_COHERENT(WRITEBACK) | AWPROT(0x0) | AWCACHE(CACHEABLE | BUFFERABLE) |
			ARUSER_COHERENT(WRITEBACK) | ARPROT(0x0) | ARCACHE(CACHEABLE | BUFFERABLE),
			COMCERTO_GPIO_A9_ACP_CONF_REG);

	remaining = len;
	i = 0;
	while (remaining > sg->in_bdesc[i].len) {

		if (sg->in_bdesc[i].phys_addr >= COMCERTO_AXI_ACP_BASE)
			sg->in_bdesc[i].phys_addr -= sg->low_phys_addr;

		comcerto_dma_set_in_bdesc(i, sg->in_bdesc[i].phys_addr, sg->in_bdesc[i].len);
		remaining -= sg->in_bdesc[i].len;
		i++;
	}

	if (sg->in_bdesc[i].phys_addr >= COMCERTO_AXI_ACP_BASE)
		sg->in_bdesc[i].phys_addr -= sg->low_phys_addr;

	comcerto_dma_set_in_bdesc(i, sg->in_bdesc[i].phys_addr, remaining | BLAST);

	remaining = len;
	i = 0;

	while (remaining > sg->out_bdesc[i].len) {
		if (sg->out_bdesc[i].phys_addr >= COMCERTO_AXI_ACP_BASE)
			sg->out_bdesc[i].phys_addr -= sg->low_phys_addr;

		comcerto_dma_set_out_bdesc(i, sg->out_bdesc[i].phys_addr, sg->out_bdesc[i].len);
		remaining -= sg->out_bdesc[i].len;
		i++;
	}

	if (sg->out_bdesc[i].phys_addr >= COMCERTO_AXI_ACP_BASE)
		sg->out_bdesc[i].phys_addr -= sg->low_phys_addr;

	comcerto_dma_set_out_bdesc(i, sg->out_bdesc[i].phys_addr, remaining | BLAST);
}
EXPORT_SYMBOL(comcerto_dma_sg_setup);

void comcerto_dma_sg_cleanup(struct comcerto_dma_sg *sg, unsigned int len)
{
	int i;
	unsigned int remaining;

	remaining = len;
	i = 0;
	while (remaining > sg->in_bdesc[i].len) {
		if (sg->in_bdesc[i].split) {
			sg->in_bdesc[i+1].phys_addr = sg->in_bdesc[i].phys_addr;
			sg->in_bdesc[i+1].len += sg->in_bdesc[i].len;
		}
		else {
			if (sg->in_bdesc[i].phys_addr < COMCERTO_AXI_ACP_BASE)
				dma_unmap_page(NULL, sg->in_bdesc[i].phys_addr, sg->in_bdesc[i].len, DMA_TO_DEVICE);
			remaining -= sg->in_bdesc[i].len;
		}
		i++;
	}

	if (sg->in_bdesc[i].phys_addr < COMCERTO_AXI_ACP_BASE)
		dma_unmap_page(NULL, sg->in_bdesc[i].phys_addr, sg->in_bdesc[i].len, DMA_TO_DEVICE);

	remaining = len;
	i = 0;
	while (remaining > sg->out_bdesc[i].len) {
		if (sg->out_bdesc[i].split) {
			sg->out_bdesc[i+1].phys_addr = sg->out_bdesc[i].phys_addr;
			sg->out_bdesc[i+1].len += sg->out_bdesc[i].len;
		}
		else {
			if (sg->out_bdesc[i].phys_addr < COMCERTO_AXI_ACP_BASE)
				dma_unmap_page(NULL, sg->out_bdesc[i].phys_addr, sg->out_bdesc[i].len, DMA_FROM_DEVICE);
			remaining -= sg->out_bdesc[i].len;
		}
		i++;
	}

	if (sg->out_bdesc[i].phys_addr < COMCERTO_AXI_ACP_BASE)
		dma_unmap_page(NULL, sg->out_bdesc[i].phys_addr, sg->out_bdesc[i].len, DMA_FROM_DEVICE);


	comcerto_dma_profiling_end(sg);
}
EXPORT_SYMBOL(comcerto_dma_sg_cleanup);

void comcerto_dma_get(void)
{
	unsigned long flags;
	DEFINE_WAIT(wait);

	spin_lock_irqsave(&mdma_lock, flags);

	if (dma_owned && (dma_owned != OWNER_MEMCPY_FREE)) {
		prepare_to_wait(&mdma_memcpy_busy_queue, &wait, TASK_UNINTERRUPTIBLE);

		memcpy_pending_count++;

		while (!dma_owned || !(dma_owned == OWNER_MEMCPY_FREE)) {
			spin_unlock_irqrestore(&mdma_lock, flags);
			schedule();
			spin_lock_irqsave(&mdma_lock, flags);
			prepare_to_wait(&mdma_memcpy_busy_queue, &wait, TASK_UNINTERRUPTIBLE);
		}

		memcpy_pending_count--;

		finish_wait(&mdma_memcpy_busy_queue, &wait);
	}
	dma_owned = OWNER_MEMCPY_BUSY;

	spin_unlock_irqrestore(&mdma_lock, flags);
}
EXPORT_SYMBOL(comcerto_dma_get);

void comcerto_dma_put(void)
{
#if 0
	unsigned long flags;

	spin_lock_irqsave(&mdma_lock, flags);
	mdma_busy = 0;
	spin_unlock_irqrestore(&mdma_lock, flags);

	wake_up(&mdma_memcpy_busy_queue);
#endif
}
EXPORT_SYMBOL(comcerto_dma_put);

/* Called once to setup common registers */
static void comcerto_dma_setup(void)
{
	/* IO2M_IRQ_ENABLE: Enable IRQ_IRQFDON*/
	writel_relaxed(IRQ_IRQFDON|IRQ_IRQFLEN|IRQ_IRQFTHLD|IRQ_IRQFLST, IO2M_IRQ_ENABLE);
	writel_relaxed(IRQ_IRQFDON|IRQ_IRQFLEN|IRQ_IRQFTHLD|IRQ_IRQFLST, M2IO_IRQ_ENABLE);

	writel_relaxed(FLENEN, M2IO_CONTROL);
	writel_relaxed(0xf | (0x3ff << 8), M2IO_BURST);
	writel_relaxed(FLENEN, IO2M_CONTROL);
	writel_relaxed(0xf | (0x3ff << 8), IO2M_BURST);
}


void comcerto_dma_start(void)
{
	mdma_done = 0;

	mdma_in_desc->next_desc = 0;
	mdma_in_desc->fcontrol = 0;
	mdma_in_desc->fstatus0 = 0;
	mdma_in_desc->fstatus1 = 0;

	// outbound
	mdma_out_desc->next_desc = 0;
	mdma_out_desc->fcontrol = 0;
	mdma_out_desc->fstatus0 = 0;
	mdma_out_desc->fstatus1 = 0;

	wmb();

	// Initialize the Outbound Head Pointer
	writel_relaxed(mdma_out_desc_phy, IO2M_HEAD);

	// Initialize the Inbound Head Pointer
	writel_relaxed(mdma_in_desc_phy, M2IO_HEAD);

	writel_relaxed(1, M2IO_FLEN);
	writel_relaxed(1, IO2M_FLEN);

	wmb();
}
EXPORT_SYMBOL(comcerto_dma_start);


void comcerto_dma_wait(void)
{
	DEFINE_WAIT(wait);

	prepare_to_wait(&mdma_done_queue, &wait, TASK_UNINTERRUPTIBLE);

	if (!mdma_done)
		schedule();

	finish_wait(&mdma_done_queue, &wait);
}
EXPORT_SYMBOL(comcerto_dma_wait);

static void comcerto_dump_regs(void)
{
	u32 val;

	val = readl_relaxed(M2IO_CONTROL);
	printk(KERN_ERR"M2IO_CONTROL         0x%8x.\n",val);

	val = readl_relaxed(M2IO_HEAD);
	printk(KERN_ERR"M2IO_HEAD            0x%8x.\n",val);

	val = readl_relaxed(M2IO_BURST);
	printk(KERN_ERR"M2IO_BURST           0x%8x.\n",val);

	val = readl_relaxed(M2IO_FLEN);
	printk(KERN_ERR"M2IO_FLEN            0x%8x.\n",val);

	val = readl_relaxed(M2IO_IRQ_ENABLE);
	printk(KERN_ERR"M2IO_IRQ_ENABLE      0x%8x.\n",val);

	val = readl_relaxed(M2IO_IRQ_STATUS);
	printk(KERN_ERR"M2IO_IRQ_STATUS      0x%8x.\n",val);

	val = readl_relaxed(M2IO_RESET);
	printk(KERN_ERR"M2IO_RESET           0x%8x.\n",val);

	val = readl_relaxed(IO2M_CONTROL);
	printk(KERN_ERR"IO2M_CONTROL         0x%8x.\n",val);

	val = readl_relaxed(IO2M_HEAD);
	printk(KERN_ERR"IO2M_HEAD            0x%8x.\n",val);

	val = readl_relaxed(IO2M_BURST);
	printk(KERN_ERR"IO2M_BURST           0x%8x.\n",val);

	val = readl_relaxed(IO2M_FLEN);
	printk(KERN_ERR"IO2M_FLEN            0x%8x.\n",val);

	val = readl_relaxed(IO2M_IRQ_ENABLE);
	printk(KERN_ERR"IO2M_IRQ_ENABLE      0x%8x.\n",val);

	val = readl_relaxed(IO2M_IRQ_STATUS);
	printk(KERN_ERR"IO2M_IRQ_STATUS      0x%8x.\n",val);

	val = readl_relaxed(IO2M_RESET);
	printk(KERN_ERR"IO2M_RESET           0x%8x.\n",val);
}

static irqreturn_t c2k_dma_handle_interrupt(int irq, void *data)
{
	int i;
	int pending_count;
	unsigned long flags;
	u32 intr_cause = readl_relaxed(IO2M_IRQ_STATUS);

	writel_relaxed(intr_cause, IO2M_IRQ_STATUS);

	if (unlikely(intr_cause & ~(IRQ_IRQFDON | IRQ_IRQFLST | IRQ_IRQFLEN))) {
		if (intr_cause & IRQ_IRQFRDYN)
			printk(KERN_ALERT "IRQFRDYN: A frame is started but the frame is not ready");

		if (intr_cause & IRQ_IRQFLSH)
			printk(KERN_ALERT "IRQFLSH: IO has more data than the memory buffer");

		if (intr_cause & IRQ_IRQFTHLD)
			printk(KERN_ALERT "IRQFTHLD: Frame threshold reached. FLEN=FTHLDL");

		if (intr_cause & IRQ_IRQFCTRL)
			printk(KERN_ALERT "IRQFCTRL: 1 frame is completed or when a frame is started but not ready");	

		comcerto_dump_regs();
	}

	if (intr_cause & IRQ_IRQFDON) {

	}

	if (intr_cause & IRQ_IRQFLEN) {

		spin_lock_irqsave(&mdma_lock, flags);
		if(!dma_owned)
			printk(KERN_ALERT " NULL MDMA Ownership !!!\n");


		if(dma_owned==OWNER_XOR_BUSY)
		{

			for(i = 0 ; i < xor_current_batch_count; i++)
				xor_dma_idx = (xor_dma_idx + 1) % XOR_FDESC_COUNT;

			xor_current_batch_count = 0;


			if(memcpy_pending_count)
			{
				dma_owned = OWNER_MEMCPY_FREE;
				wake_up(&mdma_memcpy_busy_queue);
			}
			else
			{
				pending_count = CIRC_CNT(xor_wr_idx, xor_dma_idx, XOR_FDESC_COUNT);
				if(pending_count)
				{
					dma_owned = OWNER_XOR_BUSY;
					xor_current_batch_count = pending_count;
					comcerto_xor_update_dma_flen(xor_current_batch_count);
					comcerto_xor_update_dma_head(xor_dma_idx);
				}
				else
				{
					dma_owned = 0;
				}
			}

			if(comcerto_xor_sleeping)
			{
				wake_up(&comcerto_xor_wait_queue);
			}

			tasklet_schedule(&comcerto_xor_ch.irq_tasklet);
		}
		else //memcpy
		{
			mdma_done = 1;
			wake_up(&mdma_done_queue);

			memcpy_processed_ongoing++;
			pending_count = CIRC_CNT(xor_wr_idx, xor_dma_idx, XOR_FDESC_COUNT);

			if(pending_count)
			{
				memcpy_processed_ongoing = 0;
				dma_owned = OWNER_XOR_BUSY;
				xor_current_batch_count = pending_count;
				comcerto_xor_update_dma_flen(xor_current_batch_count);
				comcerto_xor_update_dma_head(xor_dma_idx);

				if(comcerto_xor_sleeping)
				{
					wake_up(&comcerto_xor_wait_queue);
				}
			}
			else
			{
				if(memcpy_pending_count)
				{
					dma_owned = OWNER_MEMCPY_FREE;
					wake_up(&mdma_memcpy_busy_queue);
				}
				else
				{
					dma_owned = 0;
				}
			}

		}
		spin_unlock_irqrestore(&mdma_lock, flags);
	}

	return IRQ_HANDLED;
}

static int __devexit comcerto_dma_remove(struct platform_device *pdev)
{
	int irq;

	irq = platform_get_irq(pdev, 0);

	iounmap(virtbase);

	free_irq(irq, NULL);

	platform_set_drvdata(pdev, NULL);

	return 0;
}

static int __devinit comcerto_dma_probe(struct platform_device *pdev)
{
	struct resource      *io;
	int                  irq;
	void *memcpy_pool = (void *)IRAM_MEMORY_VADDR;
	void *xor_pool;
	int i;
	struct dma_device    *dma_dev;
	int ret = 0;

	/* Retrieve related resources(mem, irq) from platform_device */
	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!io)
		return -ENODEV;

	irq = platform_get_irq(pdev,0);
	if (irq < 0)
		return irq;

	ret = request_irq(irq, c2k_dma_handle_interrupt, 0, "MDMA", NULL);
	if (ret < 0)
		return ret;

	virtbase = ioremap(io->start, resource_size(io));
	if (!virtbase)
		goto err_free_irq;

	/* Initialize comcerto_xor_device */
	comcerto_xor_dev = devm_kzalloc(&pdev->dev, sizeof(struct comcerto_xor_device), GFP_KERNEL);

	if(!comcerto_xor_dev)
	{
		ret = -ENOMEM;
		goto err_free_remap;
	}

	dma_dev = &comcerto_xor_dev->device;
	INIT_LIST_HEAD(&dma_dev->channels);
	dma_cap_set(DMA_XOR,dma_dev->cap_mask);
	dma_dev->dev = &pdev->dev;
	dma_dev->device_alloc_chan_resources = comcerto_xor_alloc_chan_resources;
	dma_dev->device_free_chan_resources  = comcerto_xor_free_chan_resources;
	dma_dev->device_tx_status            = comcerto_xor_status;
	dma_dev->device_issue_pending        = comcerto_xor_issue_pending;
	dma_dev->device_prep_dma_xor         = comcerto_xor_prep_dma_xor;
	dma_dev->max_xor = XOR_MAX_SRC_CNT;
	platform_set_drvdata(pdev,comcerto_xor_dev);

	/* Initialize comcerto_xor_chan */
	comcerto_xor_ch.chan.device = dma_dev;
	list_add_tail(&comcerto_xor_ch.chan.device_node,&dma_dev->channels);

	ret = dma_async_device_register(dma_dev);
	if (unlikely(ret)) {
		printk(KERN_ERR "%s: Failed to register XOR DMA channel %d\n",__func__,ret);
		goto err_free_dma;
	}
	else
		printk(KERN_INFO "%s: XOR DMA channel registered\n",__func__);

	spin_lock_init(&comcerto_xor_ch.lock);
	spin_lock_init(&comcerto_xor_cleanup_lock);

	spin_lock_init(&mdma_lock);

	//Memcpy descriptor initializing
	mdma_in_desc = (struct comcerto_memcpy_inbound_fdesc *) (memcpy_pool);
	memcpy_pool += sizeof(struct comcerto_memcpy_inbound_fdesc);
	memcpy_pool = (void *)((unsigned long)(memcpy_pool + 15) & ~15);
	mdma_out_desc = (struct comcerto_memcpy_outbound_fdesc *) (memcpy_pool);
	memcpy_pool += sizeof(struct comcerto_memcpy_outbound_fdesc);
	memcpy_pool = (void *)((unsigned long)(memcpy_pool + 15) & ~15);

	mdma_in_desc_phy = virt_to_aram(mdma_in_desc);
	mdma_out_desc_phy = virt_to_aram(mdma_out_desc);

	//XOR descriptor initializing
	comcerto_xor_pool_virt = dma_alloc_coherent(NULL, XOR_FDESC_COUNT * (sizeof(struct comcerto_xor_inbound_fdesc) 
				+  sizeof(struct comcerto_xor_outbound_fdesc)), &comcerto_xor_pool_phy, GFP_KERNEL);
	xor_pool = comcerto_xor_pool_virt;

	for (i = 0; i < XOR_FDESC_COUNT; i++) {
		xor_in_fdesc[i] = (struct comcerto_xor_inbound_fdesc *) (xor_pool);
		xor_pool += sizeof(struct comcerto_xor_inbound_fdesc);
		xor_pool = (void *)((unsigned long)(xor_pool + 15) & ~15);
		xor_out_fdesc[i] = (struct comcerto_xor_outbound_fdesc *) (xor_pool);
		xor_pool += sizeof(struct comcerto_xor_outbound_fdesc);
		xor_pool = (void *)((unsigned long)(xor_pool + 15) & ~15);

		memset(xor_in_fdesc[i], 0 , sizeof(struct comcerto_xor_inbound_fdesc));
		memset(xor_out_fdesc[i], 0 , sizeof(struct comcerto_xor_outbound_fdesc));
	}

	for(i = 0; i < XOR_FDESC_COUNT - 1; i++) {
		xor_in_fdesc[i]->next_desc = virt_to_xor_dma(comcerto_xor_pool_phy, comcerto_xor_pool_virt, xor_in_fdesc[i+1]);
		xor_out_fdesc[i]->next_desc = virt_to_xor_dma(comcerto_xor_pool_phy, comcerto_xor_pool_virt, xor_out_fdesc[i+1]);
	}
	xor_in_fdesc[XOR_FDESC_COUNT-1]->next_desc = virt_to_xor_dma(comcerto_xor_pool_phy, comcerto_xor_pool_virt, xor_in_fdesc[0]);
	xor_out_fdesc[XOR_FDESC_COUNT-1]->next_desc = virt_to_xor_dma(comcerto_xor_pool_phy, comcerto_xor_pool_virt, xor_out_fdesc[0]);

	init_timer(&comcerto_xor_timer);
	comcerto_xor_timer.function = comcerto_xor_timer_fnc;
	comcerto_xor_timer.data = 0;

	tasklet_init(&comcerto_xor_ch.irq_tasklet, comcerto_xor_tasklet, 0);

	comcerto_dma_setup();

	goto out;

err_free_dma:
	platform_set_drvdata(pdev,NULL);
	kfree(comcerto_xor_dev);
err_free_remap:
	iounmap(virtbase);	
err_free_irq:
	free_irq(irq, NULL);
out:
	return ret;
}


static struct platform_driver comcerto_dma_driver = {
	.probe        = comcerto_dma_probe,
	.remove       = comcerto_dma_remove,
	.driver       = {
		.owner = THIS_MODULE,
		.name  = "comcerto_dma",
	},
};

static int __init comcerto_dma_init(void)
{
	return platform_driver_register(&comcerto_dma_driver);
}
module_init(comcerto_dma_init);

static void __exit comcerto_dma_exit(void)
{
	platform_driver_unregister(&comcerto_dma_driver);
}
module_exit(comcerto_dma_exit);

MODULE_DESCRIPTION("DMA engine driver for Mindspeed Comcerto C2000 devices");
MODULE_LICENSE("GPL");

