1/* dvma.c: Routines that are used to access DMA on the Sparc SBus. 2 * 3 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 4 */ 5 6#include <linux/string.h> 7#include <linux/kernel.h> 8#include <linux/slab.h> 9#include <linux/init.h> 10#include <linux/delay.h> 11 12#include <asm/oplib.h> 13#include <asm/io.h> 14#include <asm/dma.h> 15#include <asm/sbus.h> 16 17struct sbus_dma *dma_chain; 18 19void __init init_one_dvma(struct sbus_dma *dma, int num_dma) 20{ 21 printk("dma%d: ", num_dma); 22 23 dma->next = NULL; 24 dma->running = 0; /* No transfers going on as of yet */ 25 dma->allocated = 0; /* No one has allocated us yet */ 26 switch(sbus_readl(dma->regs + DMA_CSR)&DMA_DEVICE_ID) { 27 case DMA_VERS0: 28 dma->revision = dvmarev0; 29 printk("Revision 0 "); 30 break; 31 case DMA_ESCV1: 32 dma->revision = dvmaesc1; 33 printk("ESC Revision 1 "); 34 break; 35 case DMA_VERS1: 36 dma->revision = dvmarev1; 37 printk("Revision 1 "); 38 break; 39 case DMA_VERS2: 40 dma->revision = dvmarev2; 41 printk("Revision 2 "); 42 break; 43 case DMA_VERHME: 44 dma->revision = dvmahme; 45 printk("HME DVMA gate array "); 46 break; 47 case DMA_VERSPLUS: 48 dma->revision = dvmarevplus; 49 printk("Revision 1 PLUS "); 50 break; 51 default: 52 printk("unknown dma version %08x", 53 sbus_readl(dma->regs + DMA_CSR) & DMA_DEVICE_ID); 54 dma->allocated = 1; 55 break; 56 } 57 printk("\n"); 58} 59 60/* Probe this SBus DMA module(s) */ 61void __init dvma_init(struct sbus_bus *sbus) 62{ 63 struct sbus_dev *this_dev; 64 struct sbus_dma *dma; 65 struct sbus_dma *dchain; 66 static int num_dma = 0; 67 68 for_each_sbusdev(this_dev, sbus) { 69 char *name = this_dev->prom_name; 70 int hme = 0; 71 72 if(!strcmp(name, "SUNW,fas")) 73 hme = 1; 74 else if(strcmp(name, "dma") && 75 strcmp(name, "ledma") && 76 strcmp(name, "espdma")) 77 continue; 78 79 /* Found one... */ 80 dma = kmalloc(sizeof(struct sbus_dma), GFP_ATOMIC); 81 82 dma->sdev = this_dev; 83 84 /* Put at end of dma chain */ 85 dchain = dma_chain; 86 if(dchain) { 87 while(dchain->next) 88 dchain = dchain->next; 89 dchain->next = dma; 90 } else { 91 /* We're the first in line */ 92 dma_chain = dma; 93 } 94 95 dma->regs = sbus_ioremap(&dma->sdev->resource[0], 0, 96 dma->sdev->resource[0].end - dma->sdev->resource[0].start + 1, 97 "dma"); 98 99 dma->node = dma->sdev->prom_node; 100 101 init_one_dvma(dma, num_dma++); 102 } 103} 104 105#ifdef CONFIG_SUN4 106 107#include <asm/sun4paddr.h> 108 109void __init sun4_dvma_init(void) 110{ 111 struct sbus_dma *dma; 112 struct resource r; 113 114 if(sun4_dma_physaddr) { 115 dma = kmalloc(sizeof(struct sbus_dma), GFP_ATOMIC); 116 117 /* No SBUS */ 118 dma->sdev = NULL; 119 120 /* Only one DMA device */ 121 dma_chain = dma; 122 123 memset(&r, 0, sizeof(r)); 124 r.start = sun4_dma_physaddr; 125 dma->regs = sbus_ioremap(&r, 0, PAGE_SIZE, "dma"); 126 127 /* No prom node */ 128 dma->node = 0x0; 129 130 init_one_dvma(dma, 0); 131 } else { 132 dma_chain = NULL; 133 } 134} 135 136#endif 137