]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
23680863 | 2 | /* |
3264f976 | 3 | * linux/arch/m32r/platforms/mappi3/io.c |
23680863 HT |
4 | * |
5 | * Typical I/O routines for Mappi3 board. | |
6 | * | |
7 | * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, | |
8 | * Hitoshi Yamamoto, Mamoru Sakugawa | |
9 | */ | |
10 | ||
23680863 HT |
11 | #include <asm/m32r.h> |
12 | #include <asm/page.h> | |
13 | #include <asm/io.h> | |
14 | #include <asm/byteorder.h> | |
15 | ||
16 | #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) | |
17 | #include <linux/types.h> | |
18 | ||
19 | #define M32R_PCC_IOMAP_SIZE 0x1000 | |
20 | ||
21 | #define M32R_PCC_IOSTART0 0x1000 | |
22 | #define M32R_PCC_IOEND0 (M32R_PCC_IOSTART0 + M32R_PCC_IOMAP_SIZE - 1) | |
23 | ||
24 | extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int); | |
25 | extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int); | |
26 | extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int); | |
27 | extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int); | |
28 | #endif /* CONFIG_PCMCIA && CONFIG_M32R_CFC */ | |
29 | ||
30 | #define PORT2ADDR(port) _port2addr(port) | |
31 | #define PORT2ADDR_NE(port) _port2addr_ne(port) | |
32 | #define PORT2ADDR_USB(port) _port2addr_usb(port) | |
33 | ||
34 | static inline void *_port2addr(unsigned long port) | |
35 | { | |
46ea178b | 36 | return (void *)(port | NONCACHE_OFFSET); |
23680863 HT |
37 | } |
38 | ||
ad09d583 | 39 | #if defined(CONFIG_IDE) |
23680863 HT |
40 | static inline void *__port2addr_ata(unsigned long port) |
41 | { | |
42 | static int dummy_reg; | |
43 | ||
44 | switch (port) { | |
ad09d583 | 45 | /* IDE0 CF */ |
46ea178b HT |
46 | case 0x1f0: return (void *)(0x14002000 | NONCACHE_OFFSET); |
47 | case 0x1f1: return (void *)(0x14012800 | NONCACHE_OFFSET); | |
48 | case 0x1f2: return (void *)(0x14012002 | NONCACHE_OFFSET); | |
49 | case 0x1f3: return (void *)(0x14012802 | NONCACHE_OFFSET); | |
50 | case 0x1f4: return (void *)(0x14012004 | NONCACHE_OFFSET); | |
51 | case 0x1f5: return (void *)(0x14012804 | NONCACHE_OFFSET); | |
52 | case 0x1f6: return (void *)(0x14012006 | NONCACHE_OFFSET); | |
53 | case 0x1f7: return (void *)(0x14012806 | NONCACHE_OFFSET); | |
54 | case 0x3f6: return (void *)(0x1401200e | NONCACHE_OFFSET); | |
ad09d583 | 55 | /* IDE1 IDE */ |
46ea178b HT |
56 | case 0x170: /* Data 16bit */ |
57 | return (void *)(0x14810000 | NONCACHE_OFFSET); | |
58 | case 0x171: /* Features / Error */ | |
59 | return (void *)(0x14810002 | NONCACHE_OFFSET); | |
60 | case 0x172: /* Sector count */ | |
61 | return (void *)(0x14810004 | NONCACHE_OFFSET); | |
62 | case 0x173: /* Sector number */ | |
63 | return (void *)(0x14810006 | NONCACHE_OFFSET); | |
64 | case 0x174: /* Cylinder low */ | |
65 | return (void *)(0x14810008 | NONCACHE_OFFSET); | |
66 | case 0x175: /* Cylinder high */ | |
67 | return (void *)(0x1481000a | NONCACHE_OFFSET); | |
68 | case 0x176: /* Device head */ | |
69 | return (void *)(0x1481000c | NONCACHE_OFFSET); | |
70 | case 0x177: /* Command */ | |
71 | return (void *)(0x1481000e | NONCACHE_OFFSET); | |
72 | case 0x376: /* Device control / Alt status */ | |
73 | return (void *)(0x1480800c | NONCACHE_OFFSET); | |
ad09d583 | 74 | |
23680863 HT |
75 | default: return (void *)&dummy_reg; |
76 | } | |
77 | } | |
78 | #endif | |
79 | ||
46ea178b HT |
80 | #define LAN_IOSTART (0x300 | NONCACHE_OFFSET) |
81 | #define LAN_IOEND (0x320 | NONCACHE_OFFSET) | |
23680863 HT |
82 | static inline void *_port2addr_ne(unsigned long port) |
83 | { | |
f3ac9fbf | 84 | return (void *)(port + 0x10000000); |
23680863 HT |
85 | } |
86 | ||
87 | static inline void *_port2addr_usb(unsigned long port) | |
88 | { | |
89 | return (void *)(port + NONCACHE_OFFSET + 0x12000000); | |
90 | } | |
91 | static inline void delay(void) | |
92 | { | |
93 | __asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory"); | |
94 | } | |
95 | ||
96 | /* | |
97 | * NIC I/O function | |
98 | */ | |
99 | ||
100 | static inline unsigned char _ne_inb(void *portp) | |
101 | { | |
102 | return (unsigned char) *(volatile unsigned char *)portp; | |
103 | } | |
104 | ||
105 | static inline unsigned short _ne_inw(void *portp) | |
106 | { | |
107 | return (unsigned short)le16_to_cpu(*(volatile unsigned short *)portp); | |
108 | } | |
109 | ||
110 | static inline void _ne_insb(void *portp, void * addr, unsigned long count) | |
111 | { | |
112 | unsigned char *buf = addr; | |
113 | ||
114 | while (count--) | |
115 | *buf++ = *(volatile unsigned char *)portp; | |
116 | } | |
117 | ||
118 | static inline void _ne_outb(unsigned char b, void *portp) | |
119 | { | |
120 | *(volatile unsigned char *)portp = (unsigned char)b; | |
121 | } | |
122 | ||
123 | static inline void _ne_outw(unsigned short w, void *portp) | |
124 | { | |
125 | *(volatile unsigned short *)portp = cpu_to_le16(w); | |
126 | } | |
127 | ||
128 | unsigned char _inb(unsigned long port) | |
129 | { | |
130 | if (port >= LAN_IOSTART && port < LAN_IOEND) | |
131 | return _ne_inb(PORT2ADDR_NE(port)); | |
ad09d583 HT |
132 | #if defined(CONFIG_IDE) |
133 | else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || | |
134 | ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ | |
23680863 HT |
135 | return *(volatile unsigned char *)__port2addr_ata(port); |
136 | } | |
137 | #endif | |
138 | #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) | |
139 | else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { | |
140 | unsigned char b; | |
141 | pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0); | |
142 | return b; | |
143 | } else | |
144 | #endif | |
145 | return *(volatile unsigned char *)PORT2ADDR(port); | |
146 | } | |
147 | ||
148 | unsigned short _inw(unsigned long port) | |
149 | { | |
150 | if (port >= LAN_IOSTART && port < LAN_IOEND) | |
151 | return _ne_inw(PORT2ADDR_NE(port)); | |
ad09d583 HT |
152 | #if defined(CONFIG_IDE) |
153 | else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || | |
154 | ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ | |
23680863 HT |
155 | return *(volatile unsigned short *)__port2addr_ata(port); |
156 | } | |
157 | #endif | |
158 | #if defined(CONFIG_USB) | |
159 | else if (port >= 0x340 && port < 0x3a0) | |
160 | return *(volatile unsigned short *)PORT2ADDR_USB(port); | |
161 | #endif | |
162 | ||
163 | #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) | |
164 | else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { | |
165 | unsigned short w; | |
166 | pcc_ioread_word(0, port, &w, sizeof(w), 1, 0); | |
167 | return w; | |
168 | } else | |
169 | #endif | |
170 | return *(volatile unsigned short *)PORT2ADDR(port); | |
171 | } | |
172 | ||
173 | unsigned long _inl(unsigned long port) | |
174 | { | |
175 | #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) | |
176 | if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { | |
177 | unsigned long l; | |
178 | pcc_ioread_word(0, port, &l, sizeof(l), 1, 0); | |
179 | return l; | |
180 | } else | |
181 | #endif | |
182 | return *(volatile unsigned long *)PORT2ADDR(port); | |
183 | } | |
184 | ||
185 | unsigned char _inb_p(unsigned long port) | |
186 | { | |
187 | unsigned char v = _inb(port); | |
188 | delay(); | |
189 | return (v); | |
190 | } | |
191 | ||
192 | unsigned short _inw_p(unsigned long port) | |
193 | { | |
194 | unsigned short v = _inw(port); | |
195 | delay(); | |
196 | return (v); | |
197 | } | |
198 | ||
199 | unsigned long _inl_p(unsigned long port) | |
200 | { | |
201 | unsigned long v = _inl(port); | |
202 | delay(); | |
203 | return (v); | |
204 | } | |
205 | ||
206 | void _outb(unsigned char b, unsigned long port) | |
207 | { | |
208 | if (port >= LAN_IOSTART && port < LAN_IOEND) | |
209 | _ne_outb(b, PORT2ADDR_NE(port)); | |
210 | else | |
ad09d583 HT |
211 | #if defined(CONFIG_IDE) |
212 | if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || | |
213 | ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ | |
23680863 HT |
214 | *(volatile unsigned char *)__port2addr_ata(port) = b; |
215 | } else | |
216 | #endif | |
217 | #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) | |
218 | if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { | |
219 | pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0); | |
220 | } else | |
221 | #endif | |
222 | *(volatile unsigned char *)PORT2ADDR(port) = b; | |
223 | } | |
224 | ||
225 | void _outw(unsigned short w, unsigned long port) | |
226 | { | |
227 | if (port >= LAN_IOSTART && port < LAN_IOEND) | |
228 | _ne_outw(w, PORT2ADDR_NE(port)); | |
229 | else | |
ad09d583 HT |
230 | #if defined(CONFIG_IDE) |
231 | if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || | |
232 | ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ | |
23680863 HT |
233 | *(volatile unsigned short *)__port2addr_ata(port) = w; |
234 | } else | |
235 | #endif | |
236 | #if defined(CONFIG_USB) | |
237 | if (port >= 0x340 && port < 0x3a0) | |
238 | *(volatile unsigned short *)PORT2ADDR_USB(port) = w; | |
239 | else | |
240 | #endif | |
241 | #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) | |
242 | if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { | |
243 | pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0); | |
244 | } else | |
245 | #endif | |
246 | *(volatile unsigned short *)PORT2ADDR(port) = w; | |
247 | } | |
248 | ||
249 | void _outl(unsigned long l, unsigned long port) | |
250 | { | |
251 | #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) | |
252 | if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { | |
253 | pcc_iowrite_word(0, port, &l, sizeof(l), 1, 0); | |
254 | } else | |
255 | #endif | |
256 | *(volatile unsigned long *)PORT2ADDR(port) = l; | |
257 | } | |
258 | ||
259 | void _outb_p(unsigned char b, unsigned long port) | |
260 | { | |
261 | _outb(b, port); | |
262 | delay(); | |
263 | } | |
264 | ||
265 | void _outw_p(unsigned short w, unsigned long port) | |
266 | { | |
267 | _outw(w, port); | |
268 | delay(); | |
269 | } | |
270 | ||
271 | void _outl_p(unsigned long l, unsigned long port) | |
272 | { | |
273 | _outl(l, port); | |
274 | delay(); | |
275 | } | |
276 | ||
277 | void _insb(unsigned int port, void * addr, unsigned long count) | |
278 | { | |
279 | if (port >= LAN_IOSTART && port < LAN_IOEND) | |
280 | _ne_insb(PORT2ADDR_NE(port), addr, count); | |
ad09d583 HT |
281 | #if defined(CONFIG_IDE) |
282 | else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || | |
283 | ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ | |
23680863 HT |
284 | unsigned char *buf = addr; |
285 | unsigned char *portp = __port2addr_ata(port); | |
286 | while (count--) | |
287 | *buf++ = *(volatile unsigned char *)portp; | |
288 | } | |
289 | #endif | |
290 | #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) | |
291 | else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { | |
292 | pcc_ioread_byte(0, port, (void *)addr, sizeof(unsigned char), | |
293 | count, 1); | |
294 | } | |
295 | #endif | |
296 | else { | |
297 | unsigned char *buf = addr; | |
298 | unsigned char *portp = PORT2ADDR(port); | |
299 | while (count--) | |
300 | *buf++ = *(volatile unsigned char *)portp; | |
301 | } | |
302 | } | |
303 | ||
304 | void _insw(unsigned int port, void * addr, unsigned long count) | |
305 | { | |
306 | unsigned short *buf = addr; | |
307 | unsigned short *portp; | |
308 | ||
309 | if (port >= LAN_IOSTART && port < LAN_IOEND) { | |
310 | portp = PORT2ADDR_NE(port); | |
311 | while (count--) | |
312 | *buf++ = *(volatile unsigned short *)portp; | |
313 | #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) | |
314 | } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { | |
315 | pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short), | |
316 | count, 1); | |
317 | #endif | |
ad09d583 HT |
318 | #if defined(CONFIG_IDE) |
319 | } else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || | |
320 | ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ | |
23680863 HT |
321 | portp = __port2addr_ata(port); |
322 | while (count--) | |
323 | *buf++ = *(volatile unsigned short *)portp; | |
324 | #endif | |
325 | } else { | |
326 | portp = PORT2ADDR(port); | |
327 | while (count--) | |
328 | *buf++ = *(volatile unsigned short *)portp; | |
329 | } | |
330 | } | |
331 | ||
332 | void _insl(unsigned int port, void * addr, unsigned long count) | |
333 | { | |
334 | unsigned long *buf = addr; | |
335 | unsigned long *portp; | |
336 | ||
337 | portp = PORT2ADDR(port); | |
338 | while (count--) | |
339 | *buf++ = *(volatile unsigned long *)portp; | |
340 | } | |
341 | ||
342 | void _outsb(unsigned int port, const void * addr, unsigned long count) | |
343 | { | |
344 | const unsigned char *buf = addr; | |
345 | unsigned char *portp; | |
346 | ||
347 | if (port >= LAN_IOSTART && port < LAN_IOEND) { | |
348 | portp = PORT2ADDR_NE(port); | |
349 | while (count--) | |
350 | _ne_outb(*buf++, portp); | |
ad09d583 HT |
351 | #if defined(CONFIG_IDE) |
352 | } else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || | |
353 | ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ | |
23680863 HT |
354 | portp = __port2addr_ata(port); |
355 | while (count--) | |
356 | *(volatile unsigned char *)portp = *buf++; | |
357 | #endif | |
358 | #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) | |
359 | } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { | |
360 | pcc_iowrite_byte(0, port, (void *)addr, sizeof(unsigned char), | |
361 | count, 1); | |
362 | #endif | |
363 | } else { | |
364 | portp = PORT2ADDR(port); | |
365 | while (count--) | |
366 | *(volatile unsigned char *)portp = *buf++; | |
367 | } | |
368 | } | |
369 | ||
370 | void _outsw(unsigned int port, const void * addr, unsigned long count) | |
371 | { | |
372 | const unsigned short *buf = addr; | |
373 | unsigned short *portp; | |
374 | ||
375 | if (port >= LAN_IOSTART && port < LAN_IOEND) { | |
376 | portp = PORT2ADDR_NE(port); | |
377 | while (count--) | |
378 | *(volatile unsigned short *)portp = *buf++; | |
ad09d583 HT |
379 | #if defined(CONFIG_IDE) |
380 | } else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || | |
381 | ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ | |
23680863 HT |
382 | portp = __port2addr_ata(port); |
383 | while (count--) | |
384 | *(volatile unsigned short *)portp = *buf++; | |
385 | #endif | |
386 | #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) | |
387 | } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { | |
388 | pcc_iowrite_word(9, port, (void *)addr, sizeof(unsigned short), | |
389 | count, 1); | |
390 | #endif | |
391 | } else { | |
392 | portp = PORT2ADDR(port); | |
393 | while (count--) | |
394 | *(volatile unsigned short *)portp = *buf++; | |
395 | } | |
396 | } | |
397 | ||
398 | void _outsl(unsigned int port, const void * addr, unsigned long count) | |
399 | { | |
400 | const unsigned long *buf = addr; | |
401 | unsigned char *portp; | |
402 | ||
403 | portp = PORT2ADDR(port); | |
404 | while (count--) | |
405 | *(volatile unsigned long *)portp = *buf++; | |
406 | } |