All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device
@ 2010-11-08 14:07 G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 01/13] OMAP: DMA: Replace read/write macros with functions G, Manjunath Kondaiah
                   ` (11 more replies)
  0 siblings, 12 replies; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel

Changes incorporated from v3 version:
1. http://www.spinics.net/lists/arm-kernel/msg102937.html
2. http://www.spinics.net/lists/arm-kernel/msg103156.html

All the information such as build, testing etc from 'v3' is valid for 
v4 also(except this series is rebased to latest linux omap master branch). 
V3 Report can be accessed at:
http://www.spinics.net/lists/arm-kernel/msg102688.html 

Applies cleanly on top of:
git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
commit 9988a6be118d1150ffc8d1dda1f136d30bbc3936
Merge: 18e1fab 2d37882
Author: Tony Lindgren <tony@atomide.com>
Date:   Fri Nov 5 15:06:08 2010 -0700

    Linux-omap rebuilt: Merged in some fixes and new boards
   
Benoit Cousson (1):
  OMAP4: DMA: hwmod: add system DMA

G, Manjunath Kondaiah (11):
  OMAP: DMA: Replace read/write macros with functions
  OMAP: DMA: Introduce errata handling feature
  OMAP: DMA: Introduce DMA device attributes
  OMAP2420: DMA: hwmod: add system DMA
  OMAP2430: DMA: hwmod: add system DMA
  OMAP3: DMA: hwmod: add system DMA
  OMAP1: DMA: Introduce DMA driver as platform device
  OMAP2+: DMA: hwmod: Device registration
  OMAP: DMA: Convert DMA library into DMA platform Driver
  OMAP: DMA: Use DMA device attributes
  OMAP: PM: DMA: Enable runtime pm

Venkatraman S (1):
  OMAP2+: DMA: descriptor autoloading feature

 arch/arm/mach-omap1/Makefile               |    2 +-
 arch/arm/mach-omap1/dma.c                  |  667 ++++++++++
 arch/arm/mach-omap1/include/mach/dma.h     |   51 +
 arch/arm/mach-omap2/Makefile               |    2 +-
 arch/arm/mach-omap2/dma.c                  | 1583 ++++++++++++++++++++++++
 arch/arm/mach-omap2/include/mach/dma.h     |  173 +++
 arch/arm/mach-omap2/omap_hwmod_2420_data.c |   85 ++
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |   85 ++
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   94 ++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |   99 ++
 arch/arm/plat-omap/dma.c                   | 1829 ++++------------------------
 arch/arm/plat-omap/include/plat/dma.h      |  386 ++++---
 12 files changed, 3271 insertions(+), 1785 deletions(-)
 create mode 100644 arch/arm/mach-omap1/dma.c
 create mode 100644 arch/arm/mach-omap1/include/mach/dma.h
 create mode 100644 arch/arm/mach-omap2/dma.c
 create mode 100644 arch/arm/mach-omap2/include/mach/dma.h


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

* [PATCH v4 01/13] OMAP: DMA: Replace read/write macros with functions
  2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
@ 2010-11-08 14:07 ` G, Manjunath Kondaiah
  2010-11-09  0:40     ` Tony Lindgren
  2010-11-08 14:07 ` [PATCH v4 02/13] OMAP: DMA: Introduce errata handling feature G, Manjunath Kondaiah
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Benoit Cousson, Kevin Hilman, Santosh Shilimkar

The low level read/write macros are replaced with static inline
functions
and register offsets are handled through static register offset tables
mapped through enumeration constants.

The objective of this patch is to prepare for omap dma driver cleanup
and dma hwmod implementation. The code optimization and moving machine
specific code to respective mach-omapx dma file will be handled in the
rest of this patch series.

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/plat-omap/dma.c              |  741 ++++++++++++++++++++++-----------
 arch/arm/plat-omap/include/plat/dma.h |  120 ------
 2 files changed, 498 insertions(+), 363 deletions(-)

diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 2c28265..bb54be3 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -40,6 +40,147 @@
 
 #undef DEBUG
 
+enum {
+	GCR1 = 0,	GSCR,		GRST,		HW_ID,
+	PCH2_ID,	PCH0_ID,	PCH1_ID,	PCHG_ID,
+	PCHD_ID,	CAPS1_0_U,	CAPS1_0_L,	CAPS1_1_U,
+	CAPS1_1_L,	CAPS1_2,	CAPS1_3,	CAPS1_4,
+	PCH2_SR,	PCH0_SR,	PCH1_SR,	PCHD_SR,
+
+	OMAP1_CH_COMMON_START,
+
+	/* Common Registers */
+	CSDP1,		CCR1,		CICR1,		CSR1,
+	CEN1,		CFN1,		CSFI1,		CSEI1,
+	CPC,		CSAC1,		CDAC1,		CDEI1,
+	CDFI1,		CLNK_CTRL1,
+
+	/* Channel specific register offsets */
+	CSSA_L,		CSSA_U,		CDSA_L,		CDSA_U,
+	COLOR_L,	COLOR_U,	CCR1_2,		LCH_CTRL,
+
+	OMAP1_CH_COMMON_END,
+};
+
+static u16 reg_map_omap1[] = {
+	[GCR1]		= 0x400,
+	[GSCR]		= 0x404,
+	[GRST]		= 0x408,
+	[HW_ID]		= 0x442,
+	[PCH2_ID]	= 0x444,
+	[PCH0_ID]	= 0x446,
+	[PCH1_ID]	= 0x448,
+	[PCHG_ID]	= 0x44a,
+	[PCHD_ID]	= 0x44c,
+	[CAPS1_0_U]	= 0x44e,
+	[CAPS1_0_L]	= 0x450,
+	[CAPS1_1_U]	= 0x452,
+	[CAPS1_1_L]	= 0x454,
+	[CAPS1_2]	= 0x456,
+	[CAPS1_3]	= 0x458,
+	[CAPS1_4]	= 0x45a,
+	[PCH2_SR]	= 0x460,
+	[PCH0_SR]	= 0x480,
+	[PCH1_SR]	= 0x482,
+	[PCHD_SR]	= 0x4c0,
+
+	/* Common Registers */
+	[CSDP1]		= 0x00,
+	[CCR1]		= 0x02,
+	[CICR1]		= 0x04,
+	[CSR1]		= 0x06,
+	[CEN1]		= 0x10,
+	[CFN1]		= 0x12,
+	[CSFI1]		= 0x14,
+	[CSEI1]		= 0x16,
+	[CPC]		= 0x18,	/* 15xx only */
+	[CSAC1]		= 0x18,
+	[CDAC1]		= 0x1a,
+	[CDEI1]		= 0x1c,
+	[CDFI1]		= 0x1e,
+	[CLNK_CTRL1]	= 0x28,
+
+	/* Channel specific register offsets */
+	[CSSA_L]	= 0x08,
+	[CSSA_U]	= 0x0a,
+	[CDSA_L]	= 0x0c,
+	[CDSA_U]	= 0x0e,
+	[COLOR_L]	= 0x20,
+	[COLOR_U]	= 0x22,
+	[CCR1_2]	= 0x24,
+	[LCH_CTRL]	= 0x2a,
+};
+
+enum {
+	REVISION = 0,	GCR2,		IRQSTATUS_L0,	IRQSTATUS_L1,
+	IRQSTATUS_L2,	IRQSTATUS_L3,	IRQENABLE_L0,	IRQENABLE_L1,
+	IRQENABLE_L2,	IRQENABLE_L3,	SYSSTATUS,	OCP_SYSCONFIG,
+	CAPS2_0,	CAPS2_2,	CAPS2_3,	CAPS2_4,
+
+	OMAP2_CH_COMMON_START,
+
+	/* Common register offsets */
+	CCR2,		CLNK_CTRL2,	CICR2,		CSR2,
+	CSDP2,		CEN2,		CFN2,		CSEI2,
+	CSFI2,		CDEI2,		CDFI2,		CSAC2,
+	CDAC2,
+
+	/* Channel specific register offsets */
+	CSSA,		CDSA,		CCEN,		CCFN,
+	COLOR,
+
+	/* OMAP4 specific registers */
+	CDP,		CNDP,		CCDN,
+
+	OMAP2_CH_COMMON_END,
+};
+
+static u16 reg_map_omap2[] = {
+	[REVISION]		= 0x00,
+	[GCR2]			= 0x78,
+	[IRQSTATUS_L0]		= 0x08,
+	[IRQSTATUS_L1]		= 0x0c,
+	[IRQSTATUS_L2]		= 0x10,
+	[IRQSTATUS_L3]		= 0x14,
+	[IRQENABLE_L0]		= 0x18,
+	[IRQENABLE_L1]		= 0x1c,
+	[IRQENABLE_L2]		= 0x20,
+	[IRQENABLE_L3]		= 0x24,
+	[SYSSTATUS]		= 0x28,
+	[OCP_SYSCONFIG]		= 0x2c,
+	[CAPS2_0]		= 0x64,
+	[CAPS2_2]		= 0x6c,
+	[CAPS2_3]		= 0x70,
+	[CAPS2_4]		= 0x74,
+
+	/* Common register offsets */
+	[CCR2]			= 0x80,
+	[CLNK_CTRL2]		= 0x84,
+	[CICR2]			= 0x88,
+	[CSR2]			= 0x8c,
+	[CSDP2]			= 0x90,
+	[CEN2]			= 0x94,
+	[CFN2]			= 0x98,
+	[CSEI2]			= 0xa4,
+	[CSFI2]			= 0xa8,
+	[CDEI2]			= 0xac,
+	[CDFI2]			= 0xb0,
+	[CSAC2]			= 0xb4,
+	[CDAC2]			= 0xb8,
+
+	/* Channel specific register offsets */
+	[CSSA]			= 0x9c,
+	[CDSA]			= 0xa0,
+	[CCEN]			= 0xbc,
+	[CCFN]			= 0xc0,
+	[COLOR]			= 0xc4,
+
+	/* OMAP4 specific registers */
+	[CDP]			= 0xd0,
+	[CNDP]			= 0xd4,
+	[CCDN]			= 0xd8,
+};
+
 #ifndef CONFIG_ARCH_OMAP1
 enum { DMA_CH_ALLOC_DONE, DMA_CH_PARAMS_SET_DONE, DMA_CH_STARTED,
 	DMA_CH_QUEUED, DMA_CH_NOTSTARTED, DMA_CH_PAUSED, DMA_CH_LINK_ENABLED
@@ -137,7 +278,7 @@ static int omap_dma_reserve_channels;
 
 static spinlock_t dma_chan_lock;
 static struct omap_dma_lch *dma_chan;
-static void __iomem *omap_dma_base;
+static void __iomem *dma_base;
 
 static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = {
 	INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
@@ -154,23 +295,42 @@ static inline void omap_enable_channel_irq(int lch);
 #define REVISIT_24XX()		printk(KERN_ERR "FIXME: no %s on 24xx\n", \
 						__func__);
 
-#define dma_read(reg)							\
-({									\
-	u32 __val;							\
-	if (cpu_class_is_omap1())					\
-		__val = __raw_readw(omap_dma_base + OMAP1_DMA_##reg);	\
-	else								\
-		__val = __raw_readl(omap_dma_base + OMAP_DMA4_##reg);	\
-	__val;								\
-})
-
-#define dma_write(val, reg)						\
-({									\
-	if (cpu_class_is_omap1())					\
-		__raw_writew((u16)(val), omap_dma_base + OMAP1_DMA_##reg); \
-	else								\
-		__raw_writel((val), omap_dma_base + OMAP_DMA4_##reg);	\
-})
+static inline void dma_write(u32 val, int reg, int lch)
+{
+	if (cpu_class_is_omap1()) {
+		if (reg > OMAP1_CH_COMMON_START)
+			__raw_writew(val, dma_base +
+				(reg_map_omap1[reg] + 0x40 * lch));
+		else
+			__raw_writew(val, dma_base + reg_map_omap1[reg]);
+	} else {
+		if (reg > OMAP2_CH_COMMON_START)
+			__raw_writel(val, dma_base +
+				(reg_map_omap2[reg] + 0x60 * lch));
+		else
+			__raw_writel(val, dma_base + reg_map_omap2[reg]);
+	}
+}
+
+static inline u32 dma_read(int reg, int lch)
+{
+	u32 val;
+
+	if (cpu_class_is_omap1()) {
+		if (reg > OMAP1_CH_COMMON_START)
+			val = __raw_readw(dma_base +
+					(reg_map_omap1[reg] + 0x40 * lch));
+		else
+			val = __raw_readw(dma_base + reg_map_omap1[reg]);
+	} else {
+		if (reg > OMAP2_CH_COMMON_START)
+			val = __raw_readl(dma_base +
+					(reg_map_omap2[reg] + 0x60 * lch));
+		else
+			val = __raw_readl(dma_base + reg_map_omap2[reg]);
+	}
+	return val;
+}
 
 #ifdef CONFIG_ARCH_OMAP15XX
 /* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
@@ -209,11 +369,10 @@ static inline void set_gdma_dev(int req, int dev)
 /* Omap1 only */
 static void clear_lch_regs(int lch)
 {
-	int i;
-	void __iomem *lch_base = omap_dma_base + OMAP1_DMA_CH_BASE(lch);
+	int i = OMAP1_CH_COMMON_START;
 
-	for (i = 0; i < 0x2c; i += 2)
-		__raw_writew(0, lch_base + i);
+	for (; i <= OMAP1_CH_COMMON_END; i += 1)
+		dma_write(0, i, lch);
 }
 
 void omap_set_dma_priority(int lch, int dst_port, int priority)
@@ -248,12 +407,12 @@ void omap_set_dma_priority(int lch, int dst_port, int priority)
 	if (cpu_class_is_omap2()) {
 		u32 ccr;
 
-		ccr = dma_read(CCR(lch));
+		ccr = dma_read(CCR2, lch);
 		if (priority)
 			ccr |= (1 << 6);
 		else
 			ccr &= ~(1 << 6);
-		dma_write(ccr, CCR(lch));
+		dma_write(ccr, CCR2, lch);
 	}
 }
 EXPORT_SYMBOL(omap_set_dma_priority);
@@ -264,31 +423,36 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
 {
 	u32 l;
 
-	l = dma_read(CSDP(lch));
-	l &= ~0x03;
-	l |= data_type;
-	dma_write(l, CSDP(lch));
-
 	if (cpu_class_is_omap1()) {
 		u16 ccr;
 
-		ccr = dma_read(CCR(lch));
+		l = dma_read(CSDP1, lch);
+		l &= ~0x03;
+		l |= data_type;
+		dma_write(l, CSDP1, lch);
+
+		ccr = dma_read(CCR1, lch);
 		ccr &= ~(1 << 5);
 		if (sync_mode == OMAP_DMA_SYNC_FRAME)
 			ccr |= 1 << 5;
-		dma_write(ccr, CCR(lch));
+		dma_write(ccr, CCR1, lch);
 
-		ccr = dma_read(CCR2(lch));
+		ccr = dma_read(CCR1_2, lch);
 		ccr &= ~(1 << 2);
 		if (sync_mode == OMAP_DMA_SYNC_BLOCK)
 			ccr |= 1 << 2;
-		dma_write(ccr, CCR2(lch));
+		dma_write(ccr, CCR1_2, lch);
 	}
 
 	if (cpu_class_is_omap2() && dma_trigger) {
 		u32 val;
 
-		val = dma_read(CCR(lch));
+		l = dma_read(CSDP2, lch);
+		l &= ~0x03;
+		l |= data_type;
+		dma_write(l, CSDP2, lch);
+
+		val = dma_read(CCR2, lch);
 
 		/* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
 		val &= ~((1 << 23) | (3 << 19) | 0x1f);
@@ -313,11 +477,15 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
 		} else {
 			val &= ~(1 << 24);	/* dest synch */
 		}
-		dma_write(val, CCR(lch));
+		dma_write(val, CCR2, lch);
+	}
+	if (cpu_class_is_omap1()) {
+		dma_write(elem_count, CEN1, lch);
+		dma_write(frame_count, CFN1, lch);
+	} else {
+		dma_write(elem_count, CEN2, lch);
+		dma_write(frame_count, CFN2, lch);
 	}
-
-	dma_write(elem_count, CEN(lch));
-	dma_write(frame_count, CFN(lch));
 }
 EXPORT_SYMBOL(omap_set_dma_transfer_params);
 
@@ -328,7 +496,7 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
 	if (cpu_class_is_omap1()) {
 		u16 w;
 
-		w = dma_read(CCR2(lch));
+		w = dma_read(CCR1_2, lch);
 		w &= ~0x03;
 
 		switch (mode) {
@@ -343,23 +511,23 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
 		default:
 			BUG();
 		}
-		dma_write(w, CCR2(lch));
+		dma_write(w, CCR1_2, lch);
 
-		w = dma_read(LCH_CTRL(lch));
+		w = dma_read(LCH_CTRL, lch);
 		w &= ~0x0f;
 		/* Default is channel type 2D */
 		if (mode) {
-			dma_write((u16)color, COLOR_L(lch));
-			dma_write((u16)(color >> 16), COLOR_U(lch));
+			dma_write((u16)color, COLOR_L, lch);
+			dma_write((u16)(color >> 16), COLOR_U, lch);
 			w |= 1;		/* Channel type G */
 		}
-		dma_write(w, LCH_CTRL(lch));
+		dma_write(w, LCH_CTRL, lch);
 	}
 
 	if (cpu_class_is_omap2()) {
 		u32 val;
 
-		val = dma_read(CCR(lch));
+		val = dma_read(CCR2, lch);
 		val &= ~((1 << 17) | (1 << 16));
 
 		switch (mode) {
@@ -374,10 +542,10 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
 		default:
 			BUG();
 		}
-		dma_write(val, CCR(lch));
+		dma_write(val, CCR2, lch);
 
 		color &= 0xffffff;
-		dma_write(color, COLOR(lch));
+		dma_write(color, COLOR, lch);
 	}
 }
 EXPORT_SYMBOL(omap_set_dma_color_mode);
@@ -387,10 +555,10 @@ void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
 	if (cpu_class_is_omap2()) {
 		u32 csdp;
 
-		csdp = dma_read(CSDP(lch));
+		csdp = dma_read(CSDP2, lch);
 		csdp &= ~(0x3 << 16);
 		csdp |= (mode << 16);
-		dma_write(csdp, CSDP(lch));
+		dma_write(csdp, CSDP2, lch);
 	}
 }
 EXPORT_SYMBOL(omap_set_dma_write_mode);
@@ -400,10 +568,10 @@ void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
 	if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
 		u32 l;
 
-		l = dma_read(LCH_CTRL(lch));
+		l = dma_read(LCH_CTRL, lch);
 		l &= ~0x7;
 		l |= mode;
-		dma_write(l, LCH_CTRL(lch));
+		dma_write(l, LCH_CTRL, lch);
 	}
 }
 EXPORT_SYMBOL(omap_set_dma_channel_mode);
@@ -418,27 +586,38 @@ void omap_set_dma_src_params(int lch, int src_port, int src_amode,
 	if (cpu_class_is_omap1()) {
 		u16 w;
 
-		w = dma_read(CSDP(lch));
+		w = dma_read(CSDP1, lch);
 		w &= ~(0x1f << 2);
 		w |= src_port << 2;
-		dma_write(w, CSDP(lch));
-	}
+		dma_write(w, CSDP1, lch);
+
+		l = dma_read(CCR1, lch);
+	} else
+		l = dma_read(CCR2, lch);
 
-	l = dma_read(CCR(lch));
 	l &= ~(0x03 << 12);
 	l |= src_amode << 12;
-	dma_write(l, CCR(lch));
+
+	if (cpu_class_is_omap1())
+		dma_write(l, CCR1, lch);
+	else
+		dma_write(l, CCR2, lch);
 
 	if (cpu_class_is_omap1()) {
-		dma_write(src_start >> 16, CSSA_U(lch));
-		dma_write((u16)src_start, CSSA_L(lch));
+		dma_write(src_start >> 16, CSSA_U, lch);
+		dma_write((u16)src_start, CSSA_L, lch);
 	}
 
 	if (cpu_class_is_omap2())
-		dma_write(src_start, CSSA(lch));
+		dma_write(src_start, CSSA, lch);
 
-	dma_write(src_ei, CSEI(lch));
-	dma_write(src_fi, CSFI(lch));
+	if (cpu_class_is_omap1()) {
+		dma_write(src_ei, CSEI1, lch);
+		dma_write(src_fi, CSFI1, lch);
+	} else {
+		dma_write(src_ei, CSEI2, lch);
+		dma_write(src_fi, CSFI2, lch);
+	}
 }
 EXPORT_SYMBOL(omap_set_dma_src_params);
 
@@ -466,8 +645,8 @@ void omap_set_dma_src_index(int lch, int eidx, int fidx)
 	if (cpu_class_is_omap2())
 		return;
 
-	dma_write(eidx, CSEI(lch));
-	dma_write(fidx, CSFI(lch));
+	dma_write(eidx, CSEI1, lch);
+	dma_write(fidx, CSFI1, lch);
 }
 EXPORT_SYMBOL(omap_set_dma_src_index);
 
@@ -475,11 +654,19 @@ void omap_set_dma_src_data_pack(int lch, int enable)
 {
 	u32 l;
 
-	l = dma_read(CSDP(lch));
+	if (cpu_class_is_omap1())
+		l = dma_read(CSDP1, lch);
+	else
+		l = dma_read(CSDP2, lch);
+
 	l &= ~(1 << 6);
 	if (enable)
 		l |= (1 << 6);
-	dma_write(l, CSDP(lch));
+
+	if (cpu_class_is_omap1())
+		dma_write(l, CSDP1, lch);
+	else
+		dma_write(l, CSDP2, lch);
 }
 EXPORT_SYMBOL(omap_set_dma_src_data_pack);
 
@@ -488,7 +675,11 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 	unsigned int burst = 0;
 	u32 l;
 
-	l = dma_read(CSDP(lch));
+	if (cpu_class_is_omap2())
+		l = dma_read(CSDP2, lch);
+	else
+		l = dma_read(CSDP1, lch);
+
 	l &= ~(0x03 << 7);
 
 	switch (burst_mode) {
@@ -524,7 +715,11 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 	}
 
 	l |= (burst << 7);
-	dma_write(l, CSDP(lch));
+
+	if (cpu_class_is_omap2())
+		dma_write(l, CSDP2, lch);
+	else
+		dma_write(l, CSDP1, lch);
 }
 EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
 
@@ -536,27 +731,38 @@ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
 	u32 l;
 
 	if (cpu_class_is_omap1()) {
-		l = dma_read(CSDP(lch));
+		l = dma_read(CSDP1, lch);
 		l &= ~(0x1f << 9);
 		l |= dest_port << 9;
-		dma_write(l, CSDP(lch));
-	}
+		dma_write(l, CSDP1, lch);
+
+		l = dma_read(CCR1, lch);
+	} else
+		l = dma_read(CCR2, lch);
 
-	l = dma_read(CCR(lch));
 	l &= ~(0x03 << 14);
 	l |= dest_amode << 14;
-	dma_write(l, CCR(lch));
+
+	if (cpu_class_is_omap1())
+		dma_write(l, CCR1, lch);
+	else
+		dma_write(l, CCR2, lch);
 
 	if (cpu_class_is_omap1()) {
-		dma_write(dest_start >> 16, CDSA_U(lch));
-		dma_write(dest_start, CDSA_L(lch));
+		dma_write(dest_start >> 16, CDSA_U, lch);
+		dma_write(dest_start, CDSA_L, lch);
 	}
 
 	if (cpu_class_is_omap2())
-		dma_write(dest_start, CDSA(lch));
+		dma_write(dest_start, CDSA, lch);
 
-	dma_write(dst_ei, CDEI(lch));
-	dma_write(dst_fi, CDFI(lch));
+	if (cpu_class_is_omap1()) {
+		dma_write(dst_ei, CDEI1, lch);
+		dma_write(dst_fi, CDFI1, lch);
+	} else {
+		dma_write(dst_ei, CDEI2, lch);
+		dma_write(dst_fi, CDFI2, lch);
+	}
 }
 EXPORT_SYMBOL(omap_set_dma_dest_params);
 
@@ -565,8 +771,8 @@ void omap_set_dma_dest_index(int lch, int eidx, int fidx)
 	if (cpu_class_is_omap2())
 		return;
 
-	dma_write(eidx, CDEI(lch));
-	dma_write(fidx, CDFI(lch));
+	dma_write(eidx, CDEI1, lch);
+	dma_write(fidx, CDFI1, lch);
 }
 EXPORT_SYMBOL(omap_set_dma_dest_index);
 
@@ -574,11 +780,19 @@ void omap_set_dma_dest_data_pack(int lch, int enable)
 {
 	u32 l;
 
-	l = dma_read(CSDP(lch));
+	if (cpu_class_is_omap2())
+		l = dma_read(CSDP2, lch);
+	else
+		l = dma_read(CSDP1, lch);
+
 	l &= ~(1 << 13);
 	if (enable)
 		l |= 1 << 13;
-	dma_write(l, CSDP(lch));
+
+	if (cpu_class_is_omap2())
+		dma_write(l, CSDP2, lch);
+	else
+		dma_write(l, CSDP1, lch);
 }
 EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
 
@@ -586,8 +800,11 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 {
 	unsigned int burst = 0;
 	u32 l;
+	if (cpu_class_is_omap2())
+		l = dma_read(CSDP2, lch);
+	else
+		l = dma_read(CSDP1, lch);
 
-	l = dma_read(CSDP(lch));
 	l &= ~(0x03 << 14);
 
 	switch (burst_mode) {
@@ -619,8 +836,13 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 		BUG();
 		return;
 	}
+
 	l |= (burst << 14);
-	dma_write(l, CSDP(lch));
+
+	if (cpu_class_is_omap2())
+		dma_write(l, CSDP2, lch);
+	else
+		dma_write(l, CSDP1, lch);
 }
 EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
 
@@ -629,19 +851,21 @@ static inline void omap_enable_channel_irq(int lch)
 	u32 status;
 
 	/* Clear CSR */
-	if (cpu_class_is_omap1())
-		status = dma_read(CSR(lch));
-	else if (cpu_class_is_omap2())
-		dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch));
-
-	/* Enable some nice interrupts. */
-	dma_write(dma_chan[lch].enabled_irqs, CICR(lch));
+	if (cpu_class_is_omap1()) {
+		status = dma_read(CSR1, lch);
+		dma_write(dma_chan[lch].enabled_irqs, CICR1, lch);
+	} else if (cpu_class_is_omap2()) {
+		dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, lch);
+		dma_write(dma_chan[lch].enabled_irqs, CICR2, lch);
+	}
 }
 
 static void omap_disable_channel_irq(int lch)
 {
 	if (cpu_class_is_omap2())
-		dma_write(0, CICR(lch));
+		dma_write(0, CICR2, lch);
+	else
+		dma_write(0, CICR1, lch);
 }
 
 void omap_enable_dma_irq(int lch, u16 bits)
@@ -660,44 +884,44 @@ static inline void enable_lnk(int lch)
 {
 	u32 l;
 
-	l = dma_read(CLNK_CTRL(lch));
-
-	if (cpu_class_is_omap1())
+	if (cpu_class_is_omap1()) {
+		l = dma_read(CLNK_CTRL1, lch);
 		l &= ~(1 << 14);
+	} else
+		l = dma_read(CLNK_CTRL2, lch);
 
 	/* Set the ENABLE_LNK bits */
 	if (dma_chan[lch].next_lch != -1)
 		l = dma_chan[lch].next_lch | (1 << 15);
 
-#ifndef CONFIG_ARCH_OMAP1
-	if (cpu_class_is_omap2())
+	if (cpu_class_is_omap2()) {
 		if (dma_chan[lch].next_linked_ch != -1)
 			l = dma_chan[lch].next_linked_ch | (1 << 15);
-#endif
-
-	dma_write(l, CLNK_CTRL(lch));
+		dma_write(l, CLNK_CTRL2, lch);
+	} else
+		dma_write(l, CLNK_CTRL1, lch);
 }
 
 static inline void disable_lnk(int lch)
 {
 	u32 l;
 
-	l = dma_read(CLNK_CTRL(lch));
-
 	/* Disable interrupts */
 	if (cpu_class_is_omap1()) {
-		dma_write(0, CICR(lch));
+		l = dma_read(CLNK_CTRL1, lch);
+		dma_write(0, CICR1, lch);
 		/* Set the STOP_LNK bit */
 		l |= 1 << 14;
+		dma_write(l, CLNK_CTRL1, lch);
 	}
 
 	if (cpu_class_is_omap2()) {
+		l = dma_read(CLNK_CTRL2, lch);
 		omap_disable_channel_irq(lch);
 		/* Clear the ENABLE_LNK bit */
 		l &= ~(1 << 15);
+		dma_write(l, CLNK_CTRL2, lch);
 	}
-
-	dma_write(l, CLNK_CTRL(lch));
 	dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
 }
 
@@ -710,9 +934,9 @@ static inline void omap2_enable_irq_lch(int lch)
 		return;
 
 	spin_lock_irqsave(&dma_chan_lock, flags);
-	val = dma_read(IRQENABLE_L0);
+	val = dma_read(IRQENABLE_L0, 0);
 	val |= 1 << lch;
-	dma_write(val, IRQENABLE_L0);
+	dma_write(val, IRQENABLE_L0, 0);
 	spin_unlock_irqrestore(&dma_chan_lock, flags);
 }
 
@@ -725,9 +949,9 @@ static inline void omap2_disable_irq_lch(int lch)
 		return;
 
 	spin_lock_irqsave(&dma_chan_lock, flags);
-	val = dma_read(IRQENABLE_L0);
+	val = dma_read(IRQENABLE_L0, 0);
 	val &= ~(1 << lch);
-	dma_write(val, IRQENABLE_L0);
+	dma_write(val, IRQENABLE_L0, 0);
 	spin_unlock_irqrestore(&dma_chan_lock, flags);
 }
 
@@ -792,17 +1016,17 @@ int omap_request_dma(int dev_id, const char *dev_name,
 		 * Disable the 1510 compatibility mode and set the sync device
 		 * id.
 		 */
-		dma_write(dev_id | (1 << 10), CCR(free_ch));
+		dma_write(dev_id | (1 << 10), CCR1, free_ch);
 	} else if (cpu_is_omap7xx() || cpu_is_omap15xx()) {
-		dma_write(dev_id, CCR(free_ch));
+		dma_write(dev_id, CCR1, free_ch);
 	}
 
 	if (cpu_class_is_omap2()) {
 		omap2_enable_irq_lch(free_ch);
 		omap_enable_channel_irq(free_ch);
 		/* Clear the CSR register and IRQ status register */
-		dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(free_ch));
-		dma_write(1 << free_ch, IRQSTATUS_L0);
+		dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, free_ch);
+		dma_write(1 << free_ch, IRQSTATUS_L0, 0);
 	}
 
 	*dma_ch_out = free_ch;
@@ -823,23 +1047,23 @@ void omap_free_dma(int lch)
 
 	if (cpu_class_is_omap1()) {
 		/* Disable all DMA interrupts for the channel. */
-		dma_write(0, CICR(lch));
+		dma_write(0, CICR1, lch);
 		/* Make sure the DMA transfer is stopped. */
-		dma_write(0, CCR(lch));
+		dma_write(0, CCR1, lch);
 	}
 
 	if (cpu_class_is_omap2()) {
 		omap2_disable_irq_lch(lch);
 
 		/* Clear the CSR register and IRQ status register */
-		dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch));
-		dma_write(1 << lch, IRQSTATUS_L0);
+		dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, lch);
+		dma_write(1 << lch, IRQSTATUS_L0, 0);
 
 		/* Disable all DMA interrupts for the channel. */
-		dma_write(0, CICR(lch));
+		dma_write(0, CICR2, lch);
 
 		/* Make sure the DMA transfer is stopped. */
-		dma_write(0, CCR(lch));
+		dma_write(0, CCR2, lch);
 		omap_clear_dma(lch);
 	}
 
@@ -880,7 +1104,7 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
 	reg |= (0x3 & tparams) << 12;
 	reg |= (arb_rate & 0xff) << 16;
 
-	dma_write(reg, GCR);
+	dma_write(reg, GCR2, 0);
 }
 EXPORT_SYMBOL(omap_dma_set_global_params);
 
@@ -903,14 +1127,18 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio,
 		printk(KERN_ERR "Invalid channel id\n");
 		return -EINVAL;
 	}
-	l = dma_read(CCR(lch));
-	l &= ~((1 << 6) | (1 << 26));
-	if (cpu_is_omap2430() || cpu_is_omap34xx() ||  cpu_is_omap44xx())
+
+	if (cpu_is_omap2430() || cpu_is_omap34xx() ||  cpu_is_omap44xx()) {
+		l = dma_read(CCR2, lch);
+		l &= ~((1 << 6) | (1 << 26));
 		l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
-	else
+		dma_write(l, CCR2, lch);
+	} else {
+		l = dma_read(CCR1, lch);
+		l &= ~((1 << 6) | (1 << 26));
 		l |= ((read_prio & 0x1) << 6);
-
-	dma_write(l, CCR(lch));
+		dma_write(l, CCR1, lch);
+	}
 
 	return 0;
 }
@@ -929,19 +1157,19 @@ void omap_clear_dma(int lch)
 	if (cpu_class_is_omap1()) {
 		u32 l;
 
-		l = dma_read(CCR(lch));
+		l = dma_read(CCR1, lch);
 		l &= ~OMAP_DMA_CCR_EN;
-		dma_write(l, CCR(lch));
+		dma_write(l, CCR1, lch);
 
 		/* Clear pending interrupts */
-		l = dma_read(CSR(lch));
+		l = dma_read(CSR1, lch);
 	}
 
 	if (cpu_class_is_omap2()) {
-		int i;
-		void __iomem *lch_base = omap_dma_base + OMAP_DMA4_CH_BASE(lch);
-		for (i = 0; i < 0x44; i += 4)
-			__raw_writel(0, lch_base + i);
+		int i = OMAP2_CH_COMMON_START;
+
+		for (; i <= OMAP2_CH_COMMON_END; i++)
+			dma_write(0, i, lch);
 	}
 
 	local_irq_restore(flags);
@@ -957,9 +1185,12 @@ void omap_start_dma(int lch)
 	 * before starting dma transfer.
 	 */
 	if (cpu_is_omap15xx())
-		dma_write(0, CPC(lch));
+		dma_write(0, CPC, lch);
+	else if (cpu_class_is_omap1())
+		dma_write(0, CDAC1, lch);
 	else
-		dma_write(0, CDAC(lch));
+		dma_write(0, CDAC2, lch);
+
 
 	if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
 		int next_lch, cur_lch;
@@ -989,29 +1220,33 @@ void omap_start_dma(int lch)
 		(cpu_is_omap243x() &&  omap_type() <= OMAP2430_REV_ES1_0)) {
 
 		/* Errata: Need to write lch even if not using chaining */
-		dma_write(lch, CLNK_CTRL(lch));
+		dma_write(lch, CLNK_CTRL2, lch);
 	}
 
 	omap_enable_channel_irq(lch);
 
-	l = dma_read(CCR(lch));
-
-	/*
-	 * Errata: Inter Frame DMA buffering issue (All OMAP2420 and
-	 * OMAP2430ES1.0): DMA will wrongly buffer elements if packing and
-	 * bursting is enabled. This might result in data gets stalled in
-	 * FIFO at the end of the block.
-	 * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
-	 * guarantee no data will stay in the DMA FIFO in case inter frame
-	 * buffering occurs.
-	 */
-	if (cpu_is_omap2420() ||
-	    (cpu_is_omap2430() && (omap_type() == OMAP2430_REV_ES1_0)))
-		l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
-
-	l |= OMAP_DMA_CCR_EN;
-	dma_write(l, CCR(lch));
+	if (cpu_class_is_omap1()) {
+		l = dma_read(CCR1, lch);
+		l |= OMAP_DMA_CCR_EN;
+		dma_write(l, CCR1, lch);
+	} else {
+		l = dma_read(CCR2, lch);
+		/*
+		 * Errata: Inter Frame DMA buffering issue (All OMAP2420 and
+		 * OMAP2430ES1.0): DMA will wrongly buffer elements if packing
+		 * and bursting is enabled. This might result in data gets
+		 * stalled in FIFO at the end of the block.
+		 * Workaround: DMA channels must have BUFFERING_DISABLED bit
+		 * set to guarantee no data will stay in the DMA FIFO in case
+		 * inter frame buffering occurs.
+		 */
+		if (cpu_is_omap2420() || (cpu_is_omap2430() &&
+				(omap_type() == OMAP2430_REV_ES1_0)))
+			l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
 
+		l |= OMAP_DMA_CCR_EN;
+		dma_write(l, CCR2, lch);
+	}
 	dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
 }
 EXPORT_SYMBOL(omap_start_dma);
@@ -1022,41 +1257,45 @@ void omap_stop_dma(int lch)
 
 	/* Disable all interrupts on the channel */
 	if (cpu_class_is_omap1())
-		dma_write(0, CICR(lch));
+		dma_write(0, CICR1, lch);
 
-	l = dma_read(CCR(lch));
 	/* OMAP3 Errata i541: sDMA FIFO draining does not finish */
 	if (cpu_is_omap34xx() && (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
 		int i = 0;
 		u32 sys_cf;
 
 		/* Configure No-Standby */
-		l = dma_read(OCP_SYSCONFIG);
+		l = dma_read(OCP_SYSCONFIG, 0);
 		sys_cf = l;
 		l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
 		l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
-		dma_write(l , OCP_SYSCONFIG);
+		dma_write(l , OCP_SYSCONFIG, 0);
 
-		l = dma_read(CCR(lch));
+		l = dma_read(CCR2, lch);
 		l &= ~OMAP_DMA_CCR_EN;
-		dma_write(l, CCR(lch));
+		dma_write(l, CCR2, lch);
 
 		/* Wait for sDMA FIFO drain */
-		l = dma_read(CCR(lch));
+		l = dma_read(CCR2, lch);
 		while (i < 100 && (l & (OMAP_DMA_CCR_RD_ACTIVE |
 					OMAP_DMA_CCR_WR_ACTIVE))) {
 			udelay(5);
 			i++;
-			l = dma_read(CCR(lch));
+			l = dma_read(CCR2, lch);
 		}
 		if (i >= 100)
 			printk(KERN_ERR "DMA drain did not complete on "
 					"lch %d\n", lch);
 		/* Restore OCP_SYSCONFIG */
-		dma_write(sys_cf, OCP_SYSCONFIG);
+		dma_write(sys_cf, OCP_SYSCONFIG, 0);
+	} else if (cpu_class_is_omap1()) {
+		l = dma_read(CCR1, lch);
+		l &= ~OMAP_DMA_CCR_EN;
+		dma_write(l, CCR1, lch);
 	} else {
+		l = dma_read(CCR2, lch);
 		l &= ~OMAP_DMA_CCR_EN;
-		dma_write(l, CCR(lch));
+		dma_write(l, CCR2, lch);
 	}
 
 	if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
@@ -1122,19 +1361,25 @@ dma_addr_t omap_get_dma_src_pos(int lch)
 	dma_addr_t offset = 0;
 
 	if (cpu_is_omap15xx())
-		offset = dma_read(CPC(lch));
+		offset = dma_read(CPC, lch);
+	else if (cpu_class_is_omap1())
+		offset = dma_read(CSAC1, lch);
 	else
-		offset = dma_read(CSAC(lch));
+		offset = dma_read(CSAC2, lch);
 
 	/*
 	 * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
 	 * read before the DMA controller finished disabling the channel.
 	 */
-	if (!cpu_is_omap15xx() && offset == 0)
-		offset = dma_read(CSAC(lch));
+	if (!cpu_is_omap15xx() && offset == 0) {
+		if (cpu_class_is_omap1())
+			offset = dma_read(CSAC1, lch);
+		else
+			offset = dma_read(CSAC2, lch);
+	}
 
 	if (cpu_class_is_omap1())
-		offset |= (dma_read(CSSA_U(lch)) << 16);
+		offset |= (dma_read(CSSA_U, lch) << 16);
 
 	return offset;
 }
@@ -1153,19 +1398,25 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
 	dma_addr_t offset = 0;
 
 	if (cpu_is_omap15xx())
-		offset = dma_read(CPC(lch));
+		offset = dma_read(CPC, lch);
+	else if (cpu_class_is_omap1())
+		offset = dma_read(CDAC1, lch);
 	else
-		offset = dma_read(CDAC(lch));
+		offset = dma_read(CDAC2, lch);
 
 	/*
 	 * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
 	 * read before the DMA controller finished disabling the channel.
 	 */
-	if (!cpu_is_omap15xx() && offset == 0)
-		offset = dma_read(CDAC(lch));
+	if (!cpu_is_omap15xx() && offset == 0) {
+		if (cpu_class_is_omap1())
+			offset = dma_read(CDAC1, lch);
+		else
+			offset = dma_read(CDAC2, lch);
+	}
 
 	if (cpu_class_is_omap1())
-		offset |= (dma_read(CDSA_U(lch)) << 16);
+		offset |= (dma_read(CDSA_U, lch) << 16);
 
 	return offset;
 }
@@ -1173,7 +1424,10 @@ EXPORT_SYMBOL(omap_get_dma_dst_pos);
 
 int omap_get_dma_active_status(int lch)
 {
-	return (dma_read(CCR(lch)) & OMAP_DMA_CCR_EN) != 0;
+	if (cpu_class_is_omap1())
+		return (dma_read(CCR1, lch) & OMAP_DMA_CCR_EN) != 0;
+	else
+		return (dma_read(CCR2, lch) & OMAP_DMA_CCR_EN) != 0;
 }
 EXPORT_SYMBOL(omap_get_dma_active_status);
 
@@ -1181,14 +1435,15 @@ int omap_dma_running(void)
 {
 	int lch;
 
-	if (cpu_class_is_omap1())
-		if (omap_lcd_dma_running())
-			return 1;
-
-	for (lch = 0; lch < dma_chan_count; lch++)
-		if (dma_read(CCR(lch)) & OMAP_DMA_CCR_EN)
-			return 1;
-
+	for (lch = 0; lch < dma_chan_count; lch++) {
+		if (cpu_class_is_omap1()) {
+			if (dma_read(CCR1, lch) & OMAP_DMA_CCR_EN)
+				return 1;
+		} else {
+			if (dma_read(CCR2, lch) & OMAP_DMA_CCR_EN)
+				return 1;
+		}
+	}
 	return 0;
 }
 
@@ -1201,8 +1456,8 @@ void omap_dma_link_lch(int lch_head, int lch_queue)
 {
 	if (omap_dma_in_1510_mode()) {
 		if (lch_head == lch_queue) {
-			dma_write(dma_read(CCR(lch_head)) | (3 << 8),
-								CCR(lch_head));
+			dma_write(dma_read(CCR1, lch_head) | (3 << 8),
+							CCR1, lch_head);
 			return;
 		}
 		printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
@@ -1228,8 +1483,8 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)
 {
 	if (omap_dma_in_1510_mode()) {
 		if (lch_head == lch_queue) {
-			dma_write(dma_read(CCR(lch_head)) & ~(3 << 8),
-								CCR(lch_head));
+			dma_write(dma_read(CCR1, lch_head) & ~(3 << 8),
+								CCR1, lch_head);
 			return;
 		}
 		printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
@@ -1281,15 +1536,15 @@ static void create_dma_lch_chain(int lch_head, int lch_queue)
 					lch_queue;
 	}
 
-	l = dma_read(CLNK_CTRL(lch_head));
+	l = dma_read(CLNK_CTRL2, lch_head);
 	l &= ~(0x1f);
 	l |= lch_queue;
-	dma_write(l, CLNK_CTRL(lch_head));
+	dma_write(l, CLNK_CTRL2, lch_head);
 
-	l = dma_read(CLNK_CTRL(lch_queue));
+	l = dma_read(CLNK_CTRL2, lch_queue);
 	l &= ~(0x1f);
 	l |= (dma_chan[lch_queue].next_linked_ch);
-	dma_write(l, CLNK_CTRL(lch_queue));
+	dma_write(l, CLNK_CTRL2, lch_queue);
 }
 
 /**
@@ -1565,13 +1820,13 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
 
 	/* Set the params to the free channel */
 	if (src_start != 0)
-		dma_write(src_start, CSSA(lch));
+		dma_write(src_start, CSSA, lch);
 	if (dest_start != 0)
-		dma_write(dest_start, CDSA(lch));
+		dma_write(dest_start, CDSA, lch);
 
 	/* Write the buffer size */
-	dma_write(elem_count, CEN(lch));
-	dma_write(frame_count, CFN(lch));
+	dma_write(elem_count, CEN2, lch);
+	dma_write(frame_count, CFN2, lch);
 
 	/*
 	 * If the chain is dynamically linked,
@@ -1605,7 +1860,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
 				dma_chan[lch].state = DMA_CH_QUEUED;
 				start_dma = 0;
 				if (0 == ((1 << 7) & dma_read(
-					CCR(dma_chan[lch].prev_linked_ch)))) {
+					CCR2, dma_chan[lch].prev_linked_ch))) {
 					disable_lnk(dma_chan[lch].
 						    prev_linked_ch);
 					pr_debug("\n prev ch is stopped\n");
@@ -1621,7 +1876,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
 			}
 			omap_enable_channel_irq(lch);
 
-			l = dma_read(CCR(lch));
+			l = dma_read(CCR2, lch);
 
 			if ((0 == (l & (1 << 24))))
 				l &= ~(1 << 25);
@@ -1632,12 +1887,12 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
 					l |= (1 << 7);
 					dma_chan[lch].state = DMA_CH_STARTED;
 					pr_debug("starting %d\n", lch);
-					dma_write(l, CCR(lch));
+					dma_write(l, CCR2, lch);
 				} else
 					start_dma = 0;
 			} else {
 				if (0 == (l & (1 << 7)))
-					dma_write(l, CCR(lch));
+					dma_write(l, CCR2, lch);
 			}
 			dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
 		}
@@ -1682,7 +1937,7 @@ int omap_start_dma_chain_transfers(int chain_id)
 		omap_enable_channel_irq(channels[0]);
 	}
 
-	l = dma_read(CCR(channels[0]));
+	l = dma_read(CCR2, channels[0]);
 	l |= (1 << 7);
 	dma_linked_lch[chain_id].chain_state = DMA_CHAIN_STARTED;
 	dma_chan[channels[0]].state = DMA_CH_STARTED;
@@ -1691,7 +1946,7 @@ int omap_start_dma_chain_transfers(int chain_id)
 		l &= ~(1 << 25);
 	else
 		l |= (1 << 25);
-	dma_write(l, CCR(channels[0]));
+	dma_write(l, CCR2, channels[0]);
 
 	dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE;
 
@@ -1730,18 +1985,18 @@ int omap_stop_dma_chain_transfers(int chain_id)
 	 * DMA Errata:
 	 * Special programming model needed to disable DMA before end of block
 	 */
-	sys_cf = dma_read(OCP_SYSCONFIG);
+	sys_cf = dma_read(OCP_SYSCONFIG, 0);
 	l = sys_cf;
 	/* Middle mode reg set no Standby */
 	l &= ~((1 << 12)|(1 << 13));
-	dma_write(l, OCP_SYSCONFIG);
+	dma_write(l, OCP_SYSCONFIG, 0);
 
 	for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
 
 		/* Stop the Channel transmission */
-		l = dma_read(CCR(channels[i]));
+		l = dma_read(CCR2, channels[i]);
 		l &= ~(1 << 7);
-		dma_write(l, CCR(channels[i]));
+		dma_write(l, CCR2, channels[i]);
 
 		/* Disable the link in all the channels */
 		disable_lnk(channels[i]);
@@ -1754,7 +2009,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
 	OMAP_DMA_CHAIN_QINIT(chain_id);
 
 	/* Errata - put in the old value */
-	dma_write(sys_cf, OCP_SYSCONFIG);
+	dma_write(sys_cf, OCP_SYSCONFIG, 0);
 
 	return 0;
 }
@@ -1796,8 +2051,8 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi)
 	/* Get the current channel */
 	lch = channels[dma_linked_lch[chain_id].q_head];
 
-	*ei = dma_read(CCEN(lch));
-	*fi = dma_read(CCFN(lch));
+	*ei = dma_read(CCEN, lch);
+	*fi = dma_read(CCFN, lch);
 
 	return 0;
 }
@@ -1834,7 +2089,7 @@ int omap_get_dma_chain_dst_pos(int chain_id)
 	/* Get the current channel */
 	lch = channels[dma_linked_lch[chain_id].q_head];
 
-	return dma_read(CDAC(lch));
+	return dma_read(CDAC2, lch);
 }
 EXPORT_SYMBOL(omap_get_dma_chain_dst_pos);
 
@@ -1868,7 +2123,7 @@ int omap_get_dma_chain_src_pos(int chain_id)
 	/* Get the current channel */
 	lch = channels[dma_linked_lch[chain_id].q_head];
 
-	return dma_read(CSAC(lch));
+	return dma_read(CSAC2, lch);
 }
 EXPORT_SYMBOL(omap_get_dma_chain_src_pos);
 #endif	/* ifndef CONFIG_ARCH_OMAP1 */
@@ -1885,7 +2140,7 @@ static int omap1_dma_handle_ch(int ch)
 		csr = dma_chan[ch].saved_csr;
 		dma_chan[ch].saved_csr = 0;
 	} else
-		csr = dma_read(CSR(ch));
+		csr = dma_read(CSR1, ch);
 	if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
 		dma_chan[ch + 6].saved_csr = csr >> 7;
 		csr &= 0x7f;
@@ -1938,13 +2193,13 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
 
 static int omap2_dma_handle_ch(int ch)
 {
-	u32 status = dma_read(CSR(ch));
+	u32 status = dma_read(CSR2, ch);
 
 	if (!status) {
 		if (printk_ratelimit())
 			printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n",
 				ch);
-		dma_write(1 << ch, IRQSTATUS_L0);
+		dma_write(1 << ch, IRQSTATUS_L0, 0);
 		return 0;
 	}
 	if (unlikely(dma_chan[ch].dev_id == -1)) {
@@ -1968,9 +2223,9 @@ static int omap2_dma_handle_ch(int ch)
 			 */
 			u32 ccr;
 
-			ccr = dma_read(CCR(ch));
+			ccr = dma_read(CCR2, ch);
 			ccr &= ~OMAP_DMA_CCR_EN;
-			dma_write(ccr, CCR(ch));
+			dma_write(ccr, CCR2, ch);
 			dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
 		}
 	}
@@ -1981,16 +2236,16 @@ static int omap2_dma_handle_ch(int ch)
 		printk(KERN_INFO "DMA misaligned error with device %d\n",
 		       dma_chan[ch].dev_id);
 
-	dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(ch));
-	dma_write(1 << ch, IRQSTATUS_L0);
+	dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, ch);
+	dma_write(1 << ch, IRQSTATUS_L0, ch);
 	/* read back the register to flush the write */
-	dma_read(IRQSTATUS_L0);
+	dma_read(IRQSTATUS_L0, ch);
 
 	/* If the ch is not chained then chain_id will be -1 */
 	if (dma_chan[ch].chain_id != -1) {
 		int chain_id = dma_chan[ch].chain_id;
 		dma_chan[ch].state = DMA_CH_NOTSTARTED;
-		if (dma_read(CLNK_CTRL(ch)) & (1 << 15))
+		if (dma_read(CLNK_CTRL2, ch) & (1 << 15))
 			dma_chan[dma_chan[ch].next_linked_ch].state =
 							DMA_CH_STARTED;
 		if (dma_linked_lch[chain_id].chain_mode ==
@@ -2000,10 +2255,10 @@ static int omap2_dma_handle_ch(int ch)
 		if (!OMAP_DMA_CHAIN_QEMPTY(chain_id))
 			OMAP_DMA_CHAIN_INCQHEAD(chain_id);
 
-		status = dma_read(CSR(ch));
+		status = dma_read(CSR2, ch);
 	}
 
-	dma_write(status, CSR(ch));
+	dma_write(status, CSR2, ch);
 
 	if (likely(dma_chan[ch].callback != NULL))
 		dma_chan[ch].callback(ch, status, dma_chan[ch].data);
@@ -2017,13 +2272,13 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
 	u32 val, enable_reg;
 	int i;
 
-	val = dma_read(IRQSTATUS_L0);
+	val = dma_read(IRQSTATUS_L0, 0);
 	if (val == 0) {
 		if (printk_ratelimit())
 			printk(KERN_WARNING "Spurious DMA IRQ\n");
 		return IRQ_HANDLED;
 	}
-	enable_reg = dma_read(IRQENABLE_L0);
+	enable_reg = dma_read(IRQENABLE_L0, 0);
 	val &= enable_reg; /* Dispatch only relevant interrupts */
 	for (i = 0; i < dma_lch_count && val != 0; i++) {
 		if (val & 1)
@@ -2049,21 +2304,21 @@ static struct irqaction omap24xx_dma_irq;
 void omap_dma_global_context_save(void)
 {
 	omap_dma_global_context.dma_irqenable_l0 =
-		dma_read(IRQENABLE_L0);
+		dma_read(IRQENABLE_L0, 0);
 	omap_dma_global_context.dma_ocp_sysconfig =
-		dma_read(OCP_SYSCONFIG);
-	omap_dma_global_context.dma_gcr = dma_read(GCR);
+		dma_read(OCP_SYSCONFIG, 0);
+	omap_dma_global_context.dma_gcr = dma_read(GCR2, 0);
 }
 
 void omap_dma_global_context_restore(void)
 {
 	int ch;
 
-	dma_write(omap_dma_global_context.dma_gcr, GCR);
+	dma_write(omap_dma_global_context.dma_gcr, GCR2, 0);
 	dma_write(omap_dma_global_context.dma_ocp_sysconfig,
-		OCP_SYSCONFIG);
+		OCP_SYSCONFIG, 0);
 	dma_write(omap_dma_global_context.dma_irqenable_l0,
-		IRQENABLE_L0);
+		IRQENABLE_L0, 0);
 
 	/*
 	 * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
@@ -2072,7 +2327,7 @@ void omap_dma_global_context_restore(void)
 	 * affects only secure devices.
 	 */
 	if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
-		dma_write(0x3 , IRQSTATUS_L0);
+		dma_write(0x3 , IRQSTATUS_L0, 0);
 
 	for (ch = 0; ch < dma_chan_count; ch++)
 		if (dma_chan[ch].dev_id != -1)
@@ -2103,8 +2358,8 @@ static int __init omap_init_dma(void)
 		return -ENODEV;
 	}
 
-	omap_dma_base = ioremap(base, SZ_4K);
-	BUG_ON(!omap_dma_base);
+	dma_base = ioremap(base, SZ_4K);
+	BUG_ON(!dma_base);
 
 	if (cpu_class_is_omap2() && omap_dma_reserve_channels
 			&& (omap_dma_reserve_channels <= dma_lch_count))
@@ -2132,26 +2387,26 @@ static int __init omap_init_dma(void)
 		enable_1510_mode = 1;
 	} else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
 		printk(KERN_INFO "OMAP DMA hardware version %d\n",
-		       dma_read(HW_ID));
+		       dma_read(HW_ID, 0));
 		printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
-		       (dma_read(CAPS_0_U) << 16) |
-		       dma_read(CAPS_0_L),
-		       (dma_read(CAPS_1_U) << 16) |
-		       dma_read(CAPS_1_L),
-		       dma_read(CAPS_2), dma_read(CAPS_3),
-		       dma_read(CAPS_4));
+		       (dma_read(CAPS1_0_U, 0) << 16) |
+		       dma_read(CAPS1_0_L, 0),
+		       (dma_read(CAPS1_1_U, 0) << 16) |
+		       dma_read(CAPS1_1_L, 0),
+		       dma_read(CAPS1_2, 0), dma_read(CAPS1_3, 0),
+		       dma_read(CAPS1_4, 0));
 		if (!enable_1510_mode) {
 			u16 w;
 
 			/* Disable OMAP 3.0/3.1 compatibility mode. */
-			w = dma_read(GSCR);
+			w = dma_read(GSCR, 0);
 			w |= 1 << 3;
-			dma_write(w, GSCR);
+			dma_write(w, GSCR, 0);
 			dma_chan_count = 16;
 		} else
 			dma_chan_count = 9;
 	} else if (cpu_class_is_omap2()) {
-		u8 revision = dma_read(REVISION) & 0xff;
+		u8 revision = dma_read(REVISION, 0) & 0xff;
 		printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
 		       revision >> 4, revision & 0xf);
 		dma_chan_count = dma_lch_count;
@@ -2210,14 +2465,14 @@ static int __init omap_init_dma(void)
 
 	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
 		/* Enable smartidle idlemodes and autoidle */
-		u32 v = dma_read(OCP_SYSCONFIG);
+		u32 v = dma_read(OCP_SYSCONFIG, 0);
 		v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK |
 				DMA_SYSCONFIG_SIDLEMODE_MASK |
 				DMA_SYSCONFIG_AUTOIDLE);
 		v |= (DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
 			DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
 			DMA_SYSCONFIG_AUTOIDLE);
-		dma_write(v , OCP_SYSCONFIG);
+		dma_write(v , OCP_SYSCONFIG, 0);
 		/* reserve dma channels 0 and 1 in high security devices */
 		if (cpu_is_omap34xx() &&
 			(omap_type() != OMAP2_DEVICE_TYPE_GP)) {
@@ -2234,7 +2489,7 @@ out_free:
 	kfree(dma_chan);
 
 out_unmap:
-	iounmap(omap_dma_base);
+	iounmap(dma_base);
 
 	return r;
 }
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
index 0cce4ca..27578f3 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -27,134 +27,14 @@
 /* Hardware registers for omap1 */
 #define OMAP1_DMA_BASE			(0xfffed800)
 
-#define OMAP1_DMA_GCR			0x400
-#define OMAP1_DMA_GSCR			0x404
-#define OMAP1_DMA_GRST			0x408
-#define OMAP1_DMA_HW_ID			0x442
-#define OMAP1_DMA_PCH2_ID		0x444
-#define OMAP1_DMA_PCH0_ID		0x446
-#define OMAP1_DMA_PCH1_ID		0x448
-#define OMAP1_DMA_PCHG_ID		0x44a
-#define OMAP1_DMA_PCHD_ID		0x44c
-#define OMAP1_DMA_CAPS_0_U		0x44e
-#define OMAP1_DMA_CAPS_0_L		0x450
-#define OMAP1_DMA_CAPS_1_U		0x452
-#define OMAP1_DMA_CAPS_1_L		0x454
-#define OMAP1_DMA_CAPS_2		0x456
-#define OMAP1_DMA_CAPS_3		0x458
-#define OMAP1_DMA_CAPS_4		0x45a
-#define OMAP1_DMA_PCH2_SR		0x460
-#define OMAP1_DMA_PCH0_SR		0x480
-#define OMAP1_DMA_PCH1_SR		0x482
-#define OMAP1_DMA_PCHD_SR		0x4c0
-
 /* Hardware registers for omap2 and omap3 */
 #define OMAP24XX_DMA4_BASE		(L4_24XX_BASE + 0x56000)
 #define OMAP34XX_DMA4_BASE		(L4_34XX_BASE + 0x56000)
 #define OMAP44XX_DMA4_BASE		(L4_44XX_BASE + 0x56000)
 
-#define OMAP_DMA4_REVISION		0x00
-#define OMAP_DMA4_GCR			0x78
-#define OMAP_DMA4_IRQSTATUS_L0		0x08
-#define OMAP_DMA4_IRQSTATUS_L1		0x0c
-#define OMAP_DMA4_IRQSTATUS_L2		0x10
-#define OMAP_DMA4_IRQSTATUS_L3		0x14
-#define OMAP_DMA4_IRQENABLE_L0		0x18
-#define OMAP_DMA4_IRQENABLE_L1		0x1c
-#define OMAP_DMA4_IRQENABLE_L2		0x20
-#define OMAP_DMA4_IRQENABLE_L3		0x24
-#define OMAP_DMA4_SYSSTATUS		0x28
-#define OMAP_DMA4_OCP_SYSCONFIG		0x2c
-#define OMAP_DMA4_CAPS_0		0x64
-#define OMAP_DMA4_CAPS_2		0x6c
-#define OMAP_DMA4_CAPS_3		0x70
-#define OMAP_DMA4_CAPS_4		0x74
-
 #define OMAP1_LOGICAL_DMA_CH_COUNT	17
 #define OMAP_DMA4_LOGICAL_DMA_CH_COUNT	32	/* REVISIT: Is this 32 + 2? */
 
-/* Common channel specific registers for omap1 */
-#define OMAP1_DMA_CH_BASE(n)		(0x40 * (n) + 0x00)
-#define OMAP1_DMA_CSDP(n)		(0x40 * (n) + 0x00)
-#define OMAP1_DMA_CCR(n)		(0x40 * (n) + 0x02)
-#define OMAP1_DMA_CICR(n)		(0x40 * (n) + 0x04)
-#define OMAP1_DMA_CSR(n)		(0x40 * (n) + 0x06)
-#define OMAP1_DMA_CEN(n)		(0x40 * (n) + 0x10)
-#define OMAP1_DMA_CFN(n)		(0x40 * (n) + 0x12)
-#define OMAP1_DMA_CSFI(n)		(0x40 * (n) + 0x14)
-#define OMAP1_DMA_CSEI(n)		(0x40 * (n) + 0x16)
-#define OMAP1_DMA_CPC(n)		(0x40 * (n) + 0x18)	/* 15xx only */
-#define OMAP1_DMA_CSAC(n)		(0x40 * (n) + 0x18)
-#define OMAP1_DMA_CDAC(n)		(0x40 * (n) + 0x1a)
-#define OMAP1_DMA_CDEI(n)		(0x40 * (n) + 0x1c)
-#define OMAP1_DMA_CDFI(n)		(0x40 * (n) + 0x1e)
-#define OMAP1_DMA_CLNK_CTRL(n)		(0x40 * (n) + 0x28)
-
-/* Common channel specific registers for omap2 */
-#define OMAP_DMA4_CH_BASE(n)		(0x60 * (n) + 0x80)
-#define OMAP_DMA4_CCR(n)		(0x60 * (n) + 0x80)
-#define OMAP_DMA4_CLNK_CTRL(n)		(0x60 * (n) + 0x84)
-#define OMAP_DMA4_CICR(n)		(0x60 * (n) + 0x88)
-#define OMAP_DMA4_CSR(n)		(0x60 * (n) + 0x8c)
-#define OMAP_DMA4_CSDP(n)		(0x60 * (n) + 0x90)
-#define OMAP_DMA4_CEN(n)		(0x60 * (n) + 0x94)
-#define OMAP_DMA4_CFN(n)		(0x60 * (n) + 0x98)
-#define OMAP_DMA4_CSEI(n)		(0x60 * (n) + 0xa4)
-#define OMAP_DMA4_CSFI(n)		(0x60 * (n) + 0xa8)
-#define OMAP_DMA4_CDEI(n)		(0x60 * (n) + 0xac)
-#define OMAP_DMA4_CDFI(n)		(0x60 * (n) + 0xb0)
-#define OMAP_DMA4_CSAC(n)		(0x60 * (n) + 0xb4)
-#define OMAP_DMA4_CDAC(n)		(0x60 * (n) + 0xb8)
-
-/* Channel specific registers only on omap1 */
-#define OMAP1_DMA_CSSA_L(n)		(0x40 * (n) + 0x08)
-#define OMAP1_DMA_CSSA_U(n)		(0x40 * (n) + 0x0a)
-#define OMAP1_DMA_CDSA_L(n)		(0x40 * (n) + 0x0c)
-#define OMAP1_DMA_CDSA_U(n)		(0x40 * (n) + 0x0e)
-#define OMAP1_DMA_COLOR_L(n)		(0x40 * (n) + 0x20)
-#define OMAP1_DMA_COLOR_U(n)		(0x40 * (n) + 0x22)
-#define OMAP1_DMA_CCR2(n)		(0x40 * (n) + 0x24)
-#define OMAP1_DMA_LCH_CTRL(n)		(0x40 * (n) + 0x2a)	/* not on 15xx */
-#define OMAP1_DMA_CCEN(n)		0
-#define OMAP1_DMA_CCFN(n)		0
-
-/* Channel specific registers only on omap2 */
-#define OMAP_DMA4_CSSA(n)		(0x60 * (n) + 0x9c)
-#define OMAP_DMA4_CDSA(n)		(0x60 * (n) + 0xa0)
-#define OMAP_DMA4_CCEN(n)		(0x60 * (n) + 0xbc)
-#define OMAP_DMA4_CCFN(n)		(0x60 * (n) + 0xc0)
-#define OMAP_DMA4_COLOR(n)		(0x60 * (n) + 0xc4)
-
-/* Additional registers available on OMAP4 */
-#define OMAP_DMA4_CDP(n)		(0x60 * (n) + 0xd0)
-#define OMAP_DMA4_CNDP(n)		(0x60 * (n) + 0xd4)
-#define OMAP_DMA4_CCDN(n)		(0x60 * (n) + 0xd8)
-
-/* Dummy defines to keep multi-omap compiles happy */
-#define OMAP1_DMA_REVISION		0
-#define OMAP1_DMA_IRQSTATUS_L0		0
-#define OMAP1_DMA_IRQENABLE_L0		0
-#define OMAP1_DMA_OCP_SYSCONFIG		0
-#define OMAP_DMA4_HW_ID			0
-#define OMAP_DMA4_CAPS_0_L		0
-#define OMAP_DMA4_CAPS_0_U		0
-#define OMAP_DMA4_CAPS_1_L		0
-#define OMAP_DMA4_CAPS_1_U		0
-#define OMAP_DMA4_GSCR			0
-#define OMAP_DMA4_CPC(n)		0
-
-#define OMAP_DMA4_LCH_CTRL(n)		0
-#define OMAP_DMA4_COLOR_L(n)		0
-#define OMAP_DMA4_COLOR_U(n)		0
-#define OMAP_DMA4_CCR2(n)		0
-#define OMAP1_DMA_CSSA(n)		0
-#define OMAP1_DMA_CDSA(n)		0
-#define OMAP_DMA4_CSSA_L(n)		0
-#define OMAP_DMA4_CSSA_U(n)		0
-#define OMAP_DMA4_CDSA_L(n)		0
-#define OMAP_DMA4_CDSA_U(n)		0
-#define OMAP1_DMA_COLOR(n)		0
-
 /*----------------------------------------------------------------------------*/
 
 /* DMA channels for omap1 */
-- 
1.7.1


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

* [PATCH v4 02/13] OMAP: DMA: Introduce errata handling feature
  2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 01/13] OMAP: DMA: Replace read/write macros with functions G, Manjunath Kondaiah
@ 2010-11-08 14:07 ` G, Manjunath Kondaiah
  2010-12-02 19:59     ` Tony Lindgren
  2010-11-08 14:07 ` [PATCH v4 03/13] OMAP: DMA: Introduce DMA device attributes G, Manjunath Kondaiah
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Peter Ujfalusi, Benoit Cousson, Kevin Hilman,
	Santosh Shilimkar

Implement errata handling to use flags instead of cpu_is_*
and cpu_class_* in the code.

The errata flags are initialized at init time and during runtime
we are using the errata variable (via the IS_DMA_ERRATA macro)
to execute the required errata workaround.

Reused errata handling patch from Peter Ujfalusi <peter.ujfalusi@nokia.com>
https://patchwork.kernel.org/patch/231191/

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Cc: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/plat-omap/dma.c              |  134 ++++++++++++++++++++++----------
 arch/arm/plat-omap/include/plat/dma.h |   11 +++
 2 files changed, 103 insertions(+), 42 deletions(-)

diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index bb54be3..0e1c7b4 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -195,6 +195,7 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
 #define OMAP_FUNC_MUX_ARM_BASE		(0xfffe1000 + 0xec)
 
 static int enable_1510_mode;
+static u32 errata;
 
 static struct omap_dma_global_context_registers {
 	u32 dma_irqenable_l0;
@@ -1216,12 +1217,8 @@ void omap_start_dma(int lch)
 
 			cur_lch = next_lch;
 		} while (next_lch != -1);
-	} else if (cpu_is_omap242x() ||
-		(cpu_is_omap243x() &&  omap_type() <= OMAP2430_REV_ES1_0)) {
-
-		/* Errata: Need to write lch even if not using chaining */
+	} else if (IS_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS))
 		dma_write(lch, CLNK_CTRL2, lch);
-	}
 
 	omap_enable_channel_irq(lch);
 
@@ -1231,17 +1228,8 @@ void omap_start_dma(int lch)
 		dma_write(l, CCR1, lch);
 	} else {
 		l = dma_read(CCR2, lch);
-		/*
-		 * Errata: Inter Frame DMA buffering issue (All OMAP2420 and
-		 * OMAP2430ES1.0): DMA will wrongly buffer elements if packing
-		 * and bursting is enabled. This might result in data gets
-		 * stalled in FIFO at the end of the block.
-		 * Workaround: DMA channels must have BUFFERING_DISABLED bit
-		 * set to guarantee no data will stay in the DMA FIFO in case
-		 * inter frame buffering occurs.
-		 */
-		if (cpu_is_omap2420() || (cpu_is_omap2430() &&
-				(omap_type() == OMAP2430_REV_ES1_0)))
+
+		if (IS_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING))
 			l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
 
 		l |= OMAP_DMA_CCR_EN;
@@ -1253,14 +1241,14 @@ EXPORT_SYMBOL(omap_start_dma);
 
 void omap_stop_dma(int lch)
 {
-	u32 l;
+	u32 l = 0;
 
 	/* Disable all interrupts on the channel */
 	if (cpu_class_is_omap1())
 		dma_write(0, CICR1, lch);
 
-	/* OMAP3 Errata i541: sDMA FIFO draining does not finish */
-	if (cpu_is_omap34xx() && (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
+	if (IS_DMA_ERRATA(DMA_ERRATA_i541) &&
+			(l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
 		int i = 0;
 		u32 sys_cf;
 
@@ -1367,11 +1355,7 @@ dma_addr_t omap_get_dma_src_pos(int lch)
 	else
 		offset = dma_read(CSAC2, lch);
 
-	/*
-	 * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
-	 * read before the DMA controller finished disabling the channel.
-	 */
-	if (!cpu_is_omap15xx() && offset == 0) {
+	if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0) {
 		if (cpu_class_is_omap1())
 			offset = dma_read(CSAC1, lch);
 		else
@@ -1966,7 +1950,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
 {
 	int *channels;
 	u32 l, i;
-	u32 sys_cf;
+	u32 sys_cf = 0;
 
 	/* Check for input params */
 	if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
@@ -1981,15 +1965,13 @@ int omap_stop_dma_chain_transfers(int chain_id)
 	}
 	channels = dma_linked_lch[chain_id].linked_dmach_q;
 
-	/*
-	 * DMA Errata:
-	 * Special programming model needed to disable DMA before end of block
-	 */
-	sys_cf = dma_read(OCP_SYSCONFIG, 0);
-	l = sys_cf;
-	/* Middle mode reg set no Standby */
-	l &= ~((1 << 12)|(1 << 13));
-	dma_write(l, OCP_SYSCONFIG, 0);
+	if (IS_DMA_ERRATA(DMA_ERRATA_i88)) {
+		sys_cf = dma_read(OCP_SYSCONFIG, 0);
+		l = sys_cf;
+		/* Middle mode reg set no Standby */
+		l &= ~((1 << 12)|(1 << 13));
+		dma_write(l, OCP_SYSCONFIG, 0);
+	}
 
 	for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
 
@@ -2008,8 +1990,8 @@ int omap_stop_dma_chain_transfers(int chain_id)
 	/* Reset the Queue pointers */
 	OMAP_DMA_CHAIN_QINIT(chain_id);
 
-	/* Errata - put in the old value */
-	dma_write(sys_cf, OCP_SYSCONFIG, 0);
+	if (IS_DMA_ERRATA(DMA_ERRATA_i88))
+		dma_write(sys_cf, OCP_SYSCONFIG, 0);
 
 	return 0;
 }
@@ -2215,12 +2197,7 @@ static int omap2_dma_handle_ch(int ch)
 	if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ)) {
 		printk(KERN_INFO "DMA transaction error with device %d\n",
 		       dma_chan[ch].dev_id);
-		if (cpu_class_is_omap2()) {
-			/*
-			 * Errata: sDMA Channel is not disabled
-			 * after a transaction error. So we explicitely
-			 * disable the channel
-			 */
+		if (IS_DMA_ERRATA(DMA_ERRATA_i378)) {
 			u32 ccr;
 
 			ccr = dma_read(CCR2, ch);
@@ -2334,6 +2311,76 @@ void omap_dma_global_context_restore(void)
 			omap_clear_dma(ch);
 }
 
+static void configure_dma_errata(void)
+{
+
+	/*
+	 * Erratas applicable for OMAP2430ES1.0 and all omap2420
+	 *
+	 * I.
+	 * Errata ID: XX Inter Frame DMA buffering issue DMA will wrongly
+	 * buffer elements if packing and bursting is enabled. This might
+	 * result in data gets stalled in FIFO at the end of the block.
+	 * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
+	 * guarantee no data will stay in the DMA FIFO in case inter frame
+	 * buffering occurs
+	 *
+	 * II.
+	 * Errata ID: XX DMA may hang when several channels are used in parallel
+	 * In the following configuration, DMA channel hanging can occur:
+	 * a. Channel i, hardware synchronized, is enabled
+	 * b. Another channel (Channel x), software synchronized, is enabled.
+	 * c. Channel i is disabled before end of transfer
+	 * d. Channel i is reenabled.
+	 * e. Steps 1 to 4 are repeated a certain number of times.
+	 * f. A third channel (Channel y), software synchronized, is enabled.
+	 * Channel x and Channel y may hang immediately after step 'f'.
+	 * Workaround:
+	 * For any channel used - make sure NextLCH_ID is set to the value j.
+	 */
+	if (cpu_is_omap2420() || (cpu_is_omap2430() &&
+				(omap_type() == OMAP2430_REV_ES1_0))) {
+
+		SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING);
+		SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS);
+	}
+
+	/*
+	 * Errata ID: i378: OMAP2plus: sDMA Channel is not disabled
+	 * after a transaction error.
+	 * Workaround: SW should explicitely disable the channel.
+	 */
+	if (cpu_class_is_omap2())
+		SET_DMA_ERRATA(DMA_ERRATA_i378);
+
+	/*
+	 * Errata ID: i541: sDMA FIFO draining does not finish
+	 * If sDMA channel is disabled on the fly, sDMA enters standby even
+	 * through FIFO Drain is still in progress
+	 * Workaround: Put sDMA in NoStandby more before a logical channel is
+	 * disabled, then put it back to SmartStandby right after the channel
+	 * finishes FIFO draining.
+	 */
+	if (cpu_is_omap34xx())
+		SET_DMA_ERRATA(DMA_ERRATA_i541);
+
+	/*
+	 * Errata ID: i88 : Special programming model needed to disable DMA
+	 * before end of block.
+	 * Workaround: software must ensure that the DMA is configured in No
+	 * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01")
+	 */
+	if (omap_type() == OMAP3430_REV_ES1_0)
+		SET_DMA_ERRATA(DMA_ERRATA_i88);
+
+	/*
+	 * Errata 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
+	 * read before the DMA controller finished disabling the channel.
+	 */
+	if (!cpu_is_omap15xx())
+		SET_DMA_ERRATA(DMA_ERRATA_3_3);
+}
+
 /*----------------------------------------------------------------------------*/
 
 static int __init omap_init_dma(void)
@@ -2483,6 +2530,9 @@ static int __init omap_init_dma(void)
 		}
 	}
 
+	/* Configure errata handling for all omap's */
+	configure_dma_errata();
+
 	return 0;
 
 out_free:
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
index 27578f3..5e28d26 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -285,6 +285,17 @@
 #define DMA_CH_PRIO_HIGH		0x1
 #define DMA_CH_PRIO_LOW			0x0 /* Def */
 
+/* Errata handling */
+#define IS_DMA_ERRATA(id)		(errata &= (id))
+#define SET_DMA_ERRATA(id)		(errata |= (id))
+
+#define DMA_ERRATA_IFRAME_BUFFERING	(1 << 0)
+#define DMA_ERRATA_PARALLEL_CHANNELS	(1 << 1)
+#define DMA_ERRATA_i378			(1 << 2)
+#define DMA_ERRATA_i541			(1 << 3)
+#define DMA_ERRATA_i88			(1 << 4)
+#define DMA_ERRATA_3_3			(1 << 5)
+
 enum omap_dma_burst_mode {
 	OMAP_DMA_DATA_BURST_DIS = 0,
 	OMAP_DMA_DATA_BURST_4,
-- 
1.7.1


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

* [PATCH v4 03/13] OMAP: DMA: Introduce DMA device attributes
  2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 01/13] OMAP: DMA: Replace read/write macros with functions G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 02/13] OMAP: DMA: Introduce errata handling feature G, Manjunath Kondaiah
@ 2010-11-08 14:07 ` G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 04/13] OMAP2420: DMA: hwmod: add system DMA G, Manjunath Kondaiah
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Benoit Cousson, Kevin Hilman, Santosh Shilimkar

Introduce OMAP DMA device attributes for using the same in DMA
platform driver for all OMAP's and hwmod database(OMAP2+ onwards)

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/plat-omap/include/plat/dma.h |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
index 5e28d26..9757b22 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -296,6 +296,22 @@
 #define DMA_ERRATA_i88			(1 << 4)
 #define DMA_ERRATA_3_3			(1 << 5)
 
+/* Attributes for OMAP DMA Contrllers */
+#define ENABLE_1510_MODE		(1 << 0x0)
+#define DMA_LINKED_LCH			(1 << 0x1)
+#define GLOBAL_PRIORITY			(1 << 0x2)
+#define RESERVE_CHANNEL			(1 << 0x3)
+#define SRC_PORT			(1 << 0x4)
+#define DST_PORT			(1 << 0x5)
+#define IS_CSSA_32			(1 << 0x6)
+#define IS_CDSA_32			(1 << 0x7)
+#define SRC_INDEX			(1 << 0x8)
+#define DST_INDEX			(1 << 0x9)
+#define IS_BURST_ONLY4			(1 << 0xA)
+#define CLEAR_CSR_ON_READ		(1 << 0xB)
+#define IS_WORD_16			(1 << 0xC)
+#define IS_RW_PRIORITY			(1 << 0xD)
+
 enum omap_dma_burst_mode {
 	OMAP_DMA_DATA_BURST_DIS = 0,
 	OMAP_DMA_DATA_BURST_4,
@@ -361,6 +377,10 @@ struct omap_dma_channel_params {
 #endif
 };
 
+struct omap_dma_dev_attr {
+	u32 dev_caps;
+	u16 lch_count;
+};
 
 extern void omap_set_dma_priority(int lch, int dst_port, int priority);
 extern int omap_request_dma(int dev_id, const char *dev_name,
-- 
1.7.1


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

* [PATCH v4 04/13] OMAP2420: DMA: hwmod: add system DMA
  2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
                   ` (2 preceding siblings ...)
  2010-11-08 14:07 ` [PATCH v4 03/13] OMAP: DMA: Introduce DMA device attributes G, Manjunath Kondaiah
@ 2010-11-08 14:07 ` G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 05/13] OMAP2430: " G, Manjunath Kondaiah
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Benoit Cousson, Kevin Hilman, Santosh Shilimkar

Add OMAP2420 DMA hwmod structures.

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_2420_data.c |   85 ++++++++++++++++++++++++++++
 1 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index a1a3dd6..3a51392 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -38,6 +38,7 @@ static struct omap_hwmod omap2420_iva_hwmod;
 static struct omap_hwmod omap2420_l3_main_hwmod;
 static struct omap_hwmod omap2420_l4_core_hwmod;
 static struct omap_hwmod omap2420_wd_timer2_hwmod;
+static struct omap_hwmod omap2420_dma_system_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = {
@@ -557,6 +558,89 @@ static struct omap_hwmod omap2420_i2c2_hwmod = {
 	.flags		= HWMOD_16BIT_REG,
 };
 
+/* system dma */
+static struct omap_hwmod_class_sysconfig omap2420_dma_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x002c,
+	.syss_offs	= 0x0028,
+	.sysc_flags	= (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+			   SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
+			   SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_dma_hwmod_class = {
+	.name = "dma",
+	.sysc = &omap2420_dma_sysc,
+};
+
+/* dma attributes */
+static struct omap_dma_dev_attr dma_dev_attr = {
+	.dev_caps  = DMA_LINKED_LCH | GLOBAL_PRIORITY |
+				IS_CSSA_32 | IS_CDSA_32,
+	.lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT,
+};
+
+static struct omap_hwmod_irq_info omap2420_dma_system_irqs[] = {
+	{ .name = "0", .irq = INT_24XX_SDMA_IRQ0 },
+	{ .name = "1", .irq = INT_24XX_SDMA_IRQ1 },
+	{ .name = "2", .irq = INT_24XX_SDMA_IRQ2 },
+	{ .name = "3", .irq = INT_24XX_SDMA_IRQ3 },
+};
+
+static struct omap_hwmod_addr_space omap2420_dma_system_addrs[] = {
+	{
+		.pa_start	= 0x48056000,
+		.pa_end		= 0x4a0560ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* dma_system -> L3 */
+static struct omap_hwmod_ocp_if omap2420_dma_system__l3 = {
+	.master		= &omap2420_dma_system_hwmod,
+	.slave		= &omap2420_l3_main_hwmod,
+	.clk		= "l3_div_ck",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system master ports */
+static struct omap_hwmod_ocp_if *omap2420_dma_system_masters[] = {
+	&omap2420_dma_system__l3,
+};
+
+/* l4_cfg -> dma_system */
+static struct omap_hwmod_ocp_if omap2420_l4_core__dma_system = {
+	.master		= &omap2420_l4_core_hwmod,
+	.slave		= &omap2420_dma_system_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap2420_dma_system_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap2420_dma_system_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system slave ports */
+static struct omap_hwmod_ocp_if *omap2420_dma_system_slaves[] = {
+	&omap2420_l4_core__dma_system,
+};
+
+static struct omap_hwmod omap2420_dma_system_hwmod = {
+	.name		= "dma",
+	.class		= &omap2420_dma_hwmod_class,
+	.mpu_irqs	= omap2420_dma_system_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap2420_dma_system_irqs),
+	.main_clk	= "l3_div_ck",
+	.slaves		= omap2420_dma_system_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_dma_system_slaves),
+	.masters	= omap2420_dma_system_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2420_dma_system_masters),
+	.dev_attr	= &dma_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+	.flags		= HWMOD_NO_IDLEST,
+};
+
 static __initdata struct omap_hwmod *omap2420_hwmods[] = {
 	&omap2420_l3_main_hwmod,
 	&omap2420_l4_core_hwmod,
@@ -569,6 +653,7 @@ static __initdata struct omap_hwmod *omap2420_hwmods[] = {
 	&omap2420_uart3_hwmod,
 	&omap2420_i2c1_hwmod,
 	&omap2420_i2c2_hwmod,
+	&omap2420_dma_system_hwmod,
 	NULL,
 };
 
-- 
1.7.1


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

* [PATCH v4 05/13] OMAP2430: DMA: hwmod: add system DMA
  2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
                   ` (3 preceding siblings ...)
  2010-11-08 14:07 ` [PATCH v4 04/13] OMAP2420: DMA: hwmod: add system DMA G, Manjunath Kondaiah
@ 2010-11-08 14:07 ` G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 06/13] OMAP3: " G, Manjunath Kondaiah
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Benoit Cousson, Kevin Hilman, Santosh Shilimkar

Add OMAP2430 DMA hwmod structures.

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |   85 ++++++++++++++++++++++++++++
 1 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 7cf0d3a..d3b7239 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -38,6 +38,7 @@ static struct omap_hwmod omap2430_iva_hwmod;
 static struct omap_hwmod omap2430_l3_main_hwmod;
 static struct omap_hwmod omap2430_l4_core_hwmod;
 static struct omap_hwmod omap2430_wd_timer2_hwmod;
+static struct omap_hwmod omap2430_dma_system_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = {
@@ -569,6 +570,89 @@ static struct omap_hwmod omap2430_i2c2_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
 };
 
+/* dma_system */
+static struct omap_hwmod_class_sysconfig omap2430_dma_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x002c,
+	.syss_offs	= 0x0028,
+	.sysc_flags	= (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+			   SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
+			   SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_dma_hwmod_class = {
+	.name = "dma",
+	.sysc = &omap2430_dma_sysc,
+};
+
+/* dma attributes */
+static struct omap_dma_dev_attr dma_dev_attr = {
+	.dev_caps  = DMA_LINKED_LCH | GLOBAL_PRIORITY |
+				IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
+	.lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT,
+};
+
+static struct omap_hwmod_irq_info omap2430_dma_system_irqs[] = {
+	{ .name = "0", .irq = INT_24XX_SDMA_IRQ0 },
+	{ .name = "1", .irq = INT_24XX_SDMA_IRQ1 },
+	{ .name = "2", .irq = INT_24XX_SDMA_IRQ2 },
+	{ .name = "3", .irq = INT_24XX_SDMA_IRQ3 },
+};
+
+static struct omap_hwmod_addr_space omap2430_dma_system_addrs[] = {
+	{
+		.pa_start	= 0x48056000,
+		.pa_end		= 0x4a0560ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* dma_system -> L3 */
+static struct omap_hwmod_ocp_if omap2430_dma_system__l3 = {
+	.master		= &omap2430_dma_system_hwmod,
+	.slave		= &omap2430_l3_main_hwmod,
+	.clk		= "l3_div_ck",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system master ports */
+static struct omap_hwmod_ocp_if *omap2430_dma_system_masters[] = {
+	&omap2430_dma_system__l3,
+};
+
+/* l4_cfg -> dma_system */
+static struct omap_hwmod_ocp_if omap2430_l4_core__dma_system = {
+	.master		= &omap2430_l4_core_hwmod,
+	.slave		= &omap2430_dma_system_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap2430_dma_system_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap2430_dma_system_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system slave ports */
+static struct omap_hwmod_ocp_if *omap2430_dma_system_slaves[] = {
+	&omap2430_l4_core__dma_system,
+};
+
+static struct omap_hwmod omap2430_dma_system_hwmod = {
+	.name		= "dma",
+	.class		= &omap2430_dma_hwmod_class,
+	.mpu_irqs	= omap2430_dma_system_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap2430_dma_system_irqs),
+	.main_clk	= "l3_div_ck",
+	.slaves		= omap2430_dma_system_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_dma_system_slaves),
+	.masters	= omap2430_dma_system_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2430_dma_system_masters),
+	.dev_attr	= &dma_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+	.flags		= HWMOD_NO_IDLEST,
+};
+
 static __initdata struct omap_hwmod *omap2430_hwmods[] = {
 	&omap2430_l3_main_hwmod,
 	&omap2430_l4_core_hwmod,
@@ -581,6 +665,7 @@ static __initdata struct omap_hwmod *omap2430_hwmods[] = {
 	&omap2430_uart3_hwmod,
 	&omap2430_i2c1_hwmod,
 	&omap2430_i2c2_hwmod,
+	&omap2430_dma_system_hwmod,
 	NULL,
 };
 
-- 
1.7.1


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

* [PATCH v4 06/13] OMAP3: DMA: hwmod: add system DMA
  2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
                   ` (4 preceding siblings ...)
  2010-11-08 14:07 ` [PATCH v4 05/13] OMAP2430: " G, Manjunath Kondaiah
@ 2010-11-08 14:07 ` G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 07/13] OMAP4: " G, Manjunath Kondaiah
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Benoit Cousson, Kevin Hilman, Santosh Shilimkar

Add OMAP3 DMA hwmod structures.

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   94 ++++++++++++++++++++++++++++
 1 files changed, 94 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index ed6bf4a..d0d8030 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -45,6 +45,7 @@ static struct omap_hwmod omap3xxx_wd_timer2_hwmod;
 static struct omap_hwmod omap3xxx_i2c1_hwmod;
 static struct omap_hwmod omap3xxx_i2c2_hwmod;
 static struct omap_hwmod omap3xxx_i2c3_hwmod;
+static struct omap_hwmod omap3xxx_dma_system_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
@@ -736,6 +737,98 @@ static struct omap_hwmod omap3xxx_i2c3_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
 
+/* dma_system -> L3 */
+static struct omap_hwmod_ocp_if omap3xxx_dma_system__l3 = {
+	.master		= &omap3xxx_dma_system_hwmod,
+	.slave		= &omap3xxx_l3_main_hwmod,
+	.clk		= "core_l3_ick",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma attributes */
+static struct omap_dma_dev_attr dma_dev_attr = {
+	.dev_caps  = DMA_LINKED_LCH | GLOBAL_PRIORITY |
+				IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
+	.lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT,
+};
+
+static struct omap_hwmod_class_sysconfig omap3xxx_dma_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x002c,
+	.syss_offs	= 0x0028,
+	.sysc_flags	= (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+			   SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
+			   SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_dma_hwmod_class = {
+	.name = "dma",
+	.sysc = &omap3xxx_dma_sysc,
+};
+
+/* dma_system */
+static struct omap_hwmod_irq_info omap3xxx_dma_system_irqs[] = {
+	{ .name = "0", .irq = INT_24XX_SDMA_IRQ0 },
+	{ .name = "1", .irq = INT_24XX_SDMA_IRQ1 },
+	{ .name = "2", .irq = INT_24XX_SDMA_IRQ2 },
+	{ .name = "3", .irq = INT_24XX_SDMA_IRQ3 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_dma_system_addrs[] = {
+	{
+		.pa_start	= 0x48056000,
+		.pa_end		= 0x4a0560ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* dma_system master ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dma_system_masters[] = {
+	&omap3xxx_dma_system__l3,
+};
+
+/* l4_cfg -> dma_system */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dma_system = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap3xxx_dma_system_hwmod,
+	.clk		= "core_l4_ick",
+	.addr		= omap3xxx_dma_system_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_dma_system_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dma_system_slaves[] = {
+	&omap3xxx_l4_core__dma_system,
+};
+
+static struct omap_hwmod omap3xxx_dma_system_hwmod = {
+	.name		= "dma",
+	.class		= &omap3xxx_dma_hwmod_class,
+	.mpu_irqs	= omap3xxx_dma_system_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_dma_system_irqs),
+	.main_clk	= "core_l3_ick",
+	.prcm = {
+		.omap2 = {
+			.module_offs		= CORE_MOD,
+			.prcm_reg_id		= 1,
+			.module_bit		= OMAP3430_ST_SDMA_SHIFT,
+			.idlest_reg_id		= 1,
+			.idlest_idle_bit	= OMAP3430_ST_SDMA_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_dma_system_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_dma_system_slaves),
+	.masters	= omap3xxx_dma_system_masters,
+	.masters_cnt	= ARRAY_SIZE(omap3xxx_dma_system_masters),
+	.dev_attr	= &dma_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+	.flags		= HWMOD_NO_IDLEST,
+};
+
 static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_l3_main_hwmod,
 	&omap3xxx_l4_core_hwmod,
@@ -751,6 +844,7 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_i2c1_hwmod,
 	&omap3xxx_i2c2_hwmod,
 	&omap3xxx_i2c3_hwmod,
+	&omap3xxx_dma_system_hwmod,
 	NULL,
 };
 
-- 
1.7.1


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

* [PATCH v4 07/13] OMAP4: DMA: hwmod: add system DMA
  2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
                   ` (5 preceding siblings ...)
  2010-11-08 14:07 ` [PATCH v4 06/13] OMAP3: " G, Manjunath Kondaiah
@ 2010-11-08 14:07 ` G, Manjunath Kondaiah
  2010-11-09  5:02     ` Varadarajan, Charulatha
  2010-11-08 14:07 ` [PATCH v4 08/13] OMAP1: DMA: Introduce DMA driver as platform device G, Manjunath Kondaiah
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Benoit Cousson, Kevin Hilman, Santosh Shilimkar

From: Benoit Cousson <b-cousson@ti.com>

Add OMAP4 DMA hwmod structures.

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Signed-off-by: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |   99 ++++++++++++++++++++++++++++
 1 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 0d5c6eb..f749f0d 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -22,6 +22,7 @@
 
 #include <plat/omap_hwmod.h>
 #include <plat/cpu.h>
+#include <plat/dma.h>
 
 #include "omap_hwmod_common_data.h"
 
@@ -35,6 +36,7 @@
 #define OMAP44XX_DMA_REQ_START  1
 
 /* Backward references (IPs with Bus Master capability) */
+static struct omap_hwmod omap44xx_dma_system_hwmod;
 static struct omap_hwmod omap44xx_dmm_hwmod;
 static struct omap_hwmod omap44xx_emif_fw_hwmod;
 static struct omap_hwmod omap44xx_l3_instr_hwmod;
@@ -215,6 +217,14 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_2 = {
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/* dma_system -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_dma_system__l3_main_2 = {
+	.master		= &omap44xx_dma_system_hwmod,
+	.slave		= &omap44xx_l3_main_2_hwmod,
+	.clk		= "l3_div_ck",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 /* l4_cfg -> l3_main_2 */
 static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_2 = {
 	.master		= &omap44xx_l4_cfg_hwmod,
@@ -226,6 +236,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_2 = {
 /* l3_main_2 slave ports */
 static struct omap_hwmod_ocp_if *omap44xx_l3_main_2_slaves[] = {
 	&omap44xx_l3_main_1__l3_main_2,
+	&omap44xx_dma_system__l3_main_2,
 	&omap44xx_l4_cfg__l3_main_2,
 };
 
@@ -1043,6 +1054,92 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
 
+/*
+ * 'dma' class
+ * dma controller for data exchange between memory to memory (i.e. internal or
+ * external memory) and gp peripherals to memory or memory to gp peripherals
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_dma_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x002c,
+	.syss_offs	= 0x0028,
+	.sysc_flags	= (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+			   SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
+			   SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_dma_hwmod_class = {
+	.name = "dma",
+	.sysc = &omap44xx_dma_sysc,
+};
+
+/* dma attributes */
+static struct omap_dma_dev_attr dma_dev_attr = {
+	.dev_caps  = DMA_LINKED_LCH | GLOBAL_PRIORITY |
+				IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
+	.lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT,
+};
+
+/* dma_system */
+static struct omap_hwmod_irq_info omap44xx_dma_system_irqs[] = {
+	{ .name = "0", .irq = 12 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "1", .irq = 13 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "2", .irq = 14 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "3", .irq = 15 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dma_system_addrs[] = {
+	{
+		.pa_start	= 0x4a056000,
+		.pa_end		= 0x4a0560ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* dma_system master ports */
+static struct omap_hwmod_ocp_if *omap44xx_dma_system_masters[] = {
+	&omap44xx_dma_system__l3_main_2,
+};
+
+/* l4_cfg -> dma_system */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__dma_system = {
+	.master		= &omap44xx_l4_cfg_hwmod,
+	.slave		= &omap44xx_dma_system_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap44xx_dma_system_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_dma_system_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dma_system_slaves[] = {
+	&omap44xx_l4_cfg__dma_system,
+};
+
+static struct omap_hwmod omap44xx_dma_system_hwmod = {
+	.name		= "dma_system",
+	.class		= &omap44xx_dma_hwmod_class,
+	.mpu_irqs	= omap44xx_dma_system_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_dma_system_irqs),
+	.main_clk	= "l3_div_ck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM_SDMA_SDMA_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_dma_system_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_dma_system_slaves),
+	.masters	= omap44xx_dma_system_masters,
+	.masters_cnt	= ARRAY_SIZE(omap44xx_dma_system_masters),
+	.dev_attr	= &dma_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.flags		= HWMOD_NO_IDLEST,
+};
+
 static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
 	/* dmm class */
 	&omap44xx_dmm_hwmod,
@@ -1077,6 +1174,8 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
 	&omap44xx_uart2_hwmod,
 	&omap44xx_uart3_hwmod,
 	&omap44xx_uart4_hwmod,
+	/* dma class */
+	&omap44xx_dma_system_hwmod,
 	NULL,
 };
 
-- 
1.7.1


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

* [PATCH v4 08/13] OMAP1: DMA: Introduce DMA driver as platform device
  2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
                   ` (6 preceding siblings ...)
  2010-11-08 14:07 ` [PATCH v4 07/13] OMAP4: " G, Manjunath Kondaiah
@ 2010-11-08 14:07 ` G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 09/13] OMAP2+: DMA: hwmod: Device registration G, Manjunath Kondaiah
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Benoit Cousson, Kevin Hilman, Santosh Shilimkar

Register OMAP1 DMA driver as platform device and add support
for registering through platform device layer using resource
structures.

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap1/dma.c              |  182 ++++++++++++++++++++++++++++++++
 arch/arm/mach-omap1/include/mach/dma.h |   29 +++++
 2 files changed, 211 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-omap1/dma.c
 create mode 100644 arch/arm/mach-omap1/include/mach/dma.h

diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
new file mode 100644
index 0000000..e756069
--- /dev/null
+++ b/arch/arm/mach-omap1/dma.c
@@ -0,0 +1,182 @@
+/*
+ * dma.c - OMAP1/OMAP7xx-specific DMA code
+ *
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
+ * Graphics DMA and LCD DMA graphics tranformations
+ * by Imre Deak <imre.deak@nokia.com>
+ * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
+ * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Converted DMA library into platform driver
+ *                   - G, Manjunath Kondaiah <manjugk@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/device.h>
+
+#include <plat/dma.h>
+#include <plat/tc.h>
+
+#define OMAP1_DMA_BASE			(0xfffed800)
+
+static struct resource res[] __initdata = {
+	[0] = {
+		.start	= OMAP1_DMA_BASE,
+		.end	= OMAP1_DMA_BASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name   = "0",
+		.start  = INT_DMA_CH0_6,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.name   = "1",
+		.start  = INT_DMA_CH1_7,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[3] = {
+		.name   = "2",
+		.start  = INT_DMA_CH2_8,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[4] = {
+		.name   = "3",
+		.start  = INT_DMA_CH3,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[5] = {
+		.name   = "4",
+		.start  = INT_DMA_CH4,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[6] = {
+		.name   = "5",
+		.start  = INT_DMA_CH5,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[7] = {
+		.name   = "6",
+		.start  = INT_DMA_LCD,
+		.flags  = IORESOURCE_IRQ,
+	},
+	/* irq's for omap16xx and omap7xx */
+	[8] = {
+		.name   = "7",
+		.start  = 53 + IH2_BASE,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[9] = {
+		.name   = "8",
+		.start  = 54 + IH2_BASE,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[10] = {
+		.name  = "9",
+		.start = 55 + IH2_BASE,
+		.flags = IORESOURCE_IRQ,
+	},
+	[11] = {
+		.name  = "10",
+		.start = 56 + IH2_BASE,
+		.flags = IORESOURCE_IRQ,
+	},
+	[12] = {
+		.name  = "11",
+		.start = 57 + IH2_BASE,
+		.flags = IORESOURCE_IRQ,
+	},
+	[13] = {
+		.name  = "12",
+		.start = 58 + IH2_BASE,
+		.flags = IORESOURCE_IRQ,
+	},
+	[14] = {
+		.name  = "13",
+		.start = 59 + IH2_BASE,
+		.flags = IORESOURCE_IRQ,
+	},
+	[15] = {
+		.name  = "14",
+		.start = 60 + IH2_BASE,
+		.flags = IORESOURCE_IRQ,
+	},
+	[16] = {
+		.name  = "15",
+		.start = 61 + IH2_BASE,
+		.flags = IORESOURCE_IRQ,
+	},
+	[17] = {
+		.name  = "16",
+		.start = 62 + IH2_BASE,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static int __init omap1_system_dma_init(void)
+{
+	struct omap_system_dma_plat_info	*p;
+	struct platform_device			*pdev;
+	int ret;
+
+	pdev = platform_device_alloc("omap_dma_system", 0);
+	if (!pdev) {
+		pr_err("%s: Unable to device alloc for dma\n",
+			__func__);
+		return -ENOMEM;
+	}
+
+	ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+	if (ret) {
+		pr_err("%s: Unable to add resources for %s%d\n",
+			__func__, pdev->name, pdev->id);
+		goto exit_device_del;
+	}
+
+	p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
+	if (!p) {
+		dev_err(&pdev->dev, "%s: Unable to allocate 'p' for %s\n",
+			__func__, pdev->name);
+		ret = -ENOMEM;
+		goto exit_device_put;
+	}
+
+	ret = platform_device_add_data(pdev, p, sizeof(*p));
+	if (ret) {
+		dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
+			__func__, pdev->name, pdev->id);
+		goto exit_device_put;
+	}
+	ret = platform_device_add(pdev);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
+			__func__, pdev->name, pdev->id);
+		goto exit_device_put;
+	}
+	return ret;
+
+exit_device_put:
+	platform_device_put(pdev);
+exit_device_del:
+	platform_device_del(pdev);
+
+	return ret;
+}
+arch_initcall(omap1_system_dma_init);
diff --git a/arch/arm/mach-omap1/include/mach/dma.h b/arch/arm/mach-omap1/include/mach/dma.h
new file mode 100644
index 0000000..7949e3f
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/dma.h
@@ -0,0 +1,29 @@
+/*
+ *  OMAP DMA controller register offsets.
+ *
+ *  Copyright (C) 2003 Nokia Corporation
+ *  Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ *  Copyright (C) 2010 Texas Instruments
+ *  Converted DMA library into platform driver
+ *       by G, Manjunath Kondaiah <manjugk@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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
+ */
+
+#ifndef __ASM_ARCH_OMAP1_DMA_H
+#define __ASM_ARCH_OMAP1_DMA_H
+
+#endif /* __ASM_ARCH_OMAP1_DMA_H */
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 09/13] OMAP2+: DMA: hwmod: Device registration
  2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
                   ` (7 preceding siblings ...)
  2010-11-08 14:07 ` [PATCH v4 08/13] OMAP1: DMA: Introduce DMA driver as platform device G, Manjunath Kondaiah
@ 2010-11-08 14:07 ` G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 10/13] OMAP: DMA: Convert DMA library into DMA platform Driver G, Manjunath Kondaiah
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Benoit Cousson, Kevin Hilman, Santosh Shilimkar

Prepare omap2+ dma driver to use hwmod infrastructure
so that DMA driver can register as platform device.

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/dma.c              |   86 ++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/include/mach/dma.h |   32 ++++++++++++
 2 files changed, 118 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-omap2/dma.c
 create mode 100644 arch/arm/mach-omap2/include/mach/dma.h

diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
new file mode 100644
index 0000000..30b20cd
--- /dev/null
+++ b/arch/arm/mach-omap2/dma.c
@@ -0,0 +1,86 @@
+/*
+ * dma.c - OMAP2 specific DMA code
+ *
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
+ * Graphics DMA and LCD DMA graphics tranformations
+ * by Imre Deak <imre.deak@nokia.com>
+ * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
+ * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Converted DMA library into platform driver
+ *	- G, Manjunath Kondaiah <manjugk@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/device.h>
+
+#include <plat/irqs.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+#include <plat/dma.h>
+
+static struct omap_device_pm_latency omap2_dma_latency[] = {
+	{
+		.deactivate_func = omap_device_idle_hwmods,
+		.activate_func	 = omap_device_enable_hwmods,
+		.flags		 = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+	},
+};
+
+/* One time initializations */
+static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
+{
+	struct omap_device			*od;
+	struct omap_system_dma_plat_info	*p;
+	char					*name = "omap_system_dma";
+
+	p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
+	if (!p) {
+		pr_err("%s: Unable to allocate pdata for %s:%s\n",
+			__func__, name, oh->name);
+		return -ENOMEM;
+	}
+	od = omap_device_build(name, 0, oh, p, sizeof(*p),
+			omap2_dma_latency, ARRAY_SIZE(omap2_dma_latency), 0);
+
+	if (IS_ERR(od)) {
+		pr_err("%s: Cant build omap_device for %s:%s.\n",
+			__func__, name, oh->name);
+		kfree(p);
+		return IS_ERR(od);
+	}
+	kfree(p);
+
+	return 0;
+}
+
+static int __init omap2_system_dma_init(void)
+{
+	int ret;
+
+	ret = omap_hwmod_for_each_by_class("dma",
+			omap2_system_dma_init_dev, NULL);
+
+	return ret;
+}
+arch_initcall(omap2_system_dma_init);
diff --git a/arch/arm/mach-omap2/include/mach/dma.h b/arch/arm/mach-omap2/include/mach/dma.h
new file mode 100644
index 0000000..d0a7d5b
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/dma.h
@@ -0,0 +1,32 @@
+/*
+ *  OMAP DMA controller register offsets.
+ *
+ *  Copyright (C) 2003 Nokia Corporation
+ *  Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ *  Copyright (C) 2009 Texas Instruments
+ *  Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ *  Copyright (C) 2010 Texas Instruments
+ *  Converted DMA library into platform driver
+ *          - G, Manjunath Kondaiah <manjugk@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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
+ */
+
+#ifndef __ASM_ARCH_OMAP2_DMA_H
+#define __ASM_ARCH_OMAP2_DMA_H
+
+#endif /* __ASM_ARCH_OMAP2_DMA_H */
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 10/13] OMAP: DMA: Convert DMA library into DMA platform Driver
  2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
                   ` (8 preceding siblings ...)
  2010-11-08 14:07 ` [PATCH v4 09/13] OMAP2+: DMA: hwmod: Device registration G, Manjunath Kondaiah
@ 2010-11-08 14:07 ` G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 12/13] OMAP2+: DMA: descriptor autoloading feature G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 13/13] OMAP: PM: DMA: Enable runtime pm G, Manjunath Kondaiah
  11 siblings, 0 replies; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Benoit Cousson, Kevin Hilman, Santosh Shilimkar

Convert DMA library into DMA platform driver and make use
of platform data provided by hwmod data base for OMAP2PLUS onwards.
For OMAP1 processors, the DMA driver in mach-omap uses resource
structures for getting platform data.

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap1/Makefile           |    2 +-
 arch/arm/mach-omap1/dma.c              |  182 ++++++++-
 arch/arm/mach-omap2/Makefile           |    2 +-
 arch/arm/mach-omap2/dma.c              |  211 +++++++++-
 arch/arm/mach-omap2/include/mach/dma.h |    3 +
 arch/arm/plat-omap/dma.c               |  748 +++++++++++++-------------------
 arch/arm/plat-omap/include/plat/dma.h  |   52 ++-
 7 files changed, 739 insertions(+), 461 deletions(-)

diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index 9a304d8..b7dfc54 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o
+obj-y := io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o dma.o
 obj-y += clock.o clock_data.o opp_data.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index e756069..b9d1635 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -35,6 +35,81 @@
 #include <plat/tc.h>
 
 #define OMAP1_DMA_BASE			(0xfffed800)
+#define OMAP1_LOGICAL_DMA_CH_COUNT	17
+
+static u32 errata;
+static u32 enable_1510_mode;
+
+enum {
+	GCR1 = 0,	GSCR,		GRST,		HW_ID,
+	PCH2_ID,	PCH0_ID,	PCH1_ID,	PCHG_ID,
+	PCHD_ID,	CAPS_0_U,	CAPS_0_L,	CAPS_1_U,
+	CAPS_1_L,	CAPS_2,		CAPS_3,		CAPS_4,
+	PCH2_SR,	PCH0_SR,	PCH1_SR,	PCHD_SR,
+
+	CH_COMMON_START,
+
+	/* Common Registers */
+	CSDP1,		CCR1,		CICR1,		CSR1,
+	CEN1,		CFN1,		CSFI1,		CSEI1,
+	CPC,		CSAC1,		CDAC1,		CDEI1,
+	CDFI1,		CLNK_CTRL1,
+
+	/* Channel specific register offsets */
+	CSSA_L,		CSSA_U,		CDSA_L,		CDSA_U,
+	COLOR_L,	COLOR_U,	CCR1_2,		LCH_CTRL,
+
+	CH_COMMON_END,
+};
+
+static u16 reg_map[] = {
+	[GCR1]		= 0x400,
+	[GSCR]		= 0x404,
+	[GRST]		= 0x408,
+	[HW_ID]		= 0x442,
+	[PCH2_ID]	= 0x444,
+	[PCH0_ID]	= 0x446,
+	[PCH1_ID]	= 0x448,
+	[PCHG_ID]	= 0x44a,
+	[PCHD_ID]	= 0x44c,
+	[CAPS_0_U]	= 0x44e,
+	[CAPS_0_L]	= 0x450,
+	[CAPS_1_U]	= 0x452,
+	[CAPS_1_L]	= 0x454,
+	[CAPS_2]	= 0x456,
+	[CAPS_3]	= 0x458,
+	[CAPS_4]	= 0x45a,
+	[PCH2_SR]	= 0x460,
+	[PCH0_SR]	= 0x480,
+	[PCH1_SR]	= 0x482,
+	[PCHD_SR]	= 0x4c0,
+
+	/* Common Registers */
+	[CSDP1]		= 0x00,
+	[CCR1]		= 0x02,
+	[CICR1]		= 0x04,
+	[CSR1]		= 0x06,
+	[CEN1]		= 0x10,
+	[CFN1]		= 0x12,
+	[CSFI1]		= 0x14,
+	[CSEI1]		= 0x16,
+	[CPC]		= 0x18,	/* 15xx only */
+	[CSAC1]		= 0x18,
+	[CDAC1]		= 0x1a,
+	[CDEI1]		= 0x1c,
+	[CDFI1]		= 0x1e,
+	[CLNK_CTRL1]	= 0x28,
+
+	/* Channel specific register offsets */
+	[CSSA_L]	= 0x08,
+	[CSSA_U]	= 0x0a,
+	[CDSA_L]	= 0x0c,
+	[CDSA_U]	= 0x0e,
+	[COLOR_L]	= 0x20,
+	[COLOR_U]	= 0x22,
+	[CCR1_2]	= 0x24,
+	[LCH_CTRL]	= 0x2a,
+};
 
 static struct resource res[] __initdata = {
 	[0] = {
@@ -130,9 +205,64 @@ static struct resource res[] __initdata = {
 	},
 };
 
+static void __iomem *dma_base;
+static inline void dma_write(u16 val, int reg, int lch)
+{
+	if (reg > CH_COMMON_START)
+		__raw_writew(val, dma_base + (reg_map[reg] + 0x40 * lch));
+	else
+		__raw_writew(val, dma_base + reg_map[reg]);
+}
+
+static inline u16 dma_read(int reg, int lch)
+{
+	if (reg > CH_COMMON_START)
+		return __raw_readw(dma_base + (reg_map[reg] + 0x40 * lch));
+	else
+		return __raw_readw(dma_base + reg_map[reg]);
+}
+
+static void omap1_show_dma_caps(void)
+{
+	if (enable_1510_mode) {
+		printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
+	} else {
+		u16 w;
+		printk(KERN_INFO "OMAP DMA hardware version %d\n",
+		       dma_read(HW_ID, 0));
+		printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
+		       (dma_read(CAPS_0_U, 0) << 16) |
+		       dma_read(CAPS_0_L, 0),
+		       (dma_read(CAPS_1_U, 0) << 16) |
+		       dma_read(CAPS_1_L, 0),
+		       dma_read(CAPS_2, 0), dma_read(CAPS_3, 0),
+		       dma_read(CAPS_4, 0));
+
+		/* Disable OMAP 3.0/3.1 compatibility mode. */
+		w = dma_read(GSCR, 0);
+		w |= 1 << 3;
+		dma_write(w, GSCR, 0);
+	}
+	return;
+}
+
+static u32 configure_dma_errata(void)
+{
+
+	/*
+	 * Errata 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
+	 * read before the DMA controller finished disabling the channel.
+	 */
+	if (!cpu_is_omap15xx())
+		SET_DMA_ERRATA(DMA_ERRATA_3_3);
+
+	return errata;
+}
+
 static int __init omap1_system_dma_init(void)
 {
 	struct omap_system_dma_plat_info	*p;
+	struct omap_dma_dev_attr		*d;
 	struct platform_device			*pdev;
 	int ret;
 
@@ -158,20 +288,68 @@ static int __init omap1_system_dma_init(void)
 		goto exit_device_put;
 	}
 
+	d = p->dma_attr;
+	d->chan = kzalloc(sizeof(struct omap_dma_lch) *
+					(d->lch_count), GFP_KERNEL);
+	if (!d->chan) {
+		dev_err(&pdev->dev, "%s: Memory allocation failed"
+					"for d->chan!!!\n", __func__);
+		goto exit_release_p;
+	}
+
+	/* Valid attributes for omap1 plus processors */
+	if (cpu_is_omap15xx())
+		d->dev_caps = ENABLE_1510_MODE;
+	enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
+
+	d->dev_caps		|= SRC_PORT;
+	d->dev_caps		|= DST_PORT;
+	d->dev_caps		|= SRC_INDEX;
+	d->dev_caps		|= DST_INDEX;
+	d->dev_caps		|= IS_BURST_ONLY4;
+	d->dev_caps		|= CLEAR_CSR_ON_READ;
+	d->dev_caps		|= IS_WORD_16;
+
+	d->lch_count		= OMAP1_LOGICAL_DMA_CH_COUNT;
+
+	if (cpu_is_omap15xx())
+		d->chan_count = 9;
+	else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
+		if (!(d->dev_caps & ENABLE_1510_MODE))
+			d->chan_count = 16;
+		else
+			d->chan_count = 9;
+	}
+
+	p->omap_dma_base	= (void __iomem *)res[0].start;
+	dma_base		= p->omap_dma_base;
+
+	p->show_dma_caps	= omap1_show_dma_caps;
+	p->dma_write		= dma_write;
+	p->dma_read		= dma_read;
+	p->disable_irq_lch	= NULL;
+
+	/* Configure errata handling for all omap1+ */
+	p->errata = configure_dma_errata();
+
 	ret = platform_device_add_data(pdev, p, sizeof(*p));
 	if (ret) {
 		dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
 			__func__, pdev->name, pdev->id);
-		goto exit_device_put;
+		goto exit_release_chan;
 	}
 	ret = platform_device_add(pdev);
 	if (ret) {
 		dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
 			__func__, pdev->name, pdev->id);
-		goto exit_device_put;
+		goto exit_release_chan;
 	}
 	return ret;
 
+exit_release_chan:
+	kfree(d->chan);
+exit_release_p:
+	kfree(p);
 exit_device_put:
 	platform_device_put(pdev);
 exit_device_del:
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 60e51bc..f16e38e 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -4,7 +4,7 @@
 
 # Common support
 obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o \
-	 common.o
+	 common.o dma.o
 
 omap-2-3-common				= irq.o sdrc.o prm2xxx_3xxx.o
 hwmod-common				= omap_hwmod.o \
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index 30b20cd..d03c261 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -39,6 +39,79 @@
 #include <plat/omap_device.h>
 #include <plat/dma.h>
 
+static u32 errata;
+static struct omap_dma_dev_attr *d;
+
+enum {
+	REVISION = 0,	GCR2,		IRQSTATUS_L0,	IRQSTATUS_L1,
+	IRQSTATUS_L2,	IRQSTATUS_L3,	IRQENABLE_L0,	IRQENABLE_L1,
+	IRQENABLE_L2,	IRQENABLE_L3,	SYSSTATUS,	OCP_SYSCONFIG,
+	CAPS_0,		CAPS_2,		CAPS_3,		CAPS_4,
+
+	CH_COMMON_START,
+
+	/* Common register offsets */
+	CCR2,		CLNK_CTRL2,	CICR2,		CSR2,
+	CSDP2,		CEN2,		CFN2,		CSEI2,
+	CSFI2,		CDEI2,		CDFI2,		CSAC2,
+	CDAC2,
+
+	/* Channel specific register offsets */
+	CSSA,		CDSA,		CCEN,		CCFN,
+	COLOR,
+
+	/* OMAP4 specific registers */
+	CDP,		CNDP,		CCDN,
+
+	CH_COMMON_END,
+};
+
+static u16 reg_map[] = {
+	[REVISION]		= 0x00,
+	[GCR2]			= 0x78,
+	[IRQSTATUS_L0]		= 0x08,
+	[IRQSTATUS_L1]		= 0x0c,
+	[IRQSTATUS_L2]		= 0x10,
+	[IRQSTATUS_L3]		= 0x14,
+	[IRQENABLE_L0]		= 0x18,
+	[IRQENABLE_L1]		= 0x1c,
+	[IRQENABLE_L2]		= 0x20,
+	[IRQENABLE_L3]		= 0x24,
+	[SYSSTATUS]		= 0x28,
+	[OCP_SYSCONFIG]		= 0x2c,
+	[CAPS_0]		= 0x64,
+	[CAPS_2]		= 0x6c,
+	[CAPS_3]		= 0x70,
+	[CAPS_4]		= 0x74,
+
+	/* Common register offsets */
+	[CCR2]			= 0x80,
+	[CLNK_CTRL2]		= 0x84,
+	[CICR2]			= 0x88,
+	[CSR2]			= 0x8c,
+	[CSDP2]			= 0x90,
+	[CEN2]			= 0x94,
+	[CFN2]			= 0x98,
+	[CSEI2]			= 0xa4,
+	[CSFI2]			= 0xa8,
+	[CDEI2]			= 0xac,
+	[CDFI2]			= 0xb0,
+	[CSAC2]			= 0xb4,
+	[CDAC2]			= 0xb8,
+
+	/* Channel specific register offsets */
+	[CSSA]			= 0x9c,
+	[CDSA]			= 0xa0,
+	[CCEN]			= 0xbc,
+	[CCFN]			= 0xc0,
+	[COLOR]			= 0xc4,
+
+	/* OMAP4 specific registers */
+	[CDP]			= 0xd0,
+	[CNDP]			= 0xd4,
+	[CCDN]			= 0xd8,
+};
+
 static struct omap_device_pm_latency omap2_dma_latency[] = {
 	{
 		.deactivate_func = omap_device_idle_hwmods,
@@ -47,12 +120,118 @@ static struct omap_device_pm_latency omap2_dma_latency[] = {
 	},
 };
 
+static void __iomem *dma_base;
+static inline void dma_write(u32 val, int reg, int lch)
+{
+	if (reg > CH_COMMON_START)
+		__raw_writel(val, dma_base + (reg_map[reg] + 0x60 * lch));
+	else
+		__raw_writel(val, dma_base + reg_map[reg]);
+}
+
+static inline u32 dma_read(int reg, int lch)
+{
+	if (reg > CH_COMMON_START)
+		return __raw_readl(dma_base + (reg_map[reg] + 0x60 * lch));
+	else
+		return __raw_readl(dma_base + reg_map[reg]);
+}
+
+static inline void disable_irq_lch(int lch)
+{
+	u32 val;
+
+	val = dma_read(IRQENABLE_L0, lch);
+	val &= ~(1 << lch);
+	dma_write(val, IRQENABLE_L0, lch);
+}
+
+static void omap2_show_dma_caps(void)
+{
+	u8 revision = dma_read(REVISION, 0) & 0xff;
+	printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
+				revision >> 4, revision & 0xf);
+	return;
+}
+
+static u32 configure_dma_errata(void)
+{
+
+	/*
+	 * Erratas applicable for OMAP2430ES1.0 and all omap2420
+	 *
+	 * I.
+	 * Errata ID: XX Inter Frame DMA buffering issue DMA will wrongly
+	 * buffer elements if packing and bursting is enabled. This might
+	 * result in data gets stalled in FIFO at the end of the block.
+	 * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
+	 * guarantee no data will stay in the DMA FIFO in case inter frame
+	 * buffering occurs
+	 *
+	 * II.
+	 * Errata ID: XX DMA may hang when several channels are used in parallel
+	 * In the following configuration, DMA channel hanging can occur:
+	 * a. Channel i, hardware synchronized, is enabled
+	 * b. Another channel (Channel x), software synchronized, is enabled.
+	 * c. Channel i is disabled before end of transfer
+	 * d. Channel i is reenabled.
+	 * e. Steps 1 to 4 are repeated a certain number of times.
+	 * f. A third channel (Channel y), software synchronized, is enabled.
+	 * Channel x and Channel y may hang immediately after step 'f'.
+	 * Workaround:
+	 * For any channel used - make sure NextLCH_ID is set to the value j.
+	 */
+	if (cpu_is_omap2420() || (cpu_is_omap2430() &&
+				(omap_type() == OMAP2430_REV_ES1_0))) {
+
+		SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING);
+		SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS);
+	}
+
+	/*
+	 * Errata ID: i378: OMAP2plus: sDMA Channel is not disabled
+	 * after a transaction error.
+	 * Workaround: SW should explicitely disable the channel.
+	 */
+	if (cpu_class_is_omap2())
+		SET_DMA_ERRATA(DMA_ERRATA_i378);
+
+	/*
+	 * Errata ID: i541: sDMA FIFO draining does not finish
+	 * If sDMA channel is disabled on the fly, sDMA enters standby even
+	 * through FIFO Drain is still in progress
+	 * Workaround: Put sDMA in NoStandby more before a logical channel is
+	 * disabled, then put it back to SmartStandby right after the channel
+	 * finishes FIFO draining.
+	 */
+	if (cpu_is_omap34xx())
+		SET_DMA_ERRATA(DMA_ERRATA_i541);
+
+	/*
+	 * Errata ID: i88 : Special programming model needed to disable DMA
+	 * before end of block.
+	 * Workaround: software must ensure that the DMA is configured in No
+	 * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01")
+	 */
+	if (omap_type() == OMAP3430_REV_ES1_0)
+		SET_DMA_ERRATA(DMA_ERRATA_i88);
+
+	/*
+	 * Errata 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
+	 * read before the DMA controller finished disabling the channel.
+	 */
+	SET_DMA_ERRATA(DMA_ERRATA_3_3);
+
+	return errata;
+}
+
 /* One time initializations */
 static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
 {
 	struct omap_device			*od;
 	struct omap_system_dma_plat_info	*p;
-	char					*name = "omap_system_dma";
+	struct resource				*mem;
+	char					*name = "omap_dma_system";
 
 	p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
 	if (!p) {
@@ -60,6 +239,16 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
 			__func__, name, oh->name);
 		return -ENOMEM;
 	}
+	p->regs			= reg_map;
+	p->dma_attr		= (struct omap_dma_dev_attr *)oh->dev_attr;
+	p->disable_irq_lch	= disable_irq_lch;
+	p->show_dma_caps	= omap2_show_dma_caps;
+	p->dma_write		= dma_write;
+	p->dma_read		= dma_read;
+
+	/* Configure errata handling for all omap2+'s */
+	p->errata		= configure_dma_errata();
+
 	od = omap_device_build(name, 0, oh, p, sizeof(*p),
 			omap2_dma_latency, ARRAY_SIZE(omap2_dma_latency), 0);
 
@@ -71,6 +260,26 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
 	}
 	kfree(p);
 
+	mem = platform_get_resource(&od->pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(&od->pdev.dev, "%s: no mem resource\n", __func__);
+		return -EINVAL;
+	}
+
+	dma_base = ioremap(mem->start, resource_size(mem));
+	if (!dma_base) {
+		dev_err(&od->pdev.dev, "%s: ioremap fail\n", __func__);
+		return -ENOMEM;
+	}
+
+	d = oh->dev_attr;
+	d->chan = kzalloc(sizeof(struct omap_dma_lch) *
+					(d->lch_count), GFP_KERNEL);
+
+	if (!d->chan) {
+		dev_err(&od->pdev.dev, "%s: kzalloc fail\n", __func__);
+		return -ENOMEM;
+	}
 	return 0;
 }
 
diff --git a/arch/arm/mach-omap2/include/mach/dma.h b/arch/arm/mach-omap2/include/mach/dma.h
index d0a7d5b..d13c5c0 100644
--- a/arch/arm/mach-omap2/include/mach/dma.h
+++ b/arch/arm/mach-omap2/include/mach/dma.h
@@ -29,4 +29,7 @@
 #ifndef __ASM_ARCH_OMAP2_DMA_H
 #define __ASM_ARCH_OMAP2_DMA_H
 
+/* Should be part of hwmod data base ? */
+#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT	32	/* REVISIT: Is this 32 + 2? */
+
 #endif /* __ASM_ARCH_OMAP2_DMA_H */
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 0e1c7b4..562fe66 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -15,6 +15,10 @@
  *
  * Support functions for the OMAP internal DMA channels.
  *
+ * Copyright (C) 2010 Texas Instruments
+ * Converted DMA library into DMA platform driver.
+ *	- G, Manjunath Kondaiah <manjugk@ti.com>
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
@@ -194,6 +198,9 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
 
 #define OMAP_FUNC_MUX_ARM_BASE		(0xfffe1000 + 0xec)
 
+static struct omap_system_dma_plat_info *p;
+static struct omap_dma_dev_attr *d;
+static u16 *reg_map;
 static int enable_1510_mode;
 static u32 errata;
 
@@ -203,27 +210,6 @@ static struct omap_dma_global_context_registers {
 	u32 dma_gcr;
 } omap_dma_global_context;
 
-struct omap_dma_lch {
-	int next_lch;
-	int dev_id;
-	u16 saved_csr;
-	u16 enabled_irqs;
-	const char *dev_name;
-	void (*callback)(int lch, u16 ch_status, void *data);
-	void *data;
-
-#ifndef CONFIG_ARCH_OMAP1
-	/* required for Dynamic chaining */
-	int prev_linked_ch;
-	int next_linked_ch;
-	int state;
-	int chain_id;
-
-	int status;
-#endif
-	long flags;
-};
-
 struct dma_link_info {
 	int *linked_dmach_q;
 	int no_of_lchs_linked;
@@ -280,15 +266,6 @@ static int omap_dma_reserve_channels;
 static spinlock_t dma_chan_lock;
 static struct omap_dma_lch *dma_chan;
 static void __iomem *dma_base;
-
-static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = {
-	INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
-	INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
-	INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
-	INT_1610_DMA_CH11, INT_1610_DMA_CH12, INT_1610_DMA_CH13,
-	INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD
-};
-
 static inline void disable_lnk(int lch);
 static void omap_disable_channel_irq(int lch);
 static inline void omap_enable_channel_irq(int lch);
@@ -296,43 +273,6 @@ static inline void omap_enable_channel_irq(int lch);
 #define REVISIT_24XX()		printk(KERN_ERR "FIXME: no %s on 24xx\n", \
 						__func__);
 
-static inline void dma_write(u32 val, int reg, int lch)
-{
-	if (cpu_class_is_omap1()) {
-		if (reg > OMAP1_CH_COMMON_START)
-			__raw_writew(val, dma_base +
-				(reg_map_omap1[reg] + 0x40 * lch));
-		else
-			__raw_writew(val, dma_base + reg_map_omap1[reg]);
-	} else {
-		if (reg > OMAP2_CH_COMMON_START)
-			__raw_writel(val, dma_base +
-				(reg_map_omap2[reg] + 0x60 * lch));
-		else
-			__raw_writel(val, dma_base + reg_map_omap2[reg]);
-	}
-}
-
-static inline u32 dma_read(int reg, int lch)
-{
-	u32 val;
-
-	if (cpu_class_is_omap1()) {
-		if (reg > OMAP1_CH_COMMON_START)
-			val = __raw_readw(dma_base +
-					(reg_map_omap1[reg] + 0x40 * lch));
-		else
-			val = __raw_readw(dma_base + reg_map_omap1[reg]);
-	} else {
-		if (reg > OMAP2_CH_COMMON_START)
-			val = __raw_readl(dma_base +
-					(reg_map_omap2[reg] + 0x60 * lch));
-		else
-			val = __raw_readl(dma_base + reg_map_omap2[reg]);
-	}
-	return val;
-}
-
 #ifdef CONFIG_ARCH_OMAP15XX
 /* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
 int omap_dma_in_1510_mode(void)
@@ -373,7 +313,7 @@ static void clear_lch_regs(int lch)
 	int i = OMAP1_CH_COMMON_START;
 
 	for (; i <= OMAP1_CH_COMMON_END; i += 1)
-		dma_write(0, i, lch);
+		p->dma_write(0, i, lch);
 }
 
 void omap_set_dma_priority(int lch, int dst_port, int priority)
@@ -408,12 +348,12 @@ void omap_set_dma_priority(int lch, int dst_port, int priority)
 	if (cpu_class_is_omap2()) {
 		u32 ccr;
 
-		ccr = dma_read(CCR2, lch);
+		ccr = p->dma_read(CCR2, lch);
 		if (priority)
 			ccr |= (1 << 6);
 		else
 			ccr &= ~(1 << 6);
-		dma_write(ccr, CCR2, lch);
+		p->dma_write(ccr, CCR2, lch);
 	}
 }
 EXPORT_SYMBOL(omap_set_dma_priority);
@@ -427,33 +367,33 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
 	if (cpu_class_is_omap1()) {
 		u16 ccr;
 
-		l = dma_read(CSDP1, lch);
+		l = p->dma_read(CSDP1, lch);
 		l &= ~0x03;
 		l |= data_type;
-		dma_write(l, CSDP1, lch);
+		p->dma_write(l, CSDP1, lch);
 
-		ccr = dma_read(CCR1, lch);
+		ccr = p->dma_read(CCR1, lch);
 		ccr &= ~(1 << 5);
 		if (sync_mode == OMAP_DMA_SYNC_FRAME)
 			ccr |= 1 << 5;
-		dma_write(ccr, CCR1, lch);
+		p->dma_write(ccr, CCR1, lch);
 
-		ccr = dma_read(CCR1_2, lch);
+		ccr = p->dma_read(CCR1_2, lch);
 		ccr &= ~(1 << 2);
 		if (sync_mode == OMAP_DMA_SYNC_BLOCK)
 			ccr |= 1 << 2;
-		dma_write(ccr, CCR1_2, lch);
+		p->dma_write(ccr, CCR1_2, lch);
 	}
 
 	if (cpu_class_is_omap2() && dma_trigger) {
 		u32 val;
 
-		l = dma_read(CSDP2, lch);
+		l = p->dma_read(CSDP2, lch);
 		l &= ~0x03;
 		l |= data_type;
-		dma_write(l, CSDP2, lch);
+		p->dma_write(l, CSDP2, lch);
 
-		val = dma_read(CCR2, lch);
+		val = p->dma_read(CCR2, lch);
 
 		/* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
 		val &= ~((1 << 23) | (3 << 19) | 0x1f);
@@ -478,14 +418,14 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
 		} else {
 			val &= ~(1 << 24);	/* dest synch */
 		}
-		dma_write(val, CCR2, lch);
+		p->dma_write(val, CCR2, lch);
 	}
 	if (cpu_class_is_omap1()) {
-		dma_write(elem_count, CEN1, lch);
-		dma_write(frame_count, CFN1, lch);
+		p->dma_write(elem_count, CEN1, lch);
+		p->dma_write(frame_count, CFN1, lch);
 	} else {
-		dma_write(elem_count, CEN2, lch);
-		dma_write(frame_count, CFN2, lch);
+		p->dma_write(elem_count, CEN2, lch);
+		p->dma_write(frame_count, CFN2, lch);
 	}
 }
 EXPORT_SYMBOL(omap_set_dma_transfer_params);
@@ -497,7 +437,7 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
 	if (cpu_class_is_omap1()) {
 		u16 w;
 
-		w = dma_read(CCR1_2, lch);
+		w = p->dma_read(CCR1_2, lch);
 		w &= ~0x03;
 
 		switch (mode) {
@@ -512,23 +452,23 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
 		default:
 			BUG();
 		}
-		dma_write(w, CCR1_2, lch);
+		p->dma_write(w, CCR1_2, lch);
 
-		w = dma_read(LCH_CTRL, lch);
+		w = p->dma_read(LCH_CTRL, lch);
 		w &= ~0x0f;
 		/* Default is channel type 2D */
 		if (mode) {
-			dma_write((u16)color, COLOR_L, lch);
-			dma_write((u16)(color >> 16), COLOR_U, lch);
+			p->dma_write((u16)color, COLOR_L, lch);
+			p->dma_write((u16)(color >> 16), COLOR_U, lch);
 			w |= 1;		/* Channel type G */
 		}
-		dma_write(w, LCH_CTRL, lch);
+		p->dma_write(w, LCH_CTRL, lch);
 	}
 
 	if (cpu_class_is_omap2()) {
 		u32 val;
 
-		val = dma_read(CCR2, lch);
+		val = p->dma_read(CCR2, lch);
 		val &= ~((1 << 17) | (1 << 16));
 
 		switch (mode) {
@@ -543,10 +483,10 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
 		default:
 			BUG();
 		}
-		dma_write(val, CCR2, lch);
+		p->dma_write(val, CCR2, lch);
 
 		color &= 0xffffff;
-		dma_write(color, COLOR, lch);
+		p->dma_write(color, COLOR, lch);
 	}
 }
 EXPORT_SYMBOL(omap_set_dma_color_mode);
@@ -556,10 +496,10 @@ void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
 	if (cpu_class_is_omap2()) {
 		u32 csdp;
 
-		csdp = dma_read(CSDP2, lch);
+		csdp = p->dma_read(CSDP2, lch);
 		csdp &= ~(0x3 << 16);
 		csdp |= (mode << 16);
-		dma_write(csdp, CSDP2, lch);
+		p->dma_write(csdp, CSDP2, lch);
 	}
 }
 EXPORT_SYMBOL(omap_set_dma_write_mode);
@@ -569,10 +509,10 @@ void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
 	if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
 		u32 l;
 
-		l = dma_read(LCH_CTRL, lch);
+		l = p->dma_read(LCH_CTRL, lch);
 		l &= ~0x7;
 		l |= mode;
-		dma_write(l, LCH_CTRL, lch);
+		p->dma_write(l, LCH_CTRL, lch);
 	}
 }
 EXPORT_SYMBOL(omap_set_dma_channel_mode);
@@ -587,37 +527,37 @@ void omap_set_dma_src_params(int lch, int src_port, int src_amode,
 	if (cpu_class_is_omap1()) {
 		u16 w;
 
-		w = dma_read(CSDP1, lch);
+		w = p->dma_read(CSDP1, lch);
 		w &= ~(0x1f << 2);
 		w |= src_port << 2;
-		dma_write(w, CSDP1, lch);
+		p->dma_write(w, CSDP1, lch);
 
-		l = dma_read(CCR1, lch);
+		l = p->dma_read(CCR1, lch);
 	} else
-		l = dma_read(CCR2, lch);
+		l = p->dma_read(CCR2, lch);
 
 	l &= ~(0x03 << 12);
 	l |= src_amode << 12;
 
 	if (cpu_class_is_omap1())
-		dma_write(l, CCR1, lch);
+		p->dma_write(l, CCR1, lch);
 	else
-		dma_write(l, CCR2, lch);
+		p->dma_write(l, CCR2, lch);
 
 	if (cpu_class_is_omap1()) {
-		dma_write(src_start >> 16, CSSA_U, lch);
-		dma_write((u16)src_start, CSSA_L, lch);
+		p->dma_write(src_start >> 16, CSSA_U, lch);
+		p->dma_write((u16)src_start, CSSA_L, lch);
 	}
 
 	if (cpu_class_is_omap2())
-		dma_write(src_start, CSSA, lch);
+		p->dma_write(src_start, CSSA, lch);
 
 	if (cpu_class_is_omap1()) {
-		dma_write(src_ei, CSEI1, lch);
-		dma_write(src_fi, CSFI1, lch);
+		p->dma_write(src_ei, CSEI1, lch);
+		p->dma_write(src_fi, CSFI1, lch);
 	} else {
-		dma_write(src_ei, CSEI2, lch);
-		dma_write(src_fi, CSFI2, lch);
+		p->dma_write(src_ei, CSEI2, lch);
+		p->dma_write(src_fi, CSFI2, lch);
 	}
 }
 EXPORT_SYMBOL(omap_set_dma_src_params);
@@ -646,8 +586,8 @@ void omap_set_dma_src_index(int lch, int eidx, int fidx)
 	if (cpu_class_is_omap2())
 		return;
 
-	dma_write(eidx, CSEI1, lch);
-	dma_write(fidx, CSFI1, lch);
+	p->dma_write(eidx, CSEI1, lch);
+	p->dma_write(fidx, CSFI1, lch);
 }
 EXPORT_SYMBOL(omap_set_dma_src_index);
 
@@ -656,18 +596,18 @@ void omap_set_dma_src_data_pack(int lch, int enable)
 	u32 l;
 
 	if (cpu_class_is_omap1())
-		l = dma_read(CSDP1, lch);
+		l = p->dma_read(CSDP1, lch);
 	else
-		l = dma_read(CSDP2, lch);
+		l = p->dma_read(CSDP2, lch);
 
 	l &= ~(1 << 6);
 	if (enable)
 		l |= (1 << 6);
 
 	if (cpu_class_is_omap1())
-		dma_write(l, CSDP1, lch);
+		p->dma_write(l, CSDP1, lch);
 	else
-		dma_write(l, CSDP2, lch);
+		p->dma_write(l, CSDP2, lch);
 }
 EXPORT_SYMBOL(omap_set_dma_src_data_pack);
 
@@ -677,9 +617,9 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 	u32 l;
 
 	if (cpu_class_is_omap2())
-		l = dma_read(CSDP2, lch);
+		l = p->dma_read(CSDP2, lch);
 	else
-		l = dma_read(CSDP1, lch);
+		l = p->dma_read(CSDP1, lch);
 
 	l &= ~(0x03 << 7);
 
@@ -718,9 +658,9 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 	l |= (burst << 7);
 
 	if (cpu_class_is_omap2())
-		dma_write(l, CSDP2, lch);
+		p->dma_write(l, CSDP2, lch);
 	else
-		dma_write(l, CSDP1, lch);
+		p->dma_write(l, CSDP1, lch);
 }
 EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
 
@@ -732,37 +672,37 @@ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
 	u32 l;
 
 	if (cpu_class_is_omap1()) {
-		l = dma_read(CSDP1, lch);
+		l = p->dma_read(CSDP1, lch);
 		l &= ~(0x1f << 9);
 		l |= dest_port << 9;
-		dma_write(l, CSDP1, lch);
+		p->dma_write(l, CSDP1, lch);
 
-		l = dma_read(CCR1, lch);
+		l = p->dma_read(CCR1, lch);
 	} else
-		l = dma_read(CCR2, lch);
+		l = p->dma_read(CCR2, lch);
 
 	l &= ~(0x03 << 14);
 	l |= dest_amode << 14;
 
 	if (cpu_class_is_omap1())
-		dma_write(l, CCR1, lch);
+		p->dma_write(l, CCR1, lch);
 	else
-		dma_write(l, CCR2, lch);
+		p->dma_write(l, CCR2, lch);
 
 	if (cpu_class_is_omap1()) {
-		dma_write(dest_start >> 16, CDSA_U, lch);
-		dma_write(dest_start, CDSA_L, lch);
+		p->dma_write(dest_start >> 16, CDSA_U, lch);
+		p->dma_write(dest_start, CDSA_L, lch);
 	}
 
 	if (cpu_class_is_omap2())
-		dma_write(dest_start, CDSA, lch);
+		p->dma_write(dest_start, CDSA, lch);
 
 	if (cpu_class_is_omap1()) {
-		dma_write(dst_ei, CDEI1, lch);
-		dma_write(dst_fi, CDFI1, lch);
+		p->dma_write(dst_ei, CDEI1, lch);
+		p->dma_write(dst_fi, CDFI1, lch);
 	} else {
-		dma_write(dst_ei, CDEI2, lch);
-		dma_write(dst_fi, CDFI2, lch);
+		p->dma_write(dst_ei, CDEI2, lch);
+		p->dma_write(dst_fi, CDFI2, lch);
 	}
 }
 EXPORT_SYMBOL(omap_set_dma_dest_params);
@@ -772,8 +712,8 @@ void omap_set_dma_dest_index(int lch, int eidx, int fidx)
 	if (cpu_class_is_omap2())
 		return;
 
-	dma_write(eidx, CDEI1, lch);
-	dma_write(fidx, CDFI1, lch);
+	p->dma_write(eidx, CDEI1, lch);
+	p->dma_write(fidx, CDFI1, lch);
 }
 EXPORT_SYMBOL(omap_set_dma_dest_index);
 
@@ -782,18 +722,18 @@ void omap_set_dma_dest_data_pack(int lch, int enable)
 	u32 l;
 
 	if (cpu_class_is_omap2())
-		l = dma_read(CSDP2, lch);
+		l = p->dma_read(CSDP2, lch);
 	else
-		l = dma_read(CSDP1, lch);
+		l = p->dma_read(CSDP1, lch);
 
 	l &= ~(1 << 13);
 	if (enable)
 		l |= 1 << 13;
 
 	if (cpu_class_is_omap2())
-		dma_write(l, CSDP2, lch);
+		p->dma_write(l, CSDP2, lch);
 	else
-		dma_write(l, CSDP1, lch);
+		p->dma_write(l, CSDP1, lch);
 }
 EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
 
@@ -802,9 +742,9 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 	unsigned int burst = 0;
 	u32 l;
 	if (cpu_class_is_omap2())
-		l = dma_read(CSDP2, lch);
+		l = p->dma_read(CSDP2, lch);
 	else
-		l = dma_read(CSDP1, lch);
+		l = p->dma_read(CSDP1, lch);
 
 	l &= ~(0x03 << 14);
 
@@ -841,9 +781,9 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 	l |= (burst << 14);
 
 	if (cpu_class_is_omap2())
-		dma_write(l, CSDP2, lch);
+		p->dma_write(l, CSDP2, lch);
 	else
-		dma_write(l, CSDP1, lch);
+		p->dma_write(l, CSDP1, lch);
 }
 EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
 
@@ -853,20 +793,20 @@ static inline void omap_enable_channel_irq(int lch)
 
 	/* Clear CSR */
 	if (cpu_class_is_omap1()) {
-		status = dma_read(CSR1, lch);
-		dma_write(dma_chan[lch].enabled_irqs, CICR1, lch);
+		status = p->dma_read(CSR1, lch);
+		p->dma_write(dma_chan[lch].enabled_irqs, CICR1, lch);
 	} else if (cpu_class_is_omap2()) {
-		dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, lch);
-		dma_write(dma_chan[lch].enabled_irqs, CICR2, lch);
+		p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, lch);
+		p->dma_write(dma_chan[lch].enabled_irqs, CICR2, lch);
 	}
 }
 
 static void omap_disable_channel_irq(int lch)
 {
 	if (cpu_class_is_omap2())
-		dma_write(0, CICR2, lch);
+		p->dma_write(0, CICR2, lch);
 	else
-		dma_write(0, CICR1, lch);
+		p->dma_write(0, CICR1, lch);
 }
 
 void omap_enable_dma_irq(int lch, u16 bits)
@@ -886,10 +826,10 @@ static inline void enable_lnk(int lch)
 	u32 l;
 
 	if (cpu_class_is_omap1()) {
-		l = dma_read(CLNK_CTRL1, lch);
+		l = p->dma_read(CLNK_CTRL1, lch);
 		l &= ~(1 << 14);
 	} else
-		l = dma_read(CLNK_CTRL2, lch);
+		l = p->dma_read(CLNK_CTRL2, lch);
 
 	/* Set the ENABLE_LNK bits */
 	if (dma_chan[lch].next_lch != -1)
@@ -898,9 +838,9 @@ static inline void enable_lnk(int lch)
 	if (cpu_class_is_omap2()) {
 		if (dma_chan[lch].next_linked_ch != -1)
 			l = dma_chan[lch].next_linked_ch | (1 << 15);
-		dma_write(l, CLNK_CTRL2, lch);
+		p->dma_write(l, CLNK_CTRL2, lch);
 	} else
-		dma_write(l, CLNK_CTRL1, lch);
+		p->dma_write(l, CLNK_CTRL1, lch);
 }
 
 static inline void disable_lnk(int lch)
@@ -909,19 +849,19 @@ static inline void disable_lnk(int lch)
 
 	/* Disable interrupts */
 	if (cpu_class_is_omap1()) {
-		l = dma_read(CLNK_CTRL1, lch);
-		dma_write(0, CICR1, lch);
+		l = p->dma_read(CLNK_CTRL1, lch);
+		p->dma_write(0, CICR1, lch);
 		/* Set the STOP_LNK bit */
 		l |= 1 << 14;
-		dma_write(l, CLNK_CTRL1, lch);
+		p->dma_write(l, CLNK_CTRL1, lch);
 	}
 
 	if (cpu_class_is_omap2()) {
-		l = dma_read(CLNK_CTRL2, lch);
+		l = p->dma_read(CLNK_CTRL2, lch);
 		omap_disable_channel_irq(lch);
 		/* Clear the ENABLE_LNK bit */
 		l &= ~(1 << 15);
-		dma_write(l, CLNK_CTRL2, lch);
+		p->dma_write(l, CLNK_CTRL2, lch);
 	}
 	dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
 }
@@ -935,9 +875,9 @@ static inline void omap2_enable_irq_lch(int lch)
 		return;
 
 	spin_lock_irqsave(&dma_chan_lock, flags);
-	val = dma_read(IRQENABLE_L0, 0);
+	val = p->dma_read(IRQENABLE_L0, 0);
 	val |= 1 << lch;
-	dma_write(val, IRQENABLE_L0, 0);
+	p->dma_write(val, IRQENABLE_L0, 0);
 	spin_unlock_irqrestore(&dma_chan_lock, flags);
 }
 
@@ -950,9 +890,9 @@ static inline void omap2_disable_irq_lch(int lch)
 		return;
 
 	spin_lock_irqsave(&dma_chan_lock, flags);
-	val = dma_read(IRQENABLE_L0, 0);
+	val = p->dma_read(IRQENABLE_L0, 0);
 	val &= ~(1 << lch);
-	dma_write(val, IRQENABLE_L0, 0);
+	p->dma_write(val, IRQENABLE_L0, 0);
 	spin_unlock_irqrestore(&dma_chan_lock, flags);
 }
 
@@ -1017,17 +957,17 @@ int omap_request_dma(int dev_id, const char *dev_name,
 		 * Disable the 1510 compatibility mode and set the sync device
 		 * id.
 		 */
-		dma_write(dev_id | (1 << 10), CCR1, free_ch);
+		p->dma_write(dev_id | (1 << 10), CCR1, free_ch);
 	} else if (cpu_is_omap7xx() || cpu_is_omap15xx()) {
-		dma_write(dev_id, CCR1, free_ch);
+		p->dma_write(dev_id, CCR1, free_ch);
 	}
 
 	if (cpu_class_is_omap2()) {
 		omap2_enable_irq_lch(free_ch);
 		omap_enable_channel_irq(free_ch);
 		/* Clear the CSR register and IRQ status register */
-		dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, free_ch);
-		dma_write(1 << free_ch, IRQSTATUS_L0, 0);
+		p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, free_ch);
+		p->dma_write(1 << free_ch, IRQSTATUS_L0, 0);
 	}
 
 	*dma_ch_out = free_ch;
@@ -1048,23 +988,23 @@ void omap_free_dma(int lch)
 
 	if (cpu_class_is_omap1()) {
 		/* Disable all DMA interrupts for the channel. */
-		dma_write(0, CICR1, lch);
+		p->dma_write(0, CICR1, lch);
 		/* Make sure the DMA transfer is stopped. */
-		dma_write(0, CCR1, lch);
+		p->dma_write(0, CCR1, lch);
 	}
 
 	if (cpu_class_is_omap2()) {
 		omap2_disable_irq_lch(lch);
 
 		/* Clear the CSR register and IRQ status register */
-		dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, lch);
-		dma_write(1 << lch, IRQSTATUS_L0, 0);
+		p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, lch);
+		p->dma_write(1 << lch, IRQSTATUS_L0, 0);
 
 		/* Disable all DMA interrupts for the channel. */
-		dma_write(0, CICR2, lch);
+		p->dma_write(0, CICR2, lch);
 
 		/* Make sure the DMA transfer is stopped. */
-		dma_write(0, CCR2, lch);
+		p->dma_write(0, CCR2, lch);
 		omap_clear_dma(lch);
 	}
 
@@ -1105,7 +1045,7 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
 	reg |= (0x3 & tparams) << 12;
 	reg |= (arb_rate & 0xff) << 16;
 
-	dma_write(reg, GCR2, 0);
+	p->dma_write(reg, GCR2, 0);
 }
 EXPORT_SYMBOL(omap_dma_set_global_params);
 
@@ -1130,15 +1070,15 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio,
 	}
 
 	if (cpu_is_omap2430() || cpu_is_omap34xx() ||  cpu_is_omap44xx()) {
-		l = dma_read(CCR2, lch);
+		l = p->dma_read(CCR2, lch);
 		l &= ~((1 << 6) | (1 << 26));
 		l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
-		dma_write(l, CCR2, lch);
+		p->dma_write(l, CCR2, lch);
 	} else {
-		l = dma_read(CCR1, lch);
+		l = p->dma_read(CCR1, lch);
 		l &= ~((1 << 6) | (1 << 26));
 		l |= ((read_prio & 0x1) << 6);
-		dma_write(l, CCR1, lch);
+		p->dma_write(l, CCR1, lch);
 	}
 
 	return 0;
@@ -1158,19 +1098,19 @@ void omap_clear_dma(int lch)
 	if (cpu_class_is_omap1()) {
 		u32 l;
 
-		l = dma_read(CCR1, lch);
+		l = p->dma_read(CCR1, lch);
 		l &= ~OMAP_DMA_CCR_EN;
-		dma_write(l, CCR1, lch);
+		p->dma_write(l, CCR1, lch);
 
 		/* Clear pending interrupts */
-		l = dma_read(CSR1, lch);
+		l = p->dma_read(CSR1, lch);
 	}
 
 	if (cpu_class_is_omap2()) {
 		int i = OMAP2_CH_COMMON_START;
 
 		for (; i <= OMAP2_CH_COMMON_END; i++)
-			dma_write(0, i, lch);
+			p->dma_write(0, i, lch);
 	}
 
 	local_irq_restore(flags);
@@ -1186,16 +1126,16 @@ void omap_start_dma(int lch)
 	 * before starting dma transfer.
 	 */
 	if (cpu_is_omap15xx())
-		dma_write(0, CPC, lch);
+		p->dma_write(0, CPC, lch);
 	else if (cpu_class_is_omap1())
-		dma_write(0, CDAC1, lch);
+		p->dma_write(0, CDAC1, lch);
 	else
-		dma_write(0, CDAC2, lch);
+		p->dma_write(0, CDAC2, lch);
 
 
 	if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
 		int next_lch, cur_lch;
-		char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
+		char dma_chan_link_map[dma_chan_count];
 
 		dma_chan_link_map[lch] = 1;
 		/* Set the link register of the first channel */
@@ -1218,22 +1158,22 @@ void omap_start_dma(int lch)
 			cur_lch = next_lch;
 		} while (next_lch != -1);
 	} else if (IS_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS))
-		dma_write(lch, CLNK_CTRL2, lch);
+		p->dma_write(lch, CLNK_CTRL2, lch);
 
 	omap_enable_channel_irq(lch);
 
 	if (cpu_class_is_omap1()) {
-		l = dma_read(CCR1, lch);
+		l = p->dma_read(CCR1, lch);
 		l |= OMAP_DMA_CCR_EN;
-		dma_write(l, CCR1, lch);
+		p->dma_write(l, CCR1, lch);
 	} else {
-		l = dma_read(CCR2, lch);
+		l = p->dma_read(CCR2, lch);
 
 		if (IS_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING))
 			l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
 
 		l |= OMAP_DMA_CCR_EN;
-		dma_write(l, CCR2, lch);
+		p->dma_write(l, CCR2, lch);
 	}
 	dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
 }
@@ -1245,7 +1185,7 @@ void omap_stop_dma(int lch)
 
 	/* Disable all interrupts on the channel */
 	if (cpu_class_is_omap1())
-		dma_write(0, CICR1, lch);
+		p->dma_write(0, CICR1, lch);
 
 	if (IS_DMA_ERRATA(DMA_ERRATA_i541) &&
 			(l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
@@ -1253,42 +1193,42 @@ void omap_stop_dma(int lch)
 		u32 sys_cf;
 
 		/* Configure No-Standby */
-		l = dma_read(OCP_SYSCONFIG, 0);
+		l = p->dma_read(OCP_SYSCONFIG, 0);
 		sys_cf = l;
 		l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
 		l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
-		dma_write(l , OCP_SYSCONFIG, 0);
+		p->dma_write(l , OCP_SYSCONFIG, 0);
 
-		l = dma_read(CCR2, lch);
+		l = p->dma_read(CCR2, lch);
 		l &= ~OMAP_DMA_CCR_EN;
-		dma_write(l, CCR2, lch);
+		p->dma_write(l, CCR2, lch);
 
 		/* Wait for sDMA FIFO drain */
-		l = dma_read(CCR2, lch);
+		l = p->dma_read(CCR2, lch);
 		while (i < 100 && (l & (OMAP_DMA_CCR_RD_ACTIVE |
 					OMAP_DMA_CCR_WR_ACTIVE))) {
 			udelay(5);
 			i++;
-			l = dma_read(CCR2, lch);
+			l = p->dma_read(CCR2, lch);
 		}
 		if (i >= 100)
 			printk(KERN_ERR "DMA drain did not complete on "
 					"lch %d\n", lch);
 		/* Restore OCP_SYSCONFIG */
-		dma_write(sys_cf, OCP_SYSCONFIG, 0);
+		p->dma_write(sys_cf, OCP_SYSCONFIG, 0);
 	} else if (cpu_class_is_omap1()) {
-		l = dma_read(CCR1, lch);
+		l = p->dma_read(CCR1, lch);
 		l &= ~OMAP_DMA_CCR_EN;
-		dma_write(l, CCR1, lch);
+		p->dma_write(l, CCR1, lch);
 	} else {
-		l = dma_read(CCR2, lch);
+		l = p->dma_read(CCR2, lch);
 		l &= ~OMAP_DMA_CCR_EN;
-		dma_write(l, CCR2, lch);
+		p->dma_write(l, CCR2, lch);
 	}
 
 	if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
 		int next_lch, cur_lch = lch;
-		char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
+		char dma_chan_link_map[dma_chan_count];
 
 		memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
 		do {
@@ -1349,21 +1289,21 @@ dma_addr_t omap_get_dma_src_pos(int lch)
 	dma_addr_t offset = 0;
 
 	if (cpu_is_omap15xx())
-		offset = dma_read(CPC, lch);
+		offset = p->dma_read(CPC, lch);
 	else if (cpu_class_is_omap1())
-		offset = dma_read(CSAC1, lch);
+		offset = p->dma_read(CSAC1, lch);
 	else
-		offset = dma_read(CSAC2, lch);
+		offset = p->dma_read(CSAC2, lch);
 
 	if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0) {
 		if (cpu_class_is_omap1())
-			offset = dma_read(CSAC1, lch);
+			offset = p->dma_read(CSAC1, lch);
 		else
-			offset = dma_read(CSAC2, lch);
+			offset = p->dma_read(CSAC2, lch);
 	}
 
 	if (cpu_class_is_omap1())
-		offset |= (dma_read(CSSA_U, lch) << 16);
+		offset |= (p->dma_read(CSSA_U, lch) << 16);
 
 	return offset;
 }
@@ -1382,11 +1322,11 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
 	dma_addr_t offset = 0;
 
 	if (cpu_is_omap15xx())
-		offset = dma_read(CPC, lch);
+		offset = p->dma_read(CPC, lch);
 	else if (cpu_class_is_omap1())
-		offset = dma_read(CDAC1, lch);
+		offset = p->dma_read(CDAC1, lch);
 	else
-		offset = dma_read(CDAC2, lch);
+		offset = p->dma_read(CDAC2, lch);
 
 	/*
 	 * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
@@ -1394,13 +1334,13 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
 	 */
 	if (!cpu_is_omap15xx() && offset == 0) {
 		if (cpu_class_is_omap1())
-			offset = dma_read(CDAC1, lch);
+			offset = p->dma_read(CDAC1, lch);
 		else
-			offset = dma_read(CDAC2, lch);
+			offset = p->dma_read(CDAC2, lch);
 	}
 
 	if (cpu_class_is_omap1())
-		offset |= (dma_read(CDSA_U, lch) << 16);
+		offset |= (p->dma_read(CDSA_U, lch) << 16);
 
 	return offset;
 }
@@ -1409,9 +1349,9 @@ EXPORT_SYMBOL(omap_get_dma_dst_pos);
 int omap_get_dma_active_status(int lch)
 {
 	if (cpu_class_is_omap1())
-		return (dma_read(CCR1, lch) & OMAP_DMA_CCR_EN) != 0;
+		return (p->dma_read(CCR1, lch) & OMAP_DMA_CCR_EN) != 0;
 	else
-		return (dma_read(CCR2, lch) & OMAP_DMA_CCR_EN) != 0;
+		return (p->dma_read(CCR2, lch) & OMAP_DMA_CCR_EN) != 0;
 }
 EXPORT_SYMBOL(omap_get_dma_active_status);
 
@@ -1421,10 +1361,10 @@ int omap_dma_running(void)
 
 	for (lch = 0; lch < dma_chan_count; lch++) {
 		if (cpu_class_is_omap1()) {
-			if (dma_read(CCR1, lch) & OMAP_DMA_CCR_EN)
+			if (p->dma_read(CCR1, lch) & OMAP_DMA_CCR_EN)
 				return 1;
 		} else {
-			if (dma_read(CCR2, lch) & OMAP_DMA_CCR_EN)
+			if (p->dma_read(CCR2, lch) & OMAP_DMA_CCR_EN)
 				return 1;
 		}
 	}
@@ -1440,7 +1380,7 @@ void omap_dma_link_lch(int lch_head, int lch_queue)
 {
 	if (omap_dma_in_1510_mode()) {
 		if (lch_head == lch_queue) {
-			dma_write(dma_read(CCR1, lch_head) | (3 << 8),
+			p->dma_write(p->dma_read(CCR1, lch_head) | (3 << 8),
 							CCR1, lch_head);
 			return;
 		}
@@ -1467,7 +1407,7 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)
 {
 	if (omap_dma_in_1510_mode()) {
 		if (lch_head == lch_queue) {
-			dma_write(dma_read(CCR1, lch_head) & ~(3 << 8),
+			p->dma_write(p->dma_read(CCR1, lch_head) & ~(3 << 8),
 								CCR1, lch_head);
 			return;
 		}
@@ -1494,8 +1434,6 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)
 }
 EXPORT_SYMBOL(omap_dma_unlink_lch);
 
-/*----------------------------------------------------------------------------*/
-
 #ifndef CONFIG_ARCH_OMAP1
 /* Create chain of DMA channesls */
 static void create_dma_lch_chain(int lch_head, int lch_queue)
@@ -1520,15 +1458,15 @@ static void create_dma_lch_chain(int lch_head, int lch_queue)
 					lch_queue;
 	}
 
-	l = dma_read(CLNK_CTRL2, lch_head);
+	l = p->dma_read(CLNK_CTRL2, lch_head);
 	l &= ~(0x1f);
 	l |= lch_queue;
-	dma_write(l, CLNK_CTRL2, lch_head);
+	p->dma_write(l, CLNK_CTRL2, lch_head);
 
-	l = dma_read(CLNK_CTRL2, lch_queue);
+	l = p->dma_read(CLNK_CTRL2, lch_queue);
 	l &= ~(0x1f);
 	l |= (dma_chan[lch_queue].next_linked_ch);
-	dma_write(l, CLNK_CTRL2, lch_queue);
+	p->dma_write(l, CLNK_CTRL2, lch_queue);
 }
 
 /**
@@ -1804,13 +1742,13 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
 
 	/* Set the params to the free channel */
 	if (src_start != 0)
-		dma_write(src_start, CSSA, lch);
+		p->dma_write(src_start, CSSA, lch);
 	if (dest_start != 0)
-		dma_write(dest_start, CDSA, lch);
+		p->dma_write(dest_start, CDSA, lch);
 
 	/* Write the buffer size */
-	dma_write(elem_count, CEN2, lch);
-	dma_write(frame_count, CFN2, lch);
+	p->dma_write(elem_count, CEN2, lch);
+	p->dma_write(frame_count, CFN2, lch);
 
 	/*
 	 * If the chain is dynamically linked,
@@ -1843,7 +1781,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
 				enable_lnk(dma_chan[lch].prev_linked_ch);
 				dma_chan[lch].state = DMA_CH_QUEUED;
 				start_dma = 0;
-				if (0 == ((1 << 7) & dma_read(
+				if (0 == ((1 << 7) & p->dma_read(
 					CCR2, dma_chan[lch].prev_linked_ch))) {
 					disable_lnk(dma_chan[lch].
 						    prev_linked_ch);
@@ -1860,7 +1798,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
 			}
 			omap_enable_channel_irq(lch);
 
-			l = dma_read(CCR2, lch);
+			l = p->dma_read(CCR2, lch);
 
 			if ((0 == (l & (1 << 24))))
 				l &= ~(1 << 25);
@@ -1871,12 +1809,12 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
 					l |= (1 << 7);
 					dma_chan[lch].state = DMA_CH_STARTED;
 					pr_debug("starting %d\n", lch);
-					dma_write(l, CCR2, lch);
+					p->dma_write(l, CCR2, lch);
 				} else
 					start_dma = 0;
 			} else {
 				if (0 == (l & (1 << 7)))
-					dma_write(l, CCR2, lch);
+					p->dma_write(l, CCR2, lch);
 			}
 			dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
 		}
@@ -1921,7 +1859,7 @@ int omap_start_dma_chain_transfers(int chain_id)
 		omap_enable_channel_irq(channels[0]);
 	}
 
-	l = dma_read(CCR2, channels[0]);
+	l = p->dma_read(CCR2, channels[0]);
 	l |= (1 << 7);
 	dma_linked_lch[chain_id].chain_state = DMA_CHAIN_STARTED;
 	dma_chan[channels[0]].state = DMA_CH_STARTED;
@@ -1930,7 +1868,7 @@ int omap_start_dma_chain_transfers(int chain_id)
 		l &= ~(1 << 25);
 	else
 		l |= (1 << 25);
-	dma_write(l, CCR2, channels[0]);
+	p->dma_write(l, CCR2, channels[0]);
 
 	dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE;
 
@@ -1966,19 +1904,19 @@ int omap_stop_dma_chain_transfers(int chain_id)
 	channels = dma_linked_lch[chain_id].linked_dmach_q;
 
 	if (IS_DMA_ERRATA(DMA_ERRATA_i88)) {
-		sys_cf = dma_read(OCP_SYSCONFIG, 0);
+		sys_cf = p->dma_read(OCP_SYSCONFIG, 0);
 		l = sys_cf;
 		/* Middle mode reg set no Standby */
 		l &= ~((1 << 12)|(1 << 13));
-		dma_write(l, OCP_SYSCONFIG, 0);
+		p->dma_write(l, OCP_SYSCONFIG, 0);
 	}
 
 	for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
 
 		/* Stop the Channel transmission */
-		l = dma_read(CCR2, channels[i]);
+		l = p->dma_read(CCR2, channels[i]);
 		l &= ~(1 << 7);
-		dma_write(l, CCR2, channels[i]);
+		p->dma_write(l, CCR2, channels[i]);
 
 		/* Disable the link in all the channels */
 		disable_lnk(channels[i]);
@@ -1991,7 +1929,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
 	OMAP_DMA_CHAIN_QINIT(chain_id);
 
 	if (IS_DMA_ERRATA(DMA_ERRATA_i88))
-		dma_write(sys_cf, OCP_SYSCONFIG, 0);
+		p->dma_write(sys_cf, OCP_SYSCONFIG, 0);
 
 	return 0;
 }
@@ -2033,8 +1971,8 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi)
 	/* Get the current channel */
 	lch = channels[dma_linked_lch[chain_id].q_head];
 
-	*ei = dma_read(CCEN, lch);
-	*fi = dma_read(CCFN, lch);
+	*ei = p->dma_read(CCEN, lch);
+	*fi = p->dma_read(CCFN, lch);
 
 	return 0;
 }
@@ -2071,7 +2009,7 @@ int omap_get_dma_chain_dst_pos(int chain_id)
 	/* Get the current channel */
 	lch = channels[dma_linked_lch[chain_id].q_head];
 
-	return dma_read(CDAC2, lch);
+	return p->dma_read(CDAC2, lch);
 }
 EXPORT_SYMBOL(omap_get_dma_chain_dst_pos);
 
@@ -2105,7 +2043,7 @@ int omap_get_dma_chain_src_pos(int chain_id)
 	/* Get the current channel */
 	lch = channels[dma_linked_lch[chain_id].q_head];
 
-	return dma_read(CSAC2, lch);
+	return p->dma_read(CSAC2, lch);
 }
 EXPORT_SYMBOL(omap_get_dma_chain_src_pos);
 #endif	/* ifndef CONFIG_ARCH_OMAP1 */
@@ -2122,7 +2060,7 @@ static int omap1_dma_handle_ch(int ch)
 		csr = dma_chan[ch].saved_csr;
 		dma_chan[ch].saved_csr = 0;
 	} else
-		csr = dma_read(CSR1, ch);
+		csr = p->dma_read(CSR1, ch);
 	if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
 		dma_chan[ch + 6].saved_csr = csr >> 7;
 		csr &= 0x7f;
@@ -2175,13 +2113,13 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
 
 static int omap2_dma_handle_ch(int ch)
 {
-	u32 status = dma_read(CSR2, ch);
+	u32 status = p->dma_read(CSR2, ch);
 
 	if (!status) {
 		if (printk_ratelimit())
 			printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n",
 				ch);
-		dma_write(1 << ch, IRQSTATUS_L0, 0);
+		p->dma_write(1 << ch, IRQSTATUS_L0, 0);
 		return 0;
 	}
 	if (unlikely(dma_chan[ch].dev_id == -1)) {
@@ -2200,9 +2138,9 @@ static int omap2_dma_handle_ch(int ch)
 		if (IS_DMA_ERRATA(DMA_ERRATA_i378)) {
 			u32 ccr;
 
-			ccr = dma_read(CCR2, ch);
+			ccr = p->dma_read(CCR2, ch);
 			ccr &= ~OMAP_DMA_CCR_EN;
-			dma_write(ccr, CCR2, ch);
+			p->dma_write(ccr, CCR2, ch);
 			dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
 		}
 	}
@@ -2213,16 +2151,16 @@ static int omap2_dma_handle_ch(int ch)
 		printk(KERN_INFO "DMA misaligned error with device %d\n",
 		       dma_chan[ch].dev_id);
 
-	dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, ch);
-	dma_write(1 << ch, IRQSTATUS_L0, ch);
+	p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, ch);
+	p->dma_write(1 << ch, IRQSTATUS_L0, ch);
 	/* read back the register to flush the write */
-	dma_read(IRQSTATUS_L0, ch);
+	p->dma_read(IRQSTATUS_L0, ch);
 
 	/* If the ch is not chained then chain_id will be -1 */
 	if (dma_chan[ch].chain_id != -1) {
 		int chain_id = dma_chan[ch].chain_id;
 		dma_chan[ch].state = DMA_CH_NOTSTARTED;
-		if (dma_read(CLNK_CTRL2, ch) & (1 << 15))
+		if (p->dma_read(CLNK_CTRL2, ch) & (1 << 15))
 			dma_chan[dma_chan[ch].next_linked_ch].state =
 							DMA_CH_STARTED;
 		if (dma_linked_lch[chain_id].chain_mode ==
@@ -2232,10 +2170,10 @@ static int omap2_dma_handle_ch(int ch)
 		if (!OMAP_DMA_CHAIN_QEMPTY(chain_id))
 			OMAP_DMA_CHAIN_INCQHEAD(chain_id);
 
-		status = dma_read(CSR2, ch);
+		status = p->dma_read(CSR2, ch);
 	}
 
-	dma_write(status, CSR2, ch);
+	p->dma_write(status, CSR2, ch);
 
 	if (likely(dma_chan[ch].callback != NULL))
 		dma_chan[ch].callback(ch, status, dma_chan[ch].data);
@@ -2249,13 +2187,13 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
 	u32 val, enable_reg;
 	int i;
 
-	val = dma_read(IRQSTATUS_L0, 0);
+	val = p->dma_read(IRQSTATUS_L0, 0);
 	if (val == 0) {
 		if (printk_ratelimit())
 			printk(KERN_WARNING "Spurious DMA IRQ\n");
 		return IRQ_HANDLED;
 	}
-	enable_reg = dma_read(IRQENABLE_L0, 0);
+	enable_reg = p->dma_read(IRQENABLE_L0, 0);
 	val &= enable_reg; /* Dispatch only relevant interrupts */
 	for (i = 0; i < dma_lch_count && val != 0; i++) {
 		if (val & 1)
@@ -2281,20 +2219,20 @@ static struct irqaction omap24xx_dma_irq;
 void omap_dma_global_context_save(void)
 {
 	omap_dma_global_context.dma_irqenable_l0 =
-		dma_read(IRQENABLE_L0, 0);
+		p->dma_read(IRQENABLE_L0, 0);
 	omap_dma_global_context.dma_ocp_sysconfig =
-		dma_read(OCP_SYSCONFIG, 0);
-	omap_dma_global_context.dma_gcr = dma_read(GCR2, 0);
+		p->dma_read(OCP_SYSCONFIG, 0);
+	omap_dma_global_context.dma_gcr = p->dma_read(GCR2, 0);
 }
 
 void omap_dma_global_context_restore(void)
 {
 	int ch;
 
-	dma_write(omap_dma_global_context.dma_gcr, GCR2, 0);
-	dma_write(omap_dma_global_context.dma_ocp_sysconfig,
+	p->dma_write(omap_dma_global_context.dma_gcr, GCR2, 0);
+	p->dma_write(omap_dma_global_context.dma_ocp_sysconfig,
 		OCP_SYSCONFIG, 0);
-	dma_write(omap_dma_global_context.dma_irqenable_l0,
+	p->dma_write(omap_dma_global_context.dma_irqenable_l0,
 		IRQENABLE_L0, 0);
 
 	/*
@@ -2304,166 +2242,66 @@ void omap_dma_global_context_restore(void)
 	 * affects only secure devices.
 	 */
 	if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
-		dma_write(0x3 , IRQSTATUS_L0, 0);
+		p->dma_write(0x3 , IRQSTATUS_L0, 0);
 
 	for (ch = 0; ch < dma_chan_count; ch++)
 		if (dma_chan[ch].dev_id != -1)
 			omap_clear_dma(ch);
 }
 
-static void configure_dma_errata(void)
+static int __devinit omap_system_dma_probe(struct platform_device *pdev)
 {
-
-	/*
-	 * Erratas applicable for OMAP2430ES1.0 and all omap2420
-	 *
-	 * I.
-	 * Errata ID: XX Inter Frame DMA buffering issue DMA will wrongly
-	 * buffer elements if packing and bursting is enabled. This might
-	 * result in data gets stalled in FIFO at the end of the block.
-	 * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
-	 * guarantee no data will stay in the DMA FIFO in case inter frame
-	 * buffering occurs
-	 *
-	 * II.
-	 * Errata ID: XX DMA may hang when several channels are used in parallel
-	 * In the following configuration, DMA channel hanging can occur:
-	 * a. Channel i, hardware synchronized, is enabled
-	 * b. Another channel (Channel x), software synchronized, is enabled.
-	 * c. Channel i is disabled before end of transfer
-	 * d. Channel i is reenabled.
-	 * e. Steps 1 to 4 are repeated a certain number of times.
-	 * f. A third channel (Channel y), software synchronized, is enabled.
-	 * Channel x and Channel y may hang immediately after step 'f'.
-	 * Workaround:
-	 * For any channel used - make sure NextLCH_ID is set to the value j.
-	 */
-	if (cpu_is_omap2420() || (cpu_is_omap2430() &&
-				(omap_type() == OMAP2430_REV_ES1_0))) {
-
-		SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING);
-		SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS);
+	struct omap_system_dma_plat_info *pdata = pdev->dev.platform_data;
+	struct resource *mem;
+	int ch, ret = 0;
+	int dma_irq;
+	char irq_name[4];
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "%s: System DMA initialized without"
+			"platform data\n", __func__);
+		return -EINVAL;
 	}
 
-	/*
-	 * Errata ID: i378: OMAP2plus: sDMA Channel is not disabled
-	 * after a transaction error.
-	 * Workaround: SW should explicitely disable the channel.
-	 */
-	if (cpu_class_is_omap2())
-		SET_DMA_ERRATA(DMA_ERRATA_i378);
-
-	/*
-	 * Errata ID: i541: sDMA FIFO draining does not finish
-	 * If sDMA channel is disabled on the fly, sDMA enters standby even
-	 * through FIFO Drain is still in progress
-	 * Workaround: Put sDMA in NoStandby more before a logical channel is
-	 * disabled, then put it back to SmartStandby right after the channel
-	 * finishes FIFO draining.
-	 */
-	if (cpu_is_omap34xx())
-		SET_DMA_ERRATA(DMA_ERRATA_i541);
+	p	= pdata;
+	d	= p->dma_attr;
+	reg_map = pdata->regs;
+	errata	= p->errata;
 
-	/*
-	 * Errata ID: i88 : Special programming model needed to disable DMA
-	 * before end of block.
-	 * Workaround: software must ensure that the DMA is configured in No
-	 * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01")
-	 */
-	if (omap_type() == OMAP3430_REV_ES1_0)
-		SET_DMA_ERRATA(DMA_ERRATA_i88);
-
-	/*
-	 * Errata 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
-	 * read before the DMA controller finished disabling the channel.
-	 */
-	if (!cpu_is_omap15xx())
-		SET_DMA_ERRATA(DMA_ERRATA_3_3);
-}
-
-/*----------------------------------------------------------------------------*/
-
-static int __init omap_init_dma(void)
-{
-	unsigned long base;
-	int ch, r;
-
-	if (cpu_class_is_omap1()) {
-		base = OMAP1_DMA_BASE;
-		dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
-	} else if (cpu_is_omap24xx()) {
-		base = OMAP24XX_DMA4_BASE;
-		dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
-	} else if (cpu_is_omap34xx()) {
-		base = OMAP34XX_DMA4_BASE;
-		dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
-	} else if (cpu_is_omap44xx()) {
-		base = OMAP44XX_DMA4_BASE;
-		dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
-	} else {
-		pr_err("DMA init failed for unsupported omap\n");
-		return -ENODEV;
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
+		return -EINVAL;
 	}
 
-	dma_base = ioremap(base, SZ_4K);
-	BUG_ON(!dma_base);
+	dma_base = ioremap(mem->start, resource_size(mem));
+	if (!dma_base) {
+		dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
+		ret = -ENOMEM;
+		goto exit_release_region;
+	}
 
 	if (cpu_class_is_omap2() && omap_dma_reserve_channels
 			&& (omap_dma_reserve_channels <= dma_lch_count))
-		dma_lch_count = omap_dma_reserve_channels;
+		d->lch_count = omap_dma_reserve_channels;
 
-	dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count,
-				GFP_KERNEL);
-	if (!dma_chan) {
-		r = -ENOMEM;
-		goto out_unmap;
-	}
+	dma_lch_count		= d->lch_count;
+	dma_chan_count		= dma_lch_count;
+	dma_chan		= d->chan;
 
 	if (cpu_class_is_omap2()) {
 		dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
 						dma_lch_count, GFP_KERNEL);
 		if (!dma_linked_lch) {
-			r = -ENOMEM;
-			goto out_free;
+			ret = -ENOMEM;
+			goto exit_dma_chan;
 		}
 	}
+	enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
 
-	if (cpu_is_omap15xx()) {
-		printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
-		dma_chan_count = 9;
-		enable_1510_mode = 1;
-	} else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
-		printk(KERN_INFO "OMAP DMA hardware version %d\n",
-		       dma_read(HW_ID, 0));
-		printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
-		       (dma_read(CAPS1_0_U, 0) << 16) |
-		       dma_read(CAPS1_0_L, 0),
-		       (dma_read(CAPS1_1_U, 0) << 16) |
-		       dma_read(CAPS1_1_L, 0),
-		       dma_read(CAPS1_2, 0), dma_read(CAPS1_3, 0),
-		       dma_read(CAPS1_4, 0));
-		if (!enable_1510_mode) {
-			u16 w;
-
-			/* Disable OMAP 3.0/3.1 compatibility mode. */
-			w = dma_read(GSCR, 0);
-			w |= 1 << 3;
-			dma_write(w, GSCR, 0);
-			dma_chan_count = 16;
-		} else
-			dma_chan_count = 9;
-	} else if (cpu_class_is_omap2()) {
-		u8 revision = dma_read(REVISION, 0) & 0xff;
-		printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
-		       revision >> 4, revision & 0xf);
-		dma_chan_count = dma_lch_count;
-	} else {
-		dma_chan_count = 0;
-		return 0;
-	}
+	p->show_dma_caps();
 
 	spin_lock_init(&dma_chan_lock);
-
 	for (ch = 0; ch < dma_chan_count; ch++) {
 		omap_clear_dma(ch);
 		if (cpu_class_is_omap2())
@@ -2480,19 +2318,30 @@ static int __init omap_init_dma(void)
 			 * request_irq() doesn't like dev_id (ie. ch) being
 			 * zero, so we have to kludge around this.
 			 */
-			r = request_irq(omap1_dma_irq[ch],
+			sprintf(&irq_name[0], "%d", ch);
+			dma_irq = platform_get_irq_byname(pdev, irq_name);
+
+			if (dma_irq < 0) {
+				dev_err(&pdev->dev, "%s:unable to get irq\n",
+								__func__);
+				ret = dma_irq;
+				goto exit_unmap;
+			}
+			ret = request_irq(dma_irq,
 					omap1_dma_irq_handler, 0, "DMA",
 					(void *) (ch + 1));
-			if (r != 0) {
-				int i;
-
-				printk(KERN_ERR "unable to request IRQ %d "
-				       "for DMA (error %d)\n",
-				       omap1_dma_irq[ch], r);
-				for (i = 0; i < ch; i++)
-					free_irq(omap1_dma_irq[i],
-						 (void *) (i + 1));
-				goto out_free;
+			if (ret != 0) {
+				int irq_rel;
+				dev_err(&pdev->dev, "unable to request IRQ %d"
+					"for DMA (error %d)\n", dma_irq, ret);
+				for (irq_rel = 0; irq_rel < ch;
+								irq_rel++) {
+					dma_irq = platform_get_irq(pdev,
+								irq_rel);
+					free_irq(dma_irq, (void *)
+							(irq_rel + 1));
+					goto exit_dma_chan;
+				}
 			}
 		}
 	}
@@ -2502,49 +2351,62 @@ static int __init omap_init_dma(void)
 				DMA_DEFAULT_FIFO_DEPTH, 0);
 
 	if (cpu_class_is_omap2()) {
-		int irq;
-		if (cpu_is_omap44xx())
-			irq = OMAP44XX_IRQ_SDMA_0;
-		else
-			irq = INT_24XX_SDMA_IRQ0;
-		setup_irq(irq, &omap24xx_dma_irq);
-	}
-
-	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
-		/* Enable smartidle idlemodes and autoidle */
-		u32 v = dma_read(OCP_SYSCONFIG, 0);
-		v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK |
-				DMA_SYSCONFIG_SIDLEMODE_MASK |
-				DMA_SYSCONFIG_AUTOIDLE);
-		v |= (DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
-			DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
-			DMA_SYSCONFIG_AUTOIDLE);
-		dma_write(v , OCP_SYSCONFIG, 0);
-		/* reserve dma channels 0 and 1 in high security devices */
-		if (cpu_is_omap34xx() &&
-			(omap_type() != OMAP2_DEVICE_TYPE_GP)) {
-			printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
-					"HS ROM code\n");
-			dma_chan[0].dev_id = 0;
-			dma_chan[1].dev_id = 1;
-		}
+		strcpy(irq_name, "0");
+		dma_irq = platform_get_irq_byname(pdev, irq_name);
+		setup_irq(dma_irq, &omap24xx_dma_irq);
 	}
 
-	/* Configure errata handling for all omap's */
-	configure_dma_errata();
-
+	/* reserve dma channels 0 and 1 in high security devices */
+	if (cpu_is_omap34xx() &&
+		(omap_type() != OMAP2_DEVICE_TYPE_GP)) {
+		printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
+				"HS ROM code\n");
+		dma_chan[0].dev_id = 0;
+		dma_chan[1].dev_id = 1;
+	}
 	return 0;
 
-out_free:
+exit_dma_chan:
 	kfree(dma_chan);
+exit_unmap:
+	iounmap(dma_base);
+exit_release_region:
+	release_mem_region(mem->start, resource_size(mem));
+	return ret;
+}
 
-out_unmap:
+static int __devexit omap_system_dma_remove(struct platform_device *pdev)
+{
+	struct resource *mem;
 	iounmap(dma_base);
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(mem->start, resource_size(mem));
+	return 0;
+}
+
+static struct platform_driver omap_system_dma_driver = {
+	.probe		= omap_system_dma_probe,
+	.remove		= omap_system_dma_remove,
+	.driver		= {
+		.name	= "omap_dma_system"
+	},
+};
 
-	return r;
+static int __init omap_system_dma_init(void)
+{
+	return platform_driver_register(&omap_system_dma_driver);
+}
+arch_initcall(omap_system_dma_init);
+
+static void __exit omap_system_dma_exit(void)
+{
+	platform_driver_unregister(&omap_system_dma_driver);
 }
 
-arch_initcall(omap_init_dma);
+MODULE_DESCRIPTION("OMAP SYSTEM DMA DRIVER");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");
 
 /*
  * Reserve the omap SDMA channels using cmdline bootarg
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
index 9757b22..8133c75 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -21,21 +21,15 @@
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H
 
-/* Move omap4 specific defines to dma-44xx.h */
-#include "dma-44xx.h"
-
-/* Hardware registers for omap1 */
-#define OMAP1_DMA_BASE			(0xfffed800)
-
-/* Hardware registers for omap2 and omap3 */
-#define OMAP24XX_DMA4_BASE		(L4_24XX_BASE + 0x56000)
-#define OMAP34XX_DMA4_BASE		(L4_34XX_BASE + 0x56000)
-#define OMAP44XX_DMA4_BASE		(L4_44XX_BASE + 0x56000)
+#include <linux/platform_device.h>
 
-#define OMAP1_LOGICAL_DMA_CH_COUNT	17
-#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT	32	/* REVISIT: Is this 32 + 2? */
+/*
+ * TODO: These dma channel defines should go away once all
+ * the omap drivers hwmod adapted.
+ */
 
-/*----------------------------------------------------------------------------*/
+/* Move omap4 specific defines to dma-44xx.h */
+#include "dma-44xx.h"
 
 /* DMA channels for omap1 */
 #define OMAP_DMA_NO_DEVICE		0
@@ -377,9 +371,41 @@ struct omap_dma_channel_params {
 #endif
 };
 
+#include <mach/dma.h>
+struct omap_dma_lch {
+	int next_lch;
+	int dev_id;
+	u16 saved_csr;
+	u16 enabled_irqs;
+	const char *dev_name;
+	void (*callback)(int lch, u16 ch_status, void *data);
+	void *data;
+	long flags;
+	/* required for Dynamic chaining */
+	int prev_linked_ch;
+	int next_linked_ch;
+	int state;
+	int chain_id;
+	int status;
+};
+
 struct omap_dma_dev_attr {
 	u32 dev_caps;
 	u16 lch_count;
+	u16 chan_count;
+	struct omap_dma_lch *chan;
+};
+
+/* System DMA platform data structure */
+struct omap_system_dma_plat_info {
+	struct omap_dma_dev_attr *dma_attr;
+	void __iomem *omap_dma_base;
+	u32 errata;
+	u16 *regs;
+	void (*disable_irq_lch)(int lch);
+	void (*show_dma_caps)(void);
+	void (*dma_write)(u32 val, int reg, int lch);
+	u32 (*dma_read)(int reg, int lch);
 };
 
 extern void omap_set_dma_priority(int lch, int dst_port, int priority);
-- 
1.7.1


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

* [PATCH v4 12/13] OMAP2+: DMA: descriptor autoloading feature
  2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
                   ` (9 preceding siblings ...)
  2010-11-08 14:07 ` [PATCH v4 10/13] OMAP: DMA: Convert DMA library into DMA platform Driver G, Manjunath Kondaiah
@ 2010-11-08 14:07 ` G, Manjunath Kondaiah
  2010-11-08 14:07 ` [PATCH v4 13/13] OMAP: PM: DMA: Enable runtime pm G, Manjunath Kondaiah
  11 siblings, 0 replies; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Venkatraman S, Benoit Cousson, Kevin Hilman,
	Santosh Shilimkar

From: Venkatraman S <svenkatr@ti.com>

Add sDMA driver support for descriptor autoloading feature.
Descriptor autoloading is OMAP sDMA v5 hardware capability that can be
exploited for scatter gather scenarios, currently available in OMAP3630
and OMAP4430.

The feature works as described below.
1. A sDMA channel is programmed to be in 'linked list' mode.
2) The client (sDMA user) provides a list of descriptors in a linked
list format
3) Each of the 'descriptor' (element in the linked list) contains an
updated set of DMA configuration register values.
4) Client starts DMA transfer.
5) sDMA controller loads the first element to its register configuration
memory and executes the transfer.
6) After completion, loads the next element (in linked list) to
configuration memory and executes the transfer, without MCU
intervention.
7) Interrupt is generated after all transfers are completed; this can be
configured to be done differently.

Configurations and additional features
1) Fast mode & non-fast mode
Fast mode/non-fast decides on how the first transfer begins. In non-fast
mode, the first element in the linked list is loaded only after
completing the
transfer according to the configurations already in the sDMA channel
registers.
In fast mode, the loading of the first element precedes the transfer.

2) Pause / resume of transfers
A transfer can be paused after a descriptor set has been loaded,
provided the pause bit' is set in the linked list element.
An ongoing transfer cannot be paused. If the 'pause bit' is set,
transfer is not started after loading the register set from memory.
Such a transfer can be resumed later.

3) Descriptor types
Three possible configurations of descriptors (initialized as linked list
elements) are possible.
Type 1 provides the maximum flexibility, which contains most register
definitions of a DMA logical channel.
Fewer options are present in type 2.
Type 3 can just modify source/destinations address of transfers. In all
transfers, unmodified registers settings are maintained for the next
transfer.

Patch provides options / API for
1) Setting up a descriptor loading for DMA channel for sg type transfers
2) configuration with linked list elements
3) Starting / pause and resume of the said transfers, query state
4) Clearing the sglist mode

Signed-off-by: Venkatraman S <svenkatr@ti.com>
Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/dma.c              |  257 ++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/include/mach/dma.h |   87 +++++++++++
 arch/arm/plat-omap/dma.c               |    1 +
 arch/arm/plat-omap/include/plat/dma.h  |  108 +++++++++++++
 4 files changed, 453 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index 89a4b11..1a9011f 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -41,6 +41,7 @@
 
 static u32 errata;
 static int dma_chan_count;
+static int dma_caps0_status;
 
 static struct omap_dma_dev_attr *d;
 static struct dma_link_info *dma_linked_lch;
@@ -240,6 +241,76 @@ static inline void omap2_disable_lnk(int lch)
 	dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
 }
 
+static inline void omap_dma_list_set_ntype(struct omap_dma_sglist_node *node,
+					   int value)
+{
+	node->num_of_elem |= ((value) << 29);
+}
+
+static void omap_set_dma_sglist_pausebit(
+		struct omap_dma_list_config_params *lcfg, int nelem, int set)
+{
+	struct omap_dma_sglist_node *sgn = lcfg->sghead;
+
+	if (nelem > 0 && nelem < lcfg->num_elem) {
+		lcfg->pausenode = nelem;
+		sgn += nelem;
+
+		if (set)
+			sgn->next_desc_add_ptr |= DMA_LIST_DESC_PAUSE;
+		else
+			sgn->next_desc_add_ptr &= ~(DMA_LIST_DESC_PAUSE);
+	}
+}
+
+static int dma_sglist_set_phy_params(struct omap_dma_sglist_node *sghead,
+		dma_addr_t phyaddr, int nelem)
+{
+	struct omap_dma_sglist_node *sgcurr, *sgprev;
+	dma_addr_t elem_paddr = phyaddr;
+
+	for (sgprev = sghead;
+		sgprev < sghead + nelem;
+		sgprev++) {
+
+		sgcurr = sgprev + 1;
+		sgprev->next = sgcurr;
+		elem_paddr += (int)sizeof(*sgcurr);
+		sgprev->next_desc_add_ptr = elem_paddr;
+
+		switch (sgcurr->desc_type) {
+		case OMAP_DMA_SGLIST_DESCRIPTOR_TYPE1:
+			omap_dma_list_set_ntype(sgprev, 1);
+			break;
+
+		case OMAP_DMA_SGLIST_DESCRIPTOR_TYPE2a:
+		/* intentional no break */
+		case OMAP_DMA_SGLIST_DESCRIPTOR_TYPE2b:
+			omap_dma_list_set_ntype(sgprev, 2);
+			break;
+
+		case OMAP_DMA_SGLIST_DESCRIPTOR_TYPE3a:
+			/* intentional no break */
+		case OMAP_DMA_SGLIST_DESCRIPTOR_TYPE3b:
+			omap_dma_list_set_ntype(sgprev, 3);
+			break;
+
+		default:
+			return -EINVAL;
+
+		}
+		if (sgcurr->flags & OMAP_DMA_LIST_SRC_VALID)
+			sgprev->num_of_elem |= DMA_LIST_DESC_SRC_VALID;
+		if (sgcurr->flags & OMAP_DMA_LIST_DST_VALID)
+			sgprev->num_of_elem |= DMA_LIST_DESC_DST_VALID;
+		if (sgcurr->flags & OMAP_DMA_LIST_NOTIFY_BLOCK_END)
+			sgprev->num_of_elem |= DMA_LIST_DESC_BLK_END;
+	}
+	sgprev--;
+	sgprev->next_desc_add_ptr = OMAP_DMA_INVALID_DESCRIPTOR_POINTER;
+	return 0;
+}
+
 static void
 omap2_set_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
 {
@@ -1209,6 +1280,190 @@ int omap_get_dma_chain_src_pos(int chain_id)
 }
 EXPORT_SYMBOL(omap_get_dma_chain_src_pos);
 
+int omap_set_dma_sglist_mode(int lch, struct omap_dma_sglist_node *sgparams,
+	dma_addr_t padd, int nelem, struct omap_dma_channel_params *chparams)
+{
+	struct omap_dma_list_config_params *lcfg;
+	int l = DMA_LIST_CDP_LISTMODE; /* Enable Linked list mode in CDP */
+
+	if ((dma_caps0_status & DMA_CAPS_SGLIST_SUPPORT) == 0) {
+		printk(KERN_ERR "omap DMA: sglist feature not supported\n");
+		return -EPERM;
+	}
+	if (dma_chan[lch].flags & OMAP_DMA_ACTIVE) {
+		printk(KERN_ERR "omap DMA: configuring active DMA channel\n");
+		return -EPERM;
+	}
+
+	if (padd == 0) {
+		printk(KERN_ERR "omap DMA: sglist invalid dma_addr\n");
+		return -EINVAL;
+	}
+	lcfg = &dma_chan[lch].list_config;
+
+	lcfg->sghead = sgparams;
+	lcfg->num_elem = nelem;
+	lcfg->sgheadphy = padd;
+	lcfg->pausenode = -1;
+
+	if (NULL == chparams)
+		l |= DMA_LIST_CDP_FASTMODE;
+	else
+		omap_set_dma_params(lch, chparams);
+
+	dma_write(l, CDP, lch);
+	dma_write(0, CCDN, lch); /* Reset List index numbering */
+	/* Initialize frame and element counters to invalid values */
+	dma_write(OMAP_DMA_INVALID_FRAME_COUNT, CCFN, lch);
+	dma_write(OMAP_DMA_INVALID_ELEM_COUNT, CCEN, lch);
+
+	return dma_sglist_set_phy_params(sgparams, lcfg->sgheadphy, nelem);
+
+}
+EXPORT_SYMBOL(omap_set_dma_sglist_mode);
+
+void omap_clear_dma_sglist_mode(int lch)
+{
+	/* Clear entire CDP which is related to sglist handling */
+	dma_write(0, CDP, lch);
+	dma_write(0, CCDN, lch);
+	/**
+	 * Put back the original enabled irqs, which
+	 * could have been overwritten by type 1 or type 2
+	 * descriptors
+	 */
+	dma_write(dma_chan[lch].enabled_irqs, CICR, lch);
+	return;
+}
+EXPORT_SYMBOL(omap_clear_dma_sglist_mode);
+
+int omap_start_dma_sglist_transfers(int lch, int pauseafter)
+{
+	struct omap_dma_list_config_params *lcfg;
+	struct omap_dma_sglist_node *sgn;
+	unsigned int l, type_id;
+
+	lcfg = &dma_chan[lch].list_config;
+	sgn = lcfg->sghead;
+
+	lcfg->pausenode = 0;
+	omap_set_dma_sglist_pausebit(lcfg, pauseafter, 1);
+
+	/* Program the head descriptor's properties into CDP */
+	switch (lcfg->sghead->desc_type) {
+	case OMAP_DMA_SGLIST_DESCRIPTOR_TYPE1:
+		type_id = DMA_LIST_CDP_TYPE1;
+		break;
+	case OMAP_DMA_SGLIST_DESCRIPTOR_TYPE2a:
+	case OMAP_DMA_SGLIST_DESCRIPTOR_TYPE2b:
+		type_id = DMA_LIST_CDP_TYPE2;
+		break;
+	case OMAP_DMA_SGLIST_DESCRIPTOR_TYPE3a:
+	case OMAP_DMA_SGLIST_DESCRIPTOR_TYPE3b:
+		type_id = DMA_LIST_CDP_TYPE3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	l = dma_read(CDP, lch);
+	l |= type_id;
+	if (lcfg->sghead->flags & OMAP_DMA_LIST_SRC_VALID)
+		l |= DMA_LIST_CDP_SRC_VALID;
+	if (lcfg->sghead->flags & OMAP_DMA_LIST_DST_VALID)
+		l |= DMA_LIST_CDP_DST_VALID;
+
+	dma_write(l, CDP, lch);
+	dma_write((lcfg->sgheadphy), CNDP, lch);
+	/**
+	 * Barrier needed as writes to the
+	 * descriptor memory needs to be flushed
+	 * before it's used by DMA controller
+	 */
+	wmb();
+	omap_start_dma(lch);
+
+	return 0;
+}
+EXPORT_SYMBOL(omap_start_dma_sglist_transfers);
+
+int omap_resume_dma_sglist_transfers(int lch, int pauseafter)
+{
+	struct omap_dma_list_config_params *lcfg;
+	struct omap_dma_sglist_node *sgn;
+	int l;
+	u32 sys_cf = 0;
+
+	lcfg = &dma_chan[lch].list_config;
+	sgn = lcfg->sghead;
+
+	/* Maintain the pause state in descriptor */
+	omap_set_dma_sglist_pausebit(lcfg, lcfg->pausenode, 0);
+	omap_set_dma_sglist_pausebit(lcfg, pauseafter, 1);
+
+	/**
+	 * Barrier needed as writes to the
+	 * descriptor memory needs to be flushed
+	 * before it's used by DMA controller
+	 */
+	wmb();
+
+	/* Configure No-Standby */
+	if (IS_DMA_ERRATA(DMA_ERRATA_i541))
+		omap_device_mstandby(pd, &sys_cf, true);
+
+	/* Clear pause bit in CDP */
+	l = dma_read(CDP, lch);
+	l &= ~(DMA_LIST_CDP_PAUSEMODE);
+	dma_write(l, CDP, lch);
+
+	omap_start_dma(lch);
+
+	if (IS_DMA_ERRATA(DMA_ERRATA_i541))
+		omap_device_mstandby(pd, &sys_cf, false);
+
+	return 0;
+}
+EXPORT_SYMBOL(omap_resume_dma_sglist_transfers);
+
+void omap_release_dma_sglist(int lch)
+{
+	omap_clear_dma_sglist_mode(lch);
+	omap_free_dma(lch);
+
+	return;
+}
+EXPORT_SYMBOL(omap_release_dma_sglist);
+
+int omap_get_completed_sglist_nodes(int lch)
+{
+	int list_count;
+
+	list_count = dma_read(CCDN, lch);
+	return list_count & 0xffff; /* only 16 LSB bits are valid */
+}
+EXPORT_SYMBOL(omap_get_completed_sglist_nodes);
+
+int omap_dma_sglist_is_paused(int lch)
+{
+	int list_state;
+	list_state = dma_read(CDP, lch);
+	return (list_state & DMA_LIST_CDP_PAUSEMODE) ? 1 : 0;
+}
+EXPORT_SYMBOL(omap_dma_sglist_is_paused);
+
+void omap_dma_set_sglist_fastmode(int lch, int fastmode)
+{
+	int l = dma_read(CDP, lch);
+
+	if (fastmode)
+		l |= DMA_LIST_CDP_FASTMODE;
+	else
+		l &= ~(DMA_LIST_CDP_FASTMODE);
+	dma_write(l, CDP, lch);
+}
+EXPORT_SYMBOL(omap_dma_set_sglist_fastmode);
+
 /* One time initializations */
 static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
 {
@@ -1249,6 +1504,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
 	p->disable_lnk			= omap2_disable_lnk;
 
 	p->set_global_params		= omap_dma_set_global_params;
+	p->clear_dma_sglist_mode	= omap_clear_dma_sglist_mode;
 
 	p->clear_lch_regs	= NULL;
 	p->get_gdma_dev		= NULL;
@@ -1310,6 +1566,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
 		return -ENOMEM;
 	}
 	dma_chan = d->chan;
+	dma_caps0_status = dma_read(CAPS_0, 0);
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/include/mach/dma.h b/arch/arm/mach-omap2/include/mach/dma.h
index 4313539..0a2eb44 100644
--- a/arch/arm/mach-omap2/include/mach/dma.h
+++ b/arch/arm/mach-omap2/include/mach/dma.h
@@ -83,4 +83,91 @@ extern int omap_modify_dma_chain_params(int chain_id,
 					struct omap_dma_channel_params params);
 extern int omap_dma_chain_status(int chain_id);
 
+/**
+ * omap_set_dma_sglist_mode()	Switch channel to scatter gather mode
+ * @lch:	Logical channel to switch to sglist mode
+ * @sghead:	Contains the descriptor elements to be executed
+ *		Should be allocated using dma_alloc_coherent
+ * @padd:	The dma address of sghead, as returned by dma_alloc_coherent
+ * @nelem:	Number of elements in sghead
+ * @chparams:	DMA channel transfer parameters. Can be NULL
+ */
+extern int omap_set_dma_sglist_mode(int lch,
+	struct omap_dma_sglist_node *sghead, dma_addr_t padd,
+	int nelem, struct omap_dma_channel_params *chparams);
+
+/**
+ * omap_clear_dma_sglist_mode()	Switch from scatter gather mode
+ *				to normal mode
+ * @lch:	The logical channel to be switched to normal mode
+ *
+ * Switches the requested logical channel to normal mode
+ * from scatter gather mode
+ */
+extern void omap_clear_dma_sglist_mode(int lch);
+
+/**
+ * omap_start_dma_sglist_transfers()	Starts the sglist transfer
+ * @lch:	logical channel on which sglist transfer to be started
+ * @pauseafter:	index of the element on which to pause the transfer
+ *		set to -1 if no pause is needed till end of transfer
+ *
+ * Start the dma transfer in list mode
+ * The index (in pauseafter) is absolute (from the head of the list)
+ * User should have previously called omap_set_dma_sglist_mode()
+ */
+extern int omap_start_dma_sglist_transfers(int lch, int pauseafter);
+
+/**
+ * omap_resume_dma_sglist_transfers()	Resumes a previously paused
+ *					sglist transfer
+ * @lch:	The logical channel to be resumed
+ * @pauseafter:	The index of sglist to be paused again
+ *		set to -1 if no pause is needed till end of transfer
+ *
+ * Resume the previously paused transfer
+ * The index (in pauseafter) is absolute (from the head of the list)
+ */
+extern int omap_resume_dma_sglist_transfers(int lch, int pauseafter);
+
+/**
+ * omap_release_dma_sglist()	Releases a previously requested
+ *				DMA channel which is in sglist mode
+ * @lch:	The logical channel to be released
+ */
+extern void omap_release_dma_sglist(int lch);
+
+/**
+ * omap_get_completed_sglist_nodes()	Returns a list of completed
+ *					sglist nodes
+ * @lch:	The logical on which the query is to be made
+ *
+ * Returns the number of completed elements in the linked list
+ * The value is transient if the API is invoked for an ongoing transfer
+ */
+int omap_get_completed_sglist_nodes(int lch);
+
+/**
+ * omap_dma_sglist_is_paused()	Query is the logical channel in
+ *				sglist mode is paused or note
+ * @lch:	The logical on which the query is to be made
+ *
+ * Returns non zero if the linked list is currently in pause state
+ */
+int omap_dma_sglist_is_paused(int lch);
+
+/**
+ * omap_dma_set_sglist_fastmode() Set the sglist transfer to fastmode
+ * @lch:	The logical channel which is to be changed to fastmode
+ * @fastmode:	Set or clear the fastmode status
+ *		1 = set fastmode
+ *		0 = clear fastmode
+ *
+ * In fastmode, DMA register settings are updated from the first element
+ * of the linked list, before initiating the tranfer.
+ * In non-fastmode, the first element is used only after completing the
+ * transfer as already configured in the registers
+ */
+void omap_dma_set_sglist_fastmode(int lch, int fastmode);
+
 #endif /* __ASM_ARCH_OMAP2_DMA_H */
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index fdcdae6..51b6a71 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -413,6 +413,7 @@ void omap_free_dma(int lch)
 		/* Make sure the DMA transfer is stopped. */
 		p->dma_write(0, CCR, lch);
 		omap_clear_dma(lch);
+		p->clear_dma_sglist_mode(lch);
 	}
 	spin_lock_irqsave(&dma_chan_lock, flags);
 	dma_chan[lch].dev_id = -1;
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
index f760104..c9c6bbb 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -351,6 +351,112 @@ struct omap_dma_channel_params {
 #endif
 };
 
+/* CDP Register bitmaps */
+#define DMA_LIST_CDP_DST_VALID	(BIT(0))
+#define DMA_LIST_CDP_SRC_VALID	(BIT(2))
+#define DMA_LIST_CDP_TYPE1	(BIT(4))
+#define DMA_LIST_CDP_TYPE2	(BIT(5))
+#define DMA_LIST_CDP_TYPE3	(BIT(4) | BIT(5))
+#define DMA_LIST_CDP_PAUSEMODE	(BIT(7))
+#define DMA_LIST_CDP_LISTMODE	(BIT(8))
+#define DMA_LIST_CDP_FASTMODE	(BIT(10))
+/* CAPS register bitmaps */
+#define DMA_CAPS_SGLIST_SUPPORT	(BIT(20))
+
+#define DMA_LIST_DESC_PAUSE	(BIT(0))
+#define DMA_LIST_DESC_SRC_VALID	(BIT(24))
+#define DMA_LIST_DESC_DST_VALID	(BIT(26))
+#define DMA_LIST_DESC_BLK_END	(BIT(28))
+
+#define OMAP_DMA_INVALID_FRAME_COUNT	(0xffff)
+#define OMAP_DMA_INVALID_ELEM_COUNT	(0xffffff)
+#define OMAP_DMA_INVALID_DESCRIPTOR_POINTER	(0xfffffffc)
+
+struct omap_dma_list_config_params {
+	unsigned int num_elem;
+	struct omap_dma_sglist_node *sghead;
+	dma_addr_t sgheadphy;
+	unsigned int pausenode;
+};
+
+struct omap_dma_sglist_type1_params {
+	u32 src_addr;
+	u32 dst_addr;
+	u16 cfn_fn;
+	u16 cicr;
+	u16 dst_elem_idx;
+	u16 src_elem_idx;
+	u32 dst_frame_idx_or_pkt_size;
+	u32 src_frame_idx_or_pkt_size;
+	u32 color;
+	u32 csdp;
+	u32 clnk_ctrl;
+	u32 ccr;
+};
+
+struct omap_dma_sglist_type2a_params {
+	u32 src_addr;
+	u32 dst_addr;
+	u16 cfn_fn;
+	u16 cicr;
+	u16 dst_elem_idx;
+	u16 src_elem_idx;
+	u32 dst_frame_idx_or_pkt_size;
+	u32 src_frame_idx_or_pkt_size;
+};
+
+struct omap_dma_sglist_type2b_params {
+	u32 src_or_dest_addr;
+	u16 cfn_fn;
+	u16 cicr;
+	u16 dst_elem_idx;
+	u16 src_elem_idx;
+	u32 dst_frame_idx_or_pkt_size;
+	u32 src_frame_idx_or_pkt_size;
+};
+
+struct omap_dma_sglist_type3a_params {
+	u32 src_addr;
+	u32 dst_addr;
+};
+
+struct omap_dma_sglist_type3b_params {
+	u32 src_or_dest_addr;
+};
+
+enum omap_dma_sglist_descriptor_select {
+	OMAP_DMA_SGLIST_DESCRIPTOR_TYPE1,
+	OMAP_DMA_SGLIST_DESCRIPTOR_TYPE2a,
+	OMAP_DMA_SGLIST_DESCRIPTOR_TYPE2b,
+	OMAP_DMA_SGLIST_DESCRIPTOR_TYPE3a,
+	OMAP_DMA_SGLIST_DESCRIPTOR_TYPE3b,
+};
+
+union omap_dma_sglist_node_type {
+	struct omap_dma_sglist_type1_params t1;
+	struct omap_dma_sglist_type2a_params t2a;
+	struct omap_dma_sglist_type2b_params t2b;
+	struct omap_dma_sglist_type3a_params t3a;
+	struct omap_dma_sglist_type3b_params t3b;
+};
+
+struct omap_dma_sglist_node {
+
+	/* Common elements for all descriptors */
+	dma_addr_t next_desc_add_ptr;
+	u32 num_of_elem;
+	/* Type specific elements */
+	union omap_dma_sglist_node_type sg_node;
+	/* Control fields */
+	unsigned short flags;
+	/* Fields that can be set in flags variable */
+	#define OMAP_DMA_LIST_SRC_VALID		BIT(0)
+	#define OMAP_DMA_LIST_DST_VALID		BIT(1)
+	#define OMAP_DMA_LIST_NOTIFY_BLOCK_END	BIT(2)
+	enum omap_dma_sglist_descriptor_select desc_type;
+	struct omap_dma_sglist_node *next;
+};
+
 #include <mach/dma.h>
 struct omap_dma_lch {
 	int next_lch;
@@ -367,6 +473,7 @@ struct omap_dma_lch {
 	int state;
 	int chain_id;
 	int status;
+	struct omap_dma_list_config_params list_config;
 };
 
 struct omap_dma_dev_attr {
@@ -412,6 +519,7 @@ struct omap_system_dma_plat_info {
 
 	void (*set_global_params)(int arb_rate,
 			int max_fifo_depth, int tparams);
+	void (*clear_dma_sglist_mode)(int lch);
 };
 
 extern void omap_set_dma_priority(int lch, int dst_port, int priority);
-- 
1.7.1


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

* [PATCH v4 13/13] OMAP: PM: DMA: Enable runtime pm
  2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
                   ` (10 preceding siblings ...)
  2010-11-08 14:07 ` [PATCH v4 12/13] OMAP2+: DMA: descriptor autoloading feature G, Manjunath Kondaiah
@ 2010-11-08 14:07 ` G, Manjunath Kondaiah
  11 siblings, 0 replies; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-08 14:07 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Benoit Cousson, Kevin Hilman, Santosh Shilimkar

Enable runtime pm and use pm_runtime_get and pm_runtime_put
for OMAP DMA driver.

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/plat-omap/dma.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 51b6a71..6eb760c 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -35,6 +35,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/pm_runtime.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
@@ -330,6 +331,8 @@ int omap_request_dma(int dev_id, const char *dev_name,
 	chan = dma_chan + free_ch;
 	chan->dev_id = dev_id;
 
+	pm_runtime_get(&pd->dev);
+
 	if (d->dev_caps & IS_WORD_16)
 		p->clear_lch_regs(free_ch);
 	else
@@ -415,6 +418,7 @@ void omap_free_dma(int lch)
 		omap_clear_dma(lch);
 		p->clear_dma_sglist_mode(lch);
 	}
+	pm_runtime_put(&pd->dev);
 	spin_lock_irqsave(&dma_chan_lock, flags);
 	dma_chan[lch].dev_id = -1;
 	dma_chan[lch].next_lch = -1;
@@ -782,6 +786,11 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)
 	dma_chan_count		= d->chan_count;
 	dma_chan		= d->chan;
 
+	/* Enable run time PM */
+	pm_runtime_enable(&pd->dev);
+
+	/* Accessing hw registers, get clock */
+	pm_runtime_get(&pd->dev);
 	for (ch = 0; ch < dma_chan_count; ch++) {
 		unsigned long flags;
 		omap_clear_dma(ch);
@@ -809,6 +818,10 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)
 		dma_chan[0].dev_id = 0;
 		dma_chan[1].dev_id = 1;
 	}
+
+	if (!omap_dma_reserve_channels)
+		pm_runtime_put(&pd->dev);
+
 	return 0;
 
 exit_release_region:
-- 
1.7.1


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

* Re: [PATCH v4 01/13] OMAP: DMA: Replace read/write macros with functions
  2010-11-08 14:07 ` [PATCH v4 01/13] OMAP: DMA: Replace read/write macros with functions G, Manjunath Kondaiah
@ 2010-11-09  0:40     ` Tony Lindgren
  0 siblings, 0 replies; 21+ messages in thread
From: Tony Lindgren @ 2010-11-09  0:40 UTC (permalink / raw)
  To: G, Manjunath Kondaiah
  Cc: linux-omap, linux-arm-kernel, Benoit Cousson, Kevin Hilman,
	Santosh Shilimkar

Hi,

* G, Manjunath Kondaiah <manjugk@ti.com> [101108 05:58]:

> +static u16 reg_map_omap1[] = {
> +	[GCR1]		= 0x400,
> +	[GSCR]		= 0x404,
> +	[GRST]		= 0x408,
...
> +};

The above you should move to mach-omap1/dma.c and pass it in the init
function to plat-omap/dma.c. Let's try to make the common code clean
of omap1/2/3/4 specific data.

> +static u16 reg_map_omap2[] = {
> +	[REVISION]		= 0x00,
> +	[GCR2]			= 0x78,
> +	[IRQSTATUS_L0]		= 0x08,
...
> +};

And the above you should move to mach-omap2/dma.c.

It's OK to do it in a later patch if you prefer that, but in that case
the patch description here should mention it.

>  	if (cpu_class_is_omap2() && dma_trigger) {
>  		u32 val;
>  
> -		val = dma_read(CCR(lch));
> +		l = dma_read(CSDP2, lch);
> +		l &= ~0x03;
> +		l |= data_type;
> +		dma_write(l, CSDP2, lch);
> +
> +		val = dma_read(CCR2, lch);

This seems to be doing more than just change the read function?

Please keep any functional changes separate. Let's first get the
hwmod based initialization done without any functional changes
to avoid breaking things.
  
> @@ -475,11 +654,19 @@ void omap_set_dma_src_data_pack(int lch, int enable)
>  {
>  	u32 l;
>  
> -	l = dma_read(CSDP(lch));
> +	if (cpu_class_is_omap1())
> +		l = dma_read(CSDP1, lch);
> +	else
> +		l = dma_read(CSDP2, lch);
> +
>  	l &= ~(1 << 6);
>  	if (enable)
>  		l |= (1 << 6);
> -	dma_write(l, CSDP(lch));
> +
> +	if (cpu_class_is_omap1())
> +		dma_write(l, CSDP1, lch);
> +	else
> +		dma_write(l, CSDP2, lch);
>  }

Since you now have the register mapping table, why do you still need
to separate between CSDP1 and CSDP2 registers?

You should now be able to call them just CSDP, and then the register
can be mapped to the right offset for omap1 and omap2+.

So this should be just:

void omap_set_dma_src_data_pack(int lch, int enable)
{
	u32 l;

	l = p->dma_read(CSDP, lch);
	l &= ~(1 << 6);
	if (enable)
		l |= (1 << 6);
	p->dma_write(l, CSDP, lch);
}

Please check the other functions for this too, that should
leave out quite a bit of if cpu_class_is_omap1 clutter.

And looking at it more, you should only have one enum for the
registers, not separate enum for both omap1 and omap2+. The
enum should be common for all of them. If needed, the enum
should be separate for common register and channel specific
registers.

Some 32-bit registers for omap1 have the lower and upper registers,
because of the 16-bit register access. So those still need to be
handled separately for omap1. That can be handled automatically
for omap1 (untested):

static inline u32 omap1_dma_read(int reg, int lch)
{
	u32 va, val, ch_offset = 0;

	if (reg > OMAP1_CH_COMMON_START)
		ch_offset = 0x40 * lch;

	va = dma_base + reg_map_omap1[reg] + ch_offset;
	val = __raw_readw(va);

	/* Some channel registers also have an associated upper register */
	if (reg >= CSSA) {
		16 upper = __raw_readw(va + 2);
		val |= (upper << 16);
	}

	return val;
}
...

Regards,

Tony

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

* [PATCH v4 01/13] OMAP: DMA: Replace read/write macros with functions
@ 2010-11-09  0:40     ` Tony Lindgren
  0 siblings, 0 replies; 21+ messages in thread
From: Tony Lindgren @ 2010-11-09  0:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

* G, Manjunath Kondaiah <manjugk@ti.com> [101108 05:58]:

> +static u16 reg_map_omap1[] = {
> +	[GCR1]		= 0x400,
> +	[GSCR]		= 0x404,
> +	[GRST]		= 0x408,
...
> +};

The above you should move to mach-omap1/dma.c and pass it in the init
function to plat-omap/dma.c. Let's try to make the common code clean
of omap1/2/3/4 specific data.

> +static u16 reg_map_omap2[] = {
> +	[REVISION]		= 0x00,
> +	[GCR2]			= 0x78,
> +	[IRQSTATUS_L0]		= 0x08,
...
> +};

And the above you should move to mach-omap2/dma.c.

It's OK to do it in a later patch if you prefer that, but in that case
the patch description here should mention it.

>  	if (cpu_class_is_omap2() && dma_trigger) {
>  		u32 val;
>  
> -		val = dma_read(CCR(lch));
> +		l = dma_read(CSDP2, lch);
> +		l &= ~0x03;
> +		l |= data_type;
> +		dma_write(l, CSDP2, lch);
> +
> +		val = dma_read(CCR2, lch);

This seems to be doing more than just change the read function?

Please keep any functional changes separate. Let's first get the
hwmod based initialization done without any functional changes
to avoid breaking things.
  
> @@ -475,11 +654,19 @@ void omap_set_dma_src_data_pack(int lch, int enable)
>  {
>  	u32 l;
>  
> -	l = dma_read(CSDP(lch));
> +	if (cpu_class_is_omap1())
> +		l = dma_read(CSDP1, lch);
> +	else
> +		l = dma_read(CSDP2, lch);
> +
>  	l &= ~(1 << 6);
>  	if (enable)
>  		l |= (1 << 6);
> -	dma_write(l, CSDP(lch));
> +
> +	if (cpu_class_is_omap1())
> +		dma_write(l, CSDP1, lch);
> +	else
> +		dma_write(l, CSDP2, lch);
>  }

Since you now have the register mapping table, why do you still need
to separate between CSDP1 and CSDP2 registers?

You should now be able to call them just CSDP, and then the register
can be mapped to the right offset for omap1 and omap2+.

So this should be just:

void omap_set_dma_src_data_pack(int lch, int enable)
{
	u32 l;

	l = p->dma_read(CSDP, lch);
	l &= ~(1 << 6);
	if (enable)
		l |= (1 << 6);
	p->dma_write(l, CSDP, lch);
}

Please check the other functions for this too, that should
leave out quite a bit of if cpu_class_is_omap1 clutter.

And looking at it more, you should only have one enum for the
registers, not separate enum for both omap1 and omap2+. The
enum should be common for all of them. If needed, the enum
should be separate for common register and channel specific
registers.

Some 32-bit registers for omap1 have the lower and upper registers,
because of the 16-bit register access. So those still need to be
handled separately for omap1. That can be handled automatically
for omap1 (untested):

static inline u32 omap1_dma_read(int reg, int lch)
{
	u32 va, val, ch_offset = 0;

	if (reg > OMAP1_CH_COMMON_START)
		ch_offset = 0x40 * lch;

	va = dma_base + reg_map_omap1[reg] + ch_offset;
	val = __raw_readw(va);

	/* Some channel registers also have an associated upper register */
	if (reg >= CSSA) {
		16 upper = __raw_readw(va + 2);
		val |= (upper << 16);
	}

	return val;
}
...

Regards,

Tony

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

* RE: [PATCH v4 07/13] OMAP4: DMA: hwmod: add system DMA
  2010-11-08 14:07 ` [PATCH v4 07/13] OMAP4: " G, Manjunath Kondaiah
@ 2010-11-09  5:02     ` Varadarajan, Charulatha
  0 siblings, 0 replies; 21+ messages in thread
From: Varadarajan, Charulatha @ 2010-11-09  5:02 UTC (permalink / raw)
  To: G, Manjunath Kondaiah, linux-omap
  Cc: linux-arm-kernel, Cousson, Benoit, Kevin Hilman, Shilimkar, Santosh


One minor comment,
 
<<snip>>

> +
>  static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
>  	/* dmm class */
>  	&omap44xx_dmm_hwmod,
> @@ -1077,6 +1174,8 @@ static __initdata struct omap_hwmod 
> *omap44xx_hwmods[] = {
>  	&omap44xx_uart2_hwmod,
>  	&omap44xx_uart3_hwmod,
>  	&omap44xx_uart4_hwmod,
> +	/* dma class */
> +	&omap44xx_dma_system_hwmod,

Add a blank line between each class. See [1]
Same is applicable to patches 4, 5 and 6

[1] https://patchwork.kernel.org/patch/305062/


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

* [PATCH v4 07/13] OMAP4: DMA: hwmod: add system DMA
@ 2010-11-09  5:02     ` Varadarajan, Charulatha
  0 siblings, 0 replies; 21+ messages in thread
From: Varadarajan, Charulatha @ 2010-11-09  5:02 UTC (permalink / raw)
  To: linux-arm-kernel


One minor comment,
 
<<snip>>

> +
>  static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
>  	/* dmm class */
>  	&omap44xx_dmm_hwmod,
> @@ -1077,6 +1174,8 @@ static __initdata struct omap_hwmod 
> *omap44xx_hwmods[] = {
>  	&omap44xx_uart2_hwmod,
>  	&omap44xx_uart3_hwmod,
>  	&omap44xx_uart4_hwmod,
> +	/* dma class */
> +	&omap44xx_dma_system_hwmod,

Add a blank line between each class. See [1]
Same is applicable to patches 4, 5 and 6

[1] https://patchwork.kernel.org/patch/305062/

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

* RE: [PATCH v4 01/13] OMAP: DMA: Replace read/write macros with functions
  2010-11-09  0:40     ` Tony Lindgren
@ 2010-11-10 14:01       ` G, Manjunath Kondaiah
  -1 siblings, 0 replies; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-10 14:01 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: linux-omap, linux-arm-kernel, Cousson, Benoit, Kevin Hilman,
	Shilimkar, Santosh



> -----Original Message-----
> From: Tony Lindgren [mailto:tony@atomide.com] 
> Sent: Tuesday, November 09, 2010 6:11 AM
> To: G, Manjunath Kondaiah
> Cc: linux-omap@vger.kernel.org; 
> linux-arm-kernel@lists.infradead.org; Cousson, Benoit; Kevin 
> Hilman; Shilimkar, Santosh
> Subject: Re: [PATCH v4 01/13] OMAP: DMA: Replace read/write 
> macros with functions
> 
> Hi,
> 
> * G, Manjunath Kondaiah <manjugk@ti.com> [101108 05:58]:
> 
> > +static u16 reg_map_omap1[] = {
> > +	[GCR1]		= 0x400,
> > +	[GSCR]		= 0x404,
> > +	[GRST]		= 0x408,
> ...
> > +};
> 
> The above you should move to mach-omap1/dma.c and pass it in the init
> function to plat-omap/dma.c. Let's try to make the common code clean
> of omap1/2/3/4 specific data.
> 
> > +static u16 reg_map_omap2[] = {
> > +	[REVISION]		= 0x00,
> > +	[GCR2]			= 0x78,
> > +	[IRQSTATUS_L0]		= 0x08,
> ...
> > +};
> 
> And the above you should move to mach-omap2/dma.c.
> 
> It's OK to do it in a later patch if you prefer that, but in that case
> the patch description here should mention it.

It's already taken care in the later patches. I will update the patch
description accordingly.

> 
> >  	if (cpu_class_is_omap2() && dma_trigger) {
> >  		u32 val;
> >  
> > -		val = dma_read(CCR(lch));
> > +		l = dma_read(CSDP2, lch);
> > +		l &= ~0x03;
> > +		l |= data_type;
> > +		dma_write(l, CSDP2, lch);
> > +
> > +		val = dma_read(CCR2, lch);
> 
> This seems to be doing more than just change the read function?
> 
> Please keep any functional changes separate. Let's first get the
> hwmod based initialization done without any functional changes
> to avoid breaking things.
>   
> > @@ -475,11 +654,19 @@ void omap_set_dma_src_data_pack(int 
> lch, int enable)
> >  {
> >  	u32 l;
> >  
> > -	l = dma_read(CSDP(lch));
> > +	if (cpu_class_is_omap1())
> > +		l = dma_read(CSDP1, lch);
> > +	else
> > +		l = dma_read(CSDP2, lch);
> > +
> >  	l &= ~(1 << 6);
> >  	if (enable)
> >  		l |= (1 << 6);
> > -	dma_write(l, CSDP(lch));
> > +
> > +	if (cpu_class_is_omap1())
> > +		dma_write(l, CSDP1, lch);
> > +	else
> > +		dma_write(l, CSDP2, lch);
> >  }
> 
> Since you now have the register mapping table, why do you still need
> to separate between CSDP1 and CSDP2 registers?
> 
> You should now be able to call them just CSDP, and then the register
> can be mapped to the right offset for omap1 and omap2+.
> 
> So this should be just:
> 
> void omap_set_dma_src_data_pack(int lch, int enable)
> {
> 	u32 l;
> 
> 	l = p->dma_read(CSDP, lch);
> 	l &= ~(1 << 6);
> 	if (enable)
> 		l |= (1 << 6);
> 	p->dma_write(l, CSDP, lch);
> }
> 
> Please check the other functions for this too, that should
> leave out quite a bit of if cpu_class_is_omap1 clutter.
> 
> And looking at it more, you should only have one enum for the
> registers, not separate enum for both omap1 and omap2+. The
> enum should be common for all of them. If needed, the enum
> should be separate for common register and channel specific
> registers.

ok. I will use single enum for all omap's in plat/dma.h which
can be accessed by both mach-omap1/dma.c and mach-omap2/dma.c
in later patches.

> 
> Some 32-bit registers for omap1 have the lower and upper registers,
> because of the 16-bit register access. So those still need to be
> handled separately for omap1. That can be handled automatically
> for omap1 (untested):
> 
> static inline u32 omap1_dma_read(int reg, int lch)
> {
> 	u32 va, val, ch_offset = 0;
> 
> 	if (reg > OMAP1_CH_COMMON_START)
> 		ch_offset = 0x40 * lch;
> 
> 	va = dma_base + reg_map_omap1[reg] + ch_offset;
> 	val = __raw_readw(va);
> 
> 	/* Some channel registers also have an associated upper 
> register */
> 	if (reg >= CSSA) {
> 		16 upper = __raw_readw(va + 2);
> 		val |= (upper << 16);
> 	}
> 
> 	return val;
> }

Thanks for the suggestion. It will be taken care with next version 
with some more optimizations such as determining ch_offset between
omap1 and omap2+, reg_map, ch_common_start at init time as suggested
by kevin.

-Manjunath

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

* [PATCH v4 01/13] OMAP: DMA: Replace read/write macros with functions
@ 2010-11-10 14:01       ` G, Manjunath Kondaiah
  0 siblings, 0 replies; 21+ messages in thread
From: G, Manjunath Kondaiah @ 2010-11-10 14:01 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Tony Lindgren [mailto:tony at atomide.com] 
> Sent: Tuesday, November 09, 2010 6:11 AM
> To: G, Manjunath Kondaiah
> Cc: linux-omap at vger.kernel.org; 
> linux-arm-kernel at lists.infradead.org; Cousson, Benoit; Kevin 
> Hilman; Shilimkar, Santosh
> Subject: Re: [PATCH v4 01/13] OMAP: DMA: Replace read/write 
> macros with functions
> 
> Hi,
> 
> * G, Manjunath Kondaiah <manjugk@ti.com> [101108 05:58]:
> 
> > +static u16 reg_map_omap1[] = {
> > +	[GCR1]		= 0x400,
> > +	[GSCR]		= 0x404,
> > +	[GRST]		= 0x408,
> ...
> > +};
> 
> The above you should move to mach-omap1/dma.c and pass it in the init
> function to plat-omap/dma.c. Let's try to make the common code clean
> of omap1/2/3/4 specific data.
> 
> > +static u16 reg_map_omap2[] = {
> > +	[REVISION]		= 0x00,
> > +	[GCR2]			= 0x78,
> > +	[IRQSTATUS_L0]		= 0x08,
> ...
> > +};
> 
> And the above you should move to mach-omap2/dma.c.
> 
> It's OK to do it in a later patch if you prefer that, but in that case
> the patch description here should mention it.

It's already taken care in the later patches. I will update the patch
description accordingly.

> 
> >  	if (cpu_class_is_omap2() && dma_trigger) {
> >  		u32 val;
> >  
> > -		val = dma_read(CCR(lch));
> > +		l = dma_read(CSDP2, lch);
> > +		l &= ~0x03;
> > +		l |= data_type;
> > +		dma_write(l, CSDP2, lch);
> > +
> > +		val = dma_read(CCR2, lch);
> 
> This seems to be doing more than just change the read function?
> 
> Please keep any functional changes separate. Let's first get the
> hwmod based initialization done without any functional changes
> to avoid breaking things.
>   
> > @@ -475,11 +654,19 @@ void omap_set_dma_src_data_pack(int 
> lch, int enable)
> >  {
> >  	u32 l;
> >  
> > -	l = dma_read(CSDP(lch));
> > +	if (cpu_class_is_omap1())
> > +		l = dma_read(CSDP1, lch);
> > +	else
> > +		l = dma_read(CSDP2, lch);
> > +
> >  	l &= ~(1 << 6);
> >  	if (enable)
> >  		l |= (1 << 6);
> > -	dma_write(l, CSDP(lch));
> > +
> > +	if (cpu_class_is_omap1())
> > +		dma_write(l, CSDP1, lch);
> > +	else
> > +		dma_write(l, CSDP2, lch);
> >  }
> 
> Since you now have the register mapping table, why do you still need
> to separate between CSDP1 and CSDP2 registers?
> 
> You should now be able to call them just CSDP, and then the register
> can be mapped to the right offset for omap1 and omap2+.
> 
> So this should be just:
> 
> void omap_set_dma_src_data_pack(int lch, int enable)
> {
> 	u32 l;
> 
> 	l = p->dma_read(CSDP, lch);
> 	l &= ~(1 << 6);
> 	if (enable)
> 		l |= (1 << 6);
> 	p->dma_write(l, CSDP, lch);
> }
> 
> Please check the other functions for this too, that should
> leave out quite a bit of if cpu_class_is_omap1 clutter.
> 
> And looking at it more, you should only have one enum for the
> registers, not separate enum for both omap1 and omap2+. The
> enum should be common for all of them. If needed, the enum
> should be separate for common register and channel specific
> registers.

ok. I will use single enum for all omap's in plat/dma.h which
can be accessed by both mach-omap1/dma.c and mach-omap2/dma.c
in later patches.

> 
> Some 32-bit registers for omap1 have the lower and upper registers,
> because of the 16-bit register access. So those still need to be
> handled separately for omap1. That can be handled automatically
> for omap1 (untested):
> 
> static inline u32 omap1_dma_read(int reg, int lch)
> {
> 	u32 va, val, ch_offset = 0;
> 
> 	if (reg > OMAP1_CH_COMMON_START)
> 		ch_offset = 0x40 * lch;
> 
> 	va = dma_base + reg_map_omap1[reg] + ch_offset;
> 	val = __raw_readw(va);
> 
> 	/* Some channel registers also have an associated upper 
> register */
> 	if (reg >= CSSA) {
> 		16 upper = __raw_readw(va + 2);
> 		val |= (upper << 16);
> 	}
> 
> 	return val;
> }

Thanks for the suggestion. It will be taken care with next version 
with some more optimizations such as determining ch_offset between
omap1 and omap2+, reg_map, ch_common_start at init time as suggested
by kevin.

-Manjunath

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

* Re: [PATCH v4 02/13] OMAP: DMA: Introduce errata handling feature
  2010-11-08 14:07 ` [PATCH v4 02/13] OMAP: DMA: Introduce errata handling feature G, Manjunath Kondaiah
@ 2010-12-02 19:59     ` Tony Lindgren
  0 siblings, 0 replies; 21+ messages in thread
From: Tony Lindgren @ 2010-12-02 19:59 UTC (permalink / raw)
  To: G, Manjunath Kondaiah
  Cc: linux-omap, linux-arm-kernel, Peter Ujfalusi, Benoit Cousson,
	Kevin Hilman, Santosh Shilimkar

* G, Manjunath Kondaiah <manjugk@ti.com> [101108 05:58]:
> Implement errata handling to use flags instead of cpu_is_*
> and cpu_class_* in the code.
> 
> The errata flags are initialized at init time and during runtime
> we are using the errata variable (via the IS_DMA_ERRATA macro)
> to execute the required errata workaround.

Applying the first patch and this patch won't compile on omap1:

arch/arm/plat-omap/built-in.o: In function `omap_init_dma':
omap-pm-noop.c:(.init.text+0x604): undefined reference to `omap_type'

Tony

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

* [PATCH v4 02/13] OMAP: DMA: Introduce errata handling feature
@ 2010-12-02 19:59     ` Tony Lindgren
  0 siblings, 0 replies; 21+ messages in thread
From: Tony Lindgren @ 2010-12-02 19:59 UTC (permalink / raw)
  To: linux-arm-kernel

* G, Manjunath Kondaiah <manjugk@ti.com> [101108 05:58]:
> Implement errata handling to use flags instead of cpu_is_*
> and cpu_class_* in the code.
> 
> The errata flags are initialized at init time and during runtime
> we are using the errata variable (via the IS_DMA_ERRATA macro)
> to execute the required errata workaround.

Applying the first patch and this patch won't compile on omap1:

arch/arm/plat-omap/built-in.o: In function `omap_init_dma':
omap-pm-noop.c:(.init.text+0x604): undefined reference to `omap_type'

Tony

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

end of thread, other threads:[~2010-12-02 20:00 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-08 14:07 [PATCH v4 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
2010-11-08 14:07 ` [PATCH v4 01/13] OMAP: DMA: Replace read/write macros with functions G, Manjunath Kondaiah
2010-11-09  0:40   ` Tony Lindgren
2010-11-09  0:40     ` Tony Lindgren
2010-11-10 14:01     ` G, Manjunath Kondaiah
2010-11-10 14:01       ` G, Manjunath Kondaiah
2010-11-08 14:07 ` [PATCH v4 02/13] OMAP: DMA: Introduce errata handling feature G, Manjunath Kondaiah
2010-12-02 19:59   ` Tony Lindgren
2010-12-02 19:59     ` Tony Lindgren
2010-11-08 14:07 ` [PATCH v4 03/13] OMAP: DMA: Introduce DMA device attributes G, Manjunath Kondaiah
2010-11-08 14:07 ` [PATCH v4 04/13] OMAP2420: DMA: hwmod: add system DMA G, Manjunath Kondaiah
2010-11-08 14:07 ` [PATCH v4 05/13] OMAP2430: " G, Manjunath Kondaiah
2010-11-08 14:07 ` [PATCH v4 06/13] OMAP3: " G, Manjunath Kondaiah
2010-11-08 14:07 ` [PATCH v4 07/13] OMAP4: " G, Manjunath Kondaiah
2010-11-09  5:02   ` Varadarajan, Charulatha
2010-11-09  5:02     ` Varadarajan, Charulatha
2010-11-08 14:07 ` [PATCH v4 08/13] OMAP1: DMA: Introduce DMA driver as platform device G, Manjunath Kondaiah
2010-11-08 14:07 ` [PATCH v4 09/13] OMAP2+: DMA: hwmod: Device registration G, Manjunath Kondaiah
2010-11-08 14:07 ` [PATCH v4 10/13] OMAP: DMA: Convert DMA library into DMA platform Driver G, Manjunath Kondaiah
2010-11-08 14:07 ` [PATCH v4 12/13] OMAP2+: DMA: descriptor autoloading feature G, Manjunath Kondaiah
2010-11-08 14:07 ` [PATCH v4 13/13] OMAP: PM: DMA: Enable runtime pm G, Manjunath Kondaiah

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.