aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v32/mach-fs/dma.c
diff options
context:
space:
mode:
authorJesper Nilsson <jespern@stork.se.axis.com>2007-11-29 11:11:23 -0500
committerJesper Nilsson <jesper.nilsson@axis.com>2008-02-08 05:06:23 -0500
commit035e111f9a9b29843bc899f03d56f19d94bebb53 (patch)
treecb46b3c0eb6d9f2cc915522153454d3acaa7fcda /arch/cris/arch-v32/mach-fs/dma.c
parent6107c61fd3e6b47106b078db1726ad814564efef (diff)
CRIS v32: Add new machine dependent files for Etrax-FS and Artpec-3.
The two chips are somewhat different, and needs different handling. Adds handing of the dma, dram initialization, hardware settings, io, memory arbiter and pinmux Also moves the dma, dram initialization and io from CRIS v32 common files.
Diffstat (limited to 'arch/cris/arch-v32/mach-fs/dma.c')
-rw-r--r--arch/cris/arch-v32/mach-fs/dma.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/arch/cris/arch-v32/mach-fs/dma.c b/arch/cris/arch-v32/mach-fs/dma.c
new file mode 100644
index 000000000000..a6acf4e6345c
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/dma.c
@@ -0,0 +1,230 @@
1/* Wrapper for DMA channel allocator that starts clocks etc */
2
3#include <linux/kernel.h>
4#include <linux/spinlock.h>
5#include <asm/dma.h>
6#include <hwregs/reg_map.h>
7#include <hwregs/reg_rdwr.h>
8#include <hwregs/marb_defs.h>
9#include <hwregs/config_defs.h>
10#include <hwregs/strmux_defs.h>
11#include <linux/errno.h>
12#include <asm/system.h>
13#include <asm/arch/mach/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,
22 enum dma_owner owner)
23{
24 unsigned long flags;
25 reg_config_rw_clk_ctrl clk_ctrl;
26 reg_strmux_rw_cfg strmux_cfg;
27
28 if (crisv32_arbiter_allocate_bandwidth(dmanr,
29 options & DMA_INT_MEM ?
30 INT_REGION : EXT_REGION,
31 bandwidth))
32 return -ENOMEM;
33
34 spin_lock_irqsave(&dma_lock, flags);
35
36 if (used_dma_channels[dmanr]) {
37 spin_unlock_irqrestore(&dma_lock, flags);
38 if (options & DMA_VERBOSE_ON_ERROR) {
39 printk(KERN_ERR "Failed to request DMA %i for %s, "
40 "already allocated by %s\n",
41 dmanr,
42 device_id,
43 used_dma_channels_users[dmanr]);
44 }
45 if (options & DMA_PANIC_ON_ERROR)
46 panic("request_dma error!");
47 spin_unlock_irqrestore(&dma_lock, flags);
48 return -EBUSY;
49 }
50 clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
51 strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);
52
53 switch (dmanr) {
54 case 0:
55 case 1:
56 clk_ctrl.dma01_eth0 = 1;
57 break;
58 case 2:
59 case 3:
60 clk_ctrl.dma23 = 1;
61 break;
62 case 4:
63 case 5:
64 clk_ctrl.dma45 = 1;
65 break;
66 case 6:
67 case 7:
68 clk_ctrl.dma67 = 1;
69 break;
70 case 8:
71 case 9:
72 clk_ctrl.dma89_strcop = 1;
73 break;
74#if MAX_DMA_CHANNELS-1 != 9
75#error Check dma.c
76#endif
77 default:
78 spin_unlock_irqrestore(&dma_lock, flags);
79 if (options & DMA_VERBOSE_ON_ERROR) {
80 printk(KERN_ERR "Failed to request DMA %i for %s, "
81 "only 0-%i valid)\n",
82 dmanr, device_id, MAX_DMA_CHANNELS - 1);
83 }
84
85 if (options & DMA_PANIC_ON_ERROR)
86 panic("request_dma error!");
87 return -EINVAL;
88 }
89
90 switch (owner) {
91 case dma_eth0:
92 if (dmanr == 0)
93 strmux_cfg.dma0 = regk_strmux_eth0;
94 else if (dmanr == 1)
95 strmux_cfg.dma1 = regk_strmux_eth0;
96 else
97 panic("Invalid DMA channel for eth0\n");
98 break;
99 case dma_eth1:
100 if (dmanr == 6)
101 strmux_cfg.dma6 = regk_strmux_eth1;
102 else if (dmanr == 7)
103 strmux_cfg.dma7 = regk_strmux_eth1;
104 else
105 panic("Invalid DMA channel for eth1\n");
106 break;
107 case dma_iop0:
108 if (dmanr == 2)
109 strmux_cfg.dma2 = regk_strmux_iop0;
110 else if (dmanr == 3)
111 strmux_cfg.dma3 = regk_strmux_iop0;
112 else
113 panic("Invalid DMA channel for iop0\n");
114 break;
115 case dma_iop1:
116 if (dmanr == 4)
117 strmux_cfg.dma4 = regk_strmux_iop1;
118 else if (dmanr == 5)
119 strmux_cfg.dma5 = regk_strmux_iop1;
120 else
121 panic("Invalid DMA channel for iop1\n");
122 break;
123 case dma_ser0:
124 if (dmanr == 6)
125 strmux_cfg.dma6 = regk_strmux_ser0;
126 else if (dmanr == 7)
127 strmux_cfg.dma7 = regk_strmux_ser0;
128 else
129 panic("Invalid DMA channel for ser0\n");
130 break;
131 case dma_ser1:
132 if (dmanr == 4)
133 strmux_cfg.dma4 = regk_strmux_ser1;
134 else if (dmanr == 5)
135 strmux_cfg.dma5 = regk_strmux_ser1;
136 else
137 panic("Invalid DMA channel for ser1\n");
138 break;
139 case dma_ser2:
140 if (dmanr == 2)
141 strmux_cfg.dma2 = regk_strmux_ser2;
142 else if (dmanr == 3)
143 strmux_cfg.dma3 = regk_strmux_ser2;
144 else
145 panic("Invalid DMA channel for ser2\n");
146 break;
147 case dma_ser3:
148 if (dmanr == 8)
149 strmux_cfg.dma8 = regk_strmux_ser3;
150 else if (dmanr == 9)
151 strmux_cfg.dma9 = regk_strmux_ser3;
152 else
153 panic("Invalid DMA channel for ser3\n");
154 break;
155 case dma_sser0:
156 if (dmanr == 4)
157 strmux_cfg.dma4 = regk_strmux_sser0;
158 else if (dmanr == 5)
159 strmux_cfg.dma5 = regk_strmux_sser0;
160 else
161 panic("Invalid DMA channel for sser0\n");
162 break;
163 case dma_sser1:
164 if (dmanr == 6)
165 strmux_cfg.dma6 = regk_strmux_sser1;
166 else if (dmanr == 7)
167 strmux_cfg.dma7 = regk_strmux_sser1;
168 else
169 panic("Invalid DMA channel for sser1\n");
170 break;
171 case dma_ata:
172 if (dmanr == 2)
173 strmux_cfg.dma2 = regk_strmux_ata;
174 else if (dmanr == 3)
175 strmux_cfg.dma3 = regk_strmux_ata;
176 else
177 panic("Invalid DMA channel for ata\n");
178 break;
179 case dma_strp:
180 if (dmanr == 8)
181 strmux_cfg.dma8 = regk_strmux_strcop;
182 else if (dmanr == 9)
183 strmux_cfg.dma9 = regk_strmux_strcop;
184 else
185 panic("Invalid DMA channel for strp\n");
186 break;
187 case dma_ext0:
188 if (dmanr == 6)
189 strmux_cfg.dma6 = regk_strmux_ext0;
190 else
191 panic("Invalid DMA channel for ext0\n");
192 break;
193 case dma_ext1:
194 if (dmanr == 7)
195 strmux_cfg.dma7 = regk_strmux_ext1;
196 else
197 panic("Invalid DMA channel for ext1\n");
198 break;
199 case dma_ext2:
200 if (dmanr == 2)
201 strmux_cfg.dma2 = regk_strmux_ext2;
202 else if (dmanr == 8)
203 strmux_cfg.dma8 = regk_strmux_ext2;
204 else
205 panic("Invalid DMA channel for ext2\n");
206 break;
207 case dma_ext3:
208 if (dmanr == 3)
209 strmux_cfg.dma3 = regk_strmux_ext3;
210 else if (dmanr == 9)
211 strmux_cfg.dma9 = regk_strmux_ext2;
212 else
213 panic("Invalid DMA channel for ext2\n");
214 break;
215 }
216
217 used_dma_channels[dmanr] = 1;
218 used_dma_channels_users[dmanr] = device_id;
219 REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
220 REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
221 spin_unlock_irqrestore(&dma_lock, flags);
222 return 0;
223}
224
225void crisv32_free_dma(unsigned int dmanr)
226{
227 spin_lock(&dma_lock);
228 used_dma_channels[dmanr] = 0;
229 spin_unlock(&dma_lock);
230}