5 #define DMA_0_ADDR 0x00
6 #define DMA_0_COUNT 0x01
7 #define DMA_1_ADDR 0x02
8 #define DMA_1_COUNT 0x03
9 #define DMA_2_ADDR 0x04
10 #define DMA_2_COUNT 0x05
11 #define DMA_3_ADDR 0x06
12 #define DMA_3_COUNT 0x07
14 #define DMA_4_ADDR 0xc0
15 #define DMA_4_COUNT 0xc2
16 #define DMA_5_ADDR 0xc4
17 #define DMA_5_COUNT 0xc6
18 #define DMA_6_ADDR 0xc8
19 #define DMA_6_COUNT 0xca
20 #define DMA_7_ADDR 0xcc
21 #define DMA_7_COUNT 0xce
24 ((c < 4) ? DMA_0_ADDR + ((c) << 1) : (DMA_4_ADDR + ((c) << 2)))
25 #define DMA_COUNT(c) \
26 ((c < 4) ? DMA_0_COUNT + ((c) << 1) : (DMA_4_COUNT + ((c) << 2)))
28 #define DMA8_MASK 0x0a
29 #define DMA8_MODE 0x0b
30 #define DMA8_CLR_FLIPFLOP 0x0c
31 #define DMA8_RESET 0x0d
32 #define DMA8_MASK_RST 0x0e
33 #define DMA8_RMASK 0x0f
34 #define DMA16_MASK 0xd4
35 #define DMA16_MODE 0xd6
36 #define DMA16_CLR_FLIPFLOP 0xd8
37 #define DMA16_RESET 0xda
38 #define DMA16_MASK_RST 0xdc
39 #define DMA16_RMASK 0xde
41 #define DMA_MASK(c) ((c) < 4 ? DMA8_MASK : DMA16_MASK)
42 #define DMA_MODE(c) ((c) < 4 ? DMA8_MODE : DMA16_MODE)
43 #define DMA_CLR_FLIPFLOP(c) ((c) < 4 ? DMA8_CLR_FLIPFLOP : DMA16_CLR_FLIPFLOP)
44 #define DMA_RESET(c) ((c) < 4 ? DMA8_RESET : DMA16_RESET)
45 #define DMA_MASK_RST(c) ((c) < 4 ? DMA8_MASK_RST : DMA16_MASK_RST)
46 #define DMA_RMASK(c) ((c) < 4 ? DMA8_RMASK : DMA16_RMASK)
48 #define DMA_0_PAGE 0x87
49 #define DMA_1_PAGE 0x83
50 #define DMA_2_PAGE 0x81
51 #define DMA_3_PAGE 0x82
52 #define DMA_4_PAGE 0x8f
53 #define DMA_5_PAGE 0x8b
54 #define DMA_6_PAGE 0x89
55 #define DMA_7_PAGE 0x8a
57 #define MODE_CHAN(x) ((x) & 3)
58 #define MODE_WRITE 0x04
59 #define MODE_READ 0x08
60 #define MODE_AUTO 0x10
61 #define MODE_DECR 0x20
62 #define MODE_SINGLE 0x40
63 #define MODE_BLOCK 0x80
64 #define MODE_CASCADE 0xc0
66 #define MASK_CHAN(x) ((x) & 3)
67 #define MASK_DISABLE 0x04
69 #define RMASK_CHAN(x) (1 << ((x) & 3))
71 #define IS_16BIT(c) ((c) >= 4)
73 static void dma_io(int chan, uint32_t phyaddr, int size, unsigned int flags, unsigned int dir);
74 static inline void mask(int chan);
75 static inline void unmask(int chan);
77 static int page_port[] = {
78 DMA_0_PAGE, DMA_1_PAGE, DMA_2_PAGE, DMA_3_PAGE,
79 DMA_4_PAGE, DMA_5_PAGE, DMA_6_PAGE, DMA_7_PAGE
82 void dma_out(int chan, uint32_t phyaddr, int size, unsigned int flags)
84 dma_io(chan, phyaddr, size, flags, MODE_READ);
87 void dma_in(int chan, uint32_t phyaddr, int size, unsigned int flags)
89 dma_io(chan, phyaddr, size, flags, MODE_WRITE);
92 static void dma_io(int chan, uint32_t phyaddr, int size, unsigned int flags, unsigned int dir)
95 int addr_port, count_port;
97 addr_port = DMA_ADDR(chan);
98 count_port = DMA_COUNT(chan);
101 outportb(DMA_CLR_FLIPFLOP(chan), 0);
103 /* single / block / cascade */
104 mode = ((flags & 3) << 6) | MODE_CHAN(chan);
105 if(flags & DMA_DECR) mode |= MODE_DECR;
106 if(flags & DMA_AUTO) mode |= MODE_AUTO;
107 outportb(DMA_MODE(chan), mode);
114 outportb(addr_port, phyaddr & 0xff);
115 outportb(addr_port, (phyaddr >> 8) & 0xff);
116 outportb(page_port[chan], (phyaddr >> 16) & 0xff);
119 outportb(count_port, size & 0xff);
120 outportb(count_port, (size >> 8) & 0xff);
125 static inline void mask(int chan)
127 outportb(DMA_MASK(chan), MASK_CHAN(chan) | MASK_DISABLE);
130 static inline void unmask(int chan)
132 outportb(DMA_MASK(chan), MASK_CHAN(chan));