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