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