00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef _ASM_DMA_H
00013 #define _ASM_DMA_H
00014
00015 #include <asm/io.h>
00016
00017
00018 #ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
00019 #define outb outb_p
00020 #endif
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 #define MAX_DMA_CHANNELS 8
00075
00076
00077 #define IO_DMA1_BASE 0x00
00078 #define IO_DMA2_BASE 0xC0
00079
00080
00081 #define DMA1_CMD_REG 0x08
00082 #define DMA1_STAT_REG 0x08
00083 #define DMA1_REQ_REG 0x09
00084 #define DMA1_MASK_REG 0x0A
00085 #define DMA1_MODE_REG 0x0B
00086 #define DMA1_CLEAR_FF_REG 0x0C
00087 #define DMA1_TEMP_REG 0x0D
00088 #define DMA1_RESET_REG 0x0D
00089 #define DMA1_CLR_MASK_REG 0x0E
00090 #define DMA1_MASK_ALL_REG 0x0F
00091
00092 #define DMA2_CMD_REG 0xD0
00093 #define DMA2_STAT_REG 0xD0
00094 #define DMA2_REQ_REG 0xD2
00095 #define DMA2_MASK_REG 0xD4
00096 #define DMA2_MODE_REG 0xD6
00097 #define DMA2_CLEAR_FF_REG 0xD8
00098 #define DMA2_TEMP_REG 0xDA
00099 #define DMA2_RESET_REG 0xDA
00100 #define DMA2_CLR_MASK_REG 0xDC
00101 #define DMA2_MASK_ALL_REG 0xDE
00102
00103 #define DMA_ADDR_0 0x00
00104 #define DMA_ADDR_1 0x02
00105 #define DMA_ADDR_2 0x04
00106 #define DMA_ADDR_3 0x06
00107 #define DMA_ADDR_4 0xC0
00108 #define DMA_ADDR_5 0xC4
00109 #define DMA_ADDR_6 0xC8
00110 #define DMA_ADDR_7 0xCC
00111
00112 #define DMA_CNT_0 0x01
00113 #define DMA_CNT_1 0x03
00114 #define DMA_CNT_2 0x05
00115 #define DMA_CNT_3 0x07
00116 #define DMA_CNT_4 0xC2
00117 #define DMA_CNT_5 0xC6
00118 #define DMA_CNT_6 0xCA
00119 #define DMA_CNT_7 0xCE
00120
00121 #define DMA_PAGE_0 0x87
00122 #define DMA_PAGE_1 0x83
00123 #define DMA_PAGE_2 0x81
00124 #define DMA_PAGE_3 0x82
00125 #define DMA_PAGE_5 0x8B
00126 #define DMA_PAGE_6 0x89
00127 #define DMA_PAGE_7 0x8A
00128
00129 #define DMA_MODE_READ 0x44
00130 #define DMA_MODE_WRITE 0x48
00131 #define DMA_MODE_CASCADE 0xC0
00132
00133
00134 static __inline__ void enable_dma(unsigned int dmanr)
00135 {
00136 if (dmanr<=3)
00137 outb(dmanr, DMA1_MASK_REG);
00138 else
00139 outb(dmanr & 3, DMA2_MASK_REG);
00140 }
00141
00142 static __inline__ void disable_dma(unsigned int dmanr)
00143 {
00144 if (dmanr<=3)
00145 outb(dmanr | 4, DMA1_MASK_REG);
00146 else
00147 outb((dmanr & 3) | 4, DMA2_MASK_REG);
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 static __inline__ void clear_dma_ff(unsigned int dmanr)
00162 {
00163 if (dmanr<=3)
00164 outb(0, DMA1_CLEAR_FF_REG);
00165 else
00166 outb(0, DMA2_CLEAR_FF_REG);
00167 }
00168
00169
00170 static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
00171 {
00172 if (dmanr<=3)
00173 outb(mode | dmanr, DMA1_MODE_REG);
00174 else
00175 outb(mode | (dmanr&3), DMA2_MODE_REG);
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
00188 {
00189 switch(dmanr) {
00190 case 0:
00191 outb(pagenr, DMA_PAGE_0);
00192 break;
00193 case 1:
00194 outb(pagenr, DMA_PAGE_1);
00195 break;
00196 case 2:
00197 outb(pagenr, DMA_PAGE_2);
00198 break;
00199 case 3:
00200 outb(pagenr, DMA_PAGE_3);
00201 break;
00202 case 5:
00203 outb(pagenr & 0xfe, DMA_PAGE_5);
00204 break;
00205 case 6:
00206 outb(pagenr & 0xfe, DMA_PAGE_6);
00207 break;
00208 case 7:
00209 outb(pagenr & 0xfe, DMA_PAGE_7);
00210 break;
00211 }
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
00223 {
00224 set_dma_page(dmanr, a>>16);
00225 if (dmanr <= 3) {
00226 outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
00227 outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
00228 } else {
00229 outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
00230 outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
00231 }
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
00248 {
00249 count--;
00250 if (dmanr <= 3) {
00251 outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
00252 outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
00253 } else {
00254 outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
00255 outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
00256 }
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 static __inline__ int get_dma_residue(unsigned int dmanr)
00273 {
00274 unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
00275 : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
00276
00277
00278 unsigned short count;
00279
00280 count = 1 + inb(io_port);
00281 count += inb(io_port) << 8;
00282
00283 return (dmanr<=3)? count : (count<<1);
00284 }
00285
00286
00287
00288 extern int request_dma(unsigned int dmanr);
00289 extern void free_dma(unsigned int dmanr);
00290
00291
00292 #endif // _ASM_DMA_H