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