linux/arch/m32r/platforms/mappi3/io.c
<<
>>
Prefs
   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