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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | #ifndef MCA_DMA_H #define MCA_DMA_H #include <asm/io.h> #include <linux/ioport.h> /* * Microchannel specific DMA stuff. DMA on an MCA machine is fairly similar to * standard PC dma, but it certainly has its quirks. DMA register addresses * are in a different place and there are some added functions. Most of this * should be pretty obvious on inspection. Note that the user must divide * count by 2 when using 16-bit dma; that is not handled by these functions. * * Ramen Noodles are yummy. * * 1998 Tymm Twillman <tymm@computer.org> */ /* * Registers that are used by the DMA controller; FN is the function register * (tell the controller what to do) and EXE is the execution register (how * to do it) */ #define MCA_DMA_REG_FN 0x18 #define MCA_DMA_REG_EXE 0x1A /* * Functions that the DMA controller can do */ #define MCA_DMA_FN_SET_IO 0x00 #define MCA_DMA_FN_SET_ADDR 0x20 #define MCA_DMA_FN_GET_ADDR 0x30 #define MCA_DMA_FN_SET_COUNT 0x40 #define MCA_DMA_FN_GET_COUNT 0x50 #define MCA_DMA_FN_GET_STATUS 0x60 #define MCA_DMA_FN_SET_MODE 0x70 #define MCA_DMA_FN_SET_ARBUS 0x80 #define MCA_DMA_FN_MASK 0x90 #define MCA_DMA_FN_RESET_MASK 0xA0 #define MCA_DMA_FN_MASTER_CLEAR 0xD0 /* * Modes (used by setting MCA_DMA_FN_MODE in the function register) * * Note that the MODE_READ is read from memory (write to device), and * MODE_WRITE is vice-versa. */ #define MCA_DMA_MODE_XFER 0x04 /* read by default */ #define MCA_DMA_MODE_READ 0x04 /* same as XFER */ #define MCA_DMA_MODE_WRITE 0x08 /* OR with MODE_XFER to use */ #define MCA_DMA_MODE_IO 0x01 /* DMA from IO register */ #define MCA_DMA_MODE_16 0x40 /* 16 bit xfers */ /** * mca_enable_dma - channel to enable DMA on * @dmanr: DMA channel * * Enable the MCA bus DMA on a channel. This can be called from * IRQ context. */ static __inline__ void mca_enable_dma(unsigned int dmanr) { outb(MCA_DMA_FN_RESET_MASK | dmanr, MCA_DMA_REG_FN); } /** * mca_disble_dma - channel to disable DMA on * @dmanr: DMA channel * * Enable the MCA bus DMA on a channel. This can be called from * IRQ context. */ static __inline__ void mca_disable_dma(unsigned int dmanr) { outb(MCA_DMA_FN_MASK | dmanr, MCA_DMA_REG_FN); } /** * mca_set_dma_addr - load a 24bit DMA address * @dmanr: DMA channel * @a: 24bit bus address * * Load the address register in the DMA controller. This has a 24bit * limitation (16Mb). */ static __inline__ void mca_set_dma_addr(unsigned int dmanr, unsigned int a) { outb(MCA_DMA_FN_SET_ADDR | dmanr, MCA_DMA_REG_FN); outb(a & 0xff, MCA_DMA_REG_EXE); outb((a >> 8) & 0xff, MCA_DMA_REG_EXE); outb((a >> 16) & 0xff, MCA_DMA_REG_EXE); } /** * mca_get_dma_addr - load a 24bit DMA address * @dmanr: DMA channel * * Read the address register in the DMA controller. This has a 24bit * limitation (16Mb). The return is a bus address. */ static __inline__ unsigned int mca_get_dma_addr(unsigned int dmanr) { unsigned int addr; outb(MCA_DMA_FN_GET_ADDR | dmanr, MCA_DMA_REG_FN); addr = inb(MCA_DMA_REG_EXE); addr |= inb(MCA_DMA_REG_EXE) << 8; addr |= inb(MCA_DMA_REG_EXE) << 16; return addr; } /** * mca_set_dma_count - load a 16bit transfer count * @dmanr: DMA channel * @count: count * * Set the DMA count for this channel. This can be up to 64Kbytes. * Setting a count of zero will not do what you expect. */ static __inline__ void mca_set_dma_count(unsigned int dmanr, unsigned int count) { count--; /* transfers one more than count -- correct for this */ outb(MCA_DMA_FN_SET_COUNT | dmanr, MCA_DMA_REG_FN); outb(count & 0xff, MCA_DMA_REG_EXE); outb((count >> 8) & 0xff, MCA_DMA_REG_EXE); } /** * mca_get_dma_residue - get the remaining bytes to transfer * @dmanr: DMA channel * * This function returns the number of bytes left to transfer * on this DMA channel. */ static __inline__ unsigned int mca_get_dma_residue(unsigned int dmanr) { unsigned short count; outb(MCA_DMA_FN_GET_COUNT | dmanr, MCA_DMA_REG_FN); count = 1 + inb(MCA_DMA_REG_EXE); count += inb(MCA_DMA_REG_EXE) << 8; return count; } /** * mca_set_dma_io - set the port for an I/O transfer * @dmanr: DMA channel * @io_addr: an I/O port number * * Unlike the ISA bus DMA controllers the DMA on MCA bus can transfer * with an I/O port target. */ static __inline__ void mca_set_dma_io(unsigned int dmanr, unsigned int io_addr) { /* * DMA from a port address -- set the io address */ outb(MCA_DMA_FN_SET_IO | dmanr, MCA_DMA_REG_FN); outb(io_addr & 0xff, MCA_DMA_REG_EXE); outb((io_addr >> 8) & 0xff, MCA_DMA_REG_EXE); } /** * mca_set_dma_mode - set the DMA mode * @dmanr: DMA channel * @mode: mode to set * * The DMA controller supports several modes. The mode values you can * set are : * * %MCA_DMA_MODE_READ when reading from the DMA device. * * %MCA_DMA_MODE_WRITE to writing to the DMA device. * * %MCA_DMA_MODE_IO to do DMA to or from an I/O port. * * %MCA_DMA_MODE_16 to do 16bit transfers. * */ static __inline__ void mca_set_dma_mode(unsigned int dmanr, unsigned int mode) { outb(MCA_DMA_FN_SET_MODE | dmanr, MCA_DMA_REG_FN); outb(mode, MCA_DMA_REG_EXE); } #endif /* MCA_DMA_H */ |