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