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