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 27extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int); 28extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int); 29extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int); 30extern 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 36static inline void *_port2addr(unsigned long port) 37{ 38 return (void *)(port | NONCACHE_OFFSET); 39} 40 41#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) 42static 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) 68static inline void *_port2addr_ne(unsigned long port) 69{ 70 return (void *)(port + 0x10000000); 71} 72static inline void *_port2addr_usb(unsigned long port) 73{ 74 return (void *)((port & 0x0f) + NONCACHE_OFFSET + 0x10303000); 75} 76 77static 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 88static inline unsigned char _ne_inb(void *portp) 89{ 90 return *(volatile unsigned char *)portp; 91} 92 93static inline unsigned short _ne_inw(void *portp) 94{ 95 return (unsigned short)le16_to_cpu(*(volatile unsigned short *)portp); 96} 97 98static 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 106static inline void _ne_outb(unsigned char b, void *portp) 107{ 108 *(volatile unsigned char *)portp = b; 109} 110 111static inline void _ne_outw(unsigned short w, void *portp) 112{ 113 *(volatile unsigned short *)portp = cpu_to_le16(w); 114} 115 116unsigned 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 137unsigned 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 160unsigned 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 172unsigned char _inb_p(unsigned long port) 173{ 174 unsigned char v = _inb(port); 175 delay(); 176 return (v); 177} 178 179unsigned short _inw_p(unsigned long port) 180{ 181 unsigned short v = _inw(port); 182 delay(); 183 return (v); 184} 185 186unsigned long _inl_p(unsigned long port) 187{ 188 unsigned long v = _inl(port); 189 delay(); 190 return (v); 191} 192 193void _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 211void _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 234void _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 244void _outb_p(unsigned char b, unsigned long port) 245{ 246 _outb(b, port); 247 delay(); 248} 249 250void _outw_p(unsigned short w, unsigned long port) 251{ 252 _outw(w, port); 253 delay(); 254} 255 256void _outl_p(unsigned long l, unsigned long port) 257{ 258 _outl(l, port); 259 delay(); 260} 261 262void _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 288void _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 319void _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 329void _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 356void _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 387void _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