1 /*
2  *  linux/arch/m32r/platforms/mappi/io.c
3  *
4  *  Typical I/O routines for Mappi board.
5  *
6  *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
7  *                           Hitoshi Yamamoto
8  */
9 
10 #include <asm/m32r.h>
11 #include <asm/page.h>
12 #include <asm/io.h>
13 #include <asm/byteorder.h>
14 
15 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
16 #include <linux/types.h>
17 
18 #define M32R_PCC_IOMAP_SIZE 0x1000
19 
20 #define M32R_PCC_IOSTART0 0x1000
21 #define M32R_PCC_IOEND0   (M32R_PCC_IOSTART0 + M32R_PCC_IOMAP_SIZE - 1)
22 #define M32R_PCC_IOSTART1 0x2000
23 #define M32R_PCC_IOEND1   (M32R_PCC_IOSTART1 + M32R_PCC_IOMAP_SIZE - 1)
24 
25 extern void pcc_ioread(int, unsigned long, void *, size_t, size_t, int);
26 extern void pcc_iowrite(int, unsigned long, void *, size_t, size_t, int);
27 #endif /* CONFIG_PCMCIA && CONFIG_M32R_PCC */
28 
29 #define PORT2ADDR(port)  _port2addr(port)
30 
_port2addr(unsigned long port)31 static inline void *_port2addr(unsigned long port)
32 {
33 	return (void *)(port | NONCACHE_OFFSET);
34 }
35 
_port2addr_ne(unsigned long port)36 static inline void *_port2addr_ne(unsigned long port)
37 {
38 	return (void *)((port<<1) + NONCACHE_OFFSET + 0x0C000000);
39 }
40 
delay(void)41 static inline void delay(void)
42 {
43 	__asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory");
44 }
45 
46 /*
47  * NIC I/O function
48  */
49 
50 #define PORT2ADDR_NE(port)  _port2addr_ne(port)
51 
_ne_inb(void * portp)52 static inline unsigned char _ne_inb(void *portp)
53 {
54 	return (unsigned char) *(volatile unsigned short *)portp;
55 }
56 
_ne_inw(void * portp)57 static inline unsigned short _ne_inw(void *portp)
58 {
59 	unsigned short tmp;
60 
61 	tmp = *(volatile unsigned short *)portp;
62 	return le16_to_cpu(tmp);
63 }
64 
_ne_outb(unsigned char b,void * portp)65 static inline void _ne_outb(unsigned char b, void *portp)
66 {
67 	*(volatile unsigned short *)portp = (unsigned short)b;
68 }
69 
_ne_outw(unsigned short w,void * portp)70 static inline void _ne_outw(unsigned short w, void *portp)
71 {
72 	*(volatile unsigned short *)portp = cpu_to_le16(w);
73 }
74 
_inb(unsigned long port)75 unsigned char _inb(unsigned long port)
76 {
77 	if (port >= 0x300 && port < 0x320)
78 		return _ne_inb(PORT2ADDR_NE(port));
79 	else
80 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
81         if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
82 		unsigned char b;
83 		pcc_ioread(0, port, &b, sizeof(b), 1, 0);
84 		return b;
85 	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
86 		unsigned char b;
87 		pcc_ioread(1, port, &b, sizeof(b), 1, 0);
88 		return b;
89 	} else
90 #endif
91 
92 	return *(volatile unsigned char *)PORT2ADDR(port);
93 }
94 
_inw(unsigned long port)95 unsigned short _inw(unsigned long port)
96 {
97 	if (port >= 0x300 && port < 0x320)
98 		return _ne_inw(PORT2ADDR_NE(port));
99 	else
100 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
101 	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
102 		unsigned short w;
103 		pcc_ioread(0, port, &w, sizeof(w), 1, 0);
104 		return w;
105 	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
106 		unsigned short w;
107 		pcc_ioread(1, port, &w, sizeof(w), 1, 0);
108 		return w;
109 	} else
110 #endif
111 	return *(volatile unsigned short *)PORT2ADDR(port);
112 }
113 
_inl(unsigned long port)114 unsigned long _inl(unsigned long port)
115 {
116 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
117 	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
118 		unsigned long l;
119 		pcc_ioread(0, port, &l, sizeof(l), 1, 0);
120 		return l;
121 	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
122 		unsigned short l;
123 		pcc_ioread(1, port, &l, sizeof(l), 1, 0);
124 		return l;
125 	} else
126 #endif
127 	return *(volatile unsigned long *)PORT2ADDR(port);
128 }
129 
_inb_p(unsigned long port)130 unsigned char _inb_p(unsigned long port)
131 {
132 	unsigned char v = _inb(port);
133 	delay();
134 	return (v);
135 }
136 
_inw_p(unsigned long port)137 unsigned short _inw_p(unsigned long port)
138 {
139 	unsigned short v = _inw(port);
140 	delay();
141 	return (v);
142 }
143 
_inl_p(unsigned long port)144 unsigned long _inl_p(unsigned long port)
145 {
146 	unsigned long v = _inl(port);
147 	delay();
148 	return (v);
149 }
150 
_outb(unsigned char b,unsigned long port)151 void _outb(unsigned char b, unsigned long port)
152 {
153 	if (port >= 0x300 && port < 0x320)
154 		_ne_outb(b, PORT2ADDR_NE(port));
155 	else
156 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
157 	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
158 		pcc_iowrite(0, port, &b, sizeof(b), 1, 0);
159 	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
160 		pcc_iowrite(1, port, &b, sizeof(b), 1, 0);
161 	} else
162 #endif
163 		*(volatile unsigned char *)PORT2ADDR(port) = b;
164 }
165 
_outw(unsigned short w,unsigned long port)166 void _outw(unsigned short w, unsigned long port)
167 {
168 	if (port >= 0x300 && port < 0x320)
169 		_ne_outw(w, PORT2ADDR_NE(port));
170 	else
171 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
172 	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
173 		pcc_iowrite(0, port, &w, sizeof(w), 1, 0);
174 	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
175 		pcc_iowrite(1, port, &w, sizeof(w), 1, 0);
176 	} else
177 #endif
178 		*(volatile unsigned short *)PORT2ADDR(port) = w;
179 }
180 
_outl(unsigned long l,unsigned long port)181 void _outl(unsigned long l, unsigned long port)
182 {
183 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
184 	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
185 		pcc_iowrite(0, port, &l, sizeof(l), 1, 0);
186 	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
187 		pcc_iowrite(1, port, &l, sizeof(l), 1, 0);
188 	} else
189 #endif
190 	*(volatile unsigned long *)PORT2ADDR(port) = l;
191 }
192 
_outb_p(unsigned char b,unsigned long port)193 void _outb_p(unsigned char b, unsigned long port)
194 {
195 	_outb(b, port);
196 	delay();
197 }
198 
_outw_p(unsigned short w,unsigned long port)199 void _outw_p(unsigned short w, unsigned long port)
200 {
201 	_outw(w, port);
202 	delay();
203 }
204 
_outl_p(unsigned long l,unsigned long port)205 void _outl_p(unsigned long l, unsigned long port)
206 {
207 	_outl(l, port);
208 	delay();
209 }
210 
_insb(unsigned int port,void * addr,unsigned long count)211 void _insb(unsigned int port, void *addr, unsigned long count)
212 {
213 	unsigned short *buf = addr;
214 	unsigned short *portp;
215 
216 	if (port >= 0x300 && port < 0x320){
217 		portp = PORT2ADDR_NE(port);
218 		while (count--)
219 			*buf++ = *(volatile unsigned char *)portp;
220 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
221 	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
222 		pcc_ioread(0, port, (void *)addr, sizeof(unsigned char),
223 			   count, 1);
224 	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
225 		pcc_ioread(1, port, (void *)addr, sizeof(unsigned char),
226 			   count, 1);
227 #endif
228 	} else {
229 		portp = PORT2ADDR(port);
230 		while (count--)
231 			*buf++ = *(volatile unsigned char *)portp;
232 	}
233 }
234 
_insw(unsigned int port,void * addr,unsigned long count)235 void _insw(unsigned int port, void *addr, unsigned long count)
236 {
237 	unsigned short *buf = addr;
238 	unsigned short *portp;
239 
240 	if (port >= 0x300 && port < 0x320) {
241 		portp = PORT2ADDR_NE(port);
242 		while (count--)
243 			*buf++ = _ne_inw(portp);
244 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
245 	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
246 		pcc_ioread(0, port, (void *)addr, sizeof(unsigned short),
247 			   count, 1);
248 	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
249 		pcc_ioread(1, port, (void *)addr, sizeof(unsigned short),
250 			   count, 1);
251 #endif
252 	} else {
253 		portp = PORT2ADDR(port);
254 		while (count--)
255 			*buf++ = *(volatile unsigned short *)portp;
256 	}
257 }
258 
_insl(unsigned int port,void * addr,unsigned long count)259 void _insl(unsigned int port, void *addr, unsigned long count)
260 {
261 	unsigned long *buf = addr;
262 	unsigned long *portp;
263 
264 	portp = PORT2ADDR(port);
265 	while (count--)
266 		*buf++ = *(volatile unsigned long *)portp;
267 }
268 
_outsb(unsigned int port,const void * addr,unsigned long count)269 void _outsb(unsigned int port, const void *addr, unsigned long count)
270 {
271 	const unsigned char *buf = addr;
272 	unsigned char *portp;
273 
274 	if (port >= 0x300 && port < 0x320) {
275 		portp = PORT2ADDR_NE(port);
276 		while (count--)
277 			_ne_outb(*buf++, portp);
278 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
279 	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
280 		pcc_iowrite(0, port, (void *)addr, sizeof(unsigned char),
281 			    count, 1);
282 	} else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
283 		pcc_iowrite(1, port, (void *)addr, sizeof(unsigned char),
284 			    count, 1);
285 #endif
286 	} else {
287 		portp = PORT2ADDR(port);
288 		while (count--)
289 			*(volatile unsigned char *)portp = *buf++;
290 	}
291 }
292 
_outsw(unsigned int port,const void * addr,unsigned long count)293 void _outsw(unsigned int port, const void *addr, unsigned long count)
294 {
295 	const unsigned short *buf = addr;
296 	unsigned short *portp;
297 
298 	if (port >= 0x300 && port < 0x320) {
299 		portp = PORT2ADDR_NE(port);
300 		while (count--)
301 			_ne_outw(*buf++, portp);
302 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
303 	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
304 		pcc_iowrite(0, port, (void *)addr, sizeof(unsigned short),
305 			    count, 1);
306 	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
307 		pcc_iowrite(1, port, (void *)addr, sizeof(unsigned short),
308 			    count, 1);
309 #endif
310 	} else {
311 		portp = PORT2ADDR(port);
312 		while (count--)
313 			*(volatile unsigned short *)portp = *buf++;
314 	}
315 }
316 
_outsl(unsigned int port,const void * addr,unsigned long count)317 void _outsl(unsigned int port, const void *addr, unsigned long count)
318 {
319 	const unsigned long *buf = addr;
320 	unsigned char *portp;
321 
322 	portp = PORT2ADDR(port);
323 	while (count--)
324 		*(volatile unsigned long *)portp = *buf++;
325 }
326