/*
 * CPPI 4.1 support
 *
 * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
 *
 * Based on the PAL CPPI 4.1 implementation
 * Copyright (C) 1998-2006 Texas Instruments Incorporated
 *
 * This file contains the main implementation for CPPI 4.1 common peripherals,
 * including the DMA Controllers and the Queue Managers.
 *
 * This program is free software; you can distribute it and/or modify it
 * under the terms of the GNU General Public License (Version 2) as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 *
 */

#include <linux/io.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>

#include "cppi41.h"

#undef	CPPI41_DEBUG

#ifdef	CPPI41_DEBUG
#define DBG(format, args...) printk(format, ##args)
#else
#define DBG(format, args...)
#endif

static struct {
	void *virt_addr;
	dma_addr_t phys_addr;
	u32     size;
} linking_ram[CPPI41_NUM_QUEUE_MGR];

static u32 *allocated_queues[CPPI41_NUM_QUEUE_MGR];

/* First 32 packet descriptors are reserved for unallocated memory regions. */
static u32 next_desc_index[CPPI41_NUM_QUEUE_MGR] = { 1 << 5 };
static u8  next_mem_rgn[CPPI41_NUM_QUEUE_MGR];

static struct {
	size_t rgn_size;
	void *virt_addr;
	dma_addr_t phys_addr;
	struct cppi41_queue_obj queue_obj;
	u8 mem_rgn;
	u16 q_mgr;
	u16 q_num;
} dma_teardown[CPPI41_NUM_DMA_BLOCK];

struct cppi41_dma_sched_tbl_t {
	u8      pos;
	u8      dma_ch;
	u8      is_tx;
	u8      enb;
};

struct cppi41_dma_sched_tbl_t dma_sched_tbl[MAX_SCHED_TBL_ENTRY] = {
	/*pos  dma_ch#  is_tx  enb/dis*/
	{ 0,    0,      0,      1},
	{ 1,    0,      1,      1},
	{ 2,    1,      0,      1},
	{ 3,    1,      1,      1},
	{ 4,    2,      0,      1},
	{ 5,    2,      1,      1},
	{ 6,    3,      0,      1},
	{ 7,    3,      1,      1}
};

struct cppi41_queue_mgr cppi41_queue_mgr[CPPI41_NUM_QUEUE_MGR];
EXPORT_SYMBOL(cppi41_queue_mgr);

struct cppi41_dma_block cppi41_dma_block[CPPI41_NUM_DMA_BLOCK];
EXPORT_SYMBOL(cppi41_dma_block);
/******************** CPPI 4.1 Functions (External Interface) *****************/

int cppi41_queue_mgr_init(u8 q_mgr, dma_addr_t rgn0_base, u16 rgn0_size)
{
	void __iomem *q_mgr_regs;
	void *ptr;

	if (q_mgr >= cppi41_num_queue_mgr)
		return -EINVAL;

	q_mgr_regs = cppi41_queue_mgr[q_mgr].q_mgr_rgn_base;
	ptr = dma_alloc_coherent(NULL, rgn0_size * 4,
				 &linking_ram[q_mgr].phys_addr,
				 GFP_KERNEL | GFP_DMA);
	if (ptr == NULL) {
		printk(KERN_ERR "ERROR: %s: Unable to allocate "
		       "linking RAM.\n", __func__);
		return -ENOMEM;
	}
	linking_ram[q_mgr].virt_addr = ptr;
	linking_ram[q_mgr].size = rgn0_size * 4;

	__raw_writel(linking_ram[q_mgr].phys_addr,
			q_mgr_regs + QMGR_LINKING_RAM_RGN0_BASE_REG);
	DBG("Linking RAM region 0 base @ %p, value: %x\n",
	    q_mgr_regs + QMGR_LINKING_RAM_RGN0_BASE_REG,
	    __raw_readl(q_mgr_regs + QMGR_LINKING_RAM_RGN0_BASE_REG));

	__raw_writel(rgn0_size, q_mgr_regs + QMGR_LINKING_RAM_RGN0_SIZE_REG);
	DBG("Linking RAM region 0 size @ %p, value: %x\n",
	    q_mgr_regs + QMGR_LINKING_RAM_RGN0_SIZE_REG,
	    __raw_readl(q_mgr_regs + QMGR_LINKING_RAM_RGN0_SIZE_REG));

	ptr = kzalloc(BITS_TO_LONGS(cppi41_queue_mgr[q_mgr].num_queue),
		      GFP_KERNEL);
	if (ptr == NULL) {
		printk(KERN_ERR "ERROR: %s: Unable to allocate queue bitmap.\n",
		       __func__);
		dma_free_coherent(NULL, rgn0_size * 4,
				  linking_ram[q_mgr].virt_addr,
				  linking_ram[q_mgr].phys_addr);
		return -ENOMEM;
	}
	allocated_queues[q_mgr] = ptr;

	return 0;
}
EXPORT_SYMBOL(cppi41_queue_mgr_init);

int cppi41_queue_mgr_uninit(u8 q_mgr)
{
	void __iomem *q_mgr_regs;

	if (q_mgr >= cppi41_num_queue_mgr)
		return -EINVAL;

	q_mgr_regs = cppi41_queue_mgr[q_mgr].q_mgr_rgn_base;

	/* free the Queue Mgr linking ram space */
	__raw_writel(0,	q_mgr_regs + QMGR_LINKING_RAM_RGN0_BASE_REG);
	__raw_writel(0, q_mgr_regs + QMGR_LINKING_RAM_RGN0_SIZE_REG);
	dma_free_coherent(NULL, linking_ram[q_mgr].size,
			linking_ram[q_mgr].virt_addr,
			linking_ram[q_mgr].phys_addr);

	/* free the allocated queues */
	kfree(allocated_queues[q_mgr]);
	return 0;
}
EXPORT_SYMBOL(cppi41_queue_mgr_uninit);

int cppi41_dma_sched_tbl_init(u8 dma_num, u8 q_mgr,
			u32 *sched_tbl, u8 tbl_size)
{
	struct cppi41_dma_block *dma_block;
	int num_reg, k, i, val = 0;

	dma_block = (struct cppi41_dma_block *)&cppi41_dma_block[dma_num];

	num_reg = (tbl_size + 3) / 4;
	for (k = i = 0; i < num_reg; i++) {
#if 0
		for (val = j = 0; j < 4; j++, k++) {
			val >>= 8;
			if (k < tbl_size)
				val |= sched_tbl[k] << 24;
		}
#endif
		val = sched_tbl[i];
		__raw_writel(val, dma_block->sched_table_base +
			DMA_SCHED_TABLE_WORD_REG(i));
		DBG("DMA scheduler table @ %p, value written: %x\n",
		dma_block->sched_table_base + DMA_SCHED_TABLE_WORD_REG(i),
			val);
	}
	return 0;
}
EXPORT_SYMBOL(cppi41_dma_sched_tbl_init);

int cppi41_schedtbl_add_dma_ch(u8 dmanum, u8 qmgr, u8 dma_ch, u8 is_tx)
{
	struct cppi41_dma_block *dma_block;
	int num_ch, i, tbl_index = 0, j = 0, found = 0;
	u32 val;

	dma_block = (struct cppi41_dma_block *)&cppi41_dma_block[dmanum];

	val = 0;
	for (num_ch = 0, i = 0; i < MAX_SCHED_TBL_ENTRY; i++) {
		if (!found && dma_sched_tbl[i].dma_ch == dma_ch &&
			dma_sched_tbl[i].is_tx == is_tx &&
			dma_sched_tbl[i].enb == 0) {
			dma_sched_tbl[i].enb = 1;
			found = 1;
		}

		if (dma_sched_tbl[i].enb) {
			val |= ((dma_sched_tbl[i].dma_ch |
				(dma_sched_tbl[i].is_tx ? 0 : (1<<7))) << j*8);
			num_ch++;
			j++;
		}
		if (num_ch % 4 == 0) {
			__raw_writel(val, dma_block->sched_table_base +
				DMA_SCHED_TABLE_WORD_REG(tbl_index));
			tbl_index++;
			val = j = 0;
		}
	}

	if (num_ch % 4) {
		__raw_writel(val, dma_block->sched_table_base +
			DMA_SCHED_TABLE_WORD_REG(tbl_index));
	}
	return num_ch;
}
EXPORT_SYMBOL(cppi41_schedtbl_add_dma_ch);

int cppi41_schedtbl_remove_dma_ch(u8 dmanum, u8 qmgr, u8 dma_ch, u8 is_tx)
{
	struct cppi41_dma_block *dma_block;
	int num_ch, i, tbl_index = 0, j = 0, found = 0;
	u32 val;

	dma_block = (struct cppi41_dma_block *)&cppi41_dma_block[dmanum];

	val = 0;
	for (num_ch = 0, i = 0; i < MAX_SCHED_TBL_ENTRY; i++) {
		if (!found && dma_sched_tbl[i].dma_ch == dma_ch &&
			dma_sched_tbl[i].is_tx == is_tx &&
			dma_sched_tbl[i].enb == 1) {
			dma_sched_tbl[i].enb = 0;
		}

		if (dma_sched_tbl[i].enb) {
			val |= ((dma_sched_tbl[i].dma_ch |
				(dma_sched_tbl[i].is_tx ? 0 : (1<<7))) << j*8);
			num_ch++;
			j++;
		}
		if (num_ch % 4 == 0) {
			__raw_writel(val, dma_block->sched_table_base +
				DMA_SCHED_TABLE_WORD_REG(tbl_index));
			tbl_index++;
			val = j = 0;
		}
	}

	if (num_ch % 4) {
		__raw_writel(val, dma_block->sched_table_base +
			DMA_SCHED_TABLE_WORD_REG(tbl_index));
	}
	return num_ch;
}
EXPORT_SYMBOL(cppi41_schedtbl_remove_dma_ch);

int cppi41_dma_block_init(u8 dma_num, u8 q_mgr, u8 num_order,
				 u32 *sched_tbl, u8 tbl_size)
{
	const struct cppi41_dma_block *dma_block;
	struct cppi41_teardown_desc *curr_td;
	dma_addr_t td_addr;
	unsigned num_desc, num_reg;
	void *ptr;
	int error, i;
	u16 q_num;
	u32 val;

	if (dma_num >= cppi41_num_dma_block ||
	    q_mgr >= cppi41_num_queue_mgr ||
	    !tbl_size || sched_tbl == NULL)
		return -EINVAL;

	error = cppi41_queue_alloc(CPPI41_FREE_DESC_QUEUE |
				   CPPI41_UNASSIGNED_QUEUE, q_mgr, &q_num);
	if (error) {
		printk(KERN_ERR "ERROR: %s: Unable to allocate teardown "
		       "descriptor queue.\n", __func__);
		return error;
	}
	DBG("Teardown descriptor queue %d in queue manager 0 "
	    "allocated\n", q_num);

	/*
	 * Tell the hardware about the Teardown descriptor
	 * queue manager and queue number.
	 */
	dma_block = &cppi41_dma_block[dma_num];
	__raw_writel((q_mgr << DMA_TD_DESC_QMGR_SHIFT) |
		     (q_num << DMA_TD_DESC_QNUM_SHIFT),
		     dma_block->global_ctrl_base +
		     DMA_TEARDOWN_FREE_DESC_CTRL_REG);
	DBG("Teardown free descriptor control @ %p, value: %x\n",
	    dma_block->global_ctrl_base + DMA_TEARDOWN_FREE_DESC_CTRL_REG,
	    __raw_readl(dma_block->global_ctrl_base +
			DMA_TEARDOWN_FREE_DESC_CTRL_REG));

	num_desc = 1 << num_order;
	dma_teardown[dma_num].rgn_size = num_desc *
					 sizeof(struct cppi41_teardown_desc);

	/* Pre-allocate teardown descriptors. */
	ptr = dma_alloc_coherent(NULL, dma_teardown[dma_num].rgn_size,
				 &dma_teardown[dma_num].phys_addr,
				 GFP_KERNEL | GFP_DMA);
	if (ptr == NULL) {
		printk(KERN_ERR "ERROR: %s: Unable to allocate teardown "
		       "descriptors.\n", __func__);
		error = -ENOMEM;
		goto free_queue;
	}
	dma_teardown[dma_num].virt_addr = ptr;

	error = cppi41_mem_rgn_alloc(q_mgr, dma_teardown[dma_num].phys_addr, 5,
				     num_order, &dma_teardown[dma_num].mem_rgn);
	if (error) {
		printk(KERN_ERR "ERROR: %s: Unable to allocate queue manager "
		       "memory region for teardown descriptors.\n", __func__);
		goto free_mem;
	}

	error = cppi41_queue_init(&dma_teardown[dma_num].queue_obj, 0, q_num);
	if (error) {
		printk(KERN_ERR "ERROR: %s: Unable to initialize teardown "
		       "free descriptor queue.\n", __func__);
		goto free_rgn;
	}

	dma_teardown[dma_num].q_num = q_num;
	dma_teardown[dma_num].q_mgr = q_mgr;
	/*
	 * Push all teardown descriptors to the free teardown queue
	 * for the CPPI 4.1 system.
	 */
	curr_td = dma_teardown[dma_num].virt_addr;
	td_addr = dma_teardown[dma_num].phys_addr;

	for (i = 0; i < num_desc; i++) {
		cppi41_queue_push(&dma_teardown[dma_num].queue_obj, td_addr,
				  sizeof(*curr_td), 0);
		td_addr += sizeof(*curr_td);
	}

	/* Initialize the DMA scheduler. */
	num_reg = (tbl_size + 3) / 4;
	for (i = 0; i < num_reg; i++) {
		val = sched_tbl[i];
		__raw_writel(val, dma_block->sched_table_base +
			     DMA_SCHED_TABLE_WORD_REG(i));
		DBG("DMA scheduler table @ %p, value written: %x\n",
		    dma_block->sched_table_base + DMA_SCHED_TABLE_WORD_REG(i),
		    val);
	}

	__raw_writel((tbl_size - 1) << DMA_SCHED_LAST_ENTRY_SHIFT |
		     DMA_SCHED_ENABLE_MASK,
		     dma_block->sched_ctrl_base + DMA_SCHED_CTRL_REG);
	DBG("DMA scheduler control @ %p, value: %x\n",
	    dma_block->sched_ctrl_base + DMA_SCHED_CTRL_REG,
	    __raw_readl(dma_block->sched_ctrl_base + DMA_SCHED_CTRL_REG));

	return 0;

free_rgn:
	cppi41_mem_rgn_free(q_mgr, dma_teardown[dma_num].mem_rgn);
free_mem:
	dma_free_coherent(NULL, dma_teardown[dma_num].rgn_size,
			  dma_teardown[dma_num].virt_addr,
			  dma_teardown[dma_num].phys_addr);
free_queue:
	cppi41_queue_free(q_mgr, q_num);
	return error;
}
EXPORT_SYMBOL(cppi41_dma_block_init);

int cppi41_dma_block_uninit(u8 dma_num, u8 q_mgr, u8 num_order,
				 u32 *sched_tbl, u8 tbl_size)
{
	const struct cppi41_dma_block *dma_block;
	unsigned num_reg;
	int i;

	/* popout all teardown descriptors */
	cppi41_free_teardown_queue(dma_num);

	/* free queue mgr region */
	cppi41_mem_rgn_free(q_mgr, dma_teardown[dma_num].mem_rgn);
	/* free the allocated teardown descriptors */
	dma_free_coherent(NULL, dma_teardown[dma_num].rgn_size,
			dma_teardown[dma_num].virt_addr,
			dma_teardown[dma_num].phys_addr);

	/* free the teardown queue*/
	cppi41_queue_free(dma_teardown[dma_num].q_mgr,
			dma_teardown[dma_num].q_num);

	dma_block = (struct cppi41_dma_block *)&cppi41_dma_block[dma_num];
	/* disable the dma schedular */
	num_reg = (tbl_size + 3) / 4;
	for (i = 0; i < num_reg; i++) {
		__raw_writel(0, dma_block->sched_table_base +
			     DMA_SCHED_TABLE_WORD_REG(i));
		DBG("DMA scheduler table @ %p, value written: %x\n",
		    dma_block->sched_table_base + DMA_SCHED_TABLE_WORD_REG(i),
		    0);
	}

	__raw_writel(0,	dma_block->sched_ctrl_base + DMA_SCHED_CTRL_REG);

	return 0;
}
EXPORT_SYMBOL(cppi41_dma_block_uninit);
/*
 * cppi41_mem_rgn_alloc - allocate a memory region within the queue manager
 */
int cppi41_mem_rgn_alloc(u8 q_mgr, dma_addr_t rgn_addr, u8 size_order,
			 u8 num_order, u8 *mem_rgn)
{
	void __iomem *desc_mem_regs;
	u32 num_desc = 1 << num_order, index, ctrl;
	int rgn;

	DBG("%s called with rgn_addr = %08x, size_order = %d, num_order = %d\n",
	    __func__, rgn_addr, size_order, num_order);

	if (q_mgr >= cppi41_num_queue_mgr ||
	    size_order < 5 || size_order > 13 ||
	    num_order  < 5 || num_order  > 12 ||
	    (rgn_addr & ((1 << size_order) - 1)))
		return -EINVAL;

	rgn = next_mem_rgn[q_mgr];
	index = next_desc_index[q_mgr];
	if (rgn >= CPPI41_MAX_MEM_RGN || index + num_desc > 0x4000)
		return -ENOSPC;

	next_mem_rgn[q_mgr] = rgn + 1;
	next_desc_index[q_mgr] = index + num_desc;

	desc_mem_regs = cppi41_queue_mgr[q_mgr].desc_mem_rgn_base;

	/* Write the base register */
	__raw_writel(rgn_addr, desc_mem_regs + QMGR_MEM_RGN_BASE_REG(rgn));
	DBG("Descriptor region base @ %p, value: %x\n",
	    desc_mem_regs + QMGR_MEM_RGN_BASE_REG(rgn),
	    __raw_readl(desc_mem_regs + QMGR_MEM_RGN_BASE_REG(rgn)));

	/* Write the control register */
	ctrl = ((index << QMGR_MEM_RGN_INDEX_SHIFT) &
		QMGR_MEM_RGN_INDEX_MASK) |
	       (((size_order - 5) << QMGR_MEM_RGN_DESC_SIZE_SHIFT) &
		QMGR_MEM_RGN_DESC_SIZE_MASK) |
	       (((num_order - 5) << QMGR_MEM_RGN_SIZE_SHIFT) &
		QMGR_MEM_RGN_SIZE_MASK);
	__raw_writel(ctrl, desc_mem_regs + QMGR_MEM_RGN_CTRL_REG(rgn));
	DBG("Descriptor region control @ %p, value: %x\n",
	    desc_mem_regs + QMGR_MEM_RGN_CTRL_REG(rgn),
	    __raw_readl(desc_mem_regs + QMGR_MEM_RGN_CTRL_REG(rgn)));

	*mem_rgn = rgn;
	return 0;
}
EXPORT_SYMBOL(cppi41_mem_rgn_alloc);

/*
 * cppi41_mem_rgn_free - free the memory region within the queue manager
 */
int cppi41_mem_rgn_free(u8 q_mgr, u8 mem_rgn)
{
	void __iomem *desc_mem_regs;

	DBG("%s called.\n", __func__);

	if (q_mgr >= cppi41_num_queue_mgr || mem_rgn >= next_mem_rgn[q_mgr])
		return -EINVAL;

	desc_mem_regs = cppi41_queue_mgr[q_mgr].desc_mem_rgn_base;

	if (__raw_readl(desc_mem_regs + QMGR_MEM_RGN_BASE_REG(mem_rgn)) == 0)
		return -ENOENT;

	__raw_writel(0, desc_mem_regs + QMGR_MEM_RGN_BASE_REG(mem_rgn));
	__raw_writel(0, desc_mem_regs + QMGR_MEM_RGN_CTRL_REG(mem_rgn));

	return 0;
}
EXPORT_SYMBOL(cppi41_mem_rgn_free);

/*
 * cppi41_tx_ch_init - initialize a CPPI 4.1 Tx channel object
 *
 * Verify the channel info (range checking, etc.) and store the channel
 * information within the object structure.
 */
int cppi41_tx_ch_init(struct cppi41_dma_ch_obj *tx_ch_obj,
		      u8 dma_num, u8 ch_num)
{
	if (dma_num >= cppi41_num_dma_block ||
	    ch_num  >= cppi41_dma_block[dma_num].num_tx_ch)
		return -EINVAL;

	/* Populate the channel object structure */
	tx_ch_obj->base_addr  = cppi41_dma_block[dma_num].ch_ctrl_stat_base +
				DMA_CH_TX_GLOBAL_CFG_REG(ch_num);
	tx_ch_obj->global_cfg = __raw_readl(tx_ch_obj->base_addr);
	return 0;
}
EXPORT_SYMBOL(cppi41_tx_ch_init);

/*
 * cppi41_rx_ch_init - initialize a CPPI 4.1 Rx channel object
 *
 * Verify the channel info (range checking, etc.) and store the channel
 * information within the object structure.
 */
int cppi41_rx_ch_init(struct cppi41_dma_ch_obj *rx_ch_obj,
		      u8 dma_num, u8 ch_num)
{
	if (dma_num >= cppi41_num_dma_block ||
	    ch_num  >= cppi41_dma_block[dma_num].num_rx_ch)
		return -EINVAL;

	/* Populate the channel object structure */
	rx_ch_obj->base_addr  = cppi41_dma_block[dma_num].ch_ctrl_stat_base +
				DMA_CH_RX_GLOBAL_CFG_REG(ch_num);
	rx_ch_obj->global_cfg = __raw_readl(rx_ch_obj->base_addr);
	return 0;
}
EXPORT_SYMBOL(cppi41_rx_ch_init);

/*
 * We have to cache the last written Rx/Tx channel global configration register
 * value due to its bits other than enable/teardown being write-only. Yet there
 * is a caveat related to caching the enable bit: this bit may be automatically
 * cleared as a result of teardown, so we can't trust its cached value!
 * When modifying the write only register fields, we're making use of the fact
 * that they read back as zeros, and not clearing them explicitly...
 */

/*
 * cppi41_dma_ch_default_queue - set CPPI 4.1 channel default completion queue
 */
void cppi41_dma_ch_default_queue(struct cppi41_dma_ch_obj *dma_ch_obj,
				 u8 q_mgr, u16 q_num)
{
	u32 val = dma_ch_obj->global_cfg;

	/* Clear the fields to be modified. */
	val &= ~(DMA_CH_TX_DEFAULT_QMGR_MASK | DMA_CH_TX_DEFAULT_QNUM_MASK |
		 DMA_CH_TX_ENABLE_MASK);

	/* Set the default completion queue. */
	val |= ((q_mgr << DMA_CH_TX_DEFAULT_QMGR_SHIFT) &
		DMA_CH_TX_DEFAULT_QMGR_MASK) |
	       ((q_num << DMA_CH_TX_DEFAULT_QNUM_SHIFT) &
		DMA_CH_TX_DEFAULT_QNUM_MASK);

	/* Get the current state of the enable bit. */
	dma_ch_obj->global_cfg = val |= __raw_readl(dma_ch_obj->base_addr);
	__raw_writel(val, dma_ch_obj->base_addr);
	DBG("Channel global configuration @ %p, value written: %x, "
	    "value read: %x\n", dma_ch_obj->base_addr, val,
	    __raw_readl(dma_ch_obj->base_addr));

}
EXPORT_SYMBOL(cppi41_dma_ch_default_queue);

/*
 * cppi41_rx_ch_configure - configure CPPI 4.1 Rx channel
 */
void cppi41_rx_ch_configure(struct cppi41_dma_ch_obj *rx_ch_obj,
			    struct cppi41_rx_ch_cfg  *cfg)
{
	void __iomem *base = rx_ch_obj->base_addr;
	u32 val = __raw_readl(rx_ch_obj->base_addr);

	val |= ((cfg->sop_offset << DMA_CH_RX_SOP_OFFSET_SHIFT) &
		DMA_CH_RX_SOP_OFFSET_MASK) |
	       ((cfg->default_desc_type << DMA_CH_RX_DEFAULT_DESC_TYPE_SHIFT) &
		DMA_CH_RX_DEFAULT_DESC_TYPE_MASK) |
	       ((cfg->retry_starved << DMA_CH_RX_ERROR_HANDLING_SHIFT) &
		DMA_CH_RX_ERROR_HANDLING_MASK) |
	       ((cfg->rx_queue.q_mgr << DMA_CH_RX_DEFAULT_RQ_QMGR_SHIFT) &
		DMA_CH_RX_DEFAULT_RQ_QMGR_MASK) |
	       ((cfg->rx_queue.q_num << DMA_CH_RX_DEFAULT_RQ_QNUM_SHIFT) &
		DMA_CH_RX_DEFAULT_RQ_QNUM_MASK);

	rx_ch_obj->global_cfg = val;
	__raw_writel(val, base);
	DBG("Rx channel global configuration @ %p, value written: %x, "
	    "value read: %x\n", base, val, __raw_readl(base));

	base -= DMA_CH_RX_GLOBAL_CFG_REG(0);

	/*
	 * Set up the packet configuration register
	 * based on the descriptor type...
	 */
	switch (cfg->default_desc_type) {
	case DMA_CH_RX_DEFAULT_DESC_EMBED:
		val = ((cfg->cfg.embed_pkt.fd_queue.q_mgr <<
			DMA_CH_RX_EMBED_FDQ_QMGR_SHIFT) &
		       DMA_CH_RX_EMBED_FDQ_QMGR_MASK) |
		      ((cfg->cfg.embed_pkt.fd_queue.q_num <<
			DMA_CH_RX_EMBED_FDQ_QNUM_SHIFT) &
		       DMA_CH_RX_EMBED_FDQ_QNUM_MASK) |
		      ((cfg->cfg.embed_pkt.num_buf_slot <<
			DMA_CH_RX_EMBED_NUM_SLOT_SHIFT) &
		       DMA_CH_RX_EMBED_NUM_SLOT_MASK) |
		      ((cfg->cfg.embed_pkt.sop_slot_num <<
			DMA_CH_RX_EMBED_SOP_SLOT_SHIFT) &
		       DMA_CH_RX_EMBED_SOP_SLOT_MASK);

		__raw_writel(val, base + DMA_CH_RX_EMBED_PKT_CFG_REG_B(0));
		DBG("Rx channel embedded packet configuration B @ %p, "
		    "value written: %x\n",
		    base + DMA_CH_RX_EMBED_PKT_CFG_REG_B(0), val);

		val = ((cfg->cfg.embed_pkt.free_buf_pool[0].b_pool <<
			DMA_CH_RX_EMBED_FBP_PNUM_SHIFT(0)) &
		       DMA_CH_RX_EMBED_FBP_PNUM_MASK(0)) |
		      ((cfg->cfg.embed_pkt.free_buf_pool[0].b_mgr <<
			DMA_CH_RX_EMBED_FBP_BMGR_SHIFT(0)) &
		       DMA_CH_RX_EMBED_FBP_BMGR_MASK(0)) |
		      ((cfg->cfg.embed_pkt.free_buf_pool[1].b_pool <<
			DMA_CH_RX_EMBED_FBP_PNUM_SHIFT(1)) &
		       DMA_CH_RX_EMBED_FBP_PNUM_MASK(1)) |
		      ((cfg->cfg.embed_pkt.free_buf_pool[1].b_mgr <<
			DMA_CH_RX_EMBED_FBP_BMGR_SHIFT(1)) &
		       DMA_CH_RX_EMBED_FBP_BMGR_MASK(1)) |
		      ((cfg->cfg.embed_pkt.free_buf_pool[2].b_pool <<
			DMA_CH_RX_EMBED_FBP_PNUM_SHIFT(2)) &
		       DMA_CH_RX_EMBED_FBP_PNUM_MASK(2)) |
		      ((cfg->cfg.embed_pkt.free_buf_pool[2].b_mgr <<
			DMA_CH_RX_EMBED_FBP_BMGR_SHIFT(2)) &
		       DMA_CH_RX_EMBED_FBP_BMGR_MASK(2)) |
		      ((cfg->cfg.embed_pkt.free_buf_pool[3].b_pool <<
			DMA_CH_RX_EMBED_FBP_PNUM_SHIFT(3)) &
		       DMA_CH_RX_EMBED_FBP_PNUM_MASK(3)) |
		      ((cfg->cfg.embed_pkt.free_buf_pool[3].b_mgr <<
			DMA_CH_RX_EMBED_FBP_BMGR_SHIFT(3)) &
		       DMA_CH_RX_EMBED_FBP_BMGR_MASK(3));

		__raw_writel(val, base + DMA_CH_RX_EMBED_PKT_CFG_REG_A(0));
		DBG("Rx channel embedded packet configuration A @ %p, "
		    "value written: %x\n",
		    base + DMA_CH_RX_EMBED_PKT_CFG_REG_A(0), val);
		break;
	case DMA_CH_RX_DEFAULT_DESC_HOST:
		val = ((cfg->cfg.host_pkt.fdb_queue[0].q_num <<
			DMA_CH_RX_HOST_FDQ_QNUM_SHIFT(0)) &
		       DMA_CH_RX_HOST_FDQ_QNUM_MASK(0)) |
		      ((cfg->cfg.host_pkt.fdb_queue[0].q_mgr <<
			DMA_CH_RX_HOST_FDQ_QMGR_SHIFT(0)) &
		       DMA_CH_RX_HOST_FDQ_QMGR_MASK(0)) |
		      ((cfg->cfg.host_pkt.fdb_queue[1].q_num <<
			DMA_CH_RX_HOST_FDQ_QNUM_SHIFT(1)) &
		       DMA_CH_RX_HOST_FDQ_QNUM_MASK(1)) |
		      ((cfg->cfg.host_pkt.fdb_queue[1].q_mgr <<
			DMA_CH_RX_HOST_FDQ_QMGR_SHIFT(1)) &
		       DMA_CH_RX_HOST_FDQ_QMGR_MASK(1));

		__raw_writel(val, base + DMA_CH_RX_HOST_PKT_CFG_REG_A(0));
		DBG("Rx channel host packet configuration A @ %p, "
		    "value written: %x\n",
		    base + DMA_CH_RX_HOST_PKT_CFG_REG_A(0), val);

		val = ((cfg->cfg.host_pkt.fdb_queue[2].q_num <<
			DMA_CH_RX_HOST_FDQ_QNUM_SHIFT(2)) &
		       DMA_CH_RX_HOST_FDQ_QNUM_MASK(2)) |
		      ((cfg->cfg.host_pkt.fdb_queue[2].q_mgr <<
			DMA_CH_RX_HOST_FDQ_QMGR_SHIFT(2)) &
		       DMA_CH_RX_HOST_FDQ_QMGR_MASK(2)) |
		      ((cfg->cfg.host_pkt.fdb_queue[3].q_num <<
		       DMA_CH_RX_HOST_FDQ_QNUM_SHIFT(3)) &
		       DMA_CH_RX_HOST_FDQ_QNUM_MASK(3)) |
		      ((cfg->cfg.host_pkt.fdb_queue[3].q_mgr <<
			DMA_CH_RX_HOST_FDQ_QMGR_SHIFT(3)) &
		       DMA_CH_RX_HOST_FDQ_QMGR_MASK(3));

		__raw_writel(val, base + DMA_CH_RX_HOST_PKT_CFG_REG_B(0));
		DBG("Rx channel host packet configuration B @ %p, "
		    "value written: %x\n",
		    base + DMA_CH_RX_HOST_PKT_CFG_REG_B(0), val);
		break;
	case DMA_CH_RX_DEFAULT_DESC_MONO:
		val = ((cfg->cfg.mono_pkt.fd_queue.q_num <<
			DMA_CH_RX_MONO_FDQ_QNUM_SHIFT) &
		       DMA_CH_RX_MONO_FDQ_QNUM_MASK) |
		      ((cfg->cfg.mono_pkt.fd_queue.q_mgr <<
			DMA_CH_RX_MONO_FDQ_QMGR_SHIFT) &
		       DMA_CH_RX_MONO_FDQ_QMGR_MASK) |
		      ((cfg->cfg.mono_pkt.sop_offset <<
			DMA_CH_RX_MONO_SOP_OFFSET_SHIFT) &
		       DMA_CH_RX_MONO_SOP_OFFSET_MASK);

		__raw_writel(val, base + DMA_CH_RX_MONO_PKT_CFG_REG(0));
		DBG("Rx channel monolithic packet configuration @ %p, "
		    "value written: %x\n",
		    base + DMA_CH_RX_MONO_PKT_CFG_REG(0), val);
		break;
	}
}
EXPORT_SYMBOL(cppi41_rx_ch_configure);

/*
 * cppi41_dma_ch_teardown - teardown a given Tx/Rx channel
 */
void cppi41_dma_ch_teardown(struct cppi41_dma_ch_obj *dma_ch_obj)
{
	u32 val = __raw_readl(dma_ch_obj->base_addr);

	/* Initiate channel teardown. */
	val |= dma_ch_obj->global_cfg & ~DMA_CH_TX_ENABLE_MASK;
	dma_ch_obj->global_cfg = val |= DMA_CH_TX_TEARDOWN_MASK;
	__raw_writel(val, dma_ch_obj->base_addr);
	DBG("Tear down channel @ %p, value written: %x, value read: %x\n",
	    dma_ch_obj->base_addr, val, __raw_readl(dma_ch_obj->base_addr));
}
EXPORT_SYMBOL(cppi41_dma_ch_teardown);

/*
 * cppi41_dma_ch_enable - enable Tx/Rx DMA channel in hardware
 *
 * Makes the channel ready for data transmission/reception.
 */
void cppi41_dma_ch_enable(struct cppi41_dma_ch_obj *dma_ch_obj)
{
	u32 val = dma_ch_obj->global_cfg | DMA_CH_TX_ENABLE_MASK;

	/* Teardown bit remains set after completion, so clear it now... */
	dma_ch_obj->global_cfg = val &= ~DMA_CH_TX_TEARDOWN_MASK;
	__raw_writel(val, dma_ch_obj->base_addr);
	DBG("Enable channel @ %p, value written: %x, value read: %x\n",
	    dma_ch_obj->base_addr, val, __raw_readl(dma_ch_obj->base_addr));
}
EXPORT_SYMBOL(cppi41_dma_ch_enable);

/*
 * cppi41_dma_ch_disable - disable Tx/Rx DMA channel in hardware
 */
void cppi41_dma_ch_disable(struct cppi41_dma_ch_obj *dma_ch_obj)
{
	dma_ch_obj->global_cfg &= ~DMA_CH_TX_ENABLE_MASK;
	__raw_writel(dma_ch_obj->global_cfg, dma_ch_obj->base_addr);
	DBG("Disable channel @ %p, value written: %x, value read: %x\n",
	    dma_ch_obj->base_addr, dma_ch_obj->global_cfg,
	    __raw_readl(dma_ch_obj->base_addr));
}
EXPORT_SYMBOL(cppi41_dma_ch_disable);

void cppi41_free_teardown_queue(int dma_num)
{
	unsigned long td_addr;

	while (1) {
		td_addr = cppi41_queue_pop(&dma_teardown[dma_num].queue_obj);

		if (td_addr == 0)
			break;
	}
}
EXPORT_SYMBOL(cppi41_free_teardown_queue);

/**
 * alloc_queue - allocate a queue in the given range
 * @allocated:	pointer to the bitmap of the allocated queues
 * @excluded:	pointer to the bitmap of the queues excluded from allocation
 *		(optional)
 * @start:	starting queue number
 * @count:	number of queues available
 *
 * Returns queue number on success, -ENOSPC otherwise.
 */
static int alloc_queue(u32 *allocated, const u32 *excluded, unsigned start,
		       unsigned count)
{
	u32 bit, mask = 0;
	int index = -1;

	/*
	 * We're starting the loop as if we've just wrapped around 32 bits
	 * in order to save on preloading the bitmasks.
	 */
	for (bit = 0; count--; start++, bit <<= 1) {
		/* Have we just wrapped around 32 bits? */
		if (!bit) {
			/* Start over with the next bitmask word */
			bit = 1;
			index++;
			/* Have we just entered the loop? */
			if (!index) {
				/* Calculate the starting values */
				bit <<= start & 0x1f;
				index = start >> 5;
			}
			/*
			 * Load the next word of the allocated bitmask OR'ing
			 * it with the excluded bitmask if it's been passed.
			 */
			mask = allocated[index];
			if (excluded != NULL)
				mask |= excluded[index];
		}
		/*
		 * If the bit in the combined bitmask is zero,
		 * we've just found a free queue.
		 */
		if (!(mask & bit)) {
			allocated[index] |= bit;
			return start;
		}
	}
	return -ENOSPC;
}

/*
 * cppi41_queue_alloc - allocate a queue of a given type in the queue manager
 */
int cppi41_queue_alloc(u8 type, u8 q_mgr, u16 *q_num)
{
	int res = -ENOSPC;

	if (q_mgr >= cppi41_num_queue_mgr)
		return -EINVAL;

	/* Mask out the unsupported queue types */
	type &= cppi41_queue_mgr[q_mgr].queue_types;
	/* First see if a free descriptor queue was requested... */
	if (type & CPPI41_FREE_DESC_QUEUE)
		res = alloc_queue(allocated_queues[q_mgr], NULL,
				  cppi41_queue_mgr[q_mgr].base_fdq_num,  16);

	/* Then see if a free descriptor/buffer queue was requested... */
	if (res < 0 && (type & CPPI41_FREE_DESC_BUF_QUEUE))
		res = alloc_queue(allocated_queues[q_mgr], NULL,
				  cppi41_queue_mgr[q_mgr].base_fdbq_num, 16);

	/* Last see if an unassigned queue was requested... */
	if (res < 0 && (type & CPPI41_UNASSIGNED_QUEUE))
		res = alloc_queue(allocated_queues[q_mgr],
				  cppi41_queue_mgr[q_mgr].assigned, 0,
				  cppi41_queue_mgr[q_mgr].num_queue);

	/* See if any queue was allocated... */
	if (res < 0)
		return res;

	/* Return the queue allocated */
	*q_num = res;
	return 0;
}
EXPORT_SYMBOL(cppi41_queue_alloc);

/*
 * cppi41_queue_free - free the given queue in the queue manager
 */
int cppi41_queue_free(u8 q_mgr, u16 q_num)
{
	int index = q_num >> 5, bit = 1 << (q_num & 0x1f);

	if (allocated_queues[q_mgr] != NULL) {
		if (q_mgr >= cppi41_num_queue_mgr ||
		    q_num >= cppi41_queue_mgr[q_mgr].num_queue ||
		    !(allocated_queues[q_mgr][index] & bit))
			return -EINVAL;
		allocated_queues[q_mgr][index] &= ~bit;
	}
	return 0;
}
EXPORT_SYMBOL(cppi41_queue_free);

/*
 * cppi41_queue_init - initialize a CPPI 4.1 queue object
 */
int cppi41_queue_init(struct cppi41_queue_obj *queue_obj, u8 q_mgr, u16 q_num)
{
	if (q_mgr >= cppi41_num_queue_mgr ||
	    q_num >= cppi41_queue_mgr[q_mgr].num_queue)
		return -EINVAL;

	queue_obj->base_addr = cppi41_queue_mgr[q_mgr].q_mgmt_rgn_base +
			       QMGR_QUEUE_STATUS_REG_A(q_num);

	return 0;
}
EXPORT_SYMBOL(cppi41_queue_init);

/*
 * cppi41_queue_push - push a descriptor into the given queue
 */
void cppi41_queue_push(const struct cppi41_queue_obj *queue_obj, u32 desc_addr,
		       u32 desc_size, u32 pkt_size)
{
	u32 val;

	/*
	 * Write to the tail of the queue.
	 * TODO: Can't think of a reason why a queue to head may be required.
	 * If it is, the API may have to be extended.
	 */
#if 0
	/*
	 * Also, can't understand why packet size is required to queue up a
	 * descriptor. The spec says packet size *must* be written prior to
	 * the packet write operation.
	 */
	if (pkt_size)
		val = (pkt_size << QMGR_QUEUE_PKT_SIZE_SHIFT) &
		      QMGR_QUEUE_PKT_SIZE_MASK;
	__raw_writel(val, queue_obj->base_addr + QMGR_QUEUE_REG_C(0));
#endif

	val = (((desc_size - 24) >> (2 - QMGR_QUEUE_DESC_SIZE_SHIFT)) &
	       QMGR_QUEUE_DESC_SIZE_MASK) |
	      (desc_addr & QMGR_QUEUE_DESC_PTR_MASK);

	DBG("Pushing value %x to queue @ %p\n", val, queue_obj->base_addr);

	__raw_writel(val, queue_obj->base_addr + QMGR_QUEUE_REG_D(0));
}
EXPORT_SYMBOL(cppi41_queue_push);

/*
 * cppi41_queue_pop - pop a descriptor from a given queue
 */
unsigned long cppi41_queue_pop(const struct cppi41_queue_obj *queue_obj)
{
	u32 val = __raw_readl(queue_obj->base_addr + QMGR_QUEUE_REG_D(0));

	DBG("Popping value %x from queue @ %p\n", val, queue_obj->base_addr);

	return val & QMGR_QUEUE_DESC_PTR_MASK;
}
EXPORT_SYMBOL(cppi41_queue_pop);

/*
 * cppi41_get_teardown_info - extract information from a teardown descriptor
 */
int cppi41_get_teardown_info(unsigned long addr, u32 *info)
{
	struct cppi41_teardown_desc *desc;
	int dma_num;

	for (dma_num = 0; dma_num < cppi41_num_dma_block; dma_num++)
		if (addr >= dma_teardown[dma_num].phys_addr &&
		    addr <  dma_teardown[dma_num].phys_addr +
			    dma_teardown[dma_num].rgn_size)
			break;

	if (dma_num == cppi41_num_dma_block)
		return -EINVAL;

	desc = addr - dma_teardown[dma_num].phys_addr +
	       dma_teardown[dma_num].virt_addr;

	if ((desc->teardown_info & CPPI41_DESC_TYPE_MASK) !=
	    (CPPI41_DESC_TYPE_TEARDOWN << CPPI41_DESC_TYPE_SHIFT))
		return -EINVAL;

	*info = desc->teardown_info;
#if 1
	/* Hardware is not giving the current DMA number as of now. :-/ */
	*info |= (dma_num << CPPI41_TEARDOWN_DMA_NUM_SHIFT) &
		 CPPI41_TEARDOWN_DMA_NUM_MASK;
#else
	dma_num = (desc->teardown_info & CPPI41_TEARDOWN_DMA_NUM_MASK) >>
		 CPPI41_TEARDOWN_DMA_NUM_SHIFT;
#endif

	cppi41_queue_push(&dma_teardown[dma_num].queue_obj, addr,
			  sizeof(struct cppi41_teardown_desc), 0);

	return 0;
}
EXPORT_SYMBOL(cppi41_get_teardown_info);

MODULE_DESCRIPTION("TI CPPI 4.1 support");
MODULE_AUTHOR("MontaVista Software");
MODULE_LICENSE("GPL");
