linux/arch/arm/mach-ixp4xx/include/mach/io.h
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-ixp4xx/include/mach/io.h
   3 *
   4 * Author: Deepak Saxena <dsaxena@plexity.net>
   5 *
   6 * Copyright (C) 2002-2005  MontaVista Software, Inc.
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#ifndef __ASM_ARM_ARCH_IO_H
  14#define __ASM_ARM_ARCH_IO_H
  15
  16#include <linux/bitops.h>
  17
  18#include <mach/hardware.h>
  19
  20extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
  21extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
  22
  23
  24/*
  25 * IXP4xx provides two methods of accessing PCI memory space:
  26 *
  27 * 1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
  28 *    To access PCI via this space, we simply ioremap() the BAR
  29 *    into the kernel and we can use the standard read[bwl]/write[bwl]
  30 *    macros. This is the preffered method due to speed but it
  31 *    limits the system to just 64MB of PCI memory. This can be
  32 *    problematic if using video cards and other memory-heavy targets.
  33 *
  34 * 2) If > 64MB of memory space is required, the IXP4xx can use indirect
  35 *    registers to access the whole 4 GB of PCI memory space (as we do below
  36 *    for I/O transactions). This allows currently for up to 1 GB (0x10000000
  37 *    to 0x4FFFFFFF) of memory on the bus. The disadvantage of this is that
  38 *    every PCI access requires three local register accesses plus a spinlock,
  39 *    but in some cases the performance hit is acceptable. In addition, you
  40 *    cannot mmap() PCI devices in this case.
  41 */
  42#ifndef CONFIG_IXP4XX_INDIRECT_PCI
  43
  44#define __mem_pci(a)            (a)
  45
  46#else
  47
  48/*
  49 * In the case of using indirect PCI, we simply return the actual PCI
  50 * address and our read/write implementation use that to drive the 
  51 * access registers. If something outside of PCI is ioremap'd, we
  52 * fallback to the default.
  53 */
  54
  55static inline int is_pci_memory(u32 addr)
  56{
  57        return (addr >= PCIBIOS_MIN_MEM) && (addr <= 0x4FFFFFFF);
  58}
  59
  60static inline void __iomem * __indirect_ioremap(unsigned long addr, size_t size,
  61                                                unsigned int mtype)
  62{
  63        if (!is_pci_memory(addr))
  64                return __arm_ioremap(addr, size, mtype);
  65
  66        return (void __iomem *)addr;
  67}
  68
  69static inline void __indirect_iounmap(void __iomem *addr)
  70{
  71        if (!is_pci_memory((__force u32)addr))
  72                __iounmap(addr);
  73}
  74
  75#define __arch_ioremap                  __indirect_ioremap
  76#define __arch_iounmap                  __indirect_iounmap
  77
  78#define writeb(v, p)                    __indirect_writeb(v, p)
  79#define writew(v, p)                    __indirect_writew(v, p)
  80#define writel(v, p)                    __indirect_writel(v, p)
  81
  82#define writesb(p, v, l)                __indirect_writesb(p, v, l)
  83#define writesw(p, v, l)                __indirect_writesw(p, v, l)
  84#define writesl(p, v, l)                __indirect_writesl(p, v, l)
  85
  86#define readb(p)                        __indirect_readb(p)
  87#define readw(p)                        __indirect_readw(p)
  88#define readl(p)                        __indirect_readl(p)
  89
  90#define readsb(p, v, l)                 __indirect_readsb(p, v, l)
  91#define readsw(p, v, l)                 __indirect_readsw(p, v, l)
  92#define readsl(p, v, l)                 __indirect_readsl(p, v, l)
  93
  94static inline void __indirect_writeb(u8 value, volatile void __iomem *p)
  95{
  96        u32 addr = (u32)p;
  97        u32 n, byte_enables, data;
  98
  99        if (!is_pci_memory(addr)) {
 100                __raw_writeb(value, addr);
 101                return;
 102        }
 103
 104        n = addr % 4;
 105        byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
 106        data = value << (8*n);
 107        ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
 108}
 109
 110static inline void __indirect_writesb(volatile void __iomem *bus_addr,
 111                                      const u8 *vaddr, int count)
 112{
 113        while (count--)
 114                writeb(*vaddr++, bus_addr);
 115}
 116
 117static inline void __indirect_writew(u16 value, volatile void __iomem *p)
 118{
 119        u32 addr = (u32)p;
 120        u32 n, byte_enables, data;
 121
 122        if (!is_pci_memory(addr)) {
 123                __raw_writew(value, addr);
 124                return;
 125        }
 126
 127        n = addr % 4;
 128        byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
 129        data = value << (8*n);
 130        ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
 131}
 132
 133static inline void __indirect_writesw(volatile void __iomem *bus_addr,
 134                                      const u16 *vaddr, int count)
 135{
 136        while (count--)
 137                writew(*vaddr++, bus_addr);
 138}
 139
 140static inline void __indirect_writel(u32 value, volatile void __iomem *p)
 141{
 142        u32 addr = (__force u32)p;
 143
 144        if (!is_pci_memory(addr)) {
 145                __raw_writel(value, p);
 146                return;
 147        }
 148
 149        ixp4xx_pci_write(addr, NP_CMD_MEMWRITE, value);
 150}
 151
 152static inline void __indirect_writesl(volatile void __iomem *bus_addr,
 153                                      const u32 *vaddr, int count)
 154{
 155        while (count--)
 156                writel(*vaddr++, bus_addr);
 157}
 158
 159static inline unsigned char __indirect_readb(const volatile void __iomem *p)
 160{
 161        u32 addr = (u32)p;
 162        u32 n, byte_enables, data;
 163
 164        if (!is_pci_memory(addr))
 165                return __raw_readb(addr);
 166
 167        n = addr % 4;
 168        byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
 169        if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
 170                return 0xff;
 171
 172        return data >> (8*n);
 173}
 174
 175static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
 176                                     u8 *vaddr, u32 count)
 177{
 178        while (count--)
 179                *vaddr++ = readb(bus_addr);
 180}
 181
 182static inline unsigned short __indirect_readw(const volatile void __iomem *p)
 183{
 184        u32 addr = (u32)p;
 185        u32 n, byte_enables, data;
 186
 187        if (!is_pci_memory(addr))
 188                return __raw_readw(addr);
 189
 190        n = addr % 4;
 191        byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
 192        if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
 193                return 0xffff;
 194
 195        return data>>(8*n);
 196}
 197
 198static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
 199                                     u16 *vaddr, u32 count)
 200{
 201        while (count--)
 202                *vaddr++ = readw(bus_addr);
 203}
 204
 205static inline unsigned long __indirect_readl(const volatile void __iomem *p)
 206{
 207        u32 addr = (__force u32)p;
 208        u32 data;
 209
 210        if (!is_pci_memory(addr))
 211                return __raw_readl(p);
 212
 213        if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data))
 214                return 0xffffffff;
 215
 216        return data;
 217}
 218
 219static inline void __indirect_readsl(const volatile void __iomem *bus_addr,
 220                                     u32 *vaddr, u32 count)
 221{
 222        while (count--)
 223                *vaddr++ = readl(bus_addr);
 224}
 225
 226
 227/*
 228 * We can use the built-in functions b/c they end up calling writeb/readb
 229 */
 230#define memset_io(c,v,l)                _memset_io((c),(v),(l))
 231#define memcpy_fromio(a,c,l)            _memcpy_fromio((a),(c),(l))
 232#define memcpy_toio(c,a,l)              _memcpy_toio((c),(a),(l))
 233
 234#endif /* CONFIG_IXP4XX_INDIRECT_PCI */
 235
 236#ifndef CONFIG_PCI
 237
 238#define __io(v)         __typesafe_io(v)
 239
 240#else
 241
 242/*
 243 * IXP4xx does not have a transparent cpu -> PCI I/O translation
 244 * window.  Instead, it has a set of registers that must be tweaked
 245 * with the proper byte lanes, command types, and address for the
 246 * transaction.  This means that we need to override the default
 247 * I/O functions.
 248 */
 249
 250static inline void outb(u8 value, u32 addr)
 251{
 252        u32 n, byte_enables, data;
 253        n = addr % 4;
 254        byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
 255        data = value << (8*n);
 256        ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
 257}
 258
 259static inline void outsb(u32 io_addr, const u8 *vaddr, u32 count)
 260{
 261        while (count--)
 262                outb(*vaddr++, io_addr);
 263}
 264
 265static inline void outw(u16 value, u32 addr)
 266{
 267        u32 n, byte_enables, data;
 268        n = addr % 4;
 269        byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
 270        data = value << (8*n);
 271        ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
 272}
 273
 274static inline void outsw(u32 io_addr, const u16 *vaddr, u32 count)
 275{
 276        while (count--)
 277                outw(cpu_to_le16(*vaddr++), io_addr);
 278}
 279
 280static inline void outl(u32 value, u32 addr)
 281{
 282        ixp4xx_pci_write(addr, NP_CMD_IOWRITE, value);
 283}
 284
 285static inline void outsl(u32 io_addr, const u32 *vaddr, u32 count)
 286{
 287        while (count--)
 288                outl(cpu_to_le32(*vaddr++), io_addr);
 289}
 290
 291static inline u8 inb(u32 addr)
 292{
 293        u32 n, byte_enables, data;
 294        n = addr % 4;
 295        byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
 296        if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
 297                return 0xff;
 298
 299        return data >> (8*n);
 300}
 301
 302static inline void insb(u32 io_addr, u8 *vaddr, u32 count)
 303{
 304        while (count--)
 305                *vaddr++ = inb(io_addr);
 306}
 307
 308static inline u16 inw(u32 addr)
 309{
 310        u32 n, byte_enables, data;
 311        n = addr % 4;
 312        byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
 313        if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
 314                return 0xffff;
 315
 316        return data>>(8*n);
 317}
 318
 319static inline void insw(u32 io_addr, u16 *vaddr, u32 count)
 320{
 321        while (count--)
 322                *vaddr++ = le16_to_cpu(inw(io_addr));
 323}
 324
 325static inline u32 inl(u32 addr)
 326{
 327        u32 data;
 328        if (ixp4xx_pci_read(addr, NP_CMD_IOREAD, &data))
 329                return 0xffffffff;
 330
 331        return data;
 332}
 333
 334static inline void insl(u32 io_addr, u32 *vaddr, u32 count)
 335{
 336        while (count--)
 337                *vaddr++ = le32_to_cpu(inl(io_addr));
 338}
 339
 340#define PIO_OFFSET      0x10000UL
 341#define PIO_MASK        0x0ffffUL
 342
 343#define __is_io_address(p)      (((unsigned long)p >= PIO_OFFSET) && \
 344                                        ((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
 345
 346#define ioread8(p)                      ioread8(p)
 347static inline unsigned int ioread8(const void __iomem *addr)
 348{
 349        unsigned long port = (unsigned long __force)addr;
 350        if (__is_io_address(port))
 351                return (unsigned int)inb(port & PIO_MASK);
 352        else
 353#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 354                return (unsigned int)__raw_readb(addr);
 355#else
 356                return (unsigned int)__indirect_readb(addr);
 357#endif
 358}
 359
 360#define ioread8_rep(p, v, c)            ioread8_rep(p, v, c)
 361static inline void ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
 362{
 363        unsigned long port = (unsigned long __force)addr;
 364        if (__is_io_address(port))
 365                insb(port & PIO_MASK, vaddr, count);
 366        else
 367#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 368                __raw_readsb(addr, vaddr, count);
 369#else
 370                __indirect_readsb(addr, vaddr, count);
 371#endif
 372}
 373
 374#define ioread16(p)                     ioread16(p)
 375static inline unsigned int ioread16(const void __iomem *addr)
 376{
 377        unsigned long port = (unsigned long __force)addr;
 378        if (__is_io_address(port))
 379                return  (unsigned int)inw(port & PIO_MASK);
 380        else
 381#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 382                return le16_to_cpu((__force __le16)__raw_readw(addr));
 383#else
 384                return (unsigned int)__indirect_readw(addr);
 385#endif
 386}
 387
 388#define ioread16_rep(p, v, c)           ioread16_rep(p, v, c)
 389static inline void ioread16_rep(const void __iomem *addr, void *vaddr,
 390                                u32 count)
 391{
 392        unsigned long port = (unsigned long __force)addr;
 393        if (__is_io_address(port))
 394                insw(port & PIO_MASK, vaddr, count);
 395        else
 396#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 397                __raw_readsw(addr, vaddr, count);
 398#else
 399                __indirect_readsw(addr, vaddr, count);
 400#endif
 401}
 402
 403#define ioread32(p)                     ioread32(p)
 404static inline unsigned int ioread32(const void __iomem *addr)
 405{
 406        unsigned long port = (unsigned long __force)addr;
 407        if (__is_io_address(port))
 408                return  (unsigned int)inl(port & PIO_MASK);
 409        else {
 410#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 411                return le32_to_cpu((__force __le32)__raw_readl(addr));
 412#else
 413                return (unsigned int)__indirect_readl(addr);
 414#endif
 415        }
 416}
 417
 418#define ioread32_rep(p, v, c)           ioread32_rep(p, v, c)
 419static inline void ioread32_rep(const void __iomem *addr, void *vaddr,
 420                                u32 count)
 421{
 422        unsigned long port = (unsigned long __force)addr;
 423        if (__is_io_address(port))
 424                insl(port & PIO_MASK, vaddr, count);
 425        else
 426#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 427                __raw_readsl(addr, vaddr, count);
 428#else
 429                __indirect_readsl(addr, vaddr, count);
 430#endif
 431}
 432
 433#define iowrite8(v, p)                  iowrite8(v, p)
 434static inline void iowrite8(u8 value, void __iomem *addr)
 435{
 436        unsigned long port = (unsigned long __force)addr;
 437        if (__is_io_address(port))
 438                outb(value, port & PIO_MASK);
 439        else
 440#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 441                __raw_writeb(value, addr);
 442#else
 443                __indirect_writeb(value, addr);
 444#endif
 445}
 446
 447#define iowrite8_rep(p, v, c)           iowrite8_rep(p, v, c)
 448static inline void iowrite8_rep(void __iomem *addr, const void *vaddr,
 449                                u32 count)
 450{
 451        unsigned long port = (unsigned long __force)addr;
 452        if (__is_io_address(port))
 453                outsb(port & PIO_MASK, vaddr, count);
 454        else
 455#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 456                __raw_writesb(addr, vaddr, count);
 457#else
 458                __indirect_writesb(addr, vaddr, count);
 459#endif
 460}
 461
 462#define iowrite16(v, p)                 iowrite16(v, p)
 463static inline void iowrite16(u16 value, void __iomem *addr)
 464{
 465        unsigned long port = (unsigned long __force)addr;
 466        if (__is_io_address(port))
 467                outw(value, port & PIO_MASK);
 468        else
 469#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 470                __raw_writew(cpu_to_le16(value), addr);
 471#else
 472                __indirect_writew(value, addr);
 473#endif
 474}
 475
 476#define iowrite16_rep(p, v, c)          iowrite16_rep(p, v, c)
 477static inline void iowrite16_rep(void __iomem *addr, const void *vaddr,
 478                                 u32 count)
 479{
 480        unsigned long port = (unsigned long __force)addr;
 481        if (__is_io_address(port))
 482                outsw(port & PIO_MASK, vaddr, count);
 483        else
 484#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 485                __raw_writesw(addr, vaddr, count);
 486#else
 487                __indirect_writesw(addr, vaddr, count);
 488#endif
 489}
 490
 491#define iowrite32(v, p)                 iowrite32(v, p)
 492static inline void iowrite32(u32 value, void __iomem *addr)
 493{
 494        unsigned long port = (unsigned long __force)addr;
 495        if (__is_io_address(port))
 496                outl(value, port & PIO_MASK);
 497        else
 498#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 499                __raw_writel((u32 __force)cpu_to_le32(value), addr);
 500#else
 501                __indirect_writel(value, addr);
 502#endif
 503}
 504
 505#define iowrite32_rep(p, v, c)          iowrite32_rep(p, v, c)
 506static inline void iowrite32_rep(void __iomem *addr, const void *vaddr,
 507                                 u32 count)
 508{
 509        unsigned long port = (unsigned long __force)addr;
 510        if (__is_io_address(port))
 511                outsl(port & PIO_MASK, vaddr, count);
 512        else
 513#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 514                __raw_writesl(addr, vaddr, count);
 515#else
 516                __indirect_writesl(addr, vaddr, count);
 517#endif
 518}
 519
 520#define ioport_map(port, nr)            ((void __iomem*)(port + PIO_OFFSET))
 521#define ioport_unmap(addr)
 522#endif /* CONFIG_PCI */
 523
 524#endif /* __ASM_ARM_ARCH_IO_H */
 525