Merge branch 'avr32-arch' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoe...
[sfrench/cifs-2.6.git] / arch / mips / jazz / jazzdma.c
1 /*
2  * Mips Jazz DMA controller support
3  * Copyright (C) 1995, 1996 by Andreas Busse
4  *
5  * NOTE: Some of the argument checking could be removed when
6  * things have settled down. Also, instead of returning 0xffffffff
7  * on failure of vdma_alloc() one could leave page #0 unused
8  * and return the more usual NULL pointer as logical address.
9  */
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/errno.h>
14 #include <linux/mm.h>
15 #include <linux/bootmem.h>
16 #include <linux/spinlock.h>
17 #include <asm/mipsregs.h>
18 #include <asm/jazz.h>
19 #include <asm/io.h>
20 #include <asm/uaccess.h>
21 #include <asm/dma.h>
22 #include <asm/jazzdma.h>
23 #include <asm/pgtable.h>
24
25 /*
26  * Set this to one to enable additional vdma debug code.
27  */
28 #define CONF_DEBUG_VDMA 0
29
30 static VDMA_PGTBL_ENTRY *pgtbl;
31
32 static DEFINE_SPINLOCK(vdma_lock);
33
34 /*
35  * Debug stuff
36  */
37 #define vdma_debug     ((CONF_DEBUG_VDMA) ? debuglvl : 0)
38
39 static int debuglvl = 3;
40
41 /*
42  * Initialize the pagetable with a one-to-one mapping of
43  * the first 16 Mbytes of main memory and declare all
44  * entries to be unused. Using this method will at least
45  * allow some early device driver operations to work.
46  */
47 static inline void vdma_pgtbl_init(void)
48 {
49         unsigned long paddr = 0;
50         int i;
51
52         for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) {
53                 pgtbl[i].frame = paddr;
54                 pgtbl[i].owner = VDMA_PAGE_EMPTY;
55                 paddr += VDMA_PAGESIZE;
56         }
57 }
58
59 /*
60  * Initialize the Jazz R4030 dma controller
61  */
62 static int __init vdma_init(void)
63 {
64         /*
65          * Allocate 32k of memory for DMA page tables.  This needs to be page
66          * aligned and should be uncached to avoid cache flushing after every
67          * update.
68          */
69         pgtbl = (VDMA_PGTBL_ENTRY *)__get_free_pages(GFP_KERNEL | GFP_DMA,
70                                                     get_order(VDMA_PGTBL_SIZE));
71         BUG_ON(!pgtbl);
72         dma_cache_wback_inv((unsigned long)pgtbl, VDMA_PGTBL_SIZE);
73         pgtbl = (VDMA_PGTBL_ENTRY *)KSEG1ADDR(pgtbl);
74
75         /*
76          * Clear the R4030 translation table
77          */
78         vdma_pgtbl_init();
79
80         r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE, CPHYSADDR(pgtbl));
81         r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM, VDMA_PGTBL_SIZE);
82         r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
83
84         printk(KERN_INFO "VDMA: R4030 DMA pagetables initialized.\n");
85         return 0;
86 }
87
88 /*
89  * Allocate DMA pagetables using a simple first-fit algorithm
90  */
91 unsigned long vdma_alloc(unsigned long paddr, unsigned long size)
92 {
93         int first, last, pages, frame, i;
94         unsigned long laddr, flags;
95
96         /* check arguments */
97
98         if (paddr > 0x1fffffff) {
99                 if (vdma_debug)
100                         printk("vdma_alloc: Invalid physical address: %08lx\n",
101                                paddr);
102                 return VDMA_ERROR;      /* invalid physical address */
103         }
104         if (size > 0x400000 || size == 0) {
105                 if (vdma_debug)
106                         printk("vdma_alloc: Invalid size: %08lx\n", size);
107                 return VDMA_ERROR;      /* invalid physical address */
108         }
109
110         spin_lock_irqsave(&vdma_lock, flags);
111         /*
112          * Find free chunk
113          */
114         pages = VDMA_PAGE(paddr + size) - VDMA_PAGE(paddr) + 1;
115         first = 0;
116         while (1) {
117                 while (pgtbl[first].owner != VDMA_PAGE_EMPTY &&
118                        first < VDMA_PGTBL_ENTRIES) first++;
119                 if (first + pages > VDMA_PGTBL_ENTRIES) {       /* nothing free */
120                         spin_unlock_irqrestore(&vdma_lock, flags);
121                         return VDMA_ERROR;
122                 }
123
124                 last = first + 1;
125                 while (pgtbl[last].owner == VDMA_PAGE_EMPTY
126                        && last - first < pages)
127                         last++;
128
129                 if (last - first == pages)
130                         break;  /* found */
131                 first = last + 1;
132         }
133
134         /*
135          * Mark pages as allocated
136          */
137         laddr = (first << 12) + (paddr & (VDMA_PAGESIZE - 1));
138         frame = paddr & ~(VDMA_PAGESIZE - 1);
139
140         for (i = first; i < last; i++) {
141                 pgtbl[i].frame = frame;
142                 pgtbl[i].owner = laddr;
143                 frame += VDMA_PAGESIZE;
144         }
145
146         /*
147          * Update translation table and return logical start address
148          */
149         r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
150
151         if (vdma_debug > 1)
152                 printk("vdma_alloc: Allocated %d pages starting from %08lx\n",
153                      pages, laddr);
154
155         if (vdma_debug > 2) {
156                 printk("LADDR: ");
157                 for (i = first; i < last; i++)
158                         printk("%08x ", i << 12);
159                 printk("\nPADDR: ");
160                 for (i = first; i < last; i++)
161                         printk("%08x ", pgtbl[i].frame);
162                 printk("\nOWNER: ");
163                 for (i = first; i < last; i++)
164                         printk("%08x ", pgtbl[i].owner);
165                 printk("\n");
166         }
167
168         spin_unlock_irqrestore(&vdma_lock, flags);
169
170         return laddr;
171 }
172
173 EXPORT_SYMBOL(vdma_alloc);
174
175 /*
176  * Free previously allocated dma translation pages
177  * Note that this does NOT change the translation table,
178  * it just marks the free'd pages as unused!
179  */
180 int vdma_free(unsigned long laddr)
181 {
182         int i;
183
184         i = laddr >> 12;
185
186         if (pgtbl[i].owner != laddr) {
187                 printk
188                     ("vdma_free: trying to free other's dma pages, laddr=%8lx\n",
189                      laddr);
190                 return -1;
191         }
192
193         while (pgtbl[i].owner == laddr && i < VDMA_PGTBL_ENTRIES) {
194                 pgtbl[i].owner = VDMA_PAGE_EMPTY;
195                 i++;
196         }
197
198         if (vdma_debug > 1)
199                 printk("vdma_free: freed %ld pages starting from %08lx\n",
200                        i - (laddr >> 12), laddr);
201
202         return 0;
203 }
204
205 EXPORT_SYMBOL(vdma_free);
206
207 /*
208  * Map certain page(s) to another physical address.
209  * Caller must have allocated the page(s) before.
210  */
211 int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size)
212 {
213         int first, pages, npages;
214
215         if (laddr > 0xffffff) {
216                 if (vdma_debug)
217                         printk
218                             ("vdma_map: Invalid logical address: %08lx\n",
219                              laddr);
220                 return -EINVAL; /* invalid logical address */
221         }
222         if (paddr > 0x1fffffff) {
223                 if (vdma_debug)
224                         printk
225                             ("vdma_map: Invalid physical address: %08lx\n",
226                              paddr);
227                 return -EINVAL; /* invalid physical address */
228         }
229
230         npages = pages =
231             (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1;
232         first = laddr >> 12;
233         if (vdma_debug)
234                 printk("vdma_remap: first=%x, pages=%x\n", first, pages);
235         if (first + pages > VDMA_PGTBL_ENTRIES) {
236                 if (vdma_debug)
237                         printk("vdma_alloc: Invalid size: %08lx\n", size);
238                 return -EINVAL;
239         }
240
241         paddr &= ~(VDMA_PAGESIZE - 1);
242         while (pages > 0 && first < VDMA_PGTBL_ENTRIES) {
243                 if (pgtbl[first].owner != laddr) {
244                         if (vdma_debug)
245                                 printk("Trying to remap other's pages.\n");
246                         return -EPERM;  /* not owner */
247                 }
248                 pgtbl[first].frame = paddr;
249                 paddr += VDMA_PAGESIZE;
250                 first++;
251                 pages--;
252         }
253
254         /*
255          * Update translation table
256          */
257         r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
258
259         if (vdma_debug > 2) {
260                 int i;
261                 pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1;
262                 first = laddr >> 12;
263                 printk("LADDR: ");
264                 for (i = first; i < first + pages; i++)
265                         printk("%08x ", i << 12);
266                 printk("\nPADDR: ");
267                 for (i = first; i < first + pages; i++)
268                         printk("%08x ", pgtbl[i].frame);
269                 printk("\nOWNER: ");
270                 for (i = first; i < first + pages; i++)
271                         printk("%08x ", pgtbl[i].owner);
272                 printk("\n");
273         }
274
275         return 0;
276 }
277
278 /*
279  * Translate a physical address to a logical address.
280  * This will return the logical address of the first
281  * match.
282  */
283 unsigned long vdma_phys2log(unsigned long paddr)
284 {
285         int i;
286         int frame;
287
288         frame = paddr & ~(VDMA_PAGESIZE - 1);
289
290         for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) {
291                 if (pgtbl[i].frame == frame)
292                         break;
293         }
294
295         if (i == VDMA_PGTBL_ENTRIES)
296                 return ~0UL;
297
298         return (i << 12) + (paddr & (VDMA_PAGESIZE - 1));
299 }
300
301 EXPORT_SYMBOL(vdma_phys2log);
302
303 /*
304  * Translate a logical DMA address to a physical address
305  */
306 unsigned long vdma_log2phys(unsigned long laddr)
307 {
308         return pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE - 1));
309 }
310
311 EXPORT_SYMBOL(vdma_log2phys);
312
313 /*
314  * Print DMA statistics
315  */
316 void vdma_stats(void)
317 {
318         int i;
319
320         printk("vdma_stats: CONFIG: %08x\n",
321                r4030_read_reg32(JAZZ_R4030_CONFIG));
322         printk("R4030 translation table base: %08x\n",
323                r4030_read_reg32(JAZZ_R4030_TRSTBL_BASE));
324         printk("R4030 translation table limit: %08x\n",
325                r4030_read_reg32(JAZZ_R4030_TRSTBL_LIM));
326         printk("vdma_stats: INV_ADDR: %08x\n",
327                r4030_read_reg32(JAZZ_R4030_INV_ADDR));
328         printk("vdma_stats: R_FAIL_ADDR: %08x\n",
329                r4030_read_reg32(JAZZ_R4030_R_FAIL_ADDR));
330         printk("vdma_stats: M_FAIL_ADDR: %08x\n",
331                r4030_read_reg32(JAZZ_R4030_M_FAIL_ADDR));
332         printk("vdma_stats: IRQ_SOURCE: %08x\n",
333                r4030_read_reg32(JAZZ_R4030_IRQ_SOURCE));
334         printk("vdma_stats: I386_ERROR: %08x\n",
335                r4030_read_reg32(JAZZ_R4030_I386_ERROR));
336         printk("vdma_chnl_modes:   ");
337         for (i = 0; i < 8; i++)
338                 printk("%04x ",
339                        (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_MODE +
340                                                    (i << 5)));
341         printk("\n");
342         printk("vdma_chnl_enables: ");
343         for (i = 0; i < 8; i++)
344                 printk("%04x ",
345                        (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
346                                                    (i << 5)));
347         printk("\n");
348 }
349
350 /*
351  * DMA transfer functions
352  */
353
354 /*
355  * Enable a DMA channel. Also clear any error conditions.
356  */
357 void vdma_enable(int channel)
358 {
359         int status;
360
361         if (vdma_debug)
362                 printk("vdma_enable: channel %d\n", channel);
363
364         /*
365          * Check error conditions first
366          */
367         status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5));
368         if (status & 0x400)
369                 printk("VDMA: Channel %d: Address error!\n", channel);
370         if (status & 0x200)
371                 printk("VDMA: Channel %d: Memory error!\n", channel);
372
373         /*
374          * Clear all interrupt flags
375          */
376         r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
377                           r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
378                                            (channel << 5)) | R4030_TC_INTR
379                           | R4030_MEM_INTR | R4030_ADDR_INTR);
380
381         /*
382          * Enable the desired channel
383          */
384         r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
385                           r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
386                                            (channel << 5)) |
387                           R4030_CHNL_ENABLE);
388 }
389
390 EXPORT_SYMBOL(vdma_enable);
391
392 /*
393  * Disable a DMA channel
394  */
395 void vdma_disable(int channel)
396 {
397         if (vdma_debug) {
398                 int status =
399                     r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
400                                      (channel << 5));
401
402                 printk("vdma_disable: channel %d\n", channel);
403                 printk("VDMA: channel %d status: %04x (%s) mode: "
404                        "%02x addr: %06x count: %06x\n",
405                        channel, status,
406                        ((status & 0x600) ? "ERROR" : "OK"),
407                        (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_MODE +
408                                                    (channel << 5)),
409                        (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ADDR +
410                                                    (channel << 5)),
411                        (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_COUNT +
412                                                    (channel << 5)));
413         }
414
415         r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
416                           r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
417                                            (channel << 5)) &
418                           ~R4030_CHNL_ENABLE);
419
420         /*
421          * After disabling a DMA channel a remote bus register should be
422          * read to ensure that the current DMA acknowledge cycle is completed.
423          */
424         *((volatile unsigned int *) JAZZ_DUMMY_DEVICE);
425 }
426
427 EXPORT_SYMBOL(vdma_disable);
428
429 /*
430  * Set DMA mode. This function accepts the mode values used
431  * to set a PC-style DMA controller. For the SCSI and FDC
432  * channels, we also set the default modes each time we're
433  * called.
434  * NOTE: The FAST and BURST dma modes are supported by the
435  * R4030 Rev. 2 and PICA chipsets only. I leave them disabled
436  * for now.
437  */
438 void vdma_set_mode(int channel, int mode)
439 {
440         if (vdma_debug)
441                 printk("vdma_set_mode: channel %d, mode 0x%x\n", channel,
442                        mode);
443
444         switch (channel) {
445         case JAZZ_SCSI_DMA:     /* scsi */
446                 r4030_write_reg32(JAZZ_R4030_CHNL_MODE + (channel << 5),
447 /*                        R4030_MODE_FAST | */
448 /*                        R4030_MODE_BURST | */
449                                   R4030_MODE_INTR_EN |
450                                   R4030_MODE_WIDTH_16 |
451                                   R4030_MODE_ATIME_80);
452                 break;
453
454         case JAZZ_FLOPPY_DMA:   /* floppy */
455                 r4030_write_reg32(JAZZ_R4030_CHNL_MODE + (channel << 5),
456 /*                        R4030_MODE_FAST | */
457 /*                        R4030_MODE_BURST | */
458                                   R4030_MODE_INTR_EN |
459                                   R4030_MODE_WIDTH_8 |
460                                   R4030_MODE_ATIME_120);
461                 break;
462
463         case JAZZ_AUDIOL_DMA:
464         case JAZZ_AUDIOR_DMA:
465                 printk("VDMA: Audio DMA not supported yet.\n");
466                 break;
467
468         default:
469                 printk
470                     ("VDMA: vdma_set_mode() called with unsupported channel %d!\n",
471                      channel);
472         }
473
474         switch (mode) {
475         case DMA_MODE_READ:
476                 r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
477                                   r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
478                                                    (channel << 5)) &
479                                   ~R4030_CHNL_WRITE);
480                 break;
481
482         case DMA_MODE_WRITE:
483                 r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
484                                   r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
485                                                    (channel << 5)) |
486                                   R4030_CHNL_WRITE);
487                 break;
488
489         default:
490                 printk
491                     ("VDMA: vdma_set_mode() called with unknown dma mode 0x%x\n",
492                      mode);
493         }
494 }
495
496 EXPORT_SYMBOL(vdma_set_mode);
497
498 /*
499  * Set Transfer Address
500  */
501 void vdma_set_addr(int channel, long addr)
502 {
503         if (vdma_debug)
504                 printk("vdma_set_addr: channel %d, addr %lx\n", channel,
505                        addr);
506
507         r4030_write_reg32(JAZZ_R4030_CHNL_ADDR + (channel << 5), addr);
508 }
509
510 EXPORT_SYMBOL(vdma_set_addr);
511
512 /*
513  * Set Transfer Count
514  */
515 void vdma_set_count(int channel, int count)
516 {
517         if (vdma_debug)
518                 printk("vdma_set_count: channel %d, count %08x\n", channel,
519                        (unsigned) count);
520
521         r4030_write_reg32(JAZZ_R4030_CHNL_COUNT + (channel << 5), count);
522 }
523
524 EXPORT_SYMBOL(vdma_set_count);
525
526 /*
527  * Get Residual
528  */
529 int vdma_get_residue(int channel)
530 {
531         int residual;
532
533         residual = r4030_read_reg32(JAZZ_R4030_CHNL_COUNT + (channel << 5));
534
535         if (vdma_debug)
536                 printk("vdma_get_residual: channel %d: residual=%d\n",
537                        channel, residual);
538
539         return residual;
540 }
541
542 /*
543  * Get DMA channel enable register
544  */
545 int vdma_get_enable(int channel)
546 {
547         int enable;
548
549         enable = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5));
550
551         if (vdma_debug)
552                 printk("vdma_get_enable: channel %d: enable=%d\n", channel,
553                        enable);
554
555         return enable;
556 }
557
558 arch_initcall(vdma_init);