2 * arch/mips/jazz/jazzdma.c
4 * Mips Jazz DMA controller support
5 * Copyright (C) 1995, 1996 by Andreas Busse
7 * NOTE: Some of the argument checking could be removed when
8 * things have settled down. Also, instead of returning 0xffffffff
9 * on failure of vdma_alloc() one could leave page #0 unused
10 * and return the more usual NULL pointer as logical address.
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
15 #include <asm/mipsregs.h>
16 #include <asm/mipsconfig.h>
19 #include <asm/uaccess.h>
21 #include <asm/jazzdma.h>
22 #include <asm/pgtable.h>
25 * Set this to one to enable additional vdma debug code.
27 #define CONF_DEBUG_VDMA 0
29 static unsigned long vdma_pagetable_start
= 0;
30 static unsigned long vdma_pagetable_end
= 0;
35 #define vdma_debug ((CONF_DEBUG_VDMA) ? debuglvl : 0)
37 static int debuglvl
= 3;
40 * Initialize the pagetable with a one-to-one mapping of
41 * the first 16 Mbytes of main memory and declare all
42 * entries to be unused. Using this method will at least
43 * allow some early device driver operations to work.
45 static inline void vdma_pgtbl_init(void)
48 unsigned long paddr
= 0;
49 VDMA_PGTBL_ENTRY
*pgtbl
= (VDMA_PGTBL_ENTRY
*)vdma_pagetable_start
;
51 for (i
=0; i
<VDMA_PGTBL_ENTRIES
; i
++)
53 pgtbl
[i
].frame
= paddr
;
54 pgtbl
[i
].owner
= VDMA_PAGE_EMPTY
;
55 paddr
+= VDMA_PAGESIZE
;
60 * Initialize the Jazz R4030 dma controller
62 unsigned long vdma_init(unsigned long memory_start
, unsigned long memory_end
)
65 * Allocate 32k of memory for DMA page tables.
66 * This needs to be page aligned and should be
67 * uncached to avoid cache flushing after every
70 vdma_pagetable_start
= KSEG1ADDR((memory_start
+ 4095) & ~4095);
71 vdma_pagetable_end
= vdma_pagetable_start
+ VDMA_PGTBL_SIZE
;
75 * Clear the R4030 translation table
79 r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE
,PHYSADDR(vdma_pagetable_start
));
80 r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM
,VDMA_PGTBL_SIZE
);
81 r4030_write_reg32(JAZZ_R4030_TRSTBL_INV
,0);
83 printk("VDMA: R4030 DMA pagetables initialized.\n");
85 return KSEG0ADDR(vdma_pagetable_end
);
89 * Allocate DMA pagetables using a simple first-fit algorithm
91 unsigned long vdma_alloc(unsigned long paddr
, unsigned long size
)
93 VDMA_PGTBL_ENTRY
*entry
= (VDMA_PGTBL_ENTRY
*)vdma_pagetable_start
;
102 /* check arguments */
104 if (paddr
> 0x1fffffff)
107 printk("vdma_alloc: Invalid physical address: %08lx\n",paddr
);
108 return VDMA_ERROR
; /* invalid physical address */
110 if (size
> 0x400000 || size
== 0)
113 printk("vdma_alloc: Invalid size: %08lx\n",size
);
114 return VDMA_ERROR
; /* invalid physical address */
117 save_and_cli (flags
);
121 pages
= (size
+ 4095) >> 12; /* no. of pages to allocate */
125 while (entry
[first
].owner
!= VDMA_PAGE_EMPTY
&&
126 first
< VDMA_PGTBL_ENTRIES
)
128 if (first
+pages
> VDMA_PGTBL_ENTRIES
) { /* nothing free */
129 restore_flags (flags
);
134 while (entry
[last
].owner
== VDMA_PAGE_EMPTY
&& last
-first
< pages
)
137 if (last
-first
== pages
)
142 * Mark pages as allocated
144 laddr
= (first
<< 12) + (paddr
& (VDMA_PAGESIZE
-1));
145 frame
= paddr
& ~(VDMA_PAGESIZE
-1);
147 for (i
=first
; i
<last
; i
++)
149 entry
[i
].frame
= frame
;
150 entry
[i
].owner
= laddr
;
151 frame
+= VDMA_PAGESIZE
;
155 * Update translation table and return logical start address
157 r4030_write_reg32(JAZZ_R4030_TRSTBL_INV
,0);
160 printk("vdma_alloc: Allocated %d pages starting from %08lx\n",
166 for (i
=first
; i
<last
; i
++)
167 printk("%08x ",i
<<12);
169 for (i
=first
; i
<last
; i
++)
170 printk("%08x ",entry
[i
].frame
);
172 for (i
=first
; i
<last
; i
++)
173 printk("%08x ",entry
[i
].owner
);
177 restore_flags(flags
);
182 * Free previously allocated dma translation pages
183 * Note that this does NOT change the translation table,
184 * it just marks the free'd pages as unused!
186 int vdma_free(unsigned long laddr
)
188 VDMA_PGTBL_ENTRY
*pgtbl
= (VDMA_PGTBL_ENTRY
*)vdma_pagetable_start
;
193 if (pgtbl
[i
].owner
!= laddr
)
195 printk("vdma_free: trying to free other's dma pages, laddr=%8lx\n",
200 while (pgtbl
[i
].owner
== laddr
&& i
< VDMA_PGTBL_ENTRIES
)
202 pgtbl
[i
].owner
= VDMA_PAGE_EMPTY
;
207 printk("vdma_free: freed %ld pages starting from %08lx\n",
208 i
-(laddr
>>12),laddr
);
214 * Map certain page(s) to another physical address.
215 * Caller must have allocated the page(s) before.
217 int vdma_remap(unsigned long laddr
, unsigned long paddr
, unsigned long size
)
219 VDMA_PGTBL_ENTRY
*pgtbl
= (VDMA_PGTBL_ENTRY
*)vdma_pagetable_start
;
220 int first
, pages
, npages
;
222 if (laddr
> 0xffffff)
225 printk("vdma_map: Invalid logical address: %08lx\n",laddr
);
226 return -EINVAL
; /* invalid logical address */
228 if (paddr
> 0x1fffffff)
231 printk("vdma_map: Invalid physical address: %08lx\n",paddr
);
232 return -EINVAL
; /* invalid physical address */
235 npages
= pages
= (((paddr
& (VDMA_PAGESIZE
-1)) + size
) >> 12) + 1;
238 printk("vdma_remap: first=%x, pages=%x\n",first
,pages
);
239 if (first
+pages
> VDMA_PGTBL_ENTRIES
)
242 printk("vdma_alloc: Invalid size: %08lx\n",size
);
246 paddr
&= ~(VDMA_PAGESIZE
-1);
247 while (pages
> 0 && first
< VDMA_PGTBL_ENTRIES
)
249 if (pgtbl
[first
].owner
!= laddr
)
252 printk("Trying to remap other's pages.\n");
253 return -EPERM
; /* not owner */
255 pgtbl
[first
].frame
= paddr
;
256 paddr
+= VDMA_PAGESIZE
;
262 * Update translation table
264 r4030_write_reg32(JAZZ_R4030_TRSTBL_INV
,0);
269 pages
= (((paddr
& (VDMA_PAGESIZE
-1)) + size
) >> 12) + 1;
272 for (i
=first
; i
<first
+pages
; i
++)
273 printk("%08x ",i
<<12);
275 for (i
=first
; i
<first
+pages
; i
++)
276 printk("%08x ",pgtbl
[i
].frame
);
278 for (i
=first
; i
<first
+pages
; i
++)
279 printk("%08x ",pgtbl
[i
].owner
);
287 * Translate a physical address to a logical address.
288 * This will return the logical address of the first
291 unsigned long vdma_phys2log(unsigned long paddr
)
295 VDMA_PGTBL_ENTRY
*pgtbl
= (VDMA_PGTBL_ENTRY
*)vdma_pagetable_start
;
297 frame
= paddr
& ~(VDMA_PAGESIZE
-1);
299 for (i
=0; i
<VDMA_PGTBL_ENTRIES
; i
++)
301 if (pgtbl
[i
].frame
== frame
)
305 if (i
== VDMA_PGTBL_ENTRIES
)
308 return (i
<<12) + (paddr
& (VDMA_PAGESIZE
-1));
312 * Translate a logical DMA address to a physical address
314 unsigned long vdma_log2phys(unsigned long laddr
)
316 VDMA_PGTBL_ENTRY
*pgtbl
= (VDMA_PGTBL_ENTRY
*)vdma_pagetable_start
;
318 return pgtbl
[laddr
>> 12].frame
+ (laddr
& (VDMA_PAGESIZE
-1));
322 * Print DMA statistics
324 void vdma_stats(void)
328 printk("vdma_stats: CONFIG: %08x\n",
329 r4030_read_reg32(JAZZ_R4030_CONFIG
));
330 printk("R4030 translation table base: %08x\n",
331 r4030_read_reg32(JAZZ_R4030_TRSTBL_BASE
));
332 printk("R4030 translation table limit: %08x\n",
333 r4030_read_reg32(JAZZ_R4030_TRSTBL_LIM
));
334 printk("vdma_stats: INV_ADDR: %08x\n",
335 r4030_read_reg32(JAZZ_R4030_INV_ADDR
));
336 printk("vdma_stats: R_FAIL_ADDR: %08x\n",
337 r4030_read_reg32(JAZZ_R4030_R_FAIL_ADDR
));
338 printk("vdma_stats: M_FAIL_ADDR: %08x\n",
339 r4030_read_reg32(JAZZ_R4030_M_FAIL_ADDR
));
340 printk("vdma_stats: IRQ_SOURCE: %08x\n",
341 r4030_read_reg32(JAZZ_R4030_IRQ_SOURCE
));
342 printk("vdma_stats: I386_ERROR: %08x\n",
343 r4030_read_reg32(JAZZ_R4030_I386_ERROR
));
344 printk("vdma_chnl_modes: ");
347 (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_MODE
+(i
<<5)));
349 printk("vdma_chnl_enables: ");
352 (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE
+(i
<<5)));
357 * DMA transfer functions
361 * Enable a DMA channel. Also clear any error conditions.
363 void vdma_enable(int channel
)
368 printk("vdma_enable: channel %d\n",channel
);
371 * Check error conditions first
373 status
= r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5));
375 printk("VDMA: Channel %d: Address error!\n",channel
);
377 printk("VDMA: Channel %d: Memory error!\n",channel
);
380 * Clear all interrupt flags
382 r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5),
383 r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5)) |
384 R4030_TC_INTR
| R4030_MEM_INTR
| R4030_ADDR_INTR
);
387 * Enable the desired channel
389 r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5),
390 r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5)) |
395 * Disable a DMA channel
397 void vdma_disable(int channel
)
401 int status
= r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5));
403 printk("vdma_disable: channel %d\n",channel
);
404 printk("VDMA: channel %d status: %04x (%s) mode: "
405 "%02x addr: %06x count: %06x\n",
406 channel
,status
,((status
& 0x600) ? "ERROR" : "OK"),
407 (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_MODE
+(channel
<<5)),
408 (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_ADDR
+(channel
<<5)),
409 (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_COUNT
+(channel
<<5)));
412 r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5),
413 r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5)) &
417 * After disabling a DMA channel a remote bus register should be
418 * read to ensure that the current DMA acknowledge cycle is completed.
420 *((volatile unsigned int *)JAZZ_DUMMY_DEVICE
);
424 * Set DMA mode. This function accepts the mode values used
425 * to set a PC-style DMA controller. For the SCSI and FDC
426 * channels, we also set the default modes each time we're
428 * NOTE: The FAST and BURST dma modes are supported by the
429 * R4030 Rev. 2 and PICA chipsets only. I leave them disabled
432 void vdma_set_mode(int channel
, int mode
)
435 printk("vdma_set_mode: channel %d, mode 0x%x\n", channel
, mode
);
439 case JAZZ_SCSI_DMA
: /* scsi */
440 r4030_write_reg32(JAZZ_R4030_CHNL_MODE
+(channel
<<5),
441 /* R4030_MODE_FAST | */
442 /* R4030_MODE_BURST | */
444 R4030_MODE_WIDTH_16
|
445 R4030_MODE_ATIME_80
);
448 case JAZZ_FLOPPY_DMA
: /* floppy */
449 r4030_write_reg32(JAZZ_R4030_CHNL_MODE
+(channel
<<5),
450 /* R4030_MODE_FAST | */
451 /* R4030_MODE_BURST | */
454 R4030_MODE_ATIME_120
);
457 case JAZZ_AUDIOL_DMA
:
458 case JAZZ_AUDIOR_DMA
:
459 printk("VDMA: Audio DMA not supported yet.\n");
463 printk("VDMA: vdma_set_mode() called with unsupported channel %d!\n",
470 r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5),
471 r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5)) &
476 r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5),
477 r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5)) |
482 printk("VDMA: vdma_set_mode() called with unknown dma mode 0x%x\n",mode
);
487 * Set Transfer Address
489 void vdma_set_addr(int channel
, long addr
)
492 printk("vdma_set_addr: channel %d, addr %lx\n",channel
,addr
);
494 r4030_write_reg32(JAZZ_R4030_CHNL_ADDR
+(channel
<<5),addr
);
500 void vdma_set_count(int channel
, int count
)
503 printk("vdma_set_count: channel %d, count %08x\n",channel
,(unsigned)count
);
505 r4030_write_reg32(JAZZ_R4030_CHNL_COUNT
+(channel
<<5),count
);
511 int vdma_get_residue(int channel
)
515 residual
= r4030_read_reg32(JAZZ_R4030_CHNL_COUNT
+(channel
<<5));
518 printk("vdma_get_residual: channel %d: residual=%d\n",channel
,residual
);
524 * Get DMA channel enable register
526 int vdma_get_enable(int channel
)
530 enable
= r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE
+(channel
<<5));
533 printk("vdma_get_enable: channel %d: enable=%d\n",channel
,enable
);