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