Merge branch 'for-linus' into for-next
[deliverable/linux.git] / arch / arm / mach-ixp4xx / include / mach / io.h
CommitLineData
1da177e4 1/*
a09e64fb 2 * arch/arm/mach-ixp4xx/include/mach/io.h
1da177e4
LT
3 *
4 * Author: Deepak Saxena <dsaxena@plexity.net>
5 *
450008b5 6 * Copyright (C) 2002-2005 MontaVista Software, Inc.
1da177e4
LT
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
8e93675e
RW
16#include <linux/bitops.h>
17
a09e64fb 18#include <mach/hardware.h>
1da177e4 19
1da177e4
LT
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 *
ed5b9fa0 27 * 1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
1da177e4
LT
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
ed5b9fa0
KH
31 * limits the system to just 64MB of PCI memory. This can be
32 * problematic if using video cards and other memory-heavy targets.
1da177e4 33 *
ed5b9fa0
KH
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.
1da177e4 41 */
5621caac 42#ifdef CONFIG_IXP4XX_INDIRECT_PCI
1da177e4 43
1da177e4
LT
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 */
cba36222 50
926aabde 51extern unsigned long pcibios_min_mem;
cba36222
KH
52static inline int is_pci_memory(u32 addr)
53{
926aabde 54 return (addr >= pcibios_min_mem) && (addr <= 0x4FFFFFFF);
cba36222
KH
55}
56
28f85cd3
KH
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)
1da177e4 60
e43b21cb
AB
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
28f85cd3
KH
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)
1da177e4 68
28f85cd3
KH
69#define readb(p) __indirect_readb(p)
70#define readw(p) __indirect_readw(p)
71#define readl(p) __indirect_readl(p)
72
e43b21cb
AB
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
28f85cd3
KH
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)
1da177e4 82{
bfca9459 83 u32 addr = (u32)p;
1da177e4
LT
84 u32 n, byte_enables, data;
85
cba36222 86 if (!is_pci_memory(addr)) {
e43b21cb 87 __raw_writeb(value, p);
1da177e4
LT
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
28f85cd3
KH
97static inline void __indirect_writesb(volatile void __iomem *bus_addr,
98 const u8 *vaddr, int count)
1da177e4
LT
99{
100 while (count--)
101 writeb(*vaddr++, bus_addr);
102}
103
28f85cd3 104static inline void __indirect_writew(u16 value, volatile void __iomem *p)
1da177e4 105{
bfca9459 106 u32 addr = (u32)p;
1da177e4
LT
107 u32 n, byte_enables, data;
108
cba36222 109 if (!is_pci_memory(addr)) {
e43b21cb 110 __raw_writew(value, p);
1da177e4
LT
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
28f85cd3
KH
120static inline void __indirect_writesw(volatile void __iomem *bus_addr,
121 const u16 *vaddr, int count)
1da177e4
LT
122{
123 while (count--)
124 writew(*vaddr++, bus_addr);
125}
126
28f85cd3 127static inline void __indirect_writel(u32 value, volatile void __iomem *p)
1da177e4 128{
d2936b19 129 u32 addr = (__force u32)p;
cba36222
KH
130
131 if (!is_pci_memory(addr)) {
d2936b19 132 __raw_writel(value, p);
1da177e4
LT
133 return;
134 }
135
136 ixp4xx_pci_write(addr, NP_CMD_MEMWRITE, value);
137}
138
28f85cd3
KH
139static inline void __indirect_writesl(volatile void __iomem *bus_addr,
140 const u32 *vaddr, int count)
1da177e4
LT
141{
142 while (count--)
143 writel(*vaddr++, bus_addr);
144}
145
d66e5139 146static inline u8 __indirect_readb(const volatile void __iomem *p)
1da177e4 147{
bfca9459 148 u32 addr = (u32)p;
1da177e4
LT
149 u32 n, byte_enables, data;
150
cba36222 151 if (!is_pci_memory(addr))
e43b21cb 152 return __raw_readb(p);
1da177e4
LT
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
28f85cd3
KH
162static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
163 u8 *vaddr, u32 count)
1da177e4
LT
164{
165 while (count--)
166 *vaddr++ = readb(bus_addr);
167}
168
d66e5139 169static inline u16 __indirect_readw(const volatile void __iomem *p)
1da177e4 170{
bfca9459 171 u32 addr = (u32)p;
1da177e4
LT
172 u32 n, byte_enables, data;
173
cba36222 174 if (!is_pci_memory(addr))
e43b21cb 175 return __raw_readw(p);
1da177e4
LT
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
28f85cd3
KH
185static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
186 u16 *vaddr, u32 count)
1da177e4
LT
187{
188 while (count--)
189 *vaddr++ = readw(bus_addr);
190}
191
d66e5139 192static inline u32 __indirect_readl(const volatile void __iomem *p)
1da177e4 193{
d2936b19 194 u32 addr = (__force u32)p;
1da177e4
LT
195 u32 data;
196
cba36222 197 if (!is_pci_memory(addr))
d2936b19 198 return __raw_readl(p);
1da177e4
LT
199
200 if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data))
201 return 0xffffffff;
202
203 return data;
204}
205
28f85cd3
KH
206static inline void __indirect_readsl(const volatile void __iomem *bus_addr,
207 u32 *vaddr, u32 count)
1da177e4
LT
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
28f85cd3 221#endif /* CONFIG_IXP4XX_INDIRECT_PCI */
1da177e4 222
76bbb002
DS
223#ifndef CONFIG_PCI
224
0560cf5a 225#define __io(v) __typesafe_io(v)
76bbb002
DS
226
227#else
228
1da177e4
LT
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 */
1da177e4 236
2e0fa0c9 237#define outb outb
58e570d1 238static inline void outb(u8 value, u32 addr)
1da177e4
LT
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
2e0fa0c9 247#define outsb outsb
1aeb3c5c 248static inline void outsb(u32 io_addr, const void *p, u32 count)
1da177e4 249{
1aeb3c5c
AB
250 const u8 *vaddr = p;
251
1da177e4
LT
252 while (count--)
253 outb(*vaddr++, io_addr);
254}
255
2e0fa0c9 256#define outw outw
58e570d1 257static inline void outw(u16 value, u32 addr)
1da177e4
LT
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
2e0fa0c9 266#define outsw outsw
1aeb3c5c 267static inline void outsw(u32 io_addr, const void *p, u32 count)
1da177e4 268{
1aeb3c5c 269 const u16 *vaddr = p;
1da177e4
LT
270 while (count--)
271 outw(cpu_to_le16(*vaddr++), io_addr);
272}
273
2e0fa0c9 274#define outl outl
58e570d1 275static inline void outl(u32 value, u32 addr)
1da177e4
LT
276{
277 ixp4xx_pci_write(addr, NP_CMD_IOWRITE, value);
278}
279
2e0fa0c9 280#define outsl outsl
1aeb3c5c 281static inline void outsl(u32 io_addr, const void *p, u32 count)
1da177e4 282{
1aeb3c5c 283 const u32 *vaddr = p;
1da177e4 284 while (count--)
9f2c9492 285 outl(cpu_to_le32(*vaddr++), io_addr);
1da177e4
LT
286}
287
2e0fa0c9 288#define inb inb
58e570d1 289static inline u8 inb(u32 addr)
1da177e4
LT
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
2e0fa0c9 300#define insb insb
1aeb3c5c 301static inline void insb(u32 io_addr, void *p, u32 count)
1da177e4 302{
1aeb3c5c 303 u8 *vaddr = p;
1da177e4
LT
304 while (count--)
305 *vaddr++ = inb(io_addr);
306}
307
2e0fa0c9 308#define inw inw
58e570d1 309static inline u16 inw(u32 addr)
1da177e4
LT
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
2e0fa0c9 320#define insw insw
1aeb3c5c 321static inline void insw(u32 io_addr, void *p, u32 count)
1da177e4 322{
1aeb3c5c 323 u16 *vaddr = p;
1da177e4
LT
324 while (count--)
325 *vaddr++ = le16_to_cpu(inw(io_addr));
326}
327
2e0fa0c9 328#define inl inl
58e570d1 329static inline u32 inl(u32 addr)
1da177e4
LT
330{
331 u32 data;
332 if (ixp4xx_pci_read(addr, NP_CMD_IOREAD, &data))
333 return 0xffffffff;
334
335 return data;
336}
337
2e0fa0c9 338#define insl insl
1aeb3c5c 339static inline void insl(u32 io_addr, void *p, u32 count)
1da177e4 340{
1aeb3c5c 341 u32 *vaddr = p;
1da177e4 342 while (count--)
9f2c9492 343 *vaddr++ = le32_to_cpu(inl(io_addr));
1da177e4
LT
344}
345
147056fb
DV
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)))
9f2c9492 351
58e570d1 352#define ioread8(p) ioread8(p)
d66e5139 353static inline u8 ioread8(const void __iomem *addr)
450008b5 354{
147056fb 355 unsigned long port = (unsigned long __force)addr;
450008b5 356 if (__is_io_address(port))
58e570d1 357 return (unsigned int)inb(port & PIO_MASK);
450008b5
DS
358 else
359#ifndef CONFIG_IXP4XX_INDIRECT_PCI
59c29017 360 return (unsigned int)__raw_readb(addr);
450008b5 361#else
28f85cd3 362 return (unsigned int)__indirect_readb(addr);
450008b5
DS
363#endif
364}
365
58e570d1
KH
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)
450008b5 368{
147056fb 369 unsigned long port = (unsigned long __force)addr;
450008b5 370 if (__is_io_address(port))
58e570d1 371 insb(port & PIO_MASK, vaddr, count);
450008b5
DS
372 else
373#ifndef CONFIG_IXP4XX_INDIRECT_PCI
147056fb 374 __raw_readsb(addr, vaddr, count);
450008b5 375#else
28f85cd3 376 __indirect_readsb(addr, vaddr, count);
450008b5
DS
377#endif
378}
379
58e570d1 380#define ioread16(p) ioread16(p)
d66e5139 381static inline u16 ioread16(const void __iomem *addr)
450008b5 382{
147056fb 383 unsigned long port = (unsigned long __force)addr;
450008b5 384 if (__is_io_address(port))
58e570d1 385 return (unsigned int)inw(port & PIO_MASK);
450008b5
DS
386 else
387#ifndef CONFIG_IXP4XX_INDIRECT_PCI
59c29017 388 return le16_to_cpu((__force __le16)__raw_readw(addr));
450008b5 389#else
28f85cd3 390 return (unsigned int)__indirect_readw(addr);
450008b5
DS
391#endif
392}
393
58e570d1
KH
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)
450008b5 397{
147056fb 398 unsigned long port = (unsigned long __force)addr;
450008b5 399 if (__is_io_address(port))
58e570d1 400 insw(port & PIO_MASK, vaddr, count);
450008b5
DS
401 else
402#ifndef CONFIG_IXP4XX_INDIRECT_PCI
147056fb 403 __raw_readsw(addr, vaddr, count);
450008b5 404#else
28f85cd3 405 __indirect_readsw(addr, vaddr, count);
450008b5
DS
406#endif
407}
408
58e570d1 409#define ioread32(p) ioread32(p)
d66e5139 410static inline u32 ioread32(const void __iomem *addr)
450008b5 411{
147056fb 412 unsigned long port = (unsigned long __force)addr;
450008b5 413 if (__is_io_address(port))
58e570d1 414 return (unsigned int)inl(port & PIO_MASK);
450008b5
DS
415 else {
416#ifndef CONFIG_IXP4XX_INDIRECT_PCI
d2936b19 417 return le32_to_cpu((__force __le32)__raw_readl(addr));
450008b5 418#else
28f85cd3 419 return (unsigned int)__indirect_readl(addr);
450008b5
DS
420#endif
421 }
422}
423
58e570d1
KH
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)
450008b5 427{
147056fb 428 unsigned long port = (unsigned long __force)addr;
450008b5 429 if (__is_io_address(port))
58e570d1 430 insl(port & PIO_MASK, vaddr, count);
450008b5
DS
431 else
432#ifndef CONFIG_IXP4XX_INDIRECT_PCI
147056fb 433 __raw_readsl(addr, vaddr, count);
450008b5 434#else
28f85cd3 435 __indirect_readsl(addr, vaddr, count);
450008b5
DS
436#endif
437}
438
58e570d1
KH
439#define iowrite8(v, p) iowrite8(v, p)
440static inline void iowrite8(u8 value, void __iomem *addr)
450008b5 441{
147056fb 442 unsigned long port = (unsigned long __force)addr;
450008b5 443 if (__is_io_address(port))
58e570d1 444 outb(value, port & PIO_MASK);
450008b5
DS
445 else
446#ifndef CONFIG_IXP4XX_INDIRECT_PCI
59c29017 447 __raw_writeb(value, addr);
450008b5 448#else
28f85cd3 449 __indirect_writeb(value, addr);
450008b5
DS
450#endif
451}
452
58e570d1
KH
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)
450008b5 456{
147056fb 457 unsigned long port = (unsigned long __force)addr;
450008b5 458 if (__is_io_address(port))
58e570d1 459 outsb(port & PIO_MASK, vaddr, count);
147056fb 460 else
450008b5 461#ifndef CONFIG_IXP4XX_INDIRECT_PCI
147056fb 462 __raw_writesb(addr, vaddr, count);
450008b5 463#else
28f85cd3 464 __indirect_writesb(addr, vaddr, count);
450008b5
DS
465#endif
466}
467
58e570d1
KH
468#define iowrite16(v, p) iowrite16(v, p)
469static inline void iowrite16(u16 value, void __iomem *addr)
450008b5 470{
147056fb 471 unsigned long port = (unsigned long __force)addr;
450008b5 472 if (__is_io_address(port))
58e570d1 473 outw(value, port & PIO_MASK);
450008b5
DS
474 else
475#ifndef CONFIG_IXP4XX_INDIRECT_PCI
147056fb 476 __raw_writew(cpu_to_le16(value), addr);
450008b5 477#else
28f85cd3 478 __indirect_writew(value, addr);
450008b5
DS
479#endif
480}
481
58e570d1
KH
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)
450008b5 485{
147056fb 486 unsigned long port = (unsigned long __force)addr;
450008b5 487 if (__is_io_address(port))
58e570d1 488 outsw(port & PIO_MASK, vaddr, count);
147056fb 489 else
450008b5 490#ifndef CONFIG_IXP4XX_INDIRECT_PCI
147056fb 491 __raw_writesw(addr, vaddr, count);
450008b5 492#else
28f85cd3 493 __indirect_writesw(addr, vaddr, count);
450008b5
DS
494#endif
495}
496
58e570d1
KH
497#define iowrite32(v, p) iowrite32(v, p)
498static inline void iowrite32(u32 value, void __iomem *addr)
450008b5 499{
147056fb 500 unsigned long port = (unsigned long __force)addr;
450008b5 501 if (__is_io_address(port))
58e570d1 502 outl(value, port & PIO_MASK);
450008b5
DS
503 else
504#ifndef CONFIG_IXP4XX_INDIRECT_PCI
d2936b19 505 __raw_writel((u32 __force)cpu_to_le32(value), addr);
450008b5 506#else
28f85cd3 507 __indirect_writel(value, addr);
450008b5
DS
508#endif
509}
510
58e570d1
KH
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)
450008b5 514{
147056fb 515 unsigned long port = (unsigned long __force)addr;
450008b5 516 if (__is_io_address(port))
58e570d1 517 outsl(port & PIO_MASK, vaddr, count);
147056fb 518 else
450008b5 519#ifndef CONFIG_IXP4XX_INDIRECT_PCI
147056fb 520 __raw_writesl(addr, vaddr, count);
450008b5 521#else
28f85cd3 522 __indirect_writesl(addr, vaddr, count);
450008b5
DS
523#endif
524}
525
147056fb 526#define ioport_map(port, nr) ((void __iomem*)(port + PIO_OFFSET))
450008b5 527#define ioport_unmap(addr)
58e570d1 528#endif /* CONFIG_PCI */
1da177e4 529
58e570d1 530#endif /* __ASM_ARM_ARCH_IO_H */
This page took 0.770947 seconds and 5 git commands to generate.