Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #ifndef MCA_DMA_H |
2 | #define MCA_DMA_H | |
3 | ||
4 | #include <asm/io.h> | |
5 | #include <linux/ioport.h> | |
6 | ||
7 | /* | |
8 | * Microchannel specific DMA stuff. DMA on an MCA machine is fairly similar to | |
9 | * standard PC dma, but it certainly has its quirks. DMA register addresses | |
10 | * are in a different place and there are some added functions. Most of this | |
11 | * should be pretty obvious on inspection. Note that the user must divide | |
12 | * count by 2 when using 16-bit dma; that is not handled by these functions. | |
13 | * | |
14 | * Ramen Noodles are yummy. | |
15 | * | |
16 | * 1998 Tymm Twillman <tymm@computer.org> | |
17 | */ | |
18 | ||
19 | /* | |
20 | * Registers that are used by the DMA controller; FN is the function register | |
21 | * (tell the controller what to do) and EXE is the execution register (how | |
22 | * to do it) | |
23 | */ | |
24 | ||
25 | #define MCA_DMA_REG_FN 0x18 | |
26 | #define MCA_DMA_REG_EXE 0x1A | |
27 | ||
28 | /* | |
29 | * Functions that the DMA controller can do | |
30 | */ | |
31 | ||
32 | #define MCA_DMA_FN_SET_IO 0x00 | |
33 | #define MCA_DMA_FN_SET_ADDR 0x20 | |
34 | #define MCA_DMA_FN_GET_ADDR 0x30 | |
35 | #define MCA_DMA_FN_SET_COUNT 0x40 | |
36 | #define MCA_DMA_FN_GET_COUNT 0x50 | |
37 | #define MCA_DMA_FN_GET_STATUS 0x60 | |
38 | #define MCA_DMA_FN_SET_MODE 0x70 | |
39 | #define MCA_DMA_FN_SET_ARBUS 0x80 | |
40 | #define MCA_DMA_FN_MASK 0x90 | |
41 | #define MCA_DMA_FN_RESET_MASK 0xA0 | |
42 | #define MCA_DMA_FN_MASTER_CLEAR 0xD0 | |
43 | ||
44 | /* | |
45 | * Modes (used by setting MCA_DMA_FN_MODE in the function register) | |
46 | * | |
47 | * Note that the MODE_READ is read from memory (write to device), and | |
48 | * MODE_WRITE is vice-versa. | |
49 | */ | |
50 | ||
51 | #define MCA_DMA_MODE_XFER 0x04 /* read by default */ | |
52 | #define MCA_DMA_MODE_READ 0x04 /* same as XFER */ | |
53 | #define MCA_DMA_MODE_WRITE 0x08 /* OR with MODE_XFER to use */ | |
54 | #define MCA_DMA_MODE_IO 0x01 /* DMA from IO register */ | |
55 | #define MCA_DMA_MODE_16 0x40 /* 16 bit xfers */ | |
56 | ||
57 | ||
58 | /** | |
59 | * mca_enable_dma - channel to enable DMA on | |
60 | * @dmanr: DMA channel | |
61 | * | |
62 | * Enable the MCA bus DMA on a channel. This can be called from | |
63 | * IRQ context. | |
64 | */ | |
65 | ||
66 | static __inline__ void mca_enable_dma(unsigned int dmanr) | |
67 | { | |
68 | outb(MCA_DMA_FN_RESET_MASK | dmanr, MCA_DMA_REG_FN); | |
69 | } | |
70 | ||
71 | /** | |
72 | * mca_disble_dma - channel to disable DMA on | |
73 | * @dmanr: DMA channel | |
74 | * | |
75 | * Enable the MCA bus DMA on a channel. This can be called from | |
76 | * IRQ context. | |
77 | */ | |
78 | ||
79 | static __inline__ void mca_disable_dma(unsigned int dmanr) | |
80 | { | |
81 | outb(MCA_DMA_FN_MASK | dmanr, MCA_DMA_REG_FN); | |
82 | } | |
83 | ||
84 | /** | |
85 | * mca_set_dma_addr - load a 24bit DMA address | |
86 | * @dmanr: DMA channel | |
87 | * @a: 24bit bus address | |
88 | * | |
89 | * Load the address register in the DMA controller. This has a 24bit | |
90 | * limitation (16Mb). | |
91 | */ | |
92 | ||
93 | static __inline__ void mca_set_dma_addr(unsigned int dmanr, unsigned int a) | |
94 | { | |
95 | outb(MCA_DMA_FN_SET_ADDR | dmanr, MCA_DMA_REG_FN); | |
96 | outb(a & 0xff, MCA_DMA_REG_EXE); | |
97 | outb((a >> 8) & 0xff, MCA_DMA_REG_EXE); | |
98 | outb((a >> 16) & 0xff, MCA_DMA_REG_EXE); | |
99 | } | |
100 | ||
101 | /** | |
102 | * mca_get_dma_addr - load a 24bit DMA address | |
103 | * @dmanr: DMA channel | |
104 | * | |
105 | * Read the address register in the DMA controller. This has a 24bit | |
106 | * limitation (16Mb). The return is a bus address. | |
107 | */ | |
108 | ||
109 | static __inline__ unsigned int mca_get_dma_addr(unsigned int dmanr) | |
110 | { | |
111 | unsigned int addr; | |
112 | ||
113 | outb(MCA_DMA_FN_GET_ADDR | dmanr, MCA_DMA_REG_FN); | |
114 | addr = inb(MCA_DMA_REG_EXE); | |
115 | addr |= inb(MCA_DMA_REG_EXE) << 8; | |
116 | addr |= inb(MCA_DMA_REG_EXE) << 16; | |
117 | ||
118 | return addr; | |
119 | } | |
120 | ||
121 | /** | |
122 | * mca_set_dma_count - load a 16bit transfer count | |
123 | * @dmanr: DMA channel | |
124 | * @count: count | |
125 | * | |
126 | * Set the DMA count for this channel. This can be up to 64Kbytes. | |
127 | * Setting a count of zero will not do what you expect. | |
128 | */ | |
129 | ||
130 | static __inline__ void mca_set_dma_count(unsigned int dmanr, unsigned int count) | |
131 | { | |
132 | count--; /* transfers one more than count -- correct for this */ | |
133 | ||
134 | outb(MCA_DMA_FN_SET_COUNT | dmanr, MCA_DMA_REG_FN); | |
135 | outb(count & 0xff, MCA_DMA_REG_EXE); | |
136 | outb((count >> 8) & 0xff, MCA_DMA_REG_EXE); | |
137 | } | |
138 | ||
139 | /** | |
140 | * mca_get_dma_residue - get the remaining bytes to transfer | |
141 | * @dmanr: DMA channel | |
142 | * | |
143 | * This function returns the number of bytes left to transfer | |
144 | * on this DMA channel. | |
145 | */ | |
146 | ||
147 | static __inline__ unsigned int mca_get_dma_residue(unsigned int dmanr) | |
148 | { | |
149 | unsigned short count; | |
150 | ||
151 | outb(MCA_DMA_FN_GET_COUNT | dmanr, MCA_DMA_REG_FN); | |
152 | count = 1 + inb(MCA_DMA_REG_EXE); | |
153 | count += inb(MCA_DMA_REG_EXE) << 8; | |
154 | ||
155 | return count; | |
156 | } | |
157 | ||
158 | /** | |
159 | * mca_set_dma_io - set the port for an I/O transfer | |
160 | * @dmanr: DMA channel | |
161 | * @io_addr: an I/O port number | |
162 | * | |
163 | * Unlike the ISA bus DMA controllers the DMA on MCA bus can transfer | |
164 | * with an I/O port target. | |
165 | */ | |
166 | ||
167 | static __inline__ void mca_set_dma_io(unsigned int dmanr, unsigned int io_addr) | |
168 | { | |
169 | /* | |
170 | * DMA from a port address -- set the io address | |
171 | */ | |
172 | ||
173 | outb(MCA_DMA_FN_SET_IO | dmanr, MCA_DMA_REG_FN); | |
174 | outb(io_addr & 0xff, MCA_DMA_REG_EXE); | |
175 | outb((io_addr >> 8) & 0xff, MCA_DMA_REG_EXE); | |
176 | } | |
177 | ||
178 | /** | |
179 | * mca_set_dma_mode - set the DMA mode | |
180 | * @dmanr: DMA channel | |
181 | * @mode: mode to set | |
182 | * | |
183 | * The DMA controller supports several modes. The mode values you can | |
184 | * set are : | |
185 | * | |
186 | * %MCA_DMA_MODE_READ when reading from the DMA device. | |
187 | * | |
188 | * %MCA_DMA_MODE_WRITE to writing to the DMA device. | |
189 | * | |
190 | * %MCA_DMA_MODE_IO to do DMA to or from an I/O port. | |
191 | * | |
192 | * %MCA_DMA_MODE_16 to do 16bit transfers. | |
193 | * | |
194 | */ | |
195 | ||
196 | static __inline__ void mca_set_dma_mode(unsigned int dmanr, unsigned int mode) | |
197 | { | |
198 | outb(MCA_DMA_FN_SET_MODE | dmanr, MCA_DMA_REG_FN); | |
199 | outb(mode, MCA_DMA_REG_EXE); | |
200 | } | |
201 | ||
202 | #endif /* MCA_DMA_H */ |