linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
@ 2010-05-15 18:14 Sergei Shtylyov
  2010-05-28 20:55 ` Sergei Shtylyov
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Sergei Shtylyov @ 2010-05-15 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for Texas Instuments Communication Port Programming Interface 4.1
(CPPI 4.1) used on OMAP-L1x/DA8xx and AM35x.

At this moment, only the DMA controller and queue manager are supported.
Support for the buffer manager is lacking but these chips don't have it anyway.

Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>

---
Changes since the previous version:
- moved everything from arch/arm/mach-davinci/ to arch/arm/common/;
- s/CONFIG_CPPI41/CONFIG_TI_CPPI41/, made that option invisible;
- added #include <linux/slab.h> for kzalloc();
- switched alloc_queue() and cppi41_queue_free() to using bit operations;
- replaced 'static' linking_ram[] by local variable in cppi41_queue_mgr_init();
- fixed pr_debug() in cppi41_dma_ctrlr_init() to print the real queue manager #.

 arch/arm/common/Kconfig                |    3 
 arch/arm/common/Makefile               |    1 
 arch/arm/common/cppi41.c               |  759 +++++++++++++++++++++++++++++++++
 arch/arm/include/asm/hardware/cppi41.h |  718 +++++++++++++++++++++++++++++++
 4 files changed, 1481 insertions(+)

Index: linux-davinci/arch/arm/common/Kconfig
===================================================================
--- linux-davinci.orig/arch/arm/common/Kconfig
+++ linux-davinci/arch/arm/common/Kconfig
@@ -38,5 +38,8 @@ config SHARP_PARAM
 config SHARP_SCOOP
 	bool
 
+config TI_CPPI41
+	bool
+
 config COMMON_CLKDEV
 	bool
Index: linux-davinci/arch/arm/common/Makefile
===================================================================
--- linux-davinci.orig/arch/arm/common/Makefile
+++ linux-davinci/arch/arm/common/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_TIMER_ACORN)	+= time-acorn.
 obj-$(CONFIG_SHARP_LOCOMO)	+= locomo.o
 obj-$(CONFIG_SHARP_PARAM)	+= sharpsl_param.o
 obj-$(CONFIG_SHARP_SCOOP)	+= scoop.o
+obj-$(CONFIG_TI_CPPI41) 	+= cppi41.o
 obj-$(CONFIG_ARCH_IXP2000)	+= uengine.o
 obj-$(CONFIG_ARCH_IXP23XX)	+= uengine.o
 obj-$(CONFIG_PCI_HOST_ITE8152)  += it8152.o
Index: linux-davinci/arch/arm/common/cppi41.c
===================================================================
--- /dev/null
+++ linux-davinci/arch/arm/common/cppi41.c
@@ -0,0 +1,759 @@
+/*
+ * CPPI 4.1 support
+ *
+ * Copyright (C) 2008-2010 MontaVista Software, Inc. <source@mvista.com>
+ *
+ * Based on the PAL CPPI 4.1 implementation
+ * Copyright (C) 2007, Texas Instruments Inc. http://www.ti.com/
+ *
+ * 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.
+ *
+ */
+
+#undef	DEBUG
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/hardware/cppi41.h>
+
+static unsigned long *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;
+} dma_teardown[CPPI41_NUM_DMA_BLOCK];
+
+/******************** CPPI 4.1 Functions (External Interface) *****************/
+
+int __init cppi41_queue_mgr_init(u8 q_mgr, dma_addr_t rgn0_base, u16 rgn0_size)
+{
+	static struct {
+		void *virt_addr;
+		dma_addr_t phys_addr;
+	} linking_ram;
+	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;
+
+	__raw_writel(rgn0_base, q_mgr_regs + QMGR_LINKING_RAM_RGN0_BASE_REG);
+	pr_debug("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);
+	pr_debug("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 = dma_alloc_coherent(NULL, 0x10000 - rgn0_size * 4,
+				 &linking_ram.phys_addr, GFP_KERNEL | GFP_DMA);
+	if (ptr == NULL) {
+		pr_err("ERROR: %s: Unable to allocate linking RAM.\n",
+		       __func__);
+		return -ENOMEM;
+	}
+	linking_ram.virt_addr = ptr;
+
+	__raw_writel(linking_ram.phys_addr,
+		     q_mgr_regs + QMGR_LINKING_RAM_RGN1_BASE_REG);
+	pr_debug("Linking RAM region 1 base @ %p, value: %x\n",
+		 q_mgr_regs + QMGR_LINKING_RAM_RGN1_BASE_REG,
+		 __raw_readl(q_mgr_regs + QMGR_LINKING_RAM_RGN1_BASE_REG));
+
+	ptr = kzalloc(BITS_TO_LONGS(cppi41_queue_mgr[q_mgr].num_queue),
+		      GFP_KERNEL);
+	if (ptr == NULL) {
+		pr_err("ERROR: %s: Unable to allocate queue bitmap.\n",
+		       __func__);
+		dma_free_coherent(NULL, 0x10000 - rgn0_size * 4,
+				  linking_ram.virt_addr, linking_ram.phys_addr);
+		return -ENOMEM;
+	}
+	allocated_queues[q_mgr] = ptr;
+
+	return 0;
+}
+
+int __init cppi41_dma_ctrlr_init(u8 dma_num, u8 q_mgr, u8 num_order)
+{
+	const struct cppi41_dma_block *dma_block;
+	struct cppi41_teardown_desc *curr_td;
+	unsigned num_desc = 1 << num_order;
+	dma_addr_t td_addr;
+	void *ptr;
+	int error, i;
+	u16 q_num;
+
+	if (dma_num >= cppi41_num_dma_block ||
+	    q_mgr >= cppi41_num_queue_mgr)
+		return -EINVAL;
+
+	error = cppi41_queue_alloc(CPPI41_FREE_DESC_QUEUE |
+				   CPPI41_UNASSIGNED_QUEUE, q_mgr, &q_num);
+	if (error) {
+		pr_err("ERROR: %s: Unable to allocate teardown descriptor "
+		       "queue.\n", __func__);
+		return error;
+	}
+	pr_debug("Teardown descriptor queue %d in queue manager %d allocated\n",
+		 q_num, q_mgr);
+
+	/*
+	 * 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);
+	pr_debug("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));
+
+	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) {
+		pr_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) {
+		pr_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) {
+		pr_err("ERROR: %s: Unable to initialize teardown free "
+		       "descriptor queue.\n", __func__);
+		goto free_rgn;
+	}
+
+	/*
+	 * 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);
+	}
+
+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;
+}
+
+int __init cppi41_dma_sched_init(u8 dma_num, const u8 *sched_tbl, u16 tbl_size)
+{
+	const struct cppi41_dma_block *dma_block;
+	unsigned num_reg;
+	int i, j, k;
+	u32 val;
+
+	if (dma_num >= cppi41_num_dma_block ||
+	    !tbl_size || tbl_size > 0x100 || sched_tbl == NULL)
+		return -EINVAL;
+
+	/* Initialize the DMA scheduler. */
+	dma_block = &cppi41_dma_block[dma_num];
+	num_reg = (tbl_size + 3) / 4;
+	for (k = i = 0; i < num_reg; i++) {
+		for (val = j = 0; j < 4; j++, k++) {
+			val >>= 8;
+			if (k < tbl_size)
+				val |= sched_tbl[k] << 24;
+		}
+
+		__raw_writel(val, dma_block->sched_table_base +
+			     DMA_SCHED_TABLE_WORD_REG(i));
+		pr_debug("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);
+	pr_debug("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;
+}
+
+/*
+ * 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;
+
+	pr_debug("%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));
+	pr_debug("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));
+	pr_debug("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;
+
+	pr_debug("%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);
+	pr_debug("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);
+	pr_debug("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));
+		pr_debug("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));
+		pr_debug("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));
+		pr_debug("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));
+		pr_debug("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));
+		pr_debug("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);
+	pr_debug("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);
+	pr_debug("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);
+	pr_debug("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);
+
+/**
+ * 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(unsigned long *allocated, const unsigned long *excluded,
+		       unsigned start, unsigned count)
+{
+	unsigned n, end = start + count;
+
+	do {
+		n = find_next_zero_bit(allocated, end, start);
+		if (n >= end)
+			return -ENOSPC;
+		start = n + 1;
+	} while (test_bit(n, excluded) || test_and_set_bit(n, allocated));
+
+	return n;
+}
+
+/*
+ * 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)
+{
+	if (q_mgr >= cppi41_num_queue_mgr ||
+	    q_num >= cppi41_queue_mgr[q_mgr].num_queue ||
+	    !test_and_clear_bit(q_num, allocated_queues[q_mgr]))
+		return -EINVAL;
+	else
+		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);
+
+	pr_debug("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));
+
+	pr_debug("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);
Index: linux-davinci/arch/arm/include/asm/hardware/cppi41.h
===================================================================
--- /dev/null
+++ linux-davinci/arch/arm/include/asm/hardware/cppi41.h
@@ -0,0 +1,718 @@
+/*
+ * CPPI 4.1 definitions
+ *
+ * Copyright (c) 2008-2010, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * Based on the PAL CPPI 4.1 implementation
+ * Copyright (C) 2007, Texas Instruments, Inc. http://www.ti.com/
+ *
+ * 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/types.h>
+
+/*
+ * Queue Manager - Control Registers Region
+ */
+#define QMGR_REVISION_REG		0x00	/* Major and minor versions */
+						/* of the module */
+#define QMGR_QUEUE_DIVERSION_REG	0x08	/* Queue Diversion register */
+#define QMGR_FREE_DESC_BUF_STARVED_REG(n) (0x20 + ((n) << 2)) /* Free Desc./ */
+						/* Buffer Starvation Count */
+#define QMGR_FREE_DESC_STARVED_REG(n)	(0x30 + ((n) << 2)) /* Free Desc. */
+						/* Starvation Count */
+#define QMGR_LINKING_RAM_RGN0_BASE_REG	0x80	/* Linking RAM Region 0 Base */
+						/* Address */
+#define QMGR_LINKING_RAM_RGN0_SIZE_REG	0x84	/* Linking RAM Region 0 Size */
+#define QMGR_LINKING_RAM_RGN1_BASE_REG	0x88	/* Linking RAM Region 1 Base */
+						/* Address */
+#define QMGR_QUEUE_PENDING_REG(n)	(0x90 + ((n) << 2)) /* Pending status */
+						/* for all queues */
+
+/*
+ * Queue Manager - Memory Region Registers
+ */
+#define QMGR_MEM_RGN_BASE_REG(r)	(0x00 + ((r) << 4))
+#define QMGR_MEM_RGN_CTRL_REG(r)	(0x04 + ((r) << 4))
+
+/* Memory Region R Control Register bits */
+#define QMGR_MEM_RGN_INDEX_SHIFT	16
+#define QMGR_MEM_RGN_INDEX_MASK 	(0x3fff << QMGR_MEM_RGN_INDEX_SHIFT)
+#define QMGR_MEM_RGN_DESC_SIZE_SHIFT	8
+#define QMGR_MEM_RGN_DESC_SIZE_MASK	(0xf << QMGR_MEM_RGN_DESC_SIZE_SHIFT)
+#define QMGR_MEM_RGN_SIZE_SHIFT 	0
+#define QMGR_MEM_RGN_SIZE_MASK		(7 << QMGR_MEM_RGN_SIZE_SHIFT)
+
+/*
+ * Queue Manager - Queues Region
+ */
+#define QMGR_QUEUE_REG_A(n)		(0x00 + ((n) << 4))
+#define QMGR_QUEUE_REG_B(n)		(0x04 + ((n) << 4))
+#define QMGR_QUEUE_REG_C(n)		(0x08 + ((n) << 4))
+#define QMGR_QUEUE_REG_D(n)		(0x0C + ((n) << 4))
+
+/* Queue N Register C bits */
+#define QMGR_QUEUE_HEAD_TAIL_SHIFT	31
+#define QMGR_QUEUE_HEAD_TAIL_MASK	(1 << QMGR_QUEUE_HEAD_TAIL_SHIFT)
+#define QMGR_QUEUE_PKT_SIZE_SHIFT	0
+#define QMGR_QUEUE_PKT_SIZE_MASK	(0x3fff << QMGR_QUEUE_PKT_SIZE_SHIFT)
+/* Queue N Register D bits */
+#define QMGR_QUEUE_DESC_PTR_SHIFT	5
+#define QMGR_QUEUE_DESC_PTR_MASK	(0x7ffffff << QMGR_QUEUE_DESC_PTR_SHIFT)
+#define QMGR_QUEUE_DESC_SIZE_SHIFT	0
+#define QMGR_QUEUE_DESC_SIZE_MASK	(0x1f << QMGR_QUEUE_DESC_SIZE_SHIFT)
+
+/*
+ * Queue Manager - Queue Status Region
+ */
+#define QMGR_QUEUE_STATUS_REG_A(n)	(0x00 + ((n) << 4))
+#define QMGR_QUEUE_STATUS_REG_B(n)	(0x04 + ((n) << 4))
+#define QMGR_QUEUE_STATUS_REG_C(n)	(0x08 + ((n) << 4))
+
+/*
+ * DMA Controller - Global Control Registers Region
+ */
+#define DMA_REVISION_REG		0x00	/* Major and minor versions */
+						/* of the module */
+#define DMA_TEARDOWN_FREE_DESC_CTRL_REG 0x04	/* Queue  manager and queue */
+						/* number for Teardown free */
+						/* descriptor queue */
+#define DMA_EMULATION_CTRL_REG		0x08	/* Emulation control register */
+
+/* Teardown Free Descriptor Queue Control Register bits */
+#define DMA_TD_DESC_QMGR_SHIFT		12
+#define DMA_TD_DESC_QMGR_MASK		(3 << DMA_TD_DESC_QMGR_SHIFT)
+#define DMA_TD_DESC_QNUM_SHIFT		0
+#define DMA_TD_DESC_QNUM_MASK		(0xfff << DMA_TD_DESC_QNUM_SHIFT)
+
+/*
+ * DMA Controller - Channel Control / Status Registers Region
+ */
+#define DMA_CH_TX_GLOBAL_CFG_REG(n)	 (0x00 + ((n) << 5))
+#define DMA_CH_RX_GLOBAL_CFG_REG(n)	 (0x08 + ((n) << 5))
+#define DMA_CH_RX_HOST_PKT_CFG_REG_A(n)  (0x0C + ((n) << 5))
+#define DMA_CH_RX_HOST_PKT_CFG_REG_B(n)  (0x10 + ((n) << 5))
+#define DMA_CH_RX_EMBED_PKT_CFG_REG_A(n) (0x14 + ((n) << 5))
+#define DMA_CH_RX_EMBED_PKT_CFG_REG_B(n) (0x18 + ((n) << 5))
+#define DMA_CH_RX_MONO_PKT_CFG_REG(n)	 (0x1C + ((n) << 5))
+
+/* Tx Channel N Global Configuration Register bits */
+#define DMA_CH_TX_ENABLE_SHIFT		31
+#define DMA_CH_TX_ENABLE_MASK		(1 << DMA_CH_TX_ENABLE_SHIFT)
+#define DMA_CH_TX_TEARDOWN_SHIFT	30
+#define DMA_CH_TX_TEARDOWN_MASK		(1 << DMA_CH_TX_TEARDOWN_SHIFT)
+#define DMA_CH_TX_DEFAULT_QMGR_SHIFT	12
+#define DMA_CH_TX_DEFAULT_QMGR_MASK	(3 << DMA_CH_TX_DEFAULT_QMGR_SHIFT)
+#define DMA_CH_TX_DEFAULT_QNUM_SHIFT	0
+#define DMA_CH_TX_DEFAULT_QNUM_MASK	(0xfff << DMA_CH_TX_DEFAULT_QNUM_SHIFT)
+
+/* Rx Channel N Global Configuration Register bits */
+#define DMA_CH_RX_ENABLE_SHIFT		31
+#define DMA_CH_RX_ENABLE_MASK		(1 << DMA_CH_RX_ENABLE_SHIFT)
+#define DMA_CH_RX_TEARDOWN_SHIFT	30
+#define DMA_CH_RX_TEARDOWN_MASK		(1 << DMA_CH_RX_TEARDOWN_SHIFT)
+#define DMA_CH_RX_ERROR_HANDLING_SHIFT	24
+#define DMA_CH_RX_ERROR_HANDLING_MASK	(1 << DMA_CH_RX_ERROR_HANDLING_SHIFT)
+#define DMA_CH_RX_SOP_OFFSET_SHIFT	16
+#define DMA_CH_RX_SOP_OFFSET_MASK	(0xff << DMA_CH_RX_SOP_OFFSET_SHIFT)
+#define DMA_CH_RX_DEFAULT_DESC_TYPE_SHIFT 14
+#define DMA_CH_RX_DEFAULT_DESC_TYPE_MASK  (3 << \
+					   DMA_CH_RX_DEFAULT_DESC_TYPE_SHIFT)
+#define DMA_CH_RX_DEFAULT_DESC_EMBED	0
+#define DMA_CH_RX_DEFAULT_DESC_HOST	1
+#define DMA_CH_RX_DEFAULT_DESC_MONO	2
+#define DMA_CH_RX_DEFAULT_RQ_QMGR_SHIFT 12
+#define DMA_CH_RX_DEFAULT_RQ_QMGR_MASK	(3 << DMA_CH_RX_DEFAULT_RQ_QMGR_SHIFT)
+#define DMA_CH_RX_DEFAULT_RQ_QNUM_SHIFT 0
+#define DMA_CH_RX_DEFAULT_RQ_QNUM_MASK	(0xfff << \
+					 DMA_CH_RX_DEFAULT_RQ_QNUM_SHIFT)
+
+/* Rx Channel N Host Packet Configuration Register A/B bits */
+#define DMA_CH_RX_HOST_FDQ_QMGR_SHIFT(n) (12 + 16 * ((n) & 1))
+#define DMA_CH_RX_HOST_FDQ_QMGR_MASK(n)  (3 << DMA_CH_RX_HOST_FDQ_QMGR_SHIFT(n))
+#define DMA_CH_RX_HOST_FDQ_QNUM_SHIFT(n) (0 + 16 * ((n) & 1))
+#define DMA_CH_RX_HOST_FDQ_QNUM_MASK(n)  (0xfff << \
+					  DMA_CH_RX_HOST_FDQ_QNUM_SHIFT(n))
+
+/* Rx Channel N Embedded Packet Configuration Register A bits */
+#define DMA_CH_RX_EMBED_FBP_BMGR_SHIFT(n) (6 + 8 * (n))
+#define DMA_CH_RX_EMBED_FBP_BMGR_MASK(n)  (3 << \
+					   DMA_CH_RX_EMBED_FBP_BMGR_SHIFT(n))
+#define DMA_CH_RX_EMBED_FBP_PNUM_SHIFT(n) (0 + 8 * (n))
+#define DMA_CH_RX_EMBED_FBP_PNUM_MASK(n)  (0x1f << \
+					   DMA_CH_RX_EMBED_FBP_PNUM_SHIFT(n))
+
+/* Rx Channel N Embedded Packet Configuration Register B bits */
+#define DMA_CH_RX_EMBED_NUM_SLOT_SHIFT	24
+#define DMA_CH_RX_EMBED_NUM_SLOT_MASK	(7 << DMA_CH_RX_EMBED_NUM_SLOT_SHIFT)
+#define DMA_CH_RX_EMBED_SOP_SLOT_SHIFT	16
+#define DMA_CH_RX_EMBED_SOP_SLOT_MASK	(7 << DMA_CH_RX_EMBED_SOP_SLOT_SHIFT)
+#define DMA_CH_RX_EMBED_FDQ_QMGR_SHIFT	12
+#define DMA_CH_RX_EMBED_FDQ_QMGR_MASK	(3 << DMA_CH_RX_EMBED_FDQ_QMGR_SHIFT)
+#define DMA_CH_RX_EMBED_FDQ_QNUM_SHIFT	0
+#define DMA_CH_RX_EMBED_FDQ_QNUM_MASK	(0xfff << \
+					 DMA_CH_RX_EMBED_FDQ_QNUM_SHIFT)
+
+/* Rx Channel N Monolithic Packet Configuration Register bits */
+#define DMA_CH_RX_MONO_SOP_OFFSET_SHIFT 16
+#define DMA_CH_RX_MONO_SOP_OFFSET_MASK	(0xff << \
+					 DMA_CH_RX_MONO_SOP_OFFSET_SHIFT)
+#define DMA_CH_RX_MONO_FDQ_QMGR_SHIFT	12
+#define DMA_CH_RX_MONO_FDQ_QMGR_MASK	(3 << DMA_CH_RX_MONO_FDQ_QMGR_SHIFT)
+#define DMA_CH_RX_MONO_FDQ_QNUM_SHIFT	0
+#define DMA_CH_RX_MONO_FDQ_QNUM_MASK	(0xfff << DMA_CH_RX_MONO_FDQ_QNUM_SHIFT)
+
+/*
+ * DMA Scheduler - Control Region
+ */
+#define DMA_SCHED_CTRL_REG		0x00
+
+/* DMA Scheduler Control Register bits */
+#define DMA_SCHED_ENABLE_SHIFT		31
+#define DMA_SCHED_ENABLE_MASK		(1 << DMA_SCHED_ENABLE_SHIFT)
+#define DMA_SCHED_LAST_ENTRY_SHIFT	0
+#define DMA_SCHED_LAST_ENTRY_MASK	(0xff << DMA_SCHED_LAST_ENTRY_SHIFT)
+
+/*
+ * DMA Scheduler - Table Region
+ */
+#define DMA_SCHED_TABLE_WORD_REG(n)	((n) << 2)
+
+/*
+ * CPPI 4.1 Host Packet Descriptor
+ */
+struct cppi41_host_pkt_desc {
+	u32 desc_info;		/* Descriptor type, protocol specific word */
+				/* count, packet length */
+	u32 tag_info;		/* Source tag (31:16), destination tag (15:0) */
+	u32 pkt_info;		/* Packet error state, type, protocol flags, */
+				/* return info, descriptor location */
+	u32 buf_len;		/* Number of valid data bytes in the buffer */
+	u32 buf_ptr;		/* Pointer to the buffer associated with */
+				/* this descriptor */
+	u32 next_desc_ptr;	/* Pointer to the next buffer descriptor */
+	u32 orig_buf_len;	/* Original buffer length */
+	u32 orig_buf_ptr;	/* Original buffer pointer */
+	u32 stk_comms_info[2];	/* Network stack private communications info */
+};
+
+/*
+ * CPPI 4.1 Host Buffer Descriptor
+ */
+struct cppi41_host_buf_desc {
+	u32 reserved[2];
+	u32 buf_recl_info;	/* Return info, descriptor location */
+	u32 buf_len;		/* Number of valid data bytes in the buffer */
+	u32 buf_ptr;		/* Pointer to the buffer associated with */
+				/* this descriptor */
+	u32 next_desc_ptr;	/* Pointer to the next buffer descriptor */
+	u32 orig_buf_len;	/* Original buffer length */
+	u32 orig_buf_ptr;	/* Original buffer pointer */
+};
+
+#define CPPI41_DESC_TYPE_SHIFT		27
+#define CPPI41_DESC_TYPE_MASK		(0x1f << CPPI41_DESC_TYPE_SHIFT)
+#define CPPI41_DESC_TYPE_HOST		16
+#define CPPI41_DESC_TYPE_MONOLITHIC	18
+#define CPPI41_DESC_TYPE_TEARDOWN	19
+#define CPPI41_PROT_VALID_WORD_CNT_SHIFT 22
+#define CPPI41_PROT_VALID_WORD_CNT_MASK	(0x1f << CPPI41_PROT_WORD_CNT_SHIFT)
+#define CPPI41_PKT_LEN_SHIFT		0
+#define CPPI41_PKT_LEN_MASK		(0x1fffff << CPPI41_PKT_LEN_SHIFT)
+
+#define CPPI41_PKT_ERROR_SHIFT		31
+#define CPPI41_PKT_ERROR_MASK		(1 << CPPI41_PKT_ERROR_SHIFT)
+#define CPPI41_PKT_TYPE_SHIFT		26
+#define CPPI41_PKT_TYPE_MASK		(0x1f << CPPI41_PKT_TYPE_SHIFT)
+#define CPPI41_PKT_TYPE_ATM_AAL5	0
+#define CPPI41_PKT_TYPE_ATM_NULL_AAL	1
+#define CPPI41_PKT_TYPE_ATM_OAM		2
+#define CPPI41_PKT_TYPE_ATM_TRANSPARENT	3
+#define CPPI41_PKT_TYPE_EFM		4
+#define CPPI41_PKT_TYPE_USB		5
+#define CPPI41_PKT_TYPE_GENERIC		6
+#define CPPI41_PKT_TYPE_ETHERNET 	7
+#define CPPI41_RETURN_POLICY_SHIFT	15
+#define CPPI41_RETURN_POLICY_MASK 	(1 << CPPI41_RETURN_POLICY_SHIFT)
+#define CPPI41_RETURN_LINKED		0
+#define CPPI41_RETURN_UNLINKED		1
+#define CPPI41_ONCHIP_SHIFT		14
+#define CPPI41_ONCHIP_MASK		(1 << CPPI41_ONCHIP_SHIFT)
+#define CPPI41_RETURN_QMGR_SHIFT 	12
+#define CPPI41_RETURN_QMGR_MASK		(3 << CPPI41_RETURN_QMGR_SHIFT)
+#define CPPI41_RETURN_QNUM_SHIFT 	0
+#define CPPI41_RETURN_QNUM_MASK		(0xfff << CPPI41_RETURN_QNUM_SHIFT)
+
+#define CPPI41_SRC_TAG_PORT_NUM_SHIFT	27
+#define CPPI41_SRC_TAG_PORT_NUM_MASK	(0x1f << CPPI41_SRC_TAG_PORT_NUM_SHIFT)
+#define CPPI41_SRC_TAG_CH_NUM_SHIFT	21
+#define CPPI41_SRC_TAG_CH_NUM_MASK	(0x3f << CPPI41_SRC_TAG_CH_NUM_SHIFT)
+#define CPPI41_SRC_TAG_SUB_CH_NUM_SHIFT 16
+#define CPPI41_SRC_TAG_SUB_CH_NUM_MASK	(0x1f << \
+					CPPI41_SRC_TAG_SUB_CH_NUM_SHIFT)
+#define CPPI41_DEST_TAG_SHIFT		0
+#define CPPI41_DEST_TAG_MASK		(0xffff << CPPI41_DEST_TAG_SHIFT)
+
+/*
+ * CPPI 4.1 Teardown Descriptor
+ */
+struct cppi41_teardown_desc {
+	u32 teardown_info;	/* Teardown information */
+	u32 reserved[7];	/* 28 byte padding */
+};
+
+#define CPPI41_TEARDOWN_TX_RX_SHIFT	16
+#define CPPI41_TEARDOWN_TX_RX_MASK	(1 << CPPI41_TEARDOWN_TX_RX_SHIFT)
+#define CPPI41_TEARDOWN_DMA_NUM_SHIFT	10
+#define CPPI41_TEARDOWN_DMA_NUM_MASK	(0x3f << CPPI41_TEARDOWN_DMA_NUM_SHIFT)
+#define CPPI41_TEARDOWN_CHAN_NUM_SHIFT	0
+#define CPPI41_TEARDOWN_CHAN_NUM_MASK	(0x3f << CPPI41_TEARDOWN_CHAN_NUM_SHIFT)
+
+#define CPPI41_MAX_MEM_RGN		16
+
+/* CPPI 4.1 configuration for DA8xx */
+#define CPPI41_NUM_QUEUE_MGR		1	/* 4  max */
+#define CPPI41_NUM_DMA_BLOCK		4	/* 64 max */
+
+/**
+ * struct cppi41_queue - Queue Tuple
+ *
+ * The basic queue tuple in CPPI 4.1 used across all data structures
+ * where a definition of a queue is required.
+ */
+struct cppi41_queue {
+	u8  q_mgr;		/* The queue manager number */
+	u16 q_num;		/* The queue number */
+};
+
+/**
+ * struct cppi41_buf_pool - Buffer Pool Tuple
+ *
+ * The basic buffer pool tuple in CPPI 4.1 used across all data structures
+ * where a definition of a buffer pool is required.
+ */
+struct cppi41_buf_pool {
+	u8  b_mgr;		/* The buffer manager number */
+	u16 b_pool;		/* The buffer pool number */
+};
+
+/**
+ * struct cppi41_queue_mgr - Queue Manager information
+ *
+ * Contains the information about the queue manager which should be copied from
+ * the hardware spec as is.
+ */
+struct cppi41_queue_mgr {
+	void __iomem *q_mgr_rgn_base; /* Base address of the Control region. */
+	void __iomem *desc_mem_rgn_base; /* Base address of the descriptor */
+				/* memory region. */
+	void __iomem *q_mgmt_rgn_base; /* Base address of the queues region. */
+	void __iomem *q_stat_rgn_base; /* Base address of the queue status */
+				/* region. */
+	u16 num_queue;		/* Number of the queues supported. */
+	u8  queue_types; 	/* Bitmask of the supported queue types. */
+	u16 base_fdq_num;	/* The base free descriptor queue number. */
+				/* If present, there's always 16 such queues. */
+	u16 base_fdbq_num;	/* The base free descriptor/buffer queue */
+				/* number.  If present, there's always 16 */
+				/* such queues. */
+	const unsigned long *assigned; /* Pointer to the bitmask of the */
+				/* pre-assigned queues. */
+};
+
+/* Queue type flags */
+#define CPPI41_FREE_DESC_QUEUE		0x01
+#define CPPI41_FREE_DESC_BUF_QUEUE	0x02
+#define CPPI41_UNASSIGNED_QUEUE 	0x04
+
+/**
+ * struct cppi41_embed_pkt_cfg - Rx Channel Embedded packet configuration
+ *
+ * An instance of this structure forms part of the Rx channel information
+ * structure.
+ */
+struct cppi41_embed_pkt_cfg {
+	struct cppi41_queue fd_queue; /* Free Descriptor queue.*/
+	u8 num_buf_slot;	/* Number of buffer slots in the descriptor */
+	u8 sop_slot_num;	/* SOP buffer slot number. */
+	struct cppi41_buf_pool free_buf_pool[4]; /* Free Buffer pool. Element */
+				/* 0 used for the 1st Rx buffer, etc. */
+};
+
+/**
+ * struct cppi41_host_pkt_cfg - Rx Channel Host Packet Configuration
+ *
+ * An instance of this structure forms part of the Rx channel information
+ * structure.
+ */
+struct cppi41_host_pkt_cfg {
+	struct cppi41_queue fdb_queue[4]; /* Free Desc/Buffer queue. Element */
+				/* 0 used for 1st Rx buffer, etc. */
+};
+
+/**
+ * struct cppi41_mono_pkt_cfg - Rx Channel Monolithic Packet Configuration
+ *
+ * An instance of this structure forms part of the Rx channel information
+ * structure.
+ */
+struct cppi41_mono_pkt_cfg {
+	struct cppi41_queue fd_queue; /* Free descriptor queue */
+	u8 sop_offset;		/* Number of bytes to skip before writing */
+				/* payload */
+};
+
+enum cppi41_rx_desc_type {
+	cppi41_rx_embed_desc,
+	cppi41_rx_host_desc,
+	cppi41_rx_mono_desc,
+};
+
+/**
+ * struct cppi41_rx_ch_cfg - Rx Channel Configuration
+ *
+ * Must be allocated and filled by the caller of cppi41_rx_ch_configure().
+ *
+ * The same channel can be configured to receive different descripor type
+ * packets (not simultaneously). When the Rx packets on a port need to be sent
+ * to the SR, the channel's default descriptor type is set to Embedded and the
+ * Rx completion queue is set to the queue which CPU polls for input packets.
+ * When in SR bypass mode, the same channel's default descriptor type will be
+ * set to Host and the Rx completion queue set to one of the queues which host
+ * can get interrupted on (via the Queuing proxy/accumulator). In this example,
+ * the embedded mode configuration fetches free descriptor from the Free
+ * descriptor queue (as defined by struct cppi41_embed_pkt_cfg) and host
+ * mode configuration fetches free descriptors/buffers from the free descriptor/
+ * buffer queue (as defined by struct cppi41_host_pkt_cfg).
+ *
+ * NOTE: There seems to be no separate configuration for teardown completion
+ * descriptor. The assumption is rxQueue tuple is used for this purpose as well.
+ */
+struct cppi41_rx_ch_cfg {
+	enum cppi41_rx_desc_type default_desc_type; /* Describes which queue */
+				/* configuration is used for the free */
+				/* descriptors and/or buffers */
+	u8 sop_offset;		/* Number of bytes to skip in SOP buffer */
+				/* before writing payload */
+	u8 retry_starved;	/* 0 = Drop packet on descriptor/buffer */
+				/* starvartion, 1 = DMA retries FIFO block */
+				/* transfer at a later time */
+	struct cppi41_queue rx_queue; /* Rx complete packets queue */
+	union {
+		struct cppi41_host_pkt_cfg host_pkt; /* Host packet */
+				/* configuration. This defines where channel */
+				/* picks free descriptors from. */
+		struct cppi41_embed_pkt_cfg embed_pkt; /* Embedded packet */
+				/* configuration. This defines where channel */
+				/* picks free descriptors/buffers from. */
+				/* from. */
+		struct cppi41_mono_pkt_cfg mono_pkt; /* Monolithic packet */
+				/* configuration. This defines where channel */
+				/* picks free descriptors from. */
+	} cfg;			/* Union of packet configuration structures */
+				/* to be filled in depending on the */
+				/* defDescType field. */
+};
+
+/**
+ * struct cppi41_tx_ch - Tx channel information
+ *
+ * NOTE: The queues that feed into the Tx channel are fixed at SoC design time.
+ */
+struct cppi41_tx_ch {
+	u8 port_num;		/* Port number. */
+	u8 ch_num;		/* Channel number within port. */
+	u8 sub_ch_num;		/* Sub-channel number within channel. */
+	u8 num_tx_queue;	/* Number of queues from which the channel */
+				/* can feed. */
+	struct cppi41_queue tx_queue[4]; /* List of queues from which the */
+				/* channel can feed. */
+};
+
+/**
+ * struct cppi41_dma_block - CPPI 4.1 DMA configuration
+ *
+ * Configuration information for CPPI DMA functionality. Includes the Global
+ * configuration, Channel configuration, and the Scheduler configuration.
+ */
+struct cppi41_dma_block {
+	void __iomem *global_ctrl_base; /* Base address of the Global Control */
+				/* registers. */
+	void __iomem *ch_ctrl_stat_base; /* Base address of the Channel */
+				/* Control/Status registers. */
+	void __iomem *sched_ctrl_base; /* Base address of the Scheduler */
+				/* Control register. */
+	void __iomem *sched_table_base; /* Base address of the Scheduler */
+				/* Table registers. */
+	u8 num_tx_ch;		/* Number of the Tx channels. */
+	u8 num_rx_ch;		/* Number of the Rx channels. */
+	const struct cppi41_tx_ch *tx_ch_info;
+};
+
+extern const struct cppi41_queue_mgr cppi41_queue_mgr[];
+extern const struct cppi41_dma_block cppi41_dma_block[];
+extern const u8 cppi41_num_queue_mgr;
+extern const u8 cppi41_num_dma_block;
+
+/**
+ * struct cppi41_dma_ch_obj - CPPI 4.1 DMA Channel object
+ */
+struct cppi41_dma_ch_obj {
+	void __iomem *base_addr; /* The address of the channel global */
+				/* configuration register */
+	u32 global_cfg;		/* Tx/Rx global configuration backed-up value */
+};
+
+/**
+ * struct cppi41_queue_obj - CPPI 4.1 queue object
+ */
+struct cppi41_queue_obj {
+	void __iomem *base_addr; /* The base address of the queue management */
+				/* registers */
+};
+
+/**
+ * cppi41_queue_mgr_init - CPPI 4.1 queue manager initialization.
+ * @q_mgr:	the queue manager to initialize
+ * @rgn0_base:	linking RAM region 0 physical address
+ * @rgn0_size:	linking RAM region 0 size in 32-bit words (0 to 0x3fff)
+ *
+ * Returns 0 on success, error otherwise.
+ */
+int cppi41_queue_mgr_init(u8 q_mgr, dma_addr_t rgn0_base, u16 rgn0_size);
+
+/*
+ * CPPI 4.1 Queue Manager Memory Region Allocation and De-allocation APIs.
+ */
+
+/**
+ * cppi41_mem_rgn_alloc - CPPI 4.1 queue manager memory region allocation.
+ * @q_mgr:	the queue manager whose memory region to allocate
+ * @rgn_addr:	physical address of the memory region
+ * @size_order:	descriptor size as a power of two (between 5 and 13)
+ * @num_order:	number of descriptors as a power of two (between 5 and 12)
+ * @mem_rgn:	pointer to the index of the memory region allocated
+ *
+ * This function allocates a memory region within the queue manager
+ * consisiting of the descriptors of paricular size and number.
+ *
+ * Returns 0 on success, error otherwise.
+ */
+int cppi41_mem_rgn_alloc(u8 q_mgr, dma_addr_t rgn_addr, u8 size_order,
+			 u8 num_order, u8 *mem_rgn);
+
+/**
+ * cppi41_mem_rgn_free - CPPI 4.1 queue manager memory region de-allocation.
+ * @q_mgr:	the queue manager whose memory region was allocated
+ * @mem_rgn:	index of the memory region
+ *
+ * This function frees the memory region allocated by cppi41_mem_rgn_alloc().
+ *
+ * Returns 0 on success, -EINVAL otherwise.
+ */
+int cppi41_mem_rgn_free(u8 q_mgr, u8 mem_rgn);
+
+/**
+ * cppi41_dma_ctrlr_init - CPPI 4.1 DMA controller initialization.
+ * @dma_num:	number of the DMA block
+ * @q_mgr:	the queue manager in which to allocate the free teardown
+ *		descriptor queue
+ * @num_order:	number of teardown descriptors as a power of two (at least 5)
+ *
+ * Returns 0 on success, error otherwise.
+ */
+int cppi41_dma_ctrlr_init(u8 dma_num, u8 q_mgr, u8 num_order);
+
+/**
+ * cppi41_dma_sched_init - CPPI 4.1 DMA scheduler initialization.
+ * @dma_num:	number of the DMA block
+ * @sched_tbl:	the DMA scheduler table
+ * @tbl_size:	number of entries in the DMA scheduler table
+ *
+ * Returns 0 on success, error otherwise.
+ */
+int cppi41_dma_sched_init(u8 dma_num, const u8 *sched_tbl, u16 tbl_size);
+
+/*
+ * CPPI 4.1 DMA Channel Management APIs
+ */
+
+/**
+ * cppi41_tx_ch_init - initialize CPPI 4.1 transmit channel object
+ * @tx_ch_obj:	pointer to Tx channel object
+ * @dma_num:	DMA block to which this channel belongs
+ * @ch_num:	DMA channel number
+ *
+ * Returns 0 if valid Tx channel, -EINVAL otherwise.
+ */
+int cppi41_tx_ch_init(struct cppi41_dma_ch_obj *tx_ch_obj,
+		      u8 dma_num, u8 ch_num);
+
+/**
+ * cppi41_rx_ch_init - initialize CPPI 4.1 receive channel object
+ * @rx_ch_obj:	pointer to Rx channel object
+ * @dma_num:	DMA block to which this channel belongs
+ * @ch_num:	DMA channel number
+ *
+ * Returns 0 if valid Rx channel, -EINVAL otherwise.
+ */
+int cppi41_rx_ch_init(struct cppi41_dma_ch_obj *rx_ch_obj,
+		      u8 dma_num, u8 ch_num);
+
+/**
+ * cppi41_dma_ch_default_queue - set CPPI 4.1 channel default completion queue
+ * @dma_ch_obj: pointer to DMA channel object
+ * @q_mgr:	default queue manager
+ * @q_num:	default queue number
+ *
+ * This function configures the specified channel.  The caller is required to
+ * provide the default queue onto which the teardown descriptors will be queued.
+ */
+void cppi41_dma_ch_default_queue(struct cppi41_dma_ch_obj *dma_ch_obj,
+				 u8 q_mgr, u16 q_num);
+
+/**
+ * cppi41_rx_ch_configure - configure CPPI 4.1 receive channel
+ * @rx_ch_obj:	pointer to Rx channel object
+ * @cfg:	pointer to Rx channel configuration
+ *
+ * This function configures and opens the specified Rx channel.  The caller
+ * is required to provide channel configuration information by initializing
+ * a struct cppi41_rx_ch_cfg.
+ */
+void cppi41_rx_ch_configure(struct cppi41_dma_ch_obj *rx_ch_obj,
+			    struct cppi41_rx_ch_cfg  *cfg);
+
+/**
+ * cppi41_dma_ch_enable - enable CPPI 4.1 Tx/Rx DMA channel
+ * @dma_ch_obj:	pointer to DMA channel object
+ *
+ * This function enables  a specified Tx channel.  The caller is required to
+ * provide a reference to a channel object initialized by an earlier call of
+ * the cppi41_dma_ch_init() function.  After the successful completion of this
+ * function, the Tx DMA channel will be active and ready for data transmission.
+ */
+void cppi41_dma_ch_enable(struct cppi41_dma_ch_obj *dma_ch_obj);
+
+/**
+ * cppi41_dma_ch_disable - disable CPPI 4.1 Tx/Rx DMA channel
+ * @dma_ch_obj:	pointer to DMA channel object
+ *
+ * This function disables a specific Tx channel.  The caller is required to
+ * provide a reference to a channel object initialized by an earlier call of
+ * the cppi41_dma_ch_init() function.  After the successful completion of this
+ * function, the Tx DMA channel will be deactived.
+ */
+void cppi41_dma_ch_disable(struct cppi41_dma_ch_obj *dma_ch_obj);
+
+/**
+ * cppi41_dma_ch_teardown - tear down CPPI 4.1 transmit channel
+ * @dma_ch_obj:	pointer DMA channel object
+ *
+ * This function triggers the teardown of the given DMA channel.
+ *
+ * ATTENTION: Channel disable should not be called before the teardown is
+ * completed as a disable will stop the DMA scheduling on the channel resulting
+ * in the teardown complete event not being registered@all.
+ *
+ * NOTE: A successful channel teardown event is reported via queueing of a
+ * teardown descriptor.
+ *
+ * This function just sets up for the teardown of the channel and returns. The
+ * caller must detect the channel teardown event to assume that the channel is
+ * disabled.
+ *
+ * See cppi41_get_teardown_info() for the teardown completion processing.
+ */
+void cppi41_dma_ch_teardown(struct cppi41_dma_ch_obj *dma_ch_obj);
+
+/*
+ * CPPI 4.1 Queue Allocation and De-allocation APIs.
+ */
+
+/**
+ * cppi41_queue_alloc - allocate CPPI 4.1 queue
+ * @type:	queue type bitmask
+ * @q_mgr:	queue manager
+ * @q_num:	pointer to the queue number
+ *
+ * Returns 0 if queue allocated, error otherwise.
+ */
+int cppi41_queue_alloc(u8 type, u8 q_mgr, u16 *q_num);
+
+/**
+ * cppi41_queue_free - de-allocate CPPI 4.1 queue
+ * @q_mgr:	queue manager
+ * @q_num:	queue number
+ *
+ * Returns 0 on success, -EINVAL otherwise.
+ */
+int cppi41_queue_free(u8 q_mgr, u16 q_num);
+
+/*
+ *  CPPI 4.1 Queue Management APIs
+ */
+
+/**
+ * cppi41_queue_init - initialize CPPI 4.1 queue object
+ * @queue_obj:	pointer to the queue object
+ * @q_mgr:	queue manager
+ * @q_num:	queue number
+ *
+ * Returns 0 if valid queue, -EINVAL otherwise.
+ */
+int cppi41_queue_init(struct cppi41_queue_obj *queue_obj, u8 q_mgr, u16 q_num);
+
+/**
+ * cppi41_queue_push - push to CPPI 4.1 queue
+ * @queue_obj:	pointer to the queue object
+ * @desc_addr:	descriptor physical address
+ * @desc_size:	descriptor size
+ * @pkt_size:	packet size
+ *
+ * This function is called to queue a descriptor onto a queue.
+ * NOTE: pSize parameter is optional. Pass 0 in case not required.
+ */
+void cppi41_queue_push(const struct cppi41_queue_obj *queue_obj, u32 desc_addr,
+		       u32 desc_size, u32 pkt_size);
+
+/**
+ * cppi41_queue_pop - pop from CPPI 4.1 queue
+ * @queue_obj:	pointer to the queue object
+ *
+ * This function is called to pop a single descriptor from the queue.
+ *
+ * Returns a packet descriptor's physical address.
+ */
+unsigned long cppi41_queue_pop(const struct cppi41_queue_obj *queue_obj);
+
+/*
+ * CPPI 4.1 Miscellaneous APIs
+ */
+
+/**
+ * cppi41_get_teardown_info - CPPI 4.1 teardown completion processing function
+ *
+ * @addr:	physical address of teardown descriptor
+ * @info:	pointer to the teardown information word
+ *
+ * This function is called to complete the teardown processing on a channel
+ * and provides teardown information from the teardown descriptor passed to it.
+ * It also recycles the teardown descriptor back to the teardown descriptor
+ * queue.
+ *
+ * Returns 0 if valid descriptor, -EINVAL otherwise.
+ */
+int cppi41_get_teardown_info(unsigned long addr, u32 *info);

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2010-05-15 18:14 [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support Sergei Shtylyov
@ 2010-05-28 20:55 ` Sergei Shtylyov
  2010-09-28  9:13 ` Linus Walleij
  2011-01-03 16:06 ` Sergei Shtylyov
  2 siblings, 0 replies; 22+ messages in thread
From: Sergei Shtylyov @ 2010-05-28 20:55 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

I wrote:

> Add support for Texas Instuments Communication Port Programming Interface 4.1
> (CPPI 4.1) used on OMAP-L1x/DA8xx and AM35x.
> 
> At this moment, only the DMA controller and queue manager are supported.
> Support for the buffer manager is lacking but these chips don't have it anyway.
> 
> Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
> 
> ---
> Changes since the previous version:
> - moved everything from arch/arm/mach-davinci/ to arch/arm/common/;
> - s/CONFIG_CPPI41/CONFIG_TI_CPPI41/, made that option invisible;
> - added #include <linux/slab.h> for kzalloc();
> - switched alloc_queue() and cppi41_queue_free() to using bit operations;
> - replaced 'static' linking_ram[] by local variable in cppi41_queue_mgr_init();
> - fixed pr_debug() in cppi41_dma_ctrlr_init() to print the real queue manager #.

    I saw no feedback about this patch. Russel, can I put this into your 
patch system?

WBR, Sergei

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2010-05-15 18:14 [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support Sergei Shtylyov
  2010-05-28 20:55 ` Sergei Shtylyov
@ 2010-09-28  9:13 ` Linus Walleij
  2010-09-28 10:13   ` Sergei Shtylyov
  2011-01-03 16:06 ` Sergei Shtylyov
  2 siblings, 1 reply; 22+ messages in thread
From: Linus Walleij @ 2010-09-28  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

2010/5/15 Sergei Shtylyov <sshtylyov@ru.mvista.com>:

> Add support for Texas Instuments Communication Port Programming Interface 4.1
> (CPPI 4.1) used on OMAP-L1x/DA8xx and AM35x.

Sorry for late feedback ...

> +++ linux-davinci/arch/arm/common/cppi41.c

Can you migrate this driver to drivers/dma/cppi41.c and use the
DMAengine interface like so many DMA drivers we have created
recently, or is there some very special characteristics about this
DMA controller meriting it to be placed in arch/arm/*?

Note: we have the support for PL08x found in ARM reference
designs queued for drivers/dma/amba-pl08x.c,
not arch/arm/common/*.

The rationale about this is to lower the churn in arch/arm/*
and put drivers into the proper subsystems, and in this case
there is an appropriate subsystem to be used.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2010-09-28  9:13 ` Linus Walleij
@ 2010-09-28 10:13   ` Sergei Shtylyov
  0 siblings, 0 replies; 22+ messages in thread
From: Sergei Shtylyov @ 2010-09-28 10:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

On 28-09-2010 13:13, Linus Walleij wrote:

>> Add support for Texas Instuments Communication Port Programming Interface 4.1
>> (CPPI 4.1) used on OMAP-L1x/DA8xx and AM35x.

> Sorry for late feedback ...

>> +++ linux-davinci/arch/arm/common/cppi41.c

> Can you migrate this driver to drivers/dma/cppi41.c and use the
> DMAengine interface like so many DMA drivers we have created
> recently, or is there some very special characteristics about this
> DMA controller meriting it to be placed in arch/arm/*?

    I have once studied the possibility of doing this driver under 
drivers/dma/, and found that hardly achievable. Maybe I should try again though...

> Yours,
> Linus Walleij

WBR, Sergei

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2010-05-15 18:14 [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support Sergei Shtylyov
  2010-05-28 20:55 ` Sergei Shtylyov
  2010-09-28  9:13 ` Linus Walleij
@ 2011-01-03 16:06 ` Sergei Shtylyov
  2011-01-03 16:34   ` Russell King - ARM Linux
  2 siblings, 1 reply; 22+ messages in thread
From: Sergei Shtylyov @ 2011-01-03 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

On 15-05-2010 22:14, Sergei Shtylyov wrote:

> Add support for Texas Instuments Communication Port Programming Interface 4.1
> (CPPI 4.1) used on OMAP-L1x/DA8xx and AM35x.

> At this moment, only the DMA controller and queue manager are supported.
> Support for the buffer manager is lacking but these chips don't have it anyway.

> Signed-off-by: Sergei Shtylyov<sshtylyov@ru.mvista.com>
> Signed-off-by: Sekhar Nori<nsekhar@ti.com>

    Russell, you have recently discarded this patch from your patch system. 
Can we know the reason?

WBR, Sergei

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-03 16:06 ` Sergei Shtylyov
@ 2011-01-03 16:34   ` Russell King - ARM Linux
  2011-01-03 17:01     ` Gupta, Ajay Kumar
  0 siblings, 1 reply; 22+ messages in thread
From: Russell King - ARM Linux @ 2011-01-03 16:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jan 03, 2011 at 07:06:10PM +0300, Sergei Shtylyov wrote:
> Hello.
>
> On 15-05-2010 22:14, Sergei Shtylyov wrote:
>
>> Add support for Texas Instuments Communication Port Programming Interface 4.1
>> (CPPI 4.1) used on OMAP-L1x/DA8xx and AM35x.
>
>> At this moment, only the DMA controller and queue manager are supported.
>> Support for the buffer manager is lacking but these chips don't have it anyway.
>
>> Signed-off-by: Sergei Shtylyov<sshtylyov@ru.mvista.com>
>> Signed-off-by: Sekhar Nori<nsekhar@ti.com>
>
>    Russell, you have recently discarded this patch from your patch 
> system. Can we know the reason?

It was recently discussed with TI, and various people raised concerns
about it.  I don't remember the exact details, and I wish they'd raise
them with the patch author directly.  It may have been that it's
inventing its own API rather than using something like the DMA engine
API.

Adding linux-omap to try to get a response there.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-03 16:34   ` Russell King - ARM Linux
@ 2011-01-03 17:01     ` Gupta, Ajay Kumar
  2011-01-03 17:07       ` Sergei Shtylyov
  0 siblings, 1 reply; 22+ messages in thread
From: Gupta, Ajay Kumar @ 2011-01-03 17:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,
> >> Add support for Texas Instuments Communication Port Programming
> Interface 4.1
> >> (CPPI 4.1) used on OMAP-L1x/DA8xx and AM35x.
> >
> >> At this moment, only the DMA controller and queue manager are supported.
> >> Support for the buffer manager is lacking but these chips don't have it
> anyway.
> >
> >> Signed-off-by: Sergei Shtylyov<sshtylyov@ru.mvista.com>
> >> Signed-off-by: Sekhar Nori<nsekhar@ti.com>
> >
> >    Russell, you have recently discarded this patch from your patch
> > system. Can we know the reason?
> 
> It was recently discussed with TI, and various people raised concerns
> about it.  I don't remember the exact details, and I wish they'd raise
> them with the patch author directly.  It may have been that it's
> inventing its own API rather than using something like the DMA engine
> API.
> 
> Adding linux-omap to try to get a response there.

Sergei,
This issue was discussed recently at TI and proposal was to place it to
drivers/dma folder. Moreover, even Felipe also seems to move other musb
DMAs (Inventra, CPPI3.0, TUSB) to drivers/dma.

Regards,
Ajay
> _______________________________________________
> Davinci-linux-open-source mailing list
> Davinci-linux-open-source at linux.davincidsp.com
> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-03 17:01     ` Gupta, Ajay Kumar
@ 2011-01-03 17:07       ` Sergei Shtylyov
  2011-01-03 17:15         ` Gupta, Ajay Kumar
  2011-01-03 17:19         ` Russell King - ARM Linux
  0 siblings, 2 replies; 22+ messages in thread
From: Sergei Shtylyov @ 2011-01-03 17:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

On 03-01-2011 20:01, Gupta, Ajay Kumar wrote:

>>>> Add support for Texas Instuments Communication Port Programming Interface 4.1
>>>> (CPPI 4.1) used on OMAP-L1x/DA8xx and AM35x.

>>>> At this moment, only the DMA controller and queue manager are supported.
>>>> Support for the buffer manager is lacking but these chips don't have it anyway.

>>>> Signed-off-by: Sergei Shtylyov<sshtylyov@ru.mvista.com>
>>>> Signed-off-by: Sekhar Nori<nsekhar@ti.com>

>>>     Russell, you have recently discarded this patch from your patch
>>> system. Can we know the reason?

>> It was recently discussed with TI, and various people raised concerns
>> about it.  I don't remember the exact details, and I wish they'd raise
>> them with the patch author directly.  It may have been that it's
>> inventing its own API rather than using something like the DMA engine
>> API.

>> Adding linux-omap to try to get a response there.

> Sergei,
> This issue was discussed recently at TI and proposal was to place it to
> drivers/dma folder.

    Note that I have neither time nor inclination to do this work (not do I 
think it's even feasible), so it will have to fall on TI's shoulders...

> Moreover, even Felipe also seems to move other musb
> DMAs (Inventra, CPPI3.0, TUSB) to drivers/dma.

    Frankly speaking, I doubt that drivers/dma/ will have place for the purely 
MUSB specific DMA engines such as the named ones (there's no TUSB DMA BTW -- 
it uses OMAP DMA).

> Regards,
> Ajay

WBR, Sergei

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-03 17:07       ` Sergei Shtylyov
@ 2011-01-03 17:15         ` Gupta, Ajay Kumar
  2011-01-03 20:44           ` Felipe Balbi
  2011-01-03 17:19         ` Russell King - ARM Linux
  1 sibling, 1 reply; 22+ messages in thread
From: Gupta, Ajay Kumar @ 2011-01-03 17:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,
> >>>> Add support for Texas Instuments Communication Port Programming
> Interface 4.1
> >>>> (CPPI 4.1) used on OMAP-L1x/DA8xx and AM35x.
> 
> >>>> At this moment, only the DMA controller and queue manager are
> supported.
> >>>> Support for the buffer manager is lacking but these chips don't have
> it anyway.
> 
> >>>> Signed-off-by: Sergei Shtylyov<sshtylyov@ru.mvista.com>
> >>>> Signed-off-by: Sekhar Nori<nsekhar@ti.com>
> 
> >>>     Russell, you have recently discarded this patch from your patch
> >>> system. Can we know the reason?
> 
> >> It was recently discussed with TI, and various people raised concerns
> >> about it.  I don't remember the exact details, and I wish they'd raise
> >> them with the patch author directly.  It may have been that it's
> >> inventing its own API rather than using something like the DMA engine
> >> API.
> 
> >> Adding linux-omap to try to get a response there.
> 
> > Sergei,
> > This issue was discussed recently at TI and proposal was to place it to
> > drivers/dma folder.
> 
>     Note that I have neither time nor inclination to do this work (not do
> I think it's even feasible), so it will have to fall on TI's shoulders...

This is fine. No issues. We will discuss this at length at linux-usb list.

> 
> > Moreover, even Felipe also seems to move other musb
> > DMAs (Inventra, CPPI3.0, TUSB) to drivers/dma.
> 
>     Frankly speaking, I doubt that drivers/dma/ will have place for the
> purely MUSB specific DMA engines such as the named ones (there's no TUSB
> DMA BTW it uses OMAP DMA).
I think we will get more clarity once we start on this activity.

Thanks,
Ajay
> 
> > Regards,
> > Ajay
> 
> WBR, Sergei

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-03 17:07       ` Sergei Shtylyov
  2011-01-03 17:15         ` Gupta, Ajay Kumar
@ 2011-01-03 17:19         ` Russell King - ARM Linux
  2011-01-03 20:49           ` Felipe Balbi
  1 sibling, 1 reply; 22+ messages in thread
From: Russell King - ARM Linux @ 2011-01-03 17:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jan 03, 2011 at 08:07:18PM +0300, Sergei Shtylyov wrote:
> Hello.
>
> On 03-01-2011 20:01, Gupta, Ajay Kumar wrote:
>
>>>>> Add support for Texas Instuments Communication Port Programming Interface 4.1
>>>>> (CPPI 4.1) used on OMAP-L1x/DA8xx and AM35x.
>
>>>>> At this moment, only the DMA controller and queue manager are supported.
>>>>> Support for the buffer manager is lacking but these chips don't have it anyway.
>
>>>>> Signed-off-by: Sergei Shtylyov<sshtylyov@ru.mvista.com>
>>>>> Signed-off-by: Sekhar Nori<nsekhar@ti.com>
>
>>>>     Russell, you have recently discarded this patch from your patch
>>>> system. Can we know the reason?
>
>>> It was recently discussed with TI, and various people raised concerns
>>> about it.  I don't remember the exact details, and I wish they'd raise
>>> them with the patch author directly.  It may have been that it's
>>> inventing its own API rather than using something like the DMA engine
>>> API.
>
>>> Adding linux-omap to try to get a response there.
>
>> Sergei,
>> This issue was discussed recently at TI and proposal was to place it to
>> drivers/dma folder.
>
>    Note that I have neither time nor inclination to do this work (not do 
> I think it's even feasible), so it will have to fall on TI's shoulders...
>
>> Moreover, even Felipe also seems to move other musb
>> DMAs (Inventra, CPPI3.0, TUSB) to drivers/dma.
>
>    Frankly speaking, I doubt that drivers/dma/ will have place for the 
> purely MUSB specific DMA engines such as the named ones (there's no TUSB 
> DMA BTW -- it uses OMAP DMA).

Long term, we need to kill off all these platform private DMA interfaces.
There's a growing amount of IP that's being shared not only between ARM
silicon vendors, but also across architectures, and having to re-implement
drivers because the underlying DMA engine is different is not feasible.

For example, we're seeing ARMs primecells being used with various
different DMA controllers in various different ARM SoCs.  I've heard
rumours of them appearing in MIPS or PPC stuff as well.  We're seeing
PXA peripheral IP appearing in x86 stuff too.

We can't have drivers tied to their SoC DMA engines, and we can't continue
having SoC DMA engines implementing their own unique APIs.  We do need to
get on top of this before it becomes a major problem (if it hasn't
already).

The DMA engine API is still evolving, and should not be taken as concrete
- I've recently been bringing up a number of points with Dan on various
aspects of the API, some of which ultimately will lead to changes to the
async-tx API, and others which hopefully will mean that the DMA slave
API is better documented.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-03 17:15         ` Gupta, Ajay Kumar
@ 2011-01-03 20:44           ` Felipe Balbi
  2011-01-04 13:06             ` Sergei Shtylyov
  0 siblings, 1 reply; 22+ messages in thread
From: Felipe Balbi @ 2011-01-03 20:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, Jan 03, 2011 at 10:45:35PM +0530, Gupta, Ajay Kumar wrote:
>> > Moreover, even Felipe also seems to move other musb
>> > DMAs (Inventra, CPPI3.0, TUSB) to drivers/dma.
>>
>>     Frankly speaking, I doubt that drivers/dma/ will have place for the
>> purely MUSB specific DMA engines such as the named ones (there's no TUSB
>> DMA BTW it uses OMAP DMA).
>I think we will get more clarity once we start on this activity.

I agree, but I personally don't see that many limiting factors.
dmaengine is just a generic API for doing DMA transfers. If it's not
enough for us currently, we extend it.

-- 
balbi

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-03 17:19         ` Russell King - ARM Linux
@ 2011-01-03 20:49           ` Felipe Balbi
  2011-01-04 19:12             ` Tony Lindgren
  0 siblings, 1 reply; 22+ messages in thread
From: Felipe Balbi @ 2011-01-03 20:49 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, Jan 03, 2011 at 05:19:45PM +0000, Russell King - ARM Linux wrote:
>>    Frankly speaking, I doubt that drivers/dma/ will have place for the
>> purely MUSB specific DMA engines such as the named ones (there's no TUSB
>> DMA BTW -- it uses OMAP DMA).
>
>Long term, we need to kill off all these platform private DMA interfaces.
>There's a growing amount of IP that's being shared not only between ARM
>silicon vendors, but also across architectures, and having to re-implement
>drivers because the underlying DMA engine is different is not feasible.
>
>For example, we're seeing ARMs primecells being used with various
>different DMA controllers in various different ARM SoCs.  I've heard
>rumours of them appearing in MIPS or PPC stuff as well.  We're seeing
>PXA peripheral IP appearing in x86 stuff too.
>
>We can't have drivers tied to their SoC DMA engines, and we can't continue
>having SoC DMA engines implementing their own unique APIs.  We do need to
>get on top of this before it becomes a major problem (if it hasn't
>already).
>
>The DMA engine API is still evolving, and should not be taken as concrete
>- I've recently been bringing up a number of points with Dan on various
>aspects of the API, some of which ultimately will lead to changes to the
>async-tx API, and others which hopefully will mean that the DMA slave
>API is better documented.

I couldn't agree more with you Russell. If the API isn't enough
currently, we can always propose an extension.

Having all sorts of SoC-specific "APIs" has already caused enough
problems and it still does (non-generic IRQ handling on
twl?030, menelaus, cbus - which isn't in mainline yet -, etc,
non-generic McBSP usage, non-generic GPMC usage, etc etc). So, if we can
plan for making use of generic APIs, let's do so.

-- 
balbi

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-03 20:44           ` Felipe Balbi
@ 2011-01-04 13:06             ` Sergei Shtylyov
  2011-01-04 14:06               ` Felipe Balbi
  2011-01-05 22:03               ` Russell King - ARM Linux
  0 siblings, 2 replies; 22+ messages in thread
From: Sergei Shtylyov @ 2011-01-04 13:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

On 03-01-2011 23:44, Felipe Balbi wrote:

>>> > Moreover, even Felipe also seems to move other musb
>>> > DMAs (Inventra, CPPI3.0, TUSB) to drivers/dma.

>>> Frankly speaking, I doubt that drivers/dma/ will have place for the
>>> purely MUSB specific DMA engines such as the named ones (there's no TUSB
>>> DMA BTW it uses OMAP DMA).

>> I think we will get more clarity once we start on this activity.

> I agree, but I personally don't see that many limiting factors.
> dmaengine is just a generic API for doing DMA transfers. If it's not
> enough for us currently, we extend it.

    Putting MUSB DMA enignes into drivers/dma/ is the same as taking *any* 
chip capable of bus-mastering DMA, "separating" its bus mastering related code 
from its driver and putting this code into drivers/dma/. This doesn't make 
sense, in my opinion. drivers/dma/ is for the dedicated DMA controllers (which 
can *optionally* serve the slave devices).

WBR, Sergei

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-04 13:06             ` Sergei Shtylyov
@ 2011-01-04 14:06               ` Felipe Balbi
  2011-01-04 14:40                 ` Ming Lei
  2011-01-04 16:37                 ` Sergei Shtylyov
  2011-01-05 22:03               ` Russell King - ARM Linux
  1 sibling, 2 replies; 22+ messages in thread
From: Felipe Balbi @ 2011-01-04 14:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

(using personal email, left the office)

On Tue, 2011-01-04 at 16:06 +0300, Sergei Shtylyov wrote:
> >> I think we will get more clarity once we start on this activity.
> 
> > I agree, but I personally don't see that many limiting factors.
> > dmaengine is just a generic API for doing DMA transfers. If it's not
> > enough for us currently, we extend it.
> 
>     Putting MUSB DMA enignes into drivers/dma/ is the same as taking *any* 
> chip capable of bus-mastering DMA, "separating" its bus mastering related code 
> from its driver and putting this code into drivers/dma/. This doesn't make 
> sense, in my opinion. drivers/dma/ is for the dedicated DMA controllers (which 
> can *optionally* serve the slave devices).

Do I really have to spell it out ? Really ?

You don't need to physically move the part of the code to drivers/dma,
but it has to use the API. The mentor DMA is internal to MUSB.
tusb6010_omap.c isn't.

Where it makes sense to move the code under drivers/dma, it will be
done, where it doesn't, it won't be done, but it will use the same API.
That's all.

The end goal is just to drop all these ad-hoc "APIs" for accessing DMA
on musb code.

-- 
balbi

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-04 14:06               ` Felipe Balbi
@ 2011-01-04 14:40                 ` Ming Lei
  2011-01-04 14:56                   ` Felipe Balbi
  2011-01-04 16:37                 ` Sergei Shtylyov
  1 sibling, 1 reply; 22+ messages in thread
From: Ming Lei @ 2011-01-04 14:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

2011/1/4 Felipe Balbi <me@felipebalbi.com>:

> The end goal is just to drop all these ad-hoc "APIs" for accessing DMA
> on musb code.

If this kind of DMA controllers are only used by MUSB, seems not
necessary to convert to dmaengine API.  Any benefit we can get
from the convert?   MUSB is cross-platform already after all.


thanks,
-- 
Lei Ming

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-04 14:40                 ` Ming Lei
@ 2011-01-04 14:56                   ` Felipe Balbi
  2011-01-04 15:41                     ` Ming Lei
  0 siblings, 1 reply; 22+ messages in thread
From: Felipe Balbi @ 2011-01-04 14:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, 2011-01-04 at 22:40 +0800, Ming Lei wrote:
> > The end goal is just to drop all these ad-hoc "APIs" for accessing DMA
> > on musb code.
> 
> If this kind of DMA controllers are only used by MUSB, seems not
> necessary to convert to dmaengine API.  Any benefit we can get
> from the convert?   MUSB is cross-platform already after all.

<irony>
correct, OMAP GPIO controller is only used on OMAPs, so why do we even
bother having gpiolib, right ?
</irony>

-- 
balbi

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-04 14:56                   ` Felipe Balbi
@ 2011-01-04 15:41                     ` Ming Lei
  2011-01-04 18:42                       ` Felipe Balbi
  0 siblings, 1 reply; 22+ messages in thread
From: Ming Lei @ 2011-01-04 15:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

2011/1/4 Felipe Balbi <me@felipebalbi.com>:
> Hi,
>
> On Tue, 2011-01-04 at 22:40 +0800, Ming Lei wrote:
>> > The end goal is just to drop all these ad-hoc "APIs" for accessing DMA
>> > on musb code.
>>
>> If this kind of DMA controllers are only used by MUSB, seems not
>> necessary to convert to dmaengine API. ?Any benefit we can get
>> from the convert? ? MUSB is cross-platform already after all.
>
> <irony>
> correct, OMAP GPIO controller is only used on OMAPs, so why do we even
> bother having gpiolib, right ?

OMAP GPIOs have many usages or use cases, so we can use gpiolib
to simplify access to GPIOs.  If GPIOs has only one usage or use case,
it is not necessary to access GPIOs by gpiolib.

Now this kind of DMA controllers are only used by MUSB or only for
MUSB, so it doesn't matter to access them by dmaengine or not.

thanks,
-- 
Lei Ming

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-04 14:06               ` Felipe Balbi
  2011-01-04 14:40                 ` Ming Lei
@ 2011-01-04 16:37                 ` Sergei Shtylyov
  1 sibling, 0 replies; 22+ messages in thread
From: Sergei Shtylyov @ 2011-01-04 16:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

Felipe Balbi wrote:

>>>> I think we will get more clarity once we start on this activity.

>>> I agree, but I personally don't see that many limiting factors.
>>> dmaengine is just a generic API for doing DMA transfers. If it's not
>>> enough for us currently, we extend it.

>>     Putting MUSB DMA enignes into drivers/dma/ is the same as taking *any* 
>> chip capable of bus-mastering DMA, "separating" its bus mastering related code 
>> from its driver and putting this code into drivers/dma/. This doesn't make 
>> sense, in my opinion. drivers/dma/ is for the dedicated DMA controllers (which 
>> can *optionally* serve the slave devices).

> Do I really have to spell it out ? Really ?

    Yes, I'm dense. :-)
    Especially after Ajay claiming that Mentor and CPPI 3.0 DMA will be moved to 
drivers/dma/...

> You don't need to physically move the part of the code to drivers/dma,
> but it has to use the API. The mentor DMA is internal to MUSB.
> tusb6010_omap.c isn't.

    Yes, that's what I've already noted in this thread.

> Where it makes sense to move the code under drivers/dma, it will be

    Surely OMAP DMA needs to be moved under drivers/dma/, not the TUSB code
interfacing it.

> done, where it doesn't, it won't be done, but it will use the same API.
> That's all.

    I don't quite see how DMA engine API is beneficial to what we currently have...

> The end goal is just to drop all these ad-hoc "APIs" for accessing DMA
> on musb code.

    The "ad-hoc" API is well suited for use with MUSB, while DMA engine API is 
more abstract, I think. The "ad-hoc" API takes into account some things that the 
DMA engine API just can't -- like the transfer mode and packet size...

WBR, Sergei

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-04 15:41                     ` Ming Lei
@ 2011-01-04 18:42                       ` Felipe Balbi
  2011-01-04 18:50                         ` Sergei Shtylyov
  0 siblings, 1 reply; 22+ messages in thread
From: Felipe Balbi @ 2011-01-04 18:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, Jan 04, 2011 at 11:41:05PM +0800, Ming Lei wrote:
> OMAP GPIOs have many usages or use cases, so we can use gpiolib
> to simplify access to GPIOs.  If GPIOs has only one usage or use case,
> it is not necessary to access GPIOs by gpiolib.
> 
> Now this kind of DMA controllers are only used by MUSB or only for
> MUSB, so it doesn't matter to access them by dmaengine or not.

Not entirely true. TUSB uses OMAP system DMA and AFAICT CPPI is used
also for ethernet. The thing is that we want to get rid of non-standard
"APIs" as much as possible.

-- 
balbi

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-04 18:42                       ` Felipe Balbi
@ 2011-01-04 18:50                         ` Sergei Shtylyov
  0 siblings, 0 replies; 22+ messages in thread
From: Sergei Shtylyov @ 2011-01-04 18:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

Felipe Balbi wrote:

> On Tue, Jan 04, 2011 at 11:41:05PM +0800, Ming Lei wrote:
>> OMAP GPIOs have many usages or use cases, so we can use gpiolib
>> to simplify access to GPIOs.  If GPIOs has only one usage or use case,
>> it is not necessary to access GPIOs by gpiolib.

>> Now this kind of DMA controllers are only used by MUSB or only for
>> MUSB, so it doesn't matter to access them by dmaengine or not.

> Not entirely true. TUSB uses OMAP system DMA and AFAICT CPPI is used
> also for ethernet.

    Yes, but the CPPI registers are not compatible between MUSB and EMAC, only 
the descriptors are, AFAIK.

WBR, Sergei

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-03 20:49           ` Felipe Balbi
@ 2011-01-04 19:12             ` Tony Lindgren
  0 siblings, 0 replies; 22+ messages in thread
From: Tony Lindgren @ 2011-01-04 19:12 UTC (permalink / raw)
  To: linux-arm-kernel

* Felipe Balbi <balbi@ti.com> [110103 12:49]:
> Hi,
> 
> On Mon, Jan 03, 2011 at 05:19:45PM +0000, Russell King - ARM Linux wrote:
> >>   Frankly speaking, I doubt that drivers/dma/ will have place for the
> >>purely MUSB specific DMA engines such as the named ones (there's no TUSB
> >>DMA BTW -- it uses OMAP DMA).
> >
> >Long term, we need to kill off all these platform private DMA interfaces.
> >There's a growing amount of IP that's being shared not only between ARM
> >silicon vendors, but also across architectures, and having to re-implement
> >drivers because the underlying DMA engine is different is not feasible.
> >
> >For example, we're seeing ARMs primecells being used with various
> >different DMA controllers in various different ARM SoCs.  I've heard
> >rumours of them appearing in MIPS or PPC stuff as well.  We're seeing
> >PXA peripheral IP appearing in x86 stuff too.
> >
> >We can't have drivers tied to their SoC DMA engines, and we can't continue
> >having SoC DMA engines implementing their own unique APIs.  We do need to
> >get on top of this before it becomes a major problem (if it hasn't
> >already).
> >
> >The DMA engine API is still evolving, and should not be taken as concrete
> >- I've recently been bringing up a number of points with Dan on various
> >aspects of the API, some of which ultimately will lead to changes to the
> >async-tx API, and others which hopefully will mean that the DMA slave
> >API is better documented.
> 
> I couldn't agree more with you Russell. If the API isn't enough
> currently, we can always propose an extension.
> 
> Having all sorts of SoC-specific "APIs" has already caused enough
> problems and it still does (non-generic IRQ handling on
> twl?030, menelaus, cbus - which isn't in mainline yet -, etc,
> non-generic McBSP usage, non-generic GPMC usage, etc etc). So, if we can
> plan for making use of generic APIs, let's do so.

Yes I too agree with this. We just need to do whatever it takes to
make the DMA engine suitable for all drivers.

Regards,

Tony

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support
  2011-01-04 13:06             ` Sergei Shtylyov
  2011-01-04 14:06               ` Felipe Balbi
@ 2011-01-05 22:03               ` Russell King - ARM Linux
  1 sibling, 0 replies; 22+ messages in thread
From: Russell King - ARM Linux @ 2011-01-05 22:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 04, 2011 at 04:06:39PM +0300, Sergei Shtylyov wrote:
>    Putting MUSB DMA enignes into drivers/dma/ is the same as taking *any* 
> chip capable of bus-mastering DMA, "separating" its bus mastering related 
> code from its driver and putting this code into drivers/dma/. This 
> doesn't make sense, in my opinion. drivers/dma/ is for the dedicated DMA 
> controllers (which can *optionally* serve the slave devices).

Then why is it already separated into its own self-contained driver?

If it's because the DMA engine is used for different peripherals (possibly
re-used for different peripherals), then it does seem to make sense to
have it separated via some API.  And if possible that API might should
be something generic instead of specific.

Even more reason to do this is if the device being fed by the DMA has
been re-used with different DMA hardware (which I believe is the case
with MUSB.)  What if this different DMA hardware then gets re-used for
other devices?  Should they all implement the same custom API or try
for a generic API?

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2011-01-05 22:03 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-15 18:14 [PATCH v5 1/3] ARM: add CPPI 4.1 DMA support Sergei Shtylyov
2010-05-28 20:55 ` Sergei Shtylyov
2010-09-28  9:13 ` Linus Walleij
2010-09-28 10:13   ` Sergei Shtylyov
2011-01-03 16:06 ` Sergei Shtylyov
2011-01-03 16:34   ` Russell King - ARM Linux
2011-01-03 17:01     ` Gupta, Ajay Kumar
2011-01-03 17:07       ` Sergei Shtylyov
2011-01-03 17:15         ` Gupta, Ajay Kumar
2011-01-03 20:44           ` Felipe Balbi
2011-01-04 13:06             ` Sergei Shtylyov
2011-01-04 14:06               ` Felipe Balbi
2011-01-04 14:40                 ` Ming Lei
2011-01-04 14:56                   ` Felipe Balbi
2011-01-04 15:41                     ` Ming Lei
2011-01-04 18:42                       ` Felipe Balbi
2011-01-04 18:50                         ` Sergei Shtylyov
2011-01-04 16:37                 ` Sergei Shtylyov
2011-01-05 22:03               ` Russell King - ARM Linux
2011-01-03 17:19         ` Russell King - ARM Linux
2011-01-03 20:49           ` Felipe Balbi
2011-01-04 19:12             ` Tony Lindgren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).