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#ifdef  CONFIG_IXP4XX_INDIRECT_PCI
  43
  44/*
  45 * In the case of using indirect PCI, we simply return the actual PCI
  46 * address and our read/write implementation use that to drive the 
  47 * access registers. If something outside of PCI is ioremap'd, we
  48 * fallback to the default.
  49 */
  50
  51extern unsigned long pcibios_min_mem;
  52static inline int is_pci_memory(u32 addr)
  53{
  54        return (addr >= pcibios_min_mem) && (addr <= 0x4FFFFFFF);
  55}
  56
  57#define writeb(v, p)                    __indirect_writeb(v, p)
  58#define writew(v, p)                    __indirect_writew(v, p)
  59#define writel(v, p)                    __indirect_writel(v, p)
  60
  61#define writeb_relaxed(v, p)            __indirect_writeb(v, p)
  62#define writew_relaxed(v, p)            __indirect_writew(v, p)
  63#define writel_relaxed(v, p)            __indirect_writel(v, p)
  64
  65#define writesb(p, v, l)                __indirect_writesb(p, v, l)
  66#define writesw(p, v, l)                __indirect_writesw(p, v, l)
  67#define writesl(p, v, l)                __indirect_writesl(p, v, l)
  68
  69#define readb(p)                        __indirect_readb(p)
  70#define readw(p)                        __indirect_readw(p)
  71#define readl(p)                        __indirect_readl(p)
  72
  73#define readb_relaxed(p)                __indirect_readb(p)
  74#define readw_relaxed(p)                __indirect_readw(p)
  75#define readl_relaxed(p)                __indirect_readl(p)
  76
  77#define readsb(p, v, l)                 __indirect_readsb(p, v, l)
  78#define readsw(p, v, l)                 __indirect_readsw(p, v, l)
  79#define readsl(p, v, l)                 __indirect_readsl(p, v, l)
  80
  81static inline void __indirect_writeb(u8 value, volatile void __iomem *p)
  82{
  83        u32 addr = (u32)p;
  84        u32 n, byte_enables, data;
  85
  86        if (!is_pci_memory(addr)) {
  87                __raw_writeb(value, p);
  88                return;
  89        }
  90
  91        n = addr % 4;
  92        byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
  93        data = value << (8*n);
  94        ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
  95}
  96
  97static inline void __indirect_writesb(volatile void __iomem *bus_addr,
  98                                      const u8 *vaddr, int count)
  99{
 100        while (count--)
 101                writeb(*vaddr++, bus_addr);
 102}
 103
 104static inline void __indirect_writew(u16 value, volatile void __iomem *p)
 105{
 106        u32 addr = (u32)p;
 107        u32 n, byte_enables, data;
 108
 109        if (!is_pci_memory(addr)) {
 110                __raw_writew(value, p);
 111                return;
 112        }
 113
 114        n = addr % 4;
 115        byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
 116        data = value << (8*n);
 117        ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
 118}
 119
 120static inline void __indirect_writesw(volatile void __iomem *bus_addr,
 121                                      const u16 *vaddr, int count)
 122{
 123        while (count--)
 124                writew(*vaddr++, bus_addr);
 125}
 126
 127static inline void __indirect_writel(u32 value, volatile void __iomem *p)
 128{
 129        u32 addr = (__force u32)p;
 130
 131        if (!is_pci_memory(addr)) {
 132                __raw_writel(value, p);
 133                return;
 134        }
 135
 136        ixp4xx_pci_write(addr, NP_CMD_MEMWRITE, value);
 137}
 138
 139static inline void __indirect_writesl(volatile void __iomem *bus_addr,
 140                                      const u32 *vaddr, int count)
 141{
 142        while (count--)
 143                writel(*vaddr++, bus_addr);
 144}
 145
 146static inline u8 __indirect_readb(const volatile void __iomem *p)
 147{
 148        u32 addr = (u32)p;
 149        u32 n, byte_enables, data;
 150
 151        if (!is_pci_memory(addr))
 152                return __raw_readb(p);
 153
 154        n = addr % 4;
 155        byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
 156        if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
 157                return 0xff;
 158
 159        return data >> (8*n);
 160}
 161
 162static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
 163                                     u8 *vaddr, u32 count)
 164{
 165        while (count--)
 166                *vaddr++ = readb(bus_addr);
 167}
 168
 169static inline u16 __indirect_readw(const volatile void __iomem *p)
 170{
 171        u32 addr = (u32)p;
 172        u32 n, byte_enables, data;
 173
 174        if (!is_pci_memory(addr))
 175                return __raw_readw(p);
 176
 177        n = addr % 4;
 178        byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
 179        if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
 180                return 0xffff;
 181
 182        return data>>(8*n);
 183}
 184
 185static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
 186                                     u16 *vaddr, u32 count)
 187{
 188        while (count--)
 189                *vaddr++ = readw(bus_addr);
 190}
 191
 192static inline u32 __indirect_readl(const volatile void __iomem *p)
 193{
 194        u32 addr = (__force u32)p;
 195        u32 data;
 196
 197        if (!is_pci_memory(addr))
 198                return __raw_readl(p);
 199
 200        if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data))
 201                return 0xffffffff;
 202
 203        return data;
 204}
 205
 206static inline void __indirect_readsl(const volatile void __iomem *bus_addr,
 207                                     u32 *vaddr, u32 count)
 208{
 209        while (count--)
 210                *vaddr++ = readl(bus_addr);
 211}
 212
 213
 214/*
 215 * We can use the built-in functions b/c they end up calling writeb/readb
 216 */
 217#define memset_io(c,v,l)                _memset_io((c),(v),(l))
 218#define memcpy_fromio(a,c,l)            _memcpy_fromio((a),(c),(l))
 219#define memcpy_toio(c,a,l)              _memcpy_toio((c),(a),(l))
 220
 221#endif /* CONFIG_IXP4XX_INDIRECT_PCI */
 222
 223#ifndef CONFIG_PCI
 224
 225#define __io(v)         __typesafe_io(v)
 226
 227#else
 228
 229/*
 230 * IXP4xx does not have a transparent cpu -> PCI I/O translation
 231 * window.  Instead, it has a set of registers that must be tweaked
 232 * with the proper byte lanes, command types, and address for the
 233 * transaction.  This means that we need to override the default
 234 * I/O functions.
 235 */
 236
 237#define outb outb
 238static inline void outb(u8 value, u32 addr)
 239{
 240        u32 n, byte_enables, data;
 241        n = addr % 4;
 242        byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
 243        data = value << (8*n);
 244        ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
 245}
 246
 247#define outsb outsb
 248static inline void outsb(u32 io_addr, const void *p, u32 count)
 249{
 250        const u8 *vaddr = p;
 251
 252        while (count--)
 253                outb(*vaddr++, io_addr);
 254}
 255
 256#define outw outw
 257static inline void outw(u16 value, u32 addr)
 258{
 259        u32 n, byte_enables, data;
 260        n = addr % 4;
 261        byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
 262        data = value << (8*n);
 263        ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
 264}
 265
 266#define outsw outsw
 267static inline void outsw(u32 io_addr, const void *p, u32 count)
 268{
 269        const u16 *vaddr = p;
 270        while (count--)
 271                outw(cpu_to_le16(*vaddr++), io_addr);
 272}
 273
 274#define outl outl
 275static inline void outl(u32 value, u32 addr)
 276{
 277        ixp4xx_pci_write(addr, NP_CMD_IOWRITE, value);
 278}
 279
 280#define outsl outsl
 281static inline void outsl(u32 io_addr, const void *p, u32 count)
 282{
 283        const u32 *vaddr = p;
 284        while (count--)
 285                outl(cpu_to_le32(*vaddr++), io_addr);
 286}
 287
 288#define inb inb
 289static inline u8 inb(u32 addr)
 290{
 291        u32 n, byte_enables, data;
 292        n = addr % 4;
 293        byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
 294        if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
 295                return 0xff;
 296
 297        return data >> (8*n);
 298}
 299
 300#define insb insb
 301static inline void insb(u32 io_addr, void *p, u32 count)
 302{
 303        u8 *vaddr = p;
 304        while (count--)
 305                *vaddr++ = inb(io_addr);
 306}
 307
 308#define inw inw
 309static inline u16 inw(u32 addr)
 310{
 311        u32 n, byte_enables, data;
 312        n = addr % 4;
 313        byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
 314        if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
 315                return 0xffff;
 316
 317        return data>>(8*n);
 318}
 319
 320#define insw insw
 321static inline void insw(u32 io_addr, void *p, u32 count)
 322{
 323        u16 *vaddr = p;
 324        while (count--)
 325                *vaddr++ = le16_to_cpu(inw(io_addr));
 326}
 327
 328#define inl inl
 329static inline u32 inl(u32 addr)
 330{
 331        u32 data;
 332        if (ixp4xx_pci_read(addr, NP_CMD_IOREAD, &data))
 333                return 0xffffffff;
 334
 335        return data;
 336}
 337
 338#define insl insl
 339static inline void insl(u32 io_addr, void *p, u32 count)
 340{
 341        u32 *vaddr = p;
 342        while (count--)
 343                *vaddr++ = le32_to_cpu(inl(io_addr));
 344}
 345
 346#define PIO_OFFSET      0x10000UL
 347#define PIO_MASK        0x0ffffUL
 348
 349#define __is_io_address(p)      (((unsigned long)p >= PIO_OFFSET) && \
 350                                        ((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
 351
 352#define ioread8(p)                      ioread8(p)
 353static inline u8 ioread8(const void __iomem *addr)
 354{
 355        unsigned long port = (unsigned long __force)addr;
 356        if (__is_io_address(port))
 357                return (unsigned int)inb(port & PIO_MASK);
 358        else
 359#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 360                return (unsigned int)__raw_readb(addr);
 361#else
 362                return (unsigned int)__indirect_readb(addr);
 363#endif
 364}
 365
 366#define ioread8_rep(p, v, c)            ioread8_rep(p, v, c)
 367static inline void ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
 368{
 369        unsigned long port = (unsigned long __force)addr;
 370        if (__is_io_address(port))
 371                insb(port & PIO_MASK, vaddr, count);
 372        else
 373#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 374                __raw_readsb(addr, vaddr, count);
 375#else
 376                __indirect_readsb(addr, vaddr, count);
 377#endif
 378}
 379
 380#define ioread16(p)                     ioread16(p)
 381static inline u16 ioread16(const void __iomem *addr)
 382{
 383        unsigned long port = (unsigned long __force)addr;
 384        if (__is_io_address(port))
 385                return  (unsigned int)inw(port & PIO_MASK);
 386        else
 387#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 388                return le16_to_cpu((__force __le16)__raw_readw(addr));
 389#else
 390                return (unsigned int)__indirect_readw(addr);
 391#endif
 392}
 393
 394#define ioread16_rep(p, v, c)           ioread16_rep(p, v, c)
 395static inline void ioread16_rep(const void __iomem *addr, void *vaddr,
 396                                u32 count)
 397{
 398        unsigned long port = (unsigned long __force)addr;
 399        if (__is_io_address(port))
 400                insw(port & PIO_MASK, vaddr, count);
 401        else
 402#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 403                __raw_readsw(addr, vaddr, count);
 404#else
 405                __indirect_readsw(addr, vaddr, count);
 406#endif
 407}
 408
 409#define ioread32(p)                     ioread32(p)
 410static inline u32 ioread32(const void __iomem *addr)
 411{
 412        unsigned long port = (unsigned long __force)addr;
 413        if (__is_io_address(port))
 414                return  (unsigned int)inl(port & PIO_MASK);
 415        else {
 416#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 417                return le32_to_cpu((__force __le32)__raw_readl(addr));
 418#else
 419                return (unsigned int)__indirect_readl(addr);
 420#endif
 421        }
 422}
 423
 424#define ioread32_rep(p, v, c)           ioread32_rep(p, v, c)
 425static inline void ioread32_rep(const void __iomem *addr, void *vaddr,
 426                                u32 count)
 427{
 428        unsigned long port = (unsigned long __force)addr;
 429        if (__is_io_address(port))
 430                insl(port & PIO_MASK, vaddr, count);
 431        else
 432#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 433                __raw_readsl(addr, vaddr, count);
 434#else
 435                __indirect_readsl(addr, vaddr, count);
 436#endif
 437}
 438
 439#define iowrite8(v, p)                  iowrite8(v, p)
 440static inline void iowrite8(u8 value, void __iomem *addr)
 441{
 442        unsigned long port = (unsigned long __force)addr;
 443        if (__is_io_address(port))
 444                outb(value, port & PIO_MASK);
 445        else
 446#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 447                __raw_writeb(value, addr);
 448#else
 449                __indirect_writeb(value, addr);
 450#endif
 451}
 452
 453#define iowrite8_rep(p, v, c)           iowrite8_rep(p, v, c)
 454static inline void iowrite8_rep(void __iomem *addr, const void *vaddr,
 455                                u32 count)
 456{
 457        unsigned long port = (unsigned long __force)addr;
 458        if (__is_io_address(port))
 459                outsb(port & PIO_MASK, vaddr, count);
 460        else
 461#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 462                __raw_writesb(addr, vaddr, count);
 463#else
 464                __indirect_writesb(addr, vaddr, count);
 465#endif
 466}
 467
 468#define iowrite16(v, p)                 iowrite16(v, p)
 469static inline void iowrite16(u16 value, void __iomem *addr)
 470{
 471        unsigned long port = (unsigned long __force)addr;
 472        if (__is_io_address(port))
 473                outw(value, port & PIO_MASK);
 474        else
 475#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 476                __raw_writew(cpu_to_le16(value), addr);
 477#else
 478                __indirect_writew(value, addr);
 479#endif
 480}
 481
 482#define iowrite16_rep(p, v, c)          iowrite16_rep(p, v, c)
 483static inline void iowrite16_rep(void __iomem *addr, const void *vaddr,
 484                                 u32 count)
 485{
 486        unsigned long port = (unsigned long __force)addr;
 487        if (__is_io_address(port))
 488                outsw(port & PIO_MASK, vaddr, count);
 489        else
 490#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 491                __raw_writesw(addr, vaddr, count);
 492#else
 493                __indirect_writesw(addr, vaddr, count);
 494#endif
 495}
 496
 497#define iowrite32(v, p)                 iowrite32(v, p)
 498static inline void iowrite32(u32 value, void __iomem *addr)
 499{
 500        unsigned long port = (unsigned long __force)addr;
 501        if (__is_io_address(port))
 502                outl(value, port & PIO_MASK);
 503        else
 504#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 505                __raw_writel((u32 __force)cpu_to_le32(value), addr);
 506#else
 507                __indirect_writel(value, addr);
 508#endif
 509}
 510
 511#define iowrite32_rep(p, v, c)          iowrite32_rep(p, v, c)
 512static inline void iowrite32_rep(void __iomem *addr, const void *vaddr,
 513                                 u32 count)
 514{
 515        unsigned long port = (unsigned long __force)addr;
 516        if (__is_io_address(port))
 517                outsl(port & PIO_MASK, vaddr, count);
 518        else
 519#ifndef CONFIG_IXP4XX_INDIRECT_PCI
 520                __raw_writesl(addr, vaddr, count);
 521#else
 522                __indirect_writesl(addr, vaddr, count);
 523#endif
 524}
 525
 526#define ioport_map(port, nr)            ((void __iomem*)(port + PIO_OFFSET))
 527#define ioport_unmap(addr)
 528#endif /* CONFIG_PCI */
 529
 530#endif /* __ASM_ARM_ARCH_IO_H */
 531