uboot/arch/mips/include/asm/io.h
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 1994, 1995 Waldorf GmbH
   7 * Copyright (C) 1994 - 2000 Ralf Baechle
   8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
   9 * Copyright (C) 2000 FSMLabs, Inc.
  10 */
  11#ifndef _ASM_IO_H
  12#define _ASM_IO_H
  13
  14#if 0
  15#include <linux/pagemap.h>
  16#endif
  17#include <asm/addrspace.h>
  18#include <asm/byteorder.h>
  19
  20/*
  21 * Slowdown I/O port space accesses for antique hardware.
  22 */
  23#undef CONF_SLOWDOWN_IO
  24
  25/*
  26 * Sane hardware offers swapping of I/O space accesses in hardware; less
  27 * sane hardware forces software to fiddle with this ...
  28 */
  29#if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
  30
  31#define __ioswab8(x) (x)
  32#define __ioswab16(x) swab16(x)
  33#define __ioswab32(x) swab32(x)
  34
  35#else
  36
  37#define __ioswab8(x) (x)
  38#define __ioswab16(x) (x)
  39#define __ioswab32(x) (x)
  40
  41#endif
  42
  43/*
  44 * This file contains the definitions for the MIPS counterpart of the
  45 * x86 in/out instructions. This heap of macros and C results in much
  46 * better code than the approach of doing it in plain C.  The macros
  47 * result in code that is to fast for certain hardware.  On the other
  48 * side the performance of the string functions should be improved for
  49 * sake of certain devices like EIDE disks that do highspeed polled I/O.
  50 *
  51 *   Ralf
  52 *
  53 * This file contains the definitions for the x86 IO instructions
  54 * inb/inw/inl/outb/outw/outl and the "string versions" of the same
  55 * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
  56 * versions of the single-IO instructions (inb_p/inw_p/..).
  57 *
  58 * This file is not meant to be obfuscating: it's just complicated
  59 * to (a) handle it all in a way that makes gcc able to optimize it
  60 * as well as possible and (b) trying to avoid writing the same thing
  61 * over and over again with slight variations and possibly making a
  62 * mistake somewhere.
  63 */
  64
  65/*
  66 * On MIPS I/O ports are memory mapped, so we access them using normal
  67 * load/store instructions. mips_io_port_base is the virtual address to
  68 * which all ports are being mapped.  For sake of efficiency some code
  69 * assumes that this is an address that can be loaded with a single lui
  70 * instruction, so the lower 16 bits must be zero.  Should be true on
  71 * on any sane architecture; generic code does not use this assumption.
  72 */
  73extern const unsigned long mips_io_port_base;
  74
  75/*
  76 * Gcc will generate code to load the value of mips_io_port_base after each
  77 * function call which may be fairly wasteful in some cases.  So we don't
  78 * play quite by the book.  We tell gcc mips_io_port_base is a long variable
  79 * which solves the code generation issue.  Now we need to violate the
  80 * aliasing rules a little to make initialization possible and finally we
  81 * will need the barrier() to fight side effects of the aliasing chat.
  82 * This trickery will eventually collapse under gcc's optimizer.  Oh well.
  83 */
  84static inline void set_io_port_base(unsigned long base)
  85{
  86        * (unsigned long *) &mips_io_port_base = base;
  87}
  88
  89/*
  90 * Thanks to James van Artsdalen for a better timing-fix than
  91 * the two short jumps: using outb's to a nonexistent port seems
  92 * to guarantee better timings even on fast machines.
  93 *
  94 * On the other hand, I'd like to be sure of a non-existent port:
  95 * I feel a bit unsafe about using 0x80 (should be safe, though)
  96 *
  97 *              Linus
  98 *
  99 */
 100
 101#define __SLOW_DOWN_IO \
 102        __asm__ __volatile__( \
 103                "sb\t$0,0x80(%0)" \
 104                : : "r" (mips_io_port_base));
 105
 106#ifdef CONF_SLOWDOWN_IO
 107#ifdef REALLY_SLOW_IO
 108#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
 109#else
 110#define SLOW_DOWN_IO __SLOW_DOWN_IO
 111#endif
 112#else
 113#define SLOW_DOWN_IO
 114#endif
 115
 116/*
 117 * Change virtual addresses to physical addresses and vv.
 118 * These are trivial on the 1:1 Linux/MIPS mapping
 119 */
 120static inline phys_addr_t virt_to_phys(volatile void * address)
 121{
 122#ifndef CONFIG_64BIT
 123        return CPHYSADDR(address);
 124#else
 125        return XPHYSADDR(address);
 126#endif
 127}
 128
 129static inline void * phys_to_virt(unsigned long address)
 130{
 131#ifndef CONFIG_64BIT
 132        return (void *)KSEG0ADDR(address);
 133#else
 134        return (void *)CKSEG0ADDR(address);
 135#endif
 136}
 137
 138/*
 139 * IO bus memory addresses are also 1:1 with the physical address
 140 */
 141static inline unsigned long virt_to_bus(volatile void * address)
 142{
 143#ifndef CONFIG_64BIT
 144        return CPHYSADDR(address);
 145#else
 146        return XPHYSADDR(address);
 147#endif
 148}
 149
 150static inline void * bus_to_virt(unsigned long address)
 151{
 152#ifndef CONFIG_64BIT
 153        return (void *)KSEG0ADDR(address);
 154#else
 155        return (void *)CKSEG0ADDR(address);
 156#endif
 157}
 158
 159/*
 160 * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped
 161 * for the processor.
 162 */
 163extern unsigned long isa_slot_offset;
 164
 165extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
 166
 167#if 0
 168static inline void *ioremap(unsigned long offset, unsigned long size)
 169{
 170        return __ioremap(offset, size, _CACHE_UNCACHED);
 171}
 172
 173static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
 174{
 175        return __ioremap(offset, size, _CACHE_UNCACHED);
 176}
 177
 178extern void iounmap(void *addr);
 179#endif
 180
 181/*
 182 * XXX We need system specific versions of these to handle EISA address bits
 183 * 24-31 on SNI.
 184 * XXX more SNI hacks.
 185 */
 186#define __raw_readb(addr) (*(volatile unsigned char *)(addr))
 187#define __raw_readw(addr) (*(volatile unsigned short *)(addr))
 188#define __raw_readl(addr) (*(volatile unsigned int *)(addr))
 189#define readb(addr) __raw_readb((addr))
 190#define readw(addr) __ioswab16(__raw_readw((addr)))
 191#define readl(addr) __ioswab32(__raw_readl((addr)))
 192
 193#define __raw_writeb(b, addr) (*(volatile unsigned char *)(addr)) = (b)
 194#define __raw_writew(b, addr) (*(volatile unsigned short *)(addr)) = (b)
 195#define __raw_writel(b, addr) (*(volatile unsigned int *)(addr)) = (b)
 196#define writeb(b, addr) __raw_writeb((b), (addr))
 197#define writew(b, addr) __raw_writew(__ioswab16(b), (addr))
 198#define writel(b, addr) __raw_writel(__ioswab32(b), (addr))
 199
 200#define memset_io(a,b,c)        memset((void *)(a),(b),(c))
 201#define memcpy_fromio(a,b,c)    memcpy((a),(void *)(b),(c))
 202#define memcpy_toio(a,b,c)      memcpy((void *)(a),(b),(c))
 203
 204/* END SNI HACKS ... */
 205
 206/*
 207 * ISA space is 'always mapped' on currently supported MIPS systems, no need
 208 * to explicitly ioremap() it. The fact that the ISA IO space is mapped
 209 * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
 210 * are physical addresses. The following constant pointer can be
 211 * used as the IO-area pointer (it can be iounmapped as well, so the
 212 * analogy with PCI is quite large):
 213 */
 214#define __ISA_IO_base ((char *)(PAGE_OFFSET))
 215
 216#define isa_readb(a) readb(a)
 217#define isa_readw(a) readw(a)
 218#define isa_readl(a) readl(a)
 219#define isa_writeb(b,a) writeb(b,a)
 220#define isa_writew(w,a) writew(w,a)
 221#define isa_writel(l,a) writel(l,a)
 222
 223#define isa_memset_io(a,b,c)     memset_io((a),(b),(c))
 224#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),(b),(c))
 225#define isa_memcpy_toio(a,b,c)   memcpy_toio((a),(b),(c))
 226
 227/*
 228 * We don't have csum_partial_copy_fromio() yet, so we cheat here and
 229 * just copy it. The net code will then do the checksum later.
 230 */
 231#define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len))
 232#define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(b),(c),(d))
 233
 234static inline int check_signature(unsigned long io_addr,
 235                                  const unsigned char *signature, int length)
 236{
 237        int retval = 0;
 238        do {
 239                if (readb(io_addr) != *signature)
 240                        goto out;
 241                io_addr++;
 242                signature++;
 243                length--;
 244        } while (length);
 245        retval = 1;
 246out:
 247        return retval;
 248}
 249#define isa_check_signature(io, s, l) check_signature(i,s,l)
 250
 251/*
 252 * Talk about misusing macros..
 253 */
 254
 255#define __OUT1(s) \
 256static inline void __out##s(unsigned int value, unsigned int port) {
 257
 258#define __OUT2(m) \
 259__asm__ __volatile__ ("s" #m "\t%0,%1(%2)"
 260
 261#define __OUT(m,s,w) \
 262__OUT1(s) __OUT2(m) : : "r" (__ioswab##w(value)), "i" (0), "r" (mips_io_port_base+port)); } \
 263__OUT1(s##c) __OUT2(m) : : "r" (__ioswab##w(value)), "ir" (port), "r" (mips_io_port_base)); } \
 264__OUT1(s##_p) __OUT2(m) : : "r" (__ioswab##w(value)), "i" (0), "r" (mips_io_port_base+port)); \
 265        SLOW_DOWN_IO; } \
 266__OUT1(s##c_p) __OUT2(m) : : "r" (__ioswab##w(value)), "ir" (port), "r" (mips_io_port_base)); \
 267        SLOW_DOWN_IO; }
 268
 269#define __IN1(t,s) \
 270static inline t __in##s(unsigned int port) { t _v;
 271
 272/*
 273 * Required nops will be inserted by the assembler
 274 */
 275#define __IN2(m) \
 276__asm__ __volatile__ ("l" #m "\t%0,%1(%2)"
 277
 278#define __IN(t,m,s,w) \
 279__IN1(t,s) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); return __ioswab##w(_v); } \
 280__IN1(t,s##c) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); return __ioswab##w(_v); } \
 281__IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); SLOW_DOWN_IO; return __ioswab##w(_v); } \
 282__IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return __ioswab##w(_v); }
 283
 284#define __INS1(s) \
 285static inline void __ins##s(unsigned int port, void * addr, unsigned long count) {
 286
 287#define __INS2(m) \
 288if (count) \
 289__asm__ __volatile__ ( \
 290        ".set\tnoreorder\n\t" \
 291        ".set\tnoat\n" \
 292        "1:\tl" #m "\t$1,%4(%5)\n\t" \
 293        "subu\t%1,1\n\t" \
 294        "s" #m "\t$1,(%0)\n\t" \
 295        "bne\t$0,%1,1b\n\t" \
 296        "addiu\t%0,%6\n\t" \
 297        ".set\tat\n\t" \
 298        ".set\treorder"
 299
 300#define __INS(m,s,i) \
 301__INS1(s) __INS2(m) \
 302        : "=r" (addr), "=r" (count) \
 303        : "0" (addr), "1" (count), "i" (0), \
 304          "r" (mips_io_port_base+port), "I" (i) \
 305        : "$1");} \
 306__INS1(s##c) __INS2(m) \
 307        : "=r" (addr), "=r" (count) \
 308        : "0" (addr), "1" (count), "ir" (port), \
 309          "r" (mips_io_port_base), "I" (i) \
 310        : "$1");}
 311
 312#define __OUTS1(s) \
 313static inline void __outs##s(unsigned int port, const void * addr, unsigned long count) {
 314
 315#define __OUTS2(m) \
 316if (count) \
 317__asm__ __volatile__ ( \
 318        ".set\tnoreorder\n\t" \
 319        ".set\tnoat\n" \
 320        "1:\tl" #m "\t$1,(%0)\n\t" \
 321        "subu\t%1,1\n\t" \
 322        "s" #m "\t$1,%4(%5)\n\t" \
 323        "bne\t$0,%1,1b\n\t" \
 324        "addiu\t%0,%6\n\t" \
 325        ".set\tat\n\t" \
 326        ".set\treorder"
 327
 328#define __OUTS(m,s,i) \
 329__OUTS1(s) __OUTS2(m) \
 330        : "=r" (addr), "=r" (count) \
 331        : "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \
 332        : "$1");} \
 333__OUTS1(s##c) __OUTS2(m) \
 334        : "=r" (addr), "=r" (count) \
 335        : "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \
 336        : "$1");}
 337
 338__IN(unsigned char,b,b,8)
 339__IN(unsigned short,h,w,16)
 340__IN(unsigned int,w,l,32)
 341
 342__OUT(b,b,8)
 343__OUT(h,w,16)
 344__OUT(w,l,32)
 345
 346__INS(b,b,1)
 347__INS(h,w,2)
 348__INS(w,l,4)
 349
 350__OUTS(b,b,1)
 351__OUTS(h,w,2)
 352__OUTS(w,l,4)
 353
 354
 355/*
 356 * Note that due to the way __builtin_constant_p() works, you
 357 *  - can't use it inside an inline function (it will never be true)
 358 *  - you don't have to worry about side effects within the __builtin..
 359 */
 360#define outb(val,port) \
 361((__builtin_constant_p((port)) && (port) < 32768) ? \
 362        __outbc((val),(port)) : \
 363        __outb((val),(port)))
 364
 365#define inb(port) \
 366((__builtin_constant_p((port)) && (port) < 32768) ? \
 367        __inbc(port) : \
 368        __inb(port))
 369
 370#define outb_p(val,port) \
 371((__builtin_constant_p((port)) && (port) < 32768) ? \
 372        __outbc_p((val),(port)) : \
 373        __outb_p((val),(port)))
 374
 375#define inb_p(port) \
 376((__builtin_constant_p((port)) && (port) < 32768) ? \
 377        __inbc_p(port) : \
 378        __inb_p(port))
 379
 380#define outw(val,port) \
 381((__builtin_constant_p((port)) && (port) < 32768) ? \
 382        __outwc((val),(port)) : \
 383        __outw((val),(port)))
 384
 385#define inw(port) \
 386((__builtin_constant_p((port)) && (port) < 32768) ? \
 387        __inwc(port) : \
 388        __inw(port))
 389
 390#define outw_p(val,port) \
 391((__builtin_constant_p((port)) && (port) < 32768) ? \
 392        __outwc_p((val),(port)) : \
 393        __outw_p((val),(port)))
 394
 395#define inw_p(port) \
 396((__builtin_constant_p((port)) && (port) < 32768) ? \
 397        __inwc_p(port) : \
 398        __inw_p(port))
 399
 400#define outl(val,port) \
 401((__builtin_constant_p((port)) && (port) < 32768) ? \
 402        __outlc((val),(port)) : \
 403        __outl((val),(port)))
 404
 405#define inl(port) \
 406((__builtin_constant_p((port)) && (port) < 32768) ? \
 407        __inlc(port) : \
 408        __inl(port))
 409
 410#define outl_p(val,port) \
 411((__builtin_constant_p((port)) && (port) < 32768) ? \
 412        __outlc_p((val),(port)) : \
 413        __outl_p((val),(port)))
 414
 415#define inl_p(port) \
 416((__builtin_constant_p((port)) && (port) < 32768) ? \
 417        __inlc_p(port) : \
 418        __inl_p(port))
 419
 420
 421#define outsb(port,addr,count) \
 422((__builtin_constant_p((port)) && (port) < 32768) ? \
 423        __outsbc((port),(addr),(count)) : \
 424        __outsb ((port),(addr),(count)))
 425
 426#define insb(port,addr,count) \
 427((__builtin_constant_p((port)) && (port) < 32768) ? \
 428        __insbc((port),(addr),(count)) : \
 429        __insb((port),(addr),(count)))
 430
 431#define outsw(port,addr,count) \
 432((__builtin_constant_p((port)) && (port) < 32768) ? \
 433        __outswc((port),(addr),(count)) : \
 434        __outsw ((port),(addr),(count)))
 435
 436#define insw(port,addr,count) \
 437((__builtin_constant_p((port)) && (port) < 32768) ? \
 438        __inswc((port),(addr),(count)) : \
 439        __insw((port),(addr),(count)))
 440
 441#define outsl(port,addr,count) \
 442((__builtin_constant_p((port)) && (port) < 32768) ? \
 443        __outslc((port),(addr),(count)) : \
 444        __outsl ((port),(addr),(count)))
 445
 446#define insl(port,addr,count) \
 447((__builtin_constant_p((port)) && (port) < 32768) ? \
 448        __inslc((port),(addr),(count)) : \
 449        __insl((port),(addr),(count)))
 450
 451#define IO_SPACE_LIMIT 0xffff
 452
 453/*
 454 * The caches on some architectures aren't dma-coherent and have need to
 455 * handle this in software.  There are three types of operations that
 456 * can be applied to dma buffers.
 457 *
 458 *  - dma_cache_wback_inv(start, size) makes caches and coherent by
 459 *    writing the content of the caches back to memory, if necessary.
 460 *    The function also invalidates the affected part of the caches as
 461 *    necessary before DMA transfers from outside to memory.
 462 *  - dma_cache_wback(start, size) makes caches and coherent by
 463 *    writing the content of the caches back to memory, if necessary.
 464 *    The function also invalidates the affected part of the caches as
 465 *    necessary before DMA transfers from outside to memory.
 466 *  - dma_cache_inv(start, size) invalidates the affected parts of the
 467 *    caches.  Dirty lines of the caches may be written back or simply
 468 *    be discarded.  This operation is necessary before dma operations
 469 *    to the memory.
 470 */
 471extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
 472extern void (*_dma_cache_wback)(unsigned long start, unsigned long size);
 473extern void (*_dma_cache_inv)(unsigned long start, unsigned long size);
 474
 475#define dma_cache_wback_inv(start,size) _dma_cache_wback_inv(start,size)
 476#define dma_cache_wback(start,size)     _dma_cache_wback(start,size)
 477#define dma_cache_inv(start,size)       _dma_cache_inv(start,size)
 478
 479static inline void sync(void)
 480{
 481}
 482
 483/*
 484 * Given a physical address and a length, return a virtual address
 485 * that can be used to access the memory range with the caching
 486 * properties specified by "flags".
 487 */
 488#define MAP_NOCACHE     (0)
 489#define MAP_WRCOMBINE   (0)
 490#define MAP_WRBACK      (0)
 491#define MAP_WRTHROUGH   (0)
 492
 493static inline void *
 494map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
 495{
 496        return (void *)paddr;
 497}
 498
 499/*
 500 * Take down a mapping set up by map_physmem().
 501 */
 502static inline void unmap_physmem(void *vaddr, unsigned long flags)
 503{
 504
 505}
 506
 507#endif /* _ASM_IO_H */
 508