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