aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v32/mach-a3/dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris/arch-v32/mach-a3/dma.c')
-rw-r--r--arch/cris/arch-v32/mach-a3/dma.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/arch/cris/arch-v32/mach-a3/dma.c b/arch/cris/arch-v32/mach-a3/dma.c
new file mode 100644
index 000000000000..25f236ef0b81
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/dma.c
@@ -0,0 +1,185 @@
1/* Wrapper for DMA channel allocator that starts clocks etc */
2
3#include <linux/kernel.h>
4#include <linux/spinlock.h>
5#include <asm/arch/mach/dma.h>
6#include <hwregs/reg_map.h>
7#include <hwregs/reg_rdwr.h>
8#include <hwregs/marb_defs.h>
9#include <hwregs/clkgen_defs.h>
10#include <hwregs/strmux_defs.h>
11#include <linux/errno.h>
12#include <asm/system.h>
13#include <arbiter.h>
14
15static char used_dma_channels[MAX_DMA_CHANNELS];
16static const char *used_dma_channels_users[MAX_DMA_CHANNELS];
17
18static DEFINE_SPINLOCK(dma_lock);
19
20int crisv32_request_dma(unsigned int dmanr, const char *device_id,
21 unsigned options, unsigned int bandwidth, enum dma_owner owner)
22{
23 unsigned long flags;
24 reg_clkgen_rw_clk_ctrl clk_ctrl;
25 reg_strmux_rw_cfg strmux_cfg;
26
27 if (crisv32_arbiter_allocate_bandwidth(dmanr,
28 options & DMA_INT_MEM ? INT_REGION : EXT_REGION,
29 bandwidth))
30 return -ENOMEM;
31
32 spin_lock_irqsave(&dma_lock, flags);
33
34 if (used_dma_channels[dmanr]) {
35 spin_unlock_irqrestore(&dma_lock, flags);
36 if (options & DMA_VERBOSE_ON_ERROR)
37 printk(KERN_ERR "Failed to request DMA %i for %s, "
38 "already allocated by %s\n",
39 dmanr,
40 device_id,
41 used_dma_channels_users[dmanr]);
42
43 if (options & DMA_PANIC_ON_ERROR)
44 panic("request_dma error!");
45 spin_unlock_irqrestore(&dma_lock, flags);
46 return -EBUSY;
47 }
48 clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
49 strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);
50
51 switch (dmanr) {
52 case 0:
53 case 1:
54 clk_ctrl.dma0_1_eth = 1;
55 break;
56 case 2:
57 case 3:
58 clk_ctrl.dma2_3_strcop = 1;
59 break;
60 case 4:
61 case 5:
62 clk_ctrl.dma4_5_iop = 1;
63 break;
64 case 6:
65 case 7:
66 clk_ctrl.sser_ser_dma6_7 = 1;
67 break;
68 case 9:
69 case 11:
70 clk_ctrl.dma9_11 = 1;
71 break;
72#if MAX_DMA_CHANNELS-1 != 11
73#error Check dma.c
74#endif
75 default:
76 spin_unlock_irqrestore(&dma_lock, flags);
77 if (options & DMA_VERBOSE_ON_ERROR)
78 printk(KERN_ERR "Failed to request DMA %i for %s, "
79 "only 0-%i valid)\n",
80 dmanr, device_id, MAX_DMA_CHANNELS-1);
81
82 if (options & DMA_PANIC_ON_ERROR)
83 panic("request_dma error!");
84 return -EINVAL;
85 }
86
87 switch (owner) {
88 case dma_eth:
89 if (dmanr == 0)
90 strmux_cfg.dma0 = regk_strmux_eth;
91 else if (dmanr == 1)
92 strmux_cfg.dma1 = regk_strmux_eth;
93 else
94 panic("Invalid DMA channel for eth\n");
95 break;
96 case dma_ser0:
97 if (dmanr == 0)
98 strmux_cfg.dma0 = regk_strmux_ser0;
99 else if (dmanr == 1)
100 strmux_cfg.dma1 = regk_strmux_ser0;
101 else
102 panic("Invalid DMA channel for ser0\n");
103 break;
104 case dma_ser3:
105 if (dmanr == 2)
106 strmux_cfg.dma2 = regk_strmux_ser3;
107 else if (dmanr == 3)
108 strmux_cfg.dma3 = regk_strmux_ser3;
109 else
110 panic("Invalid DMA channel for ser3\n");
111 break;
112 case dma_strp:
113 if (dmanr == 2)
114 strmux_cfg.dma2 = regk_strmux_strcop;
115 else if (dmanr == 3)
116 strmux_cfg.dma3 = regk_strmux_strcop;
117 else
118 panic("Invalid DMA channel for strp\n");
119 break;
120 case dma_ser1:
121 if (dmanr == 4)
122 strmux_cfg.dma4 = regk_strmux_ser1;
123 else if (dmanr == 5)
124 strmux_cfg.dma5 = regk_strmux_ser1;
125 else
126 panic("Invalid DMA channel for ser1\n");
127 break;
128 case dma_iop:
129 if (dmanr == 4)
130 strmux_cfg.dma4 = regk_strmux_iop;
131 else if (dmanr == 5)
132 strmux_cfg.dma5 = regk_strmux_iop;
133 else
134 panic("Invalid DMA channel for iop\n");
135 break;
136 case dma_ser2:
137 if (dmanr == 6)
138 strmux_cfg.dma6 = regk_strmux_ser2;
139 else if (dmanr == 7)
140 strmux_cfg.dma7 = regk_strmux_ser2;
141 else
142 panic("Invalid DMA channel for ser2\n");
143 break;
144 case dma_sser:
145 if (dmanr == 6)
146 strmux_cfg.dma6 = regk_strmux_sser;
147 else if (dmanr == 7)
148 strmux_cfg.dma7 = regk_strmux_sser;
149 else
150 panic("Invalid DMA channel for sser\n");
151 break;
152 case dma_ser4:
153 if (dmanr == 9)
154 strmux_cfg.dma9 = regk_strmux_ser4;
155 else
156 panic("Invalid DMA channel for ser4\n");
157 break;
158 case dma_jpeg:
159 if (dmanr == 9)
160 strmux_cfg.dma9 = regk_strmux_jpeg;
161 else
162 panic("Invalid DMA channel for JPEG\n");
163 break;
164 case dma_h264:
165 if (dmanr == 11)
166 strmux_cfg.dma11 = regk_strmux_h264;
167 else
168 panic("Invalid DMA channel for H264\n");
169 break;
170 }
171
172 used_dma_channels[dmanr] = 1;
173 used_dma_channels_users[dmanr] = device_id;
174 REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
175 REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
176 spin_unlock_irqrestore(&dma_lock, flags);
177 return 0;
178}
179
180void crisv32_free_dma(unsigned int dmanr)
181{
182 spin_lock(&dma_lock);
183 used_dma_channels[dmanr] = 0;
184 spin_unlock(&dma_lock);
185}