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