1 /* $Id: dma.h,v 1.15 1999/09/08 03:44:38 davem Exp $ 2 * include/asm-sparc64/dma.h 4 * Copyright 1996 (C) David S. Miller (davem@caip.rutgers.edu) 7 #ifndef _ASM_SPARC64_DMA_H 8 #define _ASM_SPARC64_DMA_H 10 #include <linux/config.h> 11 #include <linux/kernel.h> 12 #include <linux/types.h> 13 #include <linux/spinlock.h> 16 #include <asm/delay.h> 17 #include <asm/oplib.h> 19 extern spinlock_t dma_spin_lock
; 21 #define claim_dma_lock() \ 22 ({ unsigned long flags; \ 23 spin_lock_irqsave(&dma_spin_lock, flags); \ 27 #define release_dma_lock(__flags) \ 28 spin_unlock_irqrestore(&dma_spin_lock, __flags); 30 /* These are irrelevant for Sparc DMA, but we leave it in so that 33 #define MAX_DMA_CHANNELS 8 34 #define DMA_MODE_READ 1 35 #define DMA_MODE_WRITE 2 37 /* This is actually used. */ 38 externunsigned long phys_base
; 39 #define MAX_DMA_ADDRESS (phys_base + (0xfe000000UL) + PAGE_OFFSET) 41 /* Useful constants */ 42 #define SIZE_16MB (16*1024*1024) 43 #define SIZE_64K (64*1024) 45 /* Structure to describe the current status of DMA registers on the Sparc */ 46 struct sparc_dma_registers
{ 47 __volatile__ __u32 cond_reg
;/* DMA condition register */ 48 __volatile__ __u32 st_addr
;/* Start address of this transfer */ 49 __volatile__ __u32 cnt
;/* How many bytes to transfer */ 50 __volatile__ __u32 dma_test
;/* DMA test register */ 53 /* DVMA chip revisions */ 64 #define DMA_HASCOUNT(rev) ((rev)==dvmaesc1) 66 /* Linux DMA information structure, filled during probe. */ 67 struct Linux_SBus_DMA
{ 68 struct Linux_SBus_DMA
*next
; 69 struct linux_sbus_device
*SBus_dev
; 70 struct sparc_dma_registers
*regs
; 72 /* Status, misc info */ 73 int node
;/* Prom node for this DMA device */ 74 int running
;/* Are we doing DMA now? */ 75 int allocated
;/* Are we "owned" by anyone yet? */ 77 /* Transfer information. */ 78 unsigned int addr
;/* Start address of current transfer */ 79 int nbytes
;/* Size of current transfer */ 80 int realbytes
;/* For splitting up large transfers, etc. */ 83 enum dvma_rev revision
; 86 externstruct Linux_SBus_DMA
*dma_chain
; 88 /* Broken hardware... */ 89 #define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev1) 90 #define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1) 92 /* Main routines in dma.c */ 93 externvoiddvma_init(struct linux_sbus
*); 95 /* Fields in the cond_reg register */ 96 /* First, the version identification bits */ 97 #define DMA_DEVICE_ID 0xf0000000/* Device identification bits */ 98 #define DMA_VERS0 0x00000000/* Sunray DMA version */ 99 #define DMA_ESCV1 0x40000000/* DMA ESC Version 1 */ 100 #define DMA_VERS1 0x80000000/* DMA rev 1 */ 101 #define DMA_VERS2 0xa0000000/* DMA rev 2 */ 102 #define DMA_VERHME 0xb0000000/* DMA hme gate array */ 103 #define DMA_VERSPLUS 0x90000000/* DMA rev 1 PLUS */ 105 #define DMA_HNDL_INTR 0x00000001/* An IRQ needs to be handled */ 106 #define DMA_HNDL_ERROR 0x00000002/* We need to take an error */ 107 #define DMA_FIFO_ISDRAIN 0x0000000c/* The DMA FIFO is draining */ 108 #define DMA_INT_ENAB 0x00000010/* Turn on interrupts */ 109 #define DMA_FIFO_INV 0x00000020/* Invalidate the FIFO */ 110 #define DMA_ACC_SZ_ERR 0x00000040/* The access size was bad */ 111 #define DMA_FIFO_STDRAIN 0x00000040/* DMA_VERS1 Drain the FIFO */ 112 #define DMA_RST_SCSI 0x00000080/* Reset the SCSI controller */ 113 #define DMA_RST_ENET DMA_RST_SCSI/* Reset the ENET controller */ 114 #define DMA_ST_WRITE 0x00000100/* write from device to memory */ 115 #define DMA_ENABLE 0x00000200/* Fire up DMA, handle requests */ 116 #define DMA_PEND_READ 0x00000400/* DMA_VERS1/0/PLUS Pending Read */ 117 #define DMA_ESC_BURST 0x00000800/* 1=16byte 0=32byte */ 118 #define DMA_READ_AHEAD 0x00001800/* DMA read ahead partial longword */ 119 #define DMA_DSBL_RD_DRN 0x00001000/* No EC drain on slave reads */ 120 #define DMA_BCNT_ENAB 0x00002000/* If on, use the byte counter */ 121 #define DMA_TERM_CNTR 0x00004000/* Terminal counter */ 122 #define DMA_SCSI_SBUS64 0x00008000/* HME: Enable 64-bit SBUS mode. */ 123 #define DMA_CSR_DISAB 0x00010000/* No FIFO drains during csr */ 124 #define DMA_SCSI_DISAB 0x00020000/* No FIFO drains during reg */ 125 #define DMA_DSBL_WR_INV 0x00020000/* No EC inval. on slave writes */ 126 #define DMA_ADD_ENABLE 0x00040000/* Special ESC DVMA optimization */ 127 #define DMA_E_BURST8 0x00040000/* ENET: SBUS r/w burst size */ 128 #define DMA_BRST_SZ 0x000c0000/* SCSI: SBUS r/w burst size */ 129 #define DMA_BRST64 0x000c0000/* SCSI: 64byte bursts (HME on UltraSparc only) */ 130 #define DMA_BRST32 0x00040000/* SCSI: 32byte bursts */ 131 #define DMA_BRST16 0x00000000/* SCSI: 16byte bursts */ 132 #define DMA_BRST0 0x00080000/* SCSI: no bursts (non-HME gate arrays) */ 133 #define DMA_ADDR_DISAB 0x00100000/* No FIFO drains during addr */ 134 #define DMA_2CLKS 0x00200000/* Each transfer = 2 clock ticks */ 135 #define DMA_3CLKS 0x00400000/* Each transfer = 3 clock ticks */ 136 #define DMA_EN_ENETAUI DMA_3CLKS/* Put lance into AUI-cable mode */ 137 #define DMA_CNTR_DISAB 0x00800000/* No IRQ when DMA_TERM_CNTR set */ 138 #define DMA_AUTO_NADDR 0x01000000/* Use "auto nxt addr" feature */ 139 #define DMA_SCSI_ON 0x02000000/* Enable SCSI dma */ 140 #define DMA_PARITY_OFF 0x02000000/* HME: disable parity checking */ 141 #define DMA_LOADED_ADDR 0x04000000/* Address has been loaded */ 142 #define DMA_LOADED_NADDR 0x08000000/* Next address has been loaded */ 143 #define DMA_RESET_FAS366 0x08000000/* HME: Assert RESET to FAS366 */ 145 /* Values describing the burst-size property from the PROM */ 146 #define DMA_BURST1 0x01 147 #define DMA_BURST2 0x02 148 #define DMA_BURST4 0x04 149 #define DMA_BURST8 0x08 150 #define DMA_BURST16 0x10 151 #define DMA_BURST32 0x20 152 #define DMA_BURST64 0x40 153 #define DMA_BURSTBITS 0x7f 155 /* Determine highest possible final transfer address given a base */ 156 #define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL)) 158 /* Yes, I hack a lot of elisp in my spare time... */ 159 #define DMA_ERROR_P(regs) ((((regs)->cond_reg) & DMA_HNDL_ERROR)) 160 #define DMA_IRQ_P(regs) ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))) 161 #define DMA_WRITE_P(regs) ((((regs)->cond_reg) & DMA_ST_WRITE)) 162 #define DMA_OFF(regs) ((((regs)->cond_reg) &= (~DMA_ENABLE))) 163 #define DMA_INTSOFF(regs) ((((regs)->cond_reg) &= (~DMA_INT_ENAB))) 164 #define DMA_INTSON(regs) ((((regs)->cond_reg) |= (DMA_INT_ENAB))) 165 #define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV)) 166 #define DMA_SETSTART(regs, addr) ((((regs)->st_addr) = (char *) addr)) 167 #define DMA_BEGINDMA_W(regs) \ 168 ((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB)))) 169 #define DMA_BEGINDMA_R(regs) \ 170 ((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE))))) 172 /* For certain DMA chips, we need to disable ints upon irq entry 173 * and turn them back on when we are done. So in any ESP interrupt 174 * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT 175 * when leaving the handler. You have been warned... 177 #define DMA_IRQ_ENTRY(dma, dregs) do { \ 178 if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \ 181 #define DMA_IRQ_EXIT(dma, dregs) do { \ 182 if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \ 185 #define for_each_dvma(dma) \ 186 for((dma) = dma_chain; (dma); (dma) = (dma)->next) 188 externintget_dma_list(char*); 189 externintrequest_dma(unsigned int, __const__
char*); 190 externvoidfree_dma(unsigned int); 195 externint isa_dma_bridge_buggy
; 197 #define isa_dma_bridge_buggy (0) 200 #endif/* !(_ASM_SPARC64_DMA_H) */