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