4 #define DMA_0_ADDR 0x00
5 #define DMA_0_COUNT 0x01
6 #define DMA_1_ADDR 0x02
7 #define DMA_1_COUNT 0x03
8 #define DMA_2_ADDR 0x04
9 #define DMA_2_COUNT 0x05
10 #define DMA_3_ADDR 0x06
11 #define DMA_3_COUNT 0x07
13 #define DMA_4_ADDR 0xc0
14 #define DMA_4_COUNT 0xc2
15 #define DMA_5_ADDR 0xc4
16 #define DMA_5_COUNT 0xc6
17 #define DMA_6_ADDR 0xc8
18 #define DMA_6_COUNT 0xca
19 #define DMA_7_ADDR 0xcc
20 #define DMA_7_COUNT 0xce
23 ((c < 4) ? DMA_0_ADDR + ((c) << 1) : (DMA_4_ADDR + ((c) << 2)))
24 #define DMA_COUNT(c) \
25 ((c < 4) ? DMA_0_COUNT + ((c) << 1) : (DMA_4_COUNT + ((c) << 2)))
27 #define DMA8_MASK 0x0a
28 #define DMA8_MODE 0x0b
29 #define DMA8_CLR_FLIPFLOP 0x0c
30 #define DMA8_RESET 0x0d
31 #define DMA8_MASK_RST 0x0e
32 #define DMA8_RMASK 0x0f
33 #define DMA16_MASK 0xd4
34 #define DMA16_MODE 0xd6
35 #define DMA16_CLR_FLIPFLOP 0xd8
36 #define DMA16_RESET 0xda
37 #define DMA16_MASK_RST 0xdc
38 #define DMA16_RMASK 0xde
40 #define DMA_MASK(c) ((c) < 4 ? DMA8_MASK : DMA16_MASK)
41 #define DMA_MODE(c) ((c) < 4 ? DMA8_MODE : DMA16_MODE)
42 #define DMA_CLR_FLIPFLOP(c) ((c) < 4 ? DMA8_CLR_FLIPFLOP : DMA16_CLR_FLIPFLOP)
43 #define DMA_RESET(c) ((c) < 4 ? DMA8_RESET : DMA16_RESET)
44 #define DMA_MASK_RST(c) ((c) < 4 ? DMA8_MASK_RST : DMA16_MASK_RST)
45 #define DMA_RMASK(c) ((c) < 4 ? DMA8_RMASK : DMA16_RMASK)
47 #define DMA_0_PAGE 0x87
48 #define DMA_1_PAGE 0x83
49 #define DMA_2_PAGE 0x81
50 #define DMA_3_PAGE 0x82
51 #define DMA_4_PAGE 0x8f
52 #define DMA_5_PAGE 0x8b
53 #define DMA_6_PAGE 0x89
54 #define DMA_7_PAGE 0x8a
56 #define MODE_CHAN(x) ((x) & 3)
57 #define MODE_WRITE 0x04
58 #define MODE_READ 0x08
59 #define MODE_AUTO 0x10
60 #define MODE_DECR 0x20
61 #define MODE_SINGLE 0x40
62 #define MODE_BLOCK 0x80
63 #define MODE_CASCADE 0xc0
65 #define MASK_CHAN(x) ((x) & 3)
66 #define MASK_DISABLE 0x04
68 #define RMASK_CHAN(x) (1 << ((x) & 3))
70 #define IS_16BIT(c) ((c) >= 4)
72 static void dma_io(int chan, uint32_t phyaddr, int size, unsigned int flags, unsigned int dir);
73 static inline void mask(int chan);
74 static inline void unmask(int chan);
76 static int page_port[] = {
77 DMA_0_PAGE, DMA_1_PAGE, DMA_2_PAGE, DMA_3_PAGE,
78 DMA_4_PAGE, DMA_5_PAGE, DMA_6_PAGE, DMA_7_PAGE
81 void dma_out(int chan, uint32_t phyaddr, int size, unsigned int flags)
83 dma_io(chan, phyaddr, size, flags, MODE_READ);
86 void dma_in(int chan, uint32_t phyaddr, int size, unsigned int flags)
88 dma_io(chan, phyaddr, size, flags, MODE_WRITE);
91 static void dma_io(int chan, uint32_t phyaddr, int size, unsigned int flags, unsigned int dir)
94 int addr_port, count_port;
96 addr_port = DMA_ADDR(chan);
97 count_port = DMA_COUNT(chan);
100 outportb(DMA_CLR_FLIPFLOP(chan), 0);
102 /* single / block / cascade */
103 mode = ((flags & 3) << 6) | MODE_CHAN(chan);
104 if(flags & DMA_DECR) mode |= MODE_DECR;
105 if(flags & DMA_AUTO) mode |= MODE_AUTO;
106 outportb(DMA_MODE(chan), mode);
113 outportb(addr_port, phyaddr & 0xff);
114 outportb(addr_port, (phyaddr >> 8) & 0xff);
115 outportb(page_port[chan], (phyaddr >> 16) & 0xff);
118 outportb(count_port, size & 0xff);
119 outportb(count_port, (size >> 8) & 0xff);
124 static inline void mask(int chan)
126 outportb(DMA_MASK(chan), MASK_CHAN(chan) | MASK_DISABLE);
129 static inline void unmask(int chan)
131 outportb(DMA_MASK(chan), MASK_CHAN(chan));