• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  linux/arch/m32r/platforms/m32700ut/io.c
3  *
4  *  Typical I/O routines for M32700UT board.
5  *
6  *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
7  *                           Hitoshi Yamamoto, Takeo Takahashi
8  *
9  *  This file is subject to the terms and conditions of the GNU General
10  *  Public License.  See the file "COPYING" in the main directory of this
11  *  archive for more details.
12  */
13 
14 #include <asm/m32r.h>
15 #include <asm/page.h>
16 #include <asm/io.h>
17 #include <asm/byteorder.h>
18 
19 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
20 #include <linux/types.h>
21 
22 #define M32R_PCC_IOMAP_SIZE 0x1000
23 
24 #define M32R_PCC_IOSTART0 0x1000
25 #define M32R_PCC_IOEND0   (M32R_PCC_IOSTART0 + M32R_PCC_IOMAP_SIZE - 1)
26 
27 extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int);
28 extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int);
29 extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int);
30 extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
31 #endif /* CONFIG_PCMCIA && CONFIG_M32R_CFC */
32 
33 #define PORT2ADDR(port)		_port2addr(port)
34 #define PORT2ADDR_USB(port)	_port2addr_usb(port)
35 
_port2addr(unsigned long port)36 static inline void *_port2addr(unsigned long port)
37 {
38 	return (void *)(port | NONCACHE_OFFSET);
39 }
40 
41 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
__port2addr_ata(unsigned long port)42 static inline void *__port2addr_ata(unsigned long port)
43 {
44 	static int	dummy_reg;
45 
46 	switch (port) {
47 	case 0x1f0:	return (void *)(0x0c002000 | NONCACHE_OFFSET);
48 	case 0x1f1:	return (void *)(0x0c012800 | NONCACHE_OFFSET);
49 	case 0x1f2:	return (void *)(0x0c012002 | NONCACHE_OFFSET);
50 	case 0x1f3:	return (void *)(0x0c012802 | NONCACHE_OFFSET);
51 	case 0x1f4:	return (void *)(0x0c012004 | NONCACHE_OFFSET);
52 	case 0x1f5:	return (void *)(0x0c012804 | NONCACHE_OFFSET);
53 	case 0x1f6:	return (void *)(0x0c012006 | NONCACHE_OFFSET);
54 	case 0x1f7:	return (void *)(0x0c012806 | NONCACHE_OFFSET);
55 	case 0x3f6:	return (void *)(0x0c01200e | NONCACHE_OFFSET);
56 	default: 	return (void *)&dummy_reg;
57 	}
58 }
59 #endif
60 
61 /*
62  * M32700UT-LAN is located in the extended bus space
63  * from 0x10000000 to 0x13ffffff on physical address.
64  * The base address of LAN controller(LAN91C111) is 0x300.
65  */
66 #define LAN_IOSTART	(0x300 | NONCACHE_OFFSET)
67 #define LAN_IOEND	(0x320 | NONCACHE_OFFSET)
_port2addr_ne(unsigned long port)68 static inline void *_port2addr_ne(unsigned long port)
69 {
70 	return (void *)(port + 0x10000000);
71 }
_port2addr_usb(unsigned long port)72 static inline void *_port2addr_usb(unsigned long port)
73 {
74 	return (void *)((port & 0x0f) + NONCACHE_OFFSET + 0x10303000);
75 }
76 
delay(void)77 static inline void delay(void)
78 {
79 	__asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory");
80 }
81 
82 /*
83  * NIC I/O function
84  */
85 
86 #define PORT2ADDR_NE(port)  _port2addr_ne(port)
87 
_ne_inb(void * portp)88 static inline unsigned char _ne_inb(void *portp)
89 {
90 	return *(volatile unsigned char *)portp;
91 }
92 
_ne_inw(void * portp)93 static inline unsigned short _ne_inw(void *portp)
94 {
95 	return (unsigned short)le16_to_cpu(*(volatile unsigned short *)portp);
96 }
97 
_ne_insb(void * portp,void * addr,unsigned long count)98 static inline void _ne_insb(void *portp, void *addr, unsigned long count)
99 {
100 	unsigned char *buf = (unsigned char *)addr;
101 
102 	while (count--)
103 		*buf++ = _ne_inb(portp);
104 }
105 
_ne_outb(unsigned char b,void * portp)106 static inline void _ne_outb(unsigned char b, void *portp)
107 {
108 	*(volatile unsigned char *)portp = b;
109 }
110 
_ne_outw(unsigned short w,void * portp)111 static inline void _ne_outw(unsigned short w, void *portp)
112 {
113 	*(volatile unsigned short *)portp = cpu_to_le16(w);
114 }
115 
_inb(unsigned long port)116 unsigned char _inb(unsigned long port)
117 {
118 	if (port >= LAN_IOSTART && port < LAN_IOEND)
119 		return _ne_inb(PORT2ADDR_NE(port));
120 
121 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
122 	else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
123 		return *(volatile unsigned char *)__port2addr_ata(port);
124 	}
125 #endif
126 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
127 	else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
128 		unsigned char b;
129 		pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0);
130 		return b;
131 	} else
132 #endif
133 
134 	return *(volatile unsigned char *)PORT2ADDR(port);
135 }
136 
_inw(unsigned long port)137 unsigned short _inw(unsigned long port)
138 {
139 	if (port >= LAN_IOSTART && port < LAN_IOEND)
140 		return _ne_inw(PORT2ADDR_NE(port));
141 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
142 	else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
143 		return *(volatile unsigned short *)__port2addr_ata(port);
144 	}
145 #endif
146 #if defined(CONFIG_USB)
147 	else if(port >= 0x340 && port < 0x3a0)
148 		return *(volatile unsigned short *)PORT2ADDR_USB(port);
149 #endif
150 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
151 	else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
152 		unsigned short w;
153 		pcc_ioread_word(0, port, &w, sizeof(w), 1, 0);
154 		return w;
155 	} else
156 #endif
157 	return *(volatile unsigned short *)PORT2ADDR(port);
158 }
159 
_inl(unsigned long port)160 unsigned long _inl(unsigned long port)
161 {
162 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
163 	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
164 		unsigned long l;
165 		pcc_ioread_word(0, port, &l, sizeof(l), 1, 0);
166 		return l;
167 	} else
168 #endif
169 	return *(volatile unsigned long *)PORT2ADDR(port);
170 }
171 
_inb_p(unsigned long port)172 unsigned char _inb_p(unsigned long port)
173 {
174 	unsigned char v = _inb(port);
175 	delay();
176 	return (v);
177 }
178 
_inw_p(unsigned long port)179 unsigned short _inw_p(unsigned long port)
180 {
181 	unsigned short v = _inw(port);
182 	delay();
183 	return (v);
184 }
185 
_inl_p(unsigned long port)186 unsigned long _inl_p(unsigned long port)
187 {
188 	unsigned long v = _inl(port);
189 	delay();
190 	return (v);
191 }
192 
_outb(unsigned char b,unsigned long port)193 void _outb(unsigned char b, unsigned long port)
194 {
195 	if (port >= LAN_IOSTART && port < LAN_IOEND)
196 		_ne_outb(b, PORT2ADDR_NE(port));
197 	else
198 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
199 	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
200 		*(volatile unsigned char *)__port2addr_ata(port) = b;
201 	} else
202 #endif
203 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
204 	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
205 		pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0);
206 	} else
207 #endif
208 		*(volatile unsigned char *)PORT2ADDR(port) = b;
209 }
210 
_outw(unsigned short w,unsigned long port)211 void _outw(unsigned short w, unsigned long port)
212 {
213 	if (port >= LAN_IOSTART && port < LAN_IOEND)
214 		_ne_outw(w, PORT2ADDR_NE(port));
215 	else
216 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
217 	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
218 		*(volatile unsigned short *)__port2addr_ata(port) = w;
219 	} else
220 #endif
221 #if defined(CONFIG_USB)
222 	if(port >= 0x340 && port < 0x3a0)
223 		*(volatile unsigned short *)PORT2ADDR_USB(port) = w;
224 	else
225 #endif
226 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
227 	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
228 		pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0);
229 	} else
230 #endif
231 		*(volatile unsigned short *)PORT2ADDR(port) = w;
232 }
233 
_outl(unsigned long l,unsigned long port)234 void _outl(unsigned long l, unsigned long port)
235 {
236 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
237 	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
238 		pcc_iowrite_word(0, port, &l, sizeof(l), 1, 0);
239 	} else
240 #endif
241 	*(volatile unsigned long *)PORT2ADDR(port) = l;
242 }
243 
_outb_p(unsigned char b,unsigned long port)244 void _outb_p(unsigned char b, unsigned long port)
245 {
246 	_outb(b, port);
247 	delay();
248 }
249 
_outw_p(unsigned short w,unsigned long port)250 void _outw_p(unsigned short w, unsigned long port)
251 {
252 	_outw(w, port);
253 	delay();
254 }
255 
_outl_p(unsigned long l,unsigned long port)256 void _outl_p(unsigned long l, unsigned long port)
257 {
258 	_outl(l, port);
259 	delay();
260 }
261 
_insb(unsigned int port,void * addr,unsigned long count)262 void _insb(unsigned int port, void *addr, unsigned long count)
263 {
264 	if (port >= LAN_IOSTART && port < LAN_IOEND)
265 		_ne_insb(PORT2ADDR_NE(port), addr, count);
266 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
267 	else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
268 		unsigned char *buf = addr;
269 		unsigned char *portp = __port2addr_ata(port);
270 		while (count--)
271 			*buf++ = *(volatile unsigned char *)portp;
272 	}
273 #endif
274 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
275 	else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
276 		pcc_ioread_byte(0, port, (void *)addr, sizeof(unsigned char),
277 				count, 1);
278 	}
279 #endif
280 	else {
281 		unsigned char *buf = addr;
282 		unsigned char *portp = PORT2ADDR(port);
283 		while (count--)
284 			*buf++ = *(volatile unsigned char *)portp;
285 	}
286 }
287 
_insw(unsigned int port,void * addr,unsigned long count)288 void _insw(unsigned int port, void *addr, unsigned long count)
289 {
290 	unsigned short *buf = addr;
291 	unsigned short *portp;
292 
293 	if (port >= LAN_IOSTART && port < LAN_IOEND) {
294 		/*
295 		 * This portion is only used by smc91111.c to read data
296 		 * from the DATA_REG. Do not swap the data.
297 		 */
298 		portp = PORT2ADDR_NE(port);
299 		while (count--)
300 			*buf++ = *(volatile unsigned short *)portp;
301 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
302 	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
303 		pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short),
304 				count, 1);
305 #endif
306 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
307 	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
308 		portp = __port2addr_ata(port);
309 		while (count--)
310 			*buf++ = *(volatile unsigned short *)portp;
311 #endif
312 	} else {
313 		portp = PORT2ADDR(port);
314 		while (count--)
315 			*buf++ = *(volatile unsigned short *)portp;
316 	}
317 }
318 
_insl(unsigned int port,void * addr,unsigned long count)319 void _insl(unsigned int port, void *addr, unsigned long count)
320 {
321 	unsigned long *buf = addr;
322 	unsigned long *portp;
323 
324 	portp = PORT2ADDR(port);
325 	while (count--)
326 		*buf++ = *(volatile unsigned long *)portp;
327 }
328 
_outsb(unsigned int port,const void * addr,unsigned long count)329 void _outsb(unsigned int port, const void *addr, unsigned long count)
330 {
331 	const unsigned char *buf = addr;
332 	unsigned char *portp;
333 
334 	if (port >= LAN_IOSTART && port < LAN_IOEND) {
335 		portp = PORT2ADDR_NE(port);
336 		while (count--)
337 			_ne_outb(*buf++, portp);
338 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
339 	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
340 		portp = __port2addr_ata(port);
341 		while (count--)
342 			*(volatile unsigned char *)portp = *buf++;
343 #endif
344 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
345 	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
346 		pcc_iowrite_byte(0, port, (void *)addr, sizeof(unsigned char),
347 				 count, 1);
348 #endif
349 	} else {
350 		portp = PORT2ADDR(port);
351 		while (count--)
352 			*(volatile unsigned char *)portp = *buf++;
353 	}
354 }
355 
_outsw(unsigned int port,const void * addr,unsigned long count)356 void _outsw(unsigned int port, const void *addr, unsigned long count)
357 {
358 	const unsigned short *buf = addr;
359 	unsigned short *portp;
360 
361 	if (port >= LAN_IOSTART && port < LAN_IOEND) {
362 		/*
363 		 * This portion is only used by smc91111.c to write data
364 		 * into the DATA_REG. Do not swap the data.
365 		 */
366 		portp = PORT2ADDR_NE(port);
367 		while (count--)
368 			*(volatile unsigned short *)portp = *buf++;
369 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
370 	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
371 		portp = __port2addr_ata(port);
372 		while (count--)
373 			*(volatile unsigned short *)portp = *buf++;
374 #endif
375 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
376 	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
377 		pcc_iowrite_word(9, port, (void *)addr, sizeof(unsigned short),
378 				 count, 1);
379 #endif
380 	} else {
381 		portp = PORT2ADDR(port);
382 		while (count--)
383 			*(volatile unsigned short *)portp = *buf++;
384 	}
385 }
386 
_outsl(unsigned int port,const void * addr,unsigned long count)387 void _outsl(unsigned int port, const void *addr, unsigned long count)
388 {
389 	const unsigned long *buf = addr;
390 	unsigned char *portp;
391 
392 	portp = PORT2ADDR(port);
393 	while (count--)
394 		*(volatile unsigned long *)portp = *buf++;
395 }
396