diff mbox

[05/26] davinci: EDMA: add support for dm646x

Message ID 1246914900-9034-6-git-send-email-khilman@deeprootsystems.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Kevin Hilman July 6, 2009, 9:14 p.m. UTC
From: Sudhakar Rajashekhara <sudhakar.raj@ti.com>

Enables module clock for DM646x EDMA channel controller and transfer controller.

Channel mapping logic is introduced in dm646x EDMA. This implies that there is
no fixed association for a channel number to a parameter entry number. In other
words, using the DMA channel mapping registers (DCHMAPn), a PaRAM entry can be
mapped to any channel. While in the case of dm644x and dm355 there is a fixed
mapping between the EDMA channel and Param entry number.

Signed-off-by: Naresh Medisetty <naresh@ti.com>
Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-davinci/dm646x.c |   40 ++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-davinci/dma.c    |   25 +++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index d32d2b8..5326edf 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -162,6 +162,41 @@  static struct clk arm_clk = {
 	.flags = ALWAYS_ENABLED,
 };
 
+static struct clk edma_cc_clk = {
+	.name = "edma_cc",
+	.parent = &pll1_sysclk2,
+	.lpsc = DM646X_LPSC_TPCC,
+	.flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc0_clk = {
+	.name = "edma_tc0",
+	.parent = &pll1_sysclk2,
+	.lpsc = DM646X_LPSC_TPTC0,
+	.flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc1_clk = {
+	.name = "edma_tc1",
+	.parent = &pll1_sysclk2,
+	.lpsc = DM646X_LPSC_TPTC1,
+	.flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc2_clk = {
+	.name = "edma_tc2",
+	.parent = &pll1_sysclk2,
+	.lpsc = DM646X_LPSC_TPTC2,
+	.flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc3_clk = {
+	.name = "edma_tc3",
+	.parent = &pll1_sysclk2,
+	.lpsc = DM646X_LPSC_TPTC3,
+	.flags = ALWAYS_ENABLED,
+};
+
 static struct clk uart0_clk = {
 	.name = "uart0",
 	.parent = &aux_clkin,
@@ -269,6 +304,11 @@  struct davinci_clk dm646x_clks[] = {
 	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
 	CLK(NULL, "dsp", &dsp_clk),
 	CLK(NULL, "arm", &arm_clk),
+	CLK(NULL, "edma_cc", &edma_cc_clk),
+	CLK(NULL, "edma_tc0", &edma_tc0_clk),
+	CLK(NULL, "edma_tc1", &edma_tc1_clk),
+	CLK(NULL, "edma_tc2", &edma_tc2_clk),
+	CLK(NULL, "edma_tc3", &edma_tc3_clk),
 	CLK(NULL, "uart0", &uart0_clk),
 	CLK(NULL, "uart1", &uart1_clk),
 	CLK(NULL, "uart2", &uart2_clk),
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index 50ac74f..1c60de6 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -104,6 +104,9 @@ 
 
 #define PARM_OFFSET(param_no)	(EDMA_PARM + ((param_no) << 5))
 
+#define EDMA_DCHMAP	0x0100  /* 64 registers */
+#define CHMAP_EXIST	BIT(24)
+
 #define EDMA_MAX_DMACH           64
 #define EDMA_MAX_PARAMENTRY     512
 #define EDMA_MAX_CC               2
@@ -287,6 +290,24 @@  static void __init assign_priority_to_queue(unsigned ctlr, int queue_no,
 			((priority & 0x7) << bit));
 }
 
+/**
+ * map_dmach_param - Maps channel number to param entry number
+ *
+ * This maps the dma channel number to param entry numberter. In
+ * other words using the DMA channel mapping registers a param entry
+ * can be mapped to any channel
+ *
+ * Callers are responsible for ensuring the channel mapping logic is
+ * included in that particular EDMA variant (Eg : dm646x)
+ *
+ */
+static void __init map_dmach_param(unsigned ctlr)
+{
+	int i;
+	for (i = 0; i < EDMA_MAX_DMACH; i++)
+		edma_write_array(ctlr, EDMA_DCHMAP , i , (i << 5));
+}
+
 static inline void
 setup_dma_interrupt(unsigned lch,
 	void (*callback)(unsigned channel, u16 ch_status, void *data),
@@ -1287,6 +1308,10 @@  static int __init edma_probe(struct platform_device *pdev)
 		assign_priority_to_queue(pdev->id, queue_priority_mapping[i][0],
 					 queue_priority_mapping[i][1]);
 
+	/*  Map the channel to param entry if channel mapping logic exist */
+	if (edma_read(pdev->id, EDMA_CCCFG) & CHMAP_EXIST)
+		map_dmach_param(pdev->id);
+
 	for (i = 0; i < info->n_region; i++) {
 		edma_write_array2(pdev->id, EDMA_DRAE, i, 0, 0x0);
 		edma_write_array2(pdev->id, EDMA_DRAE, i, 1, 0x0);