xref: /openbmc/linux/arch/sh/include/asm/io.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2f15cbe6fSPaul Mundt #ifndef __ASM_SH_IO_H
3f15cbe6fSPaul Mundt #define __ASM_SH_IO_H
437b7a978SPaul Mundt 
5f15cbe6fSPaul Mundt /*
6f15cbe6fSPaul Mundt  * Convention:
714866543SPaul Mundt  *    read{b,w,l,q}/write{b,w,l,q} are for PCI,
8f15cbe6fSPaul Mundt  *    while in{b,w,l}/out{b,w,l} are for ISA
914866543SPaul Mundt  *
10f15cbe6fSPaul Mundt  * In addition we have 'pausing' versions: in{b,w,l}_p/out{b,w,l}_p
11f15cbe6fSPaul Mundt  * and 'string' versions: ins{b,w,l}/outs{b,w,l}
12f15cbe6fSPaul Mundt  *
1314866543SPaul Mundt  * While read{b,w,l,q} and write{b,w,l,q} contain memory barriers
1414866543SPaul Mundt  * automatically, there are also __raw versions, which do not.
15f15cbe6fSPaul Mundt  */
164f744affSPaul Mundt #include <linux/errno.h>
17f15cbe6fSPaul Mundt #include <asm/cache.h>
18f15cbe6fSPaul Mundt #include <asm/addrspace.h>
19f15cbe6fSPaul Mundt #include <asm/machvec.h>
200cd39f46SPeter Zijlstra #include <asm/page.h>
21ca5999fdSMike Rapoport #include <linux/pgtable.h>
22f15cbe6fSPaul Mundt #include <asm-generic/iomap.h>
23f15cbe6fSPaul Mundt 
24f15cbe6fSPaul Mundt #define __IO_PREFIX     generic
25f15cbe6fSPaul Mundt #include <asm/io_generic.h>
26915c9e1bSMark Brown #include <asm-generic/pci_iomap.h>
27b7e68d68SPaul Mundt #include <mach/mangle-port.h>
28f15cbe6fSPaul Mundt 
2914866543SPaul Mundt #define __raw_writeb(v,a)	(__chk_io_ptr(a), *(volatile u8  __force *)(a) = (v))
3014866543SPaul Mundt #define __raw_writew(v,a)	(__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v))
3114866543SPaul Mundt #define __raw_writel(v,a)	(__chk_io_ptr(a), *(volatile u32 __force *)(a) = (v))
3214866543SPaul Mundt #define __raw_writeq(v,a)	(__chk_io_ptr(a), *(volatile u64 __force *)(a) = (v))
33f15cbe6fSPaul Mundt 
3414866543SPaul Mundt #define __raw_readb(a)		(__chk_io_ptr(a), *(volatile u8  __force *)(a))
3514866543SPaul Mundt #define __raw_readw(a)		(__chk_io_ptr(a), *(volatile u16 __force *)(a))
3614866543SPaul Mundt #define __raw_readl(a)		(__chk_io_ptr(a), *(volatile u32 __force *)(a))
3714866543SPaul Mundt #define __raw_readq(a)		(__chk_io_ptr(a), *(volatile u64 __force *)(a))
38f15cbe6fSPaul Mundt 
39b7e68d68SPaul Mundt #define readb_relaxed(c)	({ u8  __v = ioswabb(__raw_readb(c)); __v; })
40b7e68d68SPaul Mundt #define readw_relaxed(c)	({ u16 __v = ioswabw(__raw_readw(c)); __v; })
41b7e68d68SPaul Mundt #define readl_relaxed(c)	({ u32 __v = ioswabl(__raw_readl(c)); __v; })
42b7e68d68SPaul Mundt #define readq_relaxed(c)	({ u64 __v = ioswabq(__raw_readq(c)); __v; })
43f15cbe6fSPaul Mundt 
44b7e68d68SPaul Mundt #define writeb_relaxed(v,c)	((void)__raw_writeb((__force  u8)ioswabb(v),c))
45b7e68d68SPaul Mundt #define writew_relaxed(v,c)	((void)__raw_writew((__force u16)ioswabw(v),c))
46b7e68d68SPaul Mundt #define writel_relaxed(v,c)	((void)__raw_writel((__force u32)ioswabl(v),c))
47b7e68d68SPaul Mundt #define writeq_relaxed(v,c)	((void)__raw_writeq((__force u64)ioswabq(v),c))
4837b7a978SPaul Mundt 
4937b7a978SPaul Mundt #define readb(a)		({ u8  r_ = readb_relaxed(a); rmb(); r_; })
5037b7a978SPaul Mundt #define readw(a)		({ u16 r_ = readw_relaxed(a); rmb(); r_; })
5137b7a978SPaul Mundt #define readl(a)		({ u32 r_ = readl_relaxed(a); rmb(); r_; })
5237b7a978SPaul Mundt #define readq(a)		({ u64 r_ = readq_relaxed(a); rmb(); r_; })
5337b7a978SPaul Mundt 
5437b7a978SPaul Mundt #define writeb(v,a)		({ wmb(); writeb_relaxed((v),(a)); })
5537b7a978SPaul Mundt #define writew(v,a)		({ wmb(); writew_relaxed((v),(a)); })
5637b7a978SPaul Mundt #define writel(v,a)		({ wmb(); writel_relaxed((v),(a)); })
5737b7a978SPaul Mundt #define writeq(v,a)		({ wmb(); writeq_relaxed((v),(a)); })
5837b7a978SPaul Mundt 
5937b7a978SPaul Mundt #define readsb(p,d,l)		__raw_readsb(p,d,l)
6037b7a978SPaul Mundt #define readsw(p,d,l)		__raw_readsw(p,d,l)
6137b7a978SPaul Mundt #define readsl(p,d,l)		__raw_readsl(p,d,l)
6237b7a978SPaul Mundt 
6337b7a978SPaul Mundt #define writesb(p,d,l)		__raw_writesb(p,d,l)
6437b7a978SPaul Mundt #define writesw(p,d,l)		__raw_writesw(p,d,l)
6537b7a978SPaul Mundt #define writesl(p,d,l)		__raw_writesl(p,d,l)
6637b7a978SPaul Mundt 
6737b7a978SPaul Mundt #define __BUILD_UNCACHED_IO(bwlq, type)					\
6837b7a978SPaul Mundt static inline type read##bwlq##_uncached(unsigned long addr)		\
6937b7a978SPaul Mundt {									\
7037b7a978SPaul Mundt 	type ret;							\
7137b7a978SPaul Mundt 	jump_to_uncached();						\
7237b7a978SPaul Mundt 	ret = __raw_read##bwlq(addr);					\
7337b7a978SPaul Mundt 	back_to_cached();						\
7437b7a978SPaul Mundt 	return ret;							\
7537b7a978SPaul Mundt }									\
7637b7a978SPaul Mundt 									\
7737b7a978SPaul Mundt static inline void write##bwlq##_uncached(type v, unsigned long addr)	\
7837b7a978SPaul Mundt {									\
7937b7a978SPaul Mundt 	jump_to_uncached();						\
8037b7a978SPaul Mundt 	__raw_write##bwlq(v, addr);					\
8137b7a978SPaul Mundt 	back_to_cached();						\
8237b7a978SPaul Mundt }
8337b7a978SPaul Mundt 
8437b7a978SPaul Mundt __BUILD_UNCACHED_IO(b, u8)
8537b7a978SPaul Mundt __BUILD_UNCACHED_IO(w, u16)
8637b7a978SPaul Mundt __BUILD_UNCACHED_IO(l, u32)
8737b7a978SPaul Mundt __BUILD_UNCACHED_IO(q, u64)
8837b7a978SPaul Mundt 
8937b7a978SPaul Mundt #define __BUILD_MEMORY_STRING(pfx, bwlq, type)				\
9037b7a978SPaul Mundt 									\
9137b7a978SPaul Mundt static inline void							\
9237b7a978SPaul Mundt pfx##writes##bwlq(volatile void __iomem *mem, const void *addr,		\
9337b7a978SPaul Mundt 		  unsigned int count)					\
9437b7a978SPaul Mundt {									\
9537b7a978SPaul Mundt 	const volatile type *__addr = addr;				\
9637b7a978SPaul Mundt 									\
9737b7a978SPaul Mundt 	while (count--) {						\
9837b7a978SPaul Mundt 		__raw_write##bwlq(*__addr, mem);			\
9937b7a978SPaul Mundt 		__addr++;						\
10037b7a978SPaul Mundt 	}								\
10137b7a978SPaul Mundt }									\
10237b7a978SPaul Mundt 									\
10337b7a978SPaul Mundt static inline void pfx##reads##bwlq(volatile void __iomem *mem,		\
10437b7a978SPaul Mundt 				    void *addr, unsigned int count)	\
10537b7a978SPaul Mundt {									\
10637b7a978SPaul Mundt 	volatile type *__addr = addr;					\
10737b7a978SPaul Mundt 									\
10837b7a978SPaul Mundt 	while (count--) {						\
10937b7a978SPaul Mundt 		*__addr = __raw_read##bwlq(mem);			\
11037b7a978SPaul Mundt 		__addr++;						\
11137b7a978SPaul Mundt 	}								\
11237b7a978SPaul Mundt }
11337b7a978SPaul Mundt 
11437b7a978SPaul Mundt __BUILD_MEMORY_STRING(__raw_, b, u8)
11537b7a978SPaul Mundt __BUILD_MEMORY_STRING(__raw_, w, u16)
11637b7a978SPaul Mundt 
11737b7a978SPaul Mundt void __raw_writesl(void __iomem *addr, const void *data, int longlen);
11837b7a978SPaul Mundt void __raw_readsl(const void __iomem *addr, void *data, int longlen);
11937b7a978SPaul Mundt 
12037b7a978SPaul Mundt __BUILD_MEMORY_STRING(__raw_, q, u64)
12137b7a978SPaul Mundt 
122b94692e8SBaoquan He #define ioport_map ioport_map
123b94692e8SBaoquan He #define ioport_unmap ioport_unmap
124b94692e8SBaoquan He #define pci_iounmap pci_iounmap
125b94692e8SBaoquan He 
126b94692e8SBaoquan He #define ioread8 ioread8
127b94692e8SBaoquan He #define ioread16 ioread16
128b94692e8SBaoquan He #define ioread16be ioread16be
129b94692e8SBaoquan He #define ioread32 ioread32
130b94692e8SBaoquan He #define ioread32be ioread32be
131b94692e8SBaoquan He 
132b94692e8SBaoquan He #define iowrite8 iowrite8
133b94692e8SBaoquan He #define iowrite16 iowrite16
134b94692e8SBaoquan He #define iowrite16be iowrite16be
135b94692e8SBaoquan He #define iowrite32 iowrite32
136b94692e8SBaoquan He #define iowrite32be iowrite32be
137b94692e8SBaoquan He 
138b94692e8SBaoquan He #define ioread8_rep ioread8_rep
139b94692e8SBaoquan He #define ioread16_rep ioread16_rep
140b94692e8SBaoquan He #define ioread32_rep ioread32_rep
141b94692e8SBaoquan He 
142b94692e8SBaoquan He #define iowrite8_rep iowrite8_rep
143b94692e8SBaoquan He #define iowrite16_rep iowrite16_rep
144b94692e8SBaoquan He #define iowrite32_rep iowrite32_rep
145b94692e8SBaoquan He 
146ce816fa8SUwe Kleine-König #ifdef CONFIG_HAS_IOPORT_MAP
14737b7a978SPaul Mundt 
14837b7a978SPaul Mundt /*
14937b7a978SPaul Mundt  * Slowdown I/O port space accesses for antique hardware.
15037b7a978SPaul Mundt  */
15137b7a978SPaul Mundt #undef CONF_SLOWDOWN_IO
15237b7a978SPaul Mundt 
15337b7a978SPaul Mundt /*
15437b7a978SPaul Mundt  * On SuperH I/O ports are memory mapped, so we access them using normal
15537b7a978SPaul Mundt  * load/store instructions. sh_io_port_base is the virtual address to
15637b7a978SPaul Mundt  * which all ports are being mapped.
15737b7a978SPaul Mundt  */
158666e81fdSAndi Kleen extern unsigned long sh_io_port_base;
15937b7a978SPaul Mundt 
__set_io_port_base(unsigned long pbase)16037b7a978SPaul Mundt static inline void __set_io_port_base(unsigned long pbase)
16137b7a978SPaul Mundt {
16237b7a978SPaul Mundt 	*(unsigned long *)&sh_io_port_base = pbase;
16337b7a978SPaul Mundt 	barrier();
16437b7a978SPaul Mundt }
16537b7a978SPaul Mundt 
16637b7a978SPaul Mundt #ifdef CONFIG_GENERIC_IOMAP
16737b7a978SPaul Mundt #define __ioport_map ioport_map
16837b7a978SPaul Mundt #else
16937b7a978SPaul Mundt extern void __iomem *__ioport_map(unsigned long addr, unsigned int size);
17037b7a978SPaul Mundt #endif
17137b7a978SPaul Mundt 
17237b7a978SPaul Mundt #ifdef CONF_SLOWDOWN_IO
17337b7a978SPaul Mundt #define SLOW_DOWN_IO __raw_readw(sh_io_port_base)
17437b7a978SPaul Mundt #else
17537b7a978SPaul Mundt #define SLOW_DOWN_IO
17637b7a978SPaul Mundt #endif
17737b7a978SPaul Mundt 
17837b7a978SPaul Mundt #define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow)			\
17937b7a978SPaul Mundt 									\
18037b7a978SPaul Mundt static inline void pfx##out##bwlq##p(type val, unsigned long port)	\
18137b7a978SPaul Mundt {									\
18237b7a978SPaul Mundt 	volatile type *__addr;						\
18337b7a978SPaul Mundt 									\
18437b7a978SPaul Mundt 	__addr = __ioport_map(port, sizeof(type));			\
18537b7a978SPaul Mundt 	*__addr = val;							\
18637b7a978SPaul Mundt 	slow;								\
18737b7a978SPaul Mundt }									\
18837b7a978SPaul Mundt 									\
18937b7a978SPaul Mundt static inline type pfx##in##bwlq##p(unsigned long port)			\
19037b7a978SPaul Mundt {									\
19137b7a978SPaul Mundt 	volatile type *__addr;						\
19237b7a978SPaul Mundt 	type __val;							\
19337b7a978SPaul Mundt 									\
19437b7a978SPaul Mundt 	__addr = __ioport_map(port, sizeof(type));			\
19537b7a978SPaul Mundt 	__val = *__addr;						\
19637b7a978SPaul Mundt 	slow;								\
19737b7a978SPaul Mundt 									\
19837b7a978SPaul Mundt 	return __val;							\
19937b7a978SPaul Mundt }
20037b7a978SPaul Mundt 
20137b7a978SPaul Mundt #define __BUILD_IOPORT_PFX(bus, bwlq, type)				\
20237b7a978SPaul Mundt 	__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,)			\
20337b7a978SPaul Mundt 	__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
20437b7a978SPaul Mundt 
20537b7a978SPaul Mundt #define BUILDIO_IOPORT(bwlq, type)					\
20637b7a978SPaul Mundt 	__BUILD_IOPORT_PFX(, bwlq, type)
20737b7a978SPaul Mundt 
20837b7a978SPaul Mundt BUILDIO_IOPORT(b, u8)
20937b7a978SPaul Mundt BUILDIO_IOPORT(w, u16)
21037b7a978SPaul Mundt BUILDIO_IOPORT(l, u32)
21137b7a978SPaul Mundt BUILDIO_IOPORT(q, u64)
21237b7a978SPaul Mundt 
21337b7a978SPaul Mundt #define __BUILD_IOPORT_STRING(bwlq, type)				\
21437b7a978SPaul Mundt 									\
21537b7a978SPaul Mundt static inline void outs##bwlq(unsigned long port, const void *addr,	\
21637b7a978SPaul Mundt 			      unsigned int count)			\
21737b7a978SPaul Mundt {									\
21837b7a978SPaul Mundt 	const volatile type *__addr = addr;				\
21937b7a978SPaul Mundt 									\
22037b7a978SPaul Mundt 	while (count--) {						\
22137b7a978SPaul Mundt 		out##bwlq(*__addr, port);				\
22237b7a978SPaul Mundt 		__addr++;						\
22337b7a978SPaul Mundt 	}								\
22437b7a978SPaul Mundt }									\
22537b7a978SPaul Mundt 									\
22637b7a978SPaul Mundt static inline void ins##bwlq(unsigned long port, void *addr,		\
22737b7a978SPaul Mundt 			     unsigned int count)			\
22837b7a978SPaul Mundt {									\
22937b7a978SPaul Mundt 	volatile type *__addr = addr;					\
23037b7a978SPaul Mundt 									\
23137b7a978SPaul Mundt 	while (count--) {						\
23237b7a978SPaul Mundt 		*__addr = in##bwlq(port);				\
23337b7a978SPaul Mundt 		__addr++;						\
23437b7a978SPaul Mundt 	}								\
23537b7a978SPaul Mundt }
23637b7a978SPaul Mundt 
23737b7a978SPaul Mundt __BUILD_IOPORT_STRING(b, u8)
23837b7a978SPaul Mundt __BUILD_IOPORT_STRING(w, u16)
23937b7a978SPaul Mundt __BUILD_IOPORT_STRING(l, u32)
24037b7a978SPaul Mundt __BUILD_IOPORT_STRING(q, u64)
24137b7a978SPaul Mundt 
242ce816fa8SUwe Kleine-König #else /* !CONFIG_HAS_IOPORT_MAP */
243c5e50fa9SPaul Mundt 
244c5e50fa9SPaul Mundt #include <asm/io_noioport.h>
245c5e50fa9SPaul Mundt 
24637b7a978SPaul Mundt #endif
247f15cbe6fSPaul Mundt 
248b94692e8SBaoquan He #define inb(addr)      inb(addr)
249b94692e8SBaoquan He #define inw(addr)      inw(addr)
250b94692e8SBaoquan He #define inl(addr)      inl(addr)
251b94692e8SBaoquan He #define outb(x, addr)  outb((x), (addr))
252b94692e8SBaoquan He #define outw(x, addr)  outw((x), (addr))
253b94692e8SBaoquan He #define outl(x, addr)  outl((x), (addr))
254b94692e8SBaoquan He 
255b94692e8SBaoquan He #define inb_p(addr)    inb(addr)
256b94692e8SBaoquan He #define inw_p(addr)    inw(addr)
257b94692e8SBaoquan He #define inl_p(addr)    inl(addr)
258b94692e8SBaoquan He #define outb_p(x, addr)        outb((x), (addr))
259b94692e8SBaoquan He #define outw_p(x, addr)        outw((x), (addr))
260b94692e8SBaoquan He #define outl_p(x, addr)        outl((x), (addr))
261b94692e8SBaoquan He 
262b94692e8SBaoquan He #define insb insb
263b94692e8SBaoquan He #define insw insw
264b94692e8SBaoquan He #define insl insl
265b94692e8SBaoquan He #define outsb outsb
266b94692e8SBaoquan He #define outsw outsw
267b94692e8SBaoquan He #define outsl outsl
268c5e50fa9SPaul Mundt 
26937b7a978SPaul Mundt #define IO_SPACE_LIMIT 0xffffffff
270f15cbe6fSPaul Mundt 
271f15cbe6fSPaul Mundt /* We really want to try and get these to memcpy etc */
272b94692e8SBaoquan He #define memset_io memset_io
273b94692e8SBaoquan He #define memcpy_fromio memcpy_fromio
274b94692e8SBaoquan He #define memcpy_toio memcpy_toio
27514866543SPaul Mundt void memcpy_fromio(void *, const volatile void __iomem *, unsigned long);
27614866543SPaul Mundt void memcpy_toio(volatile void __iomem *, const void *, unsigned long);
27714866543SPaul Mundt void memset_io(volatile void __iomem *, int, unsigned long);
278f15cbe6fSPaul Mundt 
279f15cbe6fSPaul Mundt /* Quad-word real-mode I/O, don't ask.. */
280f15cbe6fSPaul Mundt unsigned long long peek_real_address_q(unsigned long long addr);
281f15cbe6fSPaul Mundt unsigned long long poke_real_address_q(unsigned long long addr,
282f15cbe6fSPaul Mundt 				       unsigned long long val);
283f15cbe6fSPaul Mundt 
284f15cbe6fSPaul Mundt #if !defined(CONFIG_MMU)
285f15cbe6fSPaul Mundt #define virt_to_phys(address)	((unsigned long)(address))
286f15cbe6fSPaul Mundt #define phys_to_virt(address)	((void *)(address))
287f15cbe6fSPaul Mundt #else
288f15cbe6fSPaul Mundt #define virt_to_phys(address)	(__pa(address))
289f15cbe6fSPaul Mundt #define phys_to_virt(address)	(__va(address))
290f15cbe6fSPaul Mundt #endif
291f15cbe6fSPaul Mundt 
292f15cbe6fSPaul Mundt #ifdef CONFIG_MMU
293*0453c9a7SBaoquan He /*
294*0453c9a7SBaoquan He  * I/O memory mapping functions.
295*0453c9a7SBaoquan He  */
296*0453c9a7SBaoquan He #define ioremap_prot ioremap_prot
297*0453c9a7SBaoquan He #define iounmap iounmap
298f15cbe6fSPaul Mundt 
299*0453c9a7SBaoquan He #define _PAGE_IOREMAP pgprot_val(PAGE_KERNEL_NOCACHE)
300d57d6408SPaul Mundt 
301*0453c9a7SBaoquan He #define ioremap_cache(addr, size)  \
302*0453c9a7SBaoquan He 	ioremap_prot((addr), (size), pgprot_val(PAGE_KERNEL))
30313f1fc87SChristoph Hellwig #endif /* CONFIG_MMU */
304d627a2ebSPaul Mundt 
3054c73e892SLuis R. Rodriguez #define ioremap_uc	ioremap
306733f0025SSam Ravnborg 
307f15cbe6fSPaul Mundt /*
308f15cbe6fSPaul Mundt  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
309f15cbe6fSPaul Mundt  * access
310f15cbe6fSPaul Mundt  */
311f15cbe6fSPaul Mundt #define xlate_dev_mem_ptr(p)	__va(p)
3127497840dSGuenter Roeck #define unxlate_dev_mem_ptr(p, v) do { } while (0)
313f15cbe6fSPaul Mundt 
314b94692e8SBaoquan He #include <asm-generic/io.h>
315b94692e8SBaoquan He 
316185aed75SPaul Mundt #define ARCH_HAS_VALID_PHYS_ADDR_RANGE
3177e6735c3SCyril Chemparathy int valid_phys_addr_range(phys_addr_t addr, size_t size);
318185aed75SPaul Mundt int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
319185aed75SPaul Mundt 
320f15cbe6fSPaul Mundt #endif /* __ASM_SH_IO_H */
321