Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * BRIEF MODULE DESCRIPTION | |
3 | * Defines for using and allocating dma channels on the Alchemy | |
4 | * Au1000 mips processor. | |
5 | * | |
6 | * Copyright 2000 MontaVista Software Inc. | |
7 | * Author: MontaVista Software, Inc. | |
8 | * stevel@mvista.com or source@mvista.com | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify it | |
11 | * under the terms of the GNU General Public License as published by the | |
12 | * Free Software Foundation; either version 2 of the License, or (at your | |
13 | * option) any later version. | |
14 | * | |
15 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
16 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
17 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
18 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
21 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
25 | * | |
26 | * You should have received a copy of the GNU General Public License along | |
27 | * with this program; if not, write to the Free Software Foundation, Inc., | |
28 | * 675 Mass Ave, Cambridge, MA 02139, USA. | |
29 | * | |
30 | */ | |
31 | #ifndef __ASM_AU1000_DMA_H | |
32 | #define __ASM_AU1000_DMA_H | |
33 | ||
34 | #include <asm/io.h> /* need byte IO */ | |
35 | #include <linux/spinlock.h> /* And spinlocks */ | |
36 | #include <linux/delay.h> | |
37 | #include <asm/system.h> | |
38 | ||
39 | #define NUM_AU1000_DMA_CHANNELS 8 | |
40 | ||
41 | /* DMA Channel Base Addresses */ | |
42 | #define DMA_CHANNEL_BASE 0xB4002000 | |
43 | #define DMA_CHANNEL_LEN 0x00000100 | |
44 | ||
45 | /* DMA Channel Register Offsets */ | |
46 | #define DMA_MODE_SET 0x00000000 | |
47 | #define DMA_MODE_READ DMA_MODE_SET | |
48 | #define DMA_MODE_CLEAR 0x00000004 | |
49 | /* DMA Mode register bits follow */ | |
50 | #define DMA_DAH_MASK (0x0f << 20) | |
51 | #define DMA_DID_BIT 16 | |
52 | #define DMA_DID_MASK (0x0f << DMA_DID_BIT) | |
53 | #define DMA_DS (1<<15) | |
54 | #define DMA_BE (1<<13) | |
55 | #define DMA_DR (1<<12) | |
56 | #define DMA_TS8 (1<<11) | |
57 | #define DMA_DW_BIT 9 | |
58 | #define DMA_DW_MASK (0x03 << DMA_DW_BIT) | |
59 | #define DMA_DW8 (0 << DMA_DW_BIT) | |
60 | #define DMA_DW16 (1 << DMA_DW_BIT) | |
61 | #define DMA_DW32 (2 << DMA_DW_BIT) | |
62 | #define DMA_NC (1<<8) | |
63 | #define DMA_IE (1<<7) | |
64 | #define DMA_HALT (1<<6) | |
65 | #define DMA_GO (1<<5) | |
66 | #define DMA_AB (1<<4) | |
67 | #define DMA_D1 (1<<3) | |
68 | #define DMA_BE1 (1<<2) | |
69 | #define DMA_D0 (1<<1) | |
70 | #define DMA_BE0 (1<<0) | |
71 | ||
72 | #define DMA_PERIPHERAL_ADDR 0x00000008 | |
73 | #define DMA_BUFFER0_START 0x0000000C | |
74 | #define DMA_BUFFER1_START 0x00000014 | |
75 | #define DMA_BUFFER0_COUNT 0x00000010 | |
76 | #define DMA_BUFFER1_COUNT 0x00000018 | |
77 | #define DMA_BAH_BIT 16 | |
78 | #define DMA_BAH_MASK (0x0f << DMA_BAH_BIT) | |
79 | #define DMA_COUNT_BIT 0 | |
80 | #define DMA_COUNT_MASK (0xffff << DMA_COUNT_BIT) | |
81 | ||
82 | /* DMA Device ID's follow */ | |
83 | enum { | |
84 | DMA_ID_UART0_TX = 0, | |
85 | DMA_ID_UART0_RX, | |
86 | DMA_ID_GP04, | |
87 | DMA_ID_GP05, | |
88 | DMA_ID_AC97C_TX, | |
89 | DMA_ID_AC97C_RX, | |
90 | DMA_ID_UART3_TX, | |
91 | DMA_ID_UART3_RX, | |
92 | DMA_ID_USBDEV_EP0_RX, | |
93 | DMA_ID_USBDEV_EP0_TX, | |
94 | DMA_ID_USBDEV_EP2_TX, | |
95 | DMA_ID_USBDEV_EP3_TX, | |
96 | DMA_ID_USBDEV_EP4_RX, | |
97 | DMA_ID_USBDEV_EP5_RX, | |
98 | DMA_ID_I2S_TX, | |
99 | DMA_ID_I2S_RX, | |
100 | DMA_NUM_DEV | |
101 | }; | |
102 | ||
103 | /* DMA Device ID's for 2nd bank (AU1100) follow */ | |
104 | enum { | |
105 | DMA_ID_SD0_TX = 0, | |
106 | DMA_ID_SD0_RX, | |
107 | DMA_ID_SD1_TX, | |
108 | DMA_ID_SD1_RX, | |
109 | DMA_NUM_DEV_BANK2 | |
110 | }; | |
111 | ||
112 | struct dma_chan { | |
113 | int dev_id; // this channel is allocated if >=0, free otherwise | |
114 | unsigned int io; | |
115 | const char *dev_str; | |
116 | int irq; | |
117 | void *irq_dev; | |
118 | unsigned int fifo_addr; | |
119 | unsigned int mode; | |
120 | }; | |
121 | ||
122 | /* These are in arch/mips/au1000/common/dma.c */ | |
123 | extern struct dma_chan au1000_dma_table[]; | |
124 | extern int request_au1000_dma(int dev_id, | |
125 | const char *dev_str, | |
937a8015 | 126 | irqreturn_t (*irqhandler)(int, void *), |
1da177e4 LT |
127 | unsigned long irqflags, |
128 | void *irq_dev_id); | |
129 | extern void free_au1000_dma(unsigned int dmanr); | |
130 | extern int au1000_dma_read_proc(char *buf, char **start, off_t fpos, | |
131 | int length, int *eof, void *data); | |
132 | extern void dump_au1000_dma_channel(unsigned int dmanr); | |
133 | extern spinlock_t au1000_dma_spin_lock; | |
134 | ||
135 | ||
136 | static __inline__ struct dma_chan *get_dma_chan(unsigned int dmanr) | |
137 | { | |
138 | if (dmanr >= NUM_AU1000_DMA_CHANNELS | |
139 | || au1000_dma_table[dmanr].dev_id < 0) | |
140 | return NULL; | |
141 | return &au1000_dma_table[dmanr]; | |
142 | } | |
143 | ||
144 | static __inline__ unsigned long claim_dma_lock(void) | |
145 | { | |
146 | unsigned long flags; | |
147 | spin_lock_irqsave(&au1000_dma_spin_lock, flags); | |
148 | return flags; | |
149 | } | |
150 | ||
151 | static __inline__ void release_dma_lock(unsigned long flags) | |
152 | { | |
153 | spin_unlock_irqrestore(&au1000_dma_spin_lock, flags); | |
154 | } | |
155 | ||
156 | /* | |
157 | * Set the DMA buffer enable bits in the mode register. | |
158 | */ | |
159 | static __inline__ void enable_dma_buffer0(unsigned int dmanr) | |
160 | { | |
161 | struct dma_chan *chan = get_dma_chan(dmanr); | |
162 | if (!chan) | |
163 | return; | |
164 | au_writel(DMA_BE0, chan->io + DMA_MODE_SET); | |
165 | } | |
166 | static __inline__ void enable_dma_buffer1(unsigned int dmanr) | |
167 | { | |
168 | struct dma_chan *chan = get_dma_chan(dmanr); | |
169 | if (!chan) | |
170 | return; | |
171 | au_writel(DMA_BE1, chan->io + DMA_MODE_SET); | |
172 | } | |
173 | static __inline__ void enable_dma_buffers(unsigned int dmanr) | |
174 | { | |
175 | struct dma_chan *chan = get_dma_chan(dmanr); | |
176 | if (!chan) | |
177 | return; | |
178 | au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET); | |
179 | } | |
180 | ||
181 | static __inline__ void start_dma(unsigned int dmanr) | |
182 | { | |
183 | struct dma_chan *chan = get_dma_chan(dmanr); | |
184 | if (!chan) | |
185 | return; | |
186 | ||
187 | au_writel(DMA_GO, chan->io + DMA_MODE_SET); | |
188 | } | |
189 | ||
190 | #define DMA_HALT_POLL 0x5000 | |
191 | ||
192 | static __inline__ void halt_dma(unsigned int dmanr) | |
193 | { | |
194 | struct dma_chan *chan = get_dma_chan(dmanr); | |
195 | int i; | |
196 | if (!chan) | |
197 | return; | |
198 | ||
199 | au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR); | |
200 | // poll the halt bit | |
201 | for (i = 0; i < DMA_HALT_POLL; i++) | |
202 | if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) | |
203 | break; | |
204 | if (i == DMA_HALT_POLL) | |
205 | printk(KERN_INFO "halt_dma: HALT poll expired!\n"); | |
206 | } | |
207 | ||
208 | ||
209 | static __inline__ void disable_dma(unsigned int dmanr) | |
210 | { | |
211 | struct dma_chan *chan = get_dma_chan(dmanr); | |
212 | if (!chan) | |
213 | return; | |
214 | ||
215 | halt_dma(dmanr); | |
216 | ||
217 | // now we can disable the buffers | |
218 | au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR); | |
219 | } | |
220 | ||
221 | static __inline__ int dma_halted(unsigned int dmanr) | |
222 | { | |
223 | struct dma_chan *chan = get_dma_chan(dmanr); | |
224 | if (!chan) | |
225 | return 1; | |
226 | return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0; | |
227 | } | |
228 | ||
229 | /* initialize a DMA channel */ | |
230 | static __inline__ void init_dma(unsigned int dmanr) | |
231 | { | |
232 | struct dma_chan *chan = get_dma_chan(dmanr); | |
233 | u32 mode; | |
234 | if (!chan) | |
235 | return; | |
236 | ||
237 | disable_dma(dmanr); | |
238 | ||
239 | // set device FIFO address | |
240 | au_writel(CPHYSADDR(chan->fifo_addr), | |
241 | chan->io + DMA_PERIPHERAL_ADDR); | |
242 | ||
243 | mode = chan->mode | (chan->dev_id << DMA_DID_BIT); | |
244 | if (chan->irq) | |
245 | mode |= DMA_IE; | |
246 | ||
247 | au_writel(~mode, chan->io + DMA_MODE_CLEAR); | |
248 | au_writel(mode, chan->io + DMA_MODE_SET); | |
249 | } | |
250 | ||
251 | /* | |
252 | * set mode for a specific DMA channel | |
253 | */ | |
254 | static __inline__ void set_dma_mode(unsigned int dmanr, unsigned int mode) | |
255 | { | |
256 | struct dma_chan *chan = get_dma_chan(dmanr); | |
257 | if (!chan) | |
258 | return; | |
259 | /* | |
260 | * set_dma_mode is only allowed to change endianess, direction, | |
261 | * transfer size, device FIFO width, and coherency settings. | |
262 | * Make sure anything else is masked off. | |
263 | */ | |
264 | mode &= (DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC); | |
265 | chan->mode &= ~(DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC); | |
266 | chan->mode |= mode; | |
267 | } | |
268 | ||
269 | static __inline__ unsigned int get_dma_mode(unsigned int dmanr) | |
270 | { | |
271 | struct dma_chan *chan = get_dma_chan(dmanr); | |
272 | if (!chan) | |
273 | return 0; | |
274 | return chan->mode; | |
275 | } | |
276 | ||
277 | static __inline__ int get_dma_active_buffer(unsigned int dmanr) | |
278 | { | |
279 | struct dma_chan *chan = get_dma_chan(dmanr); | |
280 | if (!chan) | |
281 | return -1; | |
282 | return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0; | |
283 | } | |
284 | ||
285 | ||
286 | /* | |
287 | * set the device FIFO address for a specific DMA channel - only | |
288 | * applicable to GPO4 and GPO5. All the other devices have fixed | |
289 | * FIFO addresses. | |
290 | */ | |
291 | static __inline__ void set_dma_fifo_addr(unsigned int dmanr, | |
292 | unsigned int a) | |
293 | { | |
294 | struct dma_chan *chan = get_dma_chan(dmanr); | |
295 | if (!chan) | |
296 | return; | |
297 | ||
298 | if (chan->mode & DMA_DS) /* second bank of device ids */ | |
299 | return; | |
300 | ||
301 | if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05) | |
302 | return; | |
303 | ||
304 | au_writel(CPHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR); | |
305 | } | |
306 | ||
307 | /* | |
308 | * Clear the DMA buffer done bits in the mode register. | |
309 | */ | |
310 | static __inline__ void clear_dma_done0(unsigned int dmanr) | |
311 | { | |
312 | struct dma_chan *chan = get_dma_chan(dmanr); | |
313 | if (!chan) | |
314 | return; | |
315 | au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR); | |
316 | } | |
317 | static __inline__ void clear_dma_done1(unsigned int dmanr) | |
318 | { | |
319 | struct dma_chan *chan = get_dma_chan(dmanr); | |
320 | if (!chan) | |
321 | return; | |
322 | au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR); | |
323 | } | |
324 | ||
325 | /* | |
326 | * This does nothing - not applicable to Au1000 DMA. | |
327 | */ | |
328 | static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) | |
329 | { | |
330 | } | |
331 | ||
332 | /* | |
333 | * Set Buffer 0 transfer address for specific DMA channel. | |
334 | */ | |
335 | static __inline__ void set_dma_addr0(unsigned int dmanr, unsigned int a) | |
336 | { | |
337 | struct dma_chan *chan = get_dma_chan(dmanr); | |
338 | if (!chan) | |
339 | return; | |
340 | au_writel(a, chan->io + DMA_BUFFER0_START); | |
341 | } | |
342 | ||
343 | /* | |
344 | * Set Buffer 1 transfer address for specific DMA channel. | |
345 | */ | |
346 | static __inline__ void set_dma_addr1(unsigned int dmanr, unsigned int a) | |
347 | { | |
348 | struct dma_chan *chan = get_dma_chan(dmanr); | |
349 | if (!chan) | |
350 | return; | |
351 | au_writel(a, chan->io + DMA_BUFFER1_START); | |
352 | } | |
353 | ||
354 | ||
355 | /* | |
356 | * Set Buffer 0 transfer size (max 64k) for a specific DMA channel. | |
357 | */ | |
358 | static __inline__ void set_dma_count0(unsigned int dmanr, | |
359 | unsigned int count) | |
360 | { | |
361 | struct dma_chan *chan = get_dma_chan(dmanr); | |
362 | if (!chan) | |
363 | return; | |
364 | count &= DMA_COUNT_MASK; | |
365 | au_writel(count, chan->io + DMA_BUFFER0_COUNT); | |
366 | } | |
367 | ||
368 | /* | |
369 | * Set Buffer 1 transfer size (max 64k) for a specific DMA channel. | |
370 | */ | |
371 | static __inline__ void set_dma_count1(unsigned int dmanr, | |
372 | unsigned int count) | |
373 | { | |
374 | struct dma_chan *chan = get_dma_chan(dmanr); | |
375 | if (!chan) | |
376 | return; | |
377 | count &= DMA_COUNT_MASK; | |
378 | au_writel(count, chan->io + DMA_BUFFER1_COUNT); | |
379 | } | |
380 | ||
381 | /* | |
382 | * Set both buffer transfer sizes (max 64k) for a specific DMA channel. | |
383 | */ | |
384 | static __inline__ void set_dma_count(unsigned int dmanr, | |
385 | unsigned int count) | |
386 | { | |
387 | struct dma_chan *chan = get_dma_chan(dmanr); | |
388 | if (!chan) | |
389 | return; | |
390 | count &= DMA_COUNT_MASK; | |
391 | au_writel(count, chan->io + DMA_BUFFER0_COUNT); | |
392 | au_writel(count, chan->io + DMA_BUFFER1_COUNT); | |
393 | } | |
394 | ||
395 | /* | |
396 | * Returns which buffer has its done bit set in the mode register. | |
397 | * Returns -1 if neither or both done bits set. | |
398 | */ | |
399 | static __inline__ unsigned int get_dma_buffer_done(unsigned int dmanr) | |
400 | { | |
401 | struct dma_chan *chan = get_dma_chan(dmanr); | |
402 | if (!chan) | |
403 | return 0; | |
404 | ||
405 | return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1); | |
406 | } | |
407 | ||
408 | ||
409 | /* | |
410 | * Returns the DMA channel's Buffer Done IRQ number. | |
411 | */ | |
412 | static __inline__ int get_dma_done_irq(unsigned int dmanr) | |
413 | { | |
414 | struct dma_chan *chan = get_dma_chan(dmanr); | |
415 | if (!chan) | |
416 | return -1; | |
417 | ||
418 | return chan->irq; | |
419 | } | |
420 | ||
421 | /* | |
422 | * Get DMA residue count. Returns the number of _bytes_ left to transfer. | |
423 | */ | |
424 | static __inline__ int get_dma_residue(unsigned int dmanr) | |
425 | { | |
426 | int curBufCntReg, count; | |
427 | struct dma_chan *chan = get_dma_chan(dmanr); | |
428 | if (!chan) | |
429 | return 0; | |
430 | ||
431 | curBufCntReg = (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? | |
432 | DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT; | |
433 | ||
434 | count = au_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK; | |
435 | ||
436 | if ((chan->mode & DMA_DW_MASK) == DMA_DW16) | |
437 | count <<= 1; | |
438 | else if ((chan->mode & DMA_DW_MASK) == DMA_DW32) | |
439 | count <<= 2; | |
440 | ||
441 | return count; | |
442 | } | |
443 | ||
444 | #endif /* __ASM_AU1000_DMA_H */ | |
445 |