1
2
3
4
5
6
7
8#ifndef _ASM_APOLLO_DMA_H
9#define _ASM_APOLLO_DMA_H
10
11#include <asm/apollohw.h>
12#include <linux/spinlock.h>
13#include <linux/delay.h>
14
15
16#define dma_outb(val,addr) (*((volatile unsigned char *)(addr+IO_BASE)) = (val))
17#define dma_inb(addr) (*((volatile unsigned char *)(addr+IO_BASE)))
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#define MAX_DMA_CHANNELS 8
68
69#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000)
70
71
72#define IO_DMA1_BASE 0x10C00
73#define IO_DMA2_BASE 0x10D00
74
75
76#define DMA1_CMD_REG (IO_DMA1_BASE+0x08)
77#define DMA1_STAT_REG (IO_DMA1_BASE+0x08)
78#define DMA1_REQ_REG (IO_DMA1_BASE+0x09)
79#define DMA1_MASK_REG (IO_DMA1_BASE+0x0A)
80#define DMA1_MODE_REG (IO_DMA1_BASE+0x0B)
81#define DMA1_CLEAR_FF_REG (IO_DMA1_BASE+0x0C)
82#define DMA1_TEMP_REG (IO_DMA1_BASE+0x0D)
83#define DMA1_RESET_REG (IO_DMA1_BASE+0x0D)
84#define DMA1_CLR_MASK_REG (IO_DMA1_BASE+0x0E)
85#define DMA1_MASK_ALL_REG (IO_DMA1_BASE+0x0F)
86
87#define DMA2_CMD_REG (IO_DMA2_BASE+0x10)
88#define DMA2_STAT_REG (IO_DMA2_BASE+0x10)
89#define DMA2_REQ_REG (IO_DMA2_BASE+0x12)
90#define DMA2_MASK_REG (IO_DMA2_BASE+0x14)
91#define DMA2_MODE_REG (IO_DMA2_BASE+0x16)
92#define DMA2_CLEAR_FF_REG (IO_DMA2_BASE+0x18)
93#define DMA2_TEMP_REG (IO_DMA2_BASE+0x1A)
94#define DMA2_RESET_REG (IO_DMA2_BASE+0x1A)
95#define DMA2_CLR_MASK_REG (IO_DMA2_BASE+0x1C)
96#define DMA2_MASK_ALL_REG (IO_DMA2_BASE+0x1E)
97
98#define DMA_ADDR_0 (IO_DMA1_BASE+0x00)
99#define DMA_ADDR_1 (IO_DMA1_BASE+0x02)
100#define DMA_ADDR_2 (IO_DMA1_BASE+0x04)
101#define DMA_ADDR_3 (IO_DMA1_BASE+0x06)
102#define DMA_ADDR_4 (IO_DMA2_BASE+0x00)
103#define DMA_ADDR_5 (IO_DMA2_BASE+0x04)
104#define DMA_ADDR_6 (IO_DMA2_BASE+0x08)
105#define DMA_ADDR_7 (IO_DMA2_BASE+0x0C)
106
107#define DMA_CNT_0 (IO_DMA1_BASE+0x01)
108#define DMA_CNT_1 (IO_DMA1_BASE+0x03)
109#define DMA_CNT_2 (IO_DMA1_BASE+0x05)
110#define DMA_CNT_3 (IO_DMA1_BASE+0x07)
111#define DMA_CNT_4 (IO_DMA2_BASE+0x02)
112#define DMA_CNT_5 (IO_DMA2_BASE+0x06)
113#define DMA_CNT_6 (IO_DMA2_BASE+0x0A)
114#define DMA_CNT_7 (IO_DMA2_BASE+0x0E)
115
116#define DMA_MODE_READ 0x44
117#define DMA_MODE_WRITE 0x48
118#define DMA_MODE_CASCADE 0xC0
119
120#define DMA_AUTOINIT 0x10
121
122#define DMA_8BIT 0
123#define DMA_16BIT 1
124#define DMA_BUSMASTER 2
125
126extern spinlock_t dma_spin_lock;
127
128static __inline__ unsigned long claim_dma_lock(void)
129{
130 unsigned long flags;
131 spin_lock_irqsave(&dma_spin_lock, flags);
132 return flags;
133}
134
135static __inline__ void release_dma_lock(unsigned long flags)
136{
137 spin_unlock_irqrestore(&dma_spin_lock, flags);
138}
139
140
141static __inline__ void enable_dma(unsigned int dmanr)
142{
143 if (dmanr<=3)
144 dma_outb(dmanr, DMA1_MASK_REG);
145 else
146 dma_outb(dmanr & 3, DMA2_MASK_REG);
147}
148
149static __inline__ void disable_dma(unsigned int dmanr)
150{
151 if (dmanr<=3)
152 dma_outb(dmanr | 4, DMA1_MASK_REG);
153 else
154 dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
155}
156
157
158
159
160
161
162
163
164static __inline__ void clear_dma_ff(unsigned int dmanr)
165{
166 if (dmanr<=3)
167 dma_outb(0, DMA1_CLEAR_FF_REG);
168 else
169 dma_outb(0, DMA2_CLEAR_FF_REG);
170}
171
172
173static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
174{
175 if (dmanr<=3)
176 dma_outb(mode | dmanr, DMA1_MODE_REG);
177 else
178 dma_outb(mode | (dmanr&3), DMA2_MODE_REG);
179}
180
181
182
183
184static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
185{
186 if (dmanr <= 3) {
187 dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
188 dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
189 } else {
190 dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
191 dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
192 }
193}
194
195
196
197
198
199
200
201
202
203
204static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
205{
206 count--;
207 if (dmanr <= 3) {
208 dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
209 dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
210 } else {
211 dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
212 dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
213 }
214}
215
216
217
218
219
220
221
222
223
224
225static __inline__ int get_dma_residue(unsigned int dmanr)
226{
227 unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
228 : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
229
230
231 unsigned short count;
232
233 count = 1 + dma_inb(io_port);
234 count += dma_inb(io_port) << 8;
235
236 return (dmanr<=3)? count : (count<<1);
237}
238
239
240
241extern int request_dma(unsigned int dmanr, const char * device_id);
242extern void free_dma(unsigned int dmanr);
243
244
245extern unsigned short dma_map_page(unsigned long phys_addr,int count,int type);
246extern void dma_unmap_page(unsigned short dma_addr);
247
248#endif
249