Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-ixp4xx/include/mach/io.h
17687 views
1
/*
2
* arch/arm/mach-ixp4xx/include/mach/io.h
3
*
4
* Author: Deepak Saxena <[email protected]>
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
22
extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
23
extern 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
57
static inline int is_pci_memory(u32 addr)
58
{
59
return (addr >= PCIBIOS_MIN_MEM) && (addr <= 0x4FFFFFFF);
60
}
61
62
static 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
71
static 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 __indirect_ioremap
78
#define __arch_iounmap __indirect_iounmap
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
96
static 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
112
static 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
119
static 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
135
static 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
142
static 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
154
static 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
161
static 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
177
static 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
184
static 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
200
static 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
207
static 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
221
static 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
252
static 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
261
static inline void outsb(u32 io_addr, const u8 *vaddr, u32 count)
262
{
263
while (count--)
264
outb(*vaddr++, io_addr);
265
}
266
267
static 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
276
static 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
282
static inline void outl(u32 value, u32 addr)
283
{
284
ixp4xx_pci_write(addr, NP_CMD_IOWRITE, value);
285
}
286
287
static 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
293
static 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
304
static inline void insb(u32 io_addr, u8 *vaddr, u32 count)
305
{
306
while (count--)
307
*vaddr++ = inb(io_addr);
308
}
309
310
static 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
321
static inline void insw(u32 io_addr, u16 *vaddr, u32 count)
322
{
323
while (count--)
324
*vaddr++ = le16_to_cpu(inw(io_addr));
325
}
326
327
static 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
336
static 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)
349
static 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)
363
static 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)
377
static 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)
391
static 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)
406
static 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)
421
static 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)
436
static 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)
450
static 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)
465
static 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)
479
static 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)
494
static 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)
508
static 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
528