Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | /* dvma.c: Routines that are used to access DMA on the Sparc SBus. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ #include <linux/kernel.h> #include <linux/malloc.h> #include <linux/init.h> #include <asm/oplib.h> #include <asm/delay.h> #include <asm/io.h> #include <asm/dma.h> #include <asm/sbus.h> struct Linux_SBus_DMA *dma_chain; /* Print out the current values in the DMA control registers */ static __inline__ void dump_dma_regs(struct sparc_dma_registers *dregs) { printk("DMA CONTROL<%08lx> ADDR<%08lx> CNT<%08lx> TEST<%08lx>\n", (unsigned long) dregs->cond_reg, (unsigned long) dregs->st_addr, (unsigned long) dregs->cnt, (unsigned long) dregs->dma_test); return; } /* Probe this SBus DMA module(s) */ __initfunc(unsigned long dvma_init(struct linux_sbus *sbus, unsigned long memory_start)) { struct linux_sbus_device *this_dev; struct Linux_SBus_DMA *dma; struct Linux_SBus_DMA *dchain; static int num_dma=0; for_each_sbusdev(this_dev, sbus) { int hme = 0; if(!strcmp(this_dev->prom_name, "SUNW,fas")) { hme = 1; } else if(strcmp(this_dev->prom_name, "dma") && strcmp(this_dev->prom_name, "ledma") && strcmp(this_dev->prom_name, "espdma")) continue; /* Found one... */ dma = (struct Linux_SBus_DMA *) memory_start; memory_start += sizeof(struct Linux_SBus_DMA); dma->SBus_dev = this_dev; /* Put at end of dma chain */ dchain = dma_chain; if(dchain) { while(dchain->next) dchain=dchain->next; dchain->next=dma; } else { /* We're the first in line */ dma_chain=dma; } dma->next = 0; printk("dma%d: ", num_dma); num_dma++; /* The constant PAGE_SIZE that is passed to sparc_alloc_io makes the * routine only alloc 1 page, that was what the original code did */ if(hme) /* On HME cards, dvma lives with esp, 2 reg sets. */ prom_apply_sbus_ranges(sbus, dma->SBus_dev->reg_addrs, 0x2, dma->SBus_dev); else /* All others have only 1 reg set. */ prom_apply_sbus_ranges(sbus, dma->SBus_dev->reg_addrs, 0x1, dma->SBus_dev); dma->regs = (struct sparc_dma_registers *) sparc_alloc_io (dma->SBus_dev->reg_addrs[0].phys_addr, 0, PAGE_SIZE, "dma", dma->SBus_dev->reg_addrs[0].which_io, 0x0); dma->node = dma->SBus_dev->prom_node; dma->running=0; /* No transfers going on as of yet */ dma->allocated=0; /* No one has allocated us yet */ switch((dma->regs->cond_reg)&DMA_DEVICE_ID) { case DMA_VERS0: dma->revision=dvmarev0; printk("Revision 0 "); break; case DMA_ESCV1: dma->revision=dvmaesc1; printk("ESC Revision 1 "); break; case DMA_VERS1: dma->revision=dvmarev1; printk("Revision 1 "); break; case DMA_VERS2: dma->revision=dvmarev2; printk("Revision 2 "); break; case DMA_VERHME: dma->revision=dvmahme; printk("HME DVMA gate array "); break; case DMA_VERSPLUS: dma->revision=dvmarevplus; printk("Revision 1 PLUS "); break; default: printk("unknown dma version %x", (dma->regs->cond_reg)&DMA_DEVICE_ID); dma->allocated = 1; break; } printk("\n"); #if 0 /* Clutters up the screen */ dump_dma_regs(dma->regs); #endif }; /* while(this_dev) */ return memory_start; } |