xref: /OK3568_Linux_fs/u-boot/arch/m68k/include/asm/io.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * IO header file
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc.
5*4882a593Smuzhiyun  * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #ifndef __ASM_M68K_IO_H__
11*4882a593Smuzhiyun #define __ASM_M68K_IO_H__
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <asm/byteorder.h>
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #ifndef _IO_BASE
16*4882a593Smuzhiyun #define _IO_BASE 0
17*4882a593Smuzhiyun #endif
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #define __raw_readb(addr) (*(volatile u8 *)(addr))
20*4882a593Smuzhiyun #define __raw_readw(addr) (*(volatile u16 *)(addr))
21*4882a593Smuzhiyun #define __raw_readl(addr) (*(volatile u32 *)(addr))
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #define __raw_writeb(b,addr) ((*(volatile u8 *) (addr)) = (b))
24*4882a593Smuzhiyun #define __raw_writew(w,addr) ((*(volatile u16 *) (addr)) = (w))
25*4882a593Smuzhiyun #define __raw_writel(l,addr) ((*(volatile u32 *) (addr)) = (l))
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define readb(addr)		in_8((volatile u8 *)(addr))
28*4882a593Smuzhiyun #define writeb(b,addr)		out_8((volatile u8 *)(addr), (b))
29*4882a593Smuzhiyun #if !defined(__BIG_ENDIAN)
30*4882a593Smuzhiyun #define readw(addr)		(*(volatile u16 *) (addr))
31*4882a593Smuzhiyun #define readl(addr)		(*(volatile u32 *) (addr))
32*4882a593Smuzhiyun #define writew(b,addr)		((*(volatile u16 *) (addr)) = (b))
33*4882a593Smuzhiyun #define writel(b,addr)		((*(volatile u32 *) (addr)) = (b))
34*4882a593Smuzhiyun #else
35*4882a593Smuzhiyun #define readw(addr)		in_be16((volatile u16 *)(addr))
36*4882a593Smuzhiyun #define readl(addr)		in_be32((volatile u32 *)(addr))
37*4882a593Smuzhiyun #define writew(b,addr)		out_be16((volatile u16 *)(addr),(b))
38*4882a593Smuzhiyun #define writel(b,addr)		out_be32((volatile u32 *)(addr),(b))
39*4882a593Smuzhiyun #endif
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /*
42*4882a593Smuzhiyun  * The insw/outsw/insl/outsl macros don't do byte-swapping.
43*4882a593Smuzhiyun  * They are only used in practice for transferring buffers which
44*4882a593Smuzhiyun  * are arrays of bytes, and byte-swapping is not appropriate in
45*4882a593Smuzhiyun  * that case.  - paulus
46*4882a593Smuzhiyun  */
47*4882a593Smuzhiyun #define insb(port, buf, ns)	_insb((u8 *)((port)+_IO_BASE), (buf), (ns))
48*4882a593Smuzhiyun #define outsb(port, buf, ns)	_outsb((u8 *)((port)+_IO_BASE), (buf), (ns))
49*4882a593Smuzhiyun #define insw(port, buf, ns)	_insw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
50*4882a593Smuzhiyun #define outsw(port, buf, ns)	_outsw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
51*4882a593Smuzhiyun #define insl(port, buf, nl)	_insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
52*4882a593Smuzhiyun #define outsl(port, buf, nl)	_outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define inb(port)		in_8((u8 *)((port)+_IO_BASE))
55*4882a593Smuzhiyun #define outb(val, port)		out_8((u8 *)((port)+_IO_BASE), (val))
56*4882a593Smuzhiyun #if !defined(__BIG_ENDIAN)
57*4882a593Smuzhiyun #define inw(port)		in_be16((u16 *)((port)+_IO_BASE))
58*4882a593Smuzhiyun #define outw(val, port)		out_be16((u16 *)((port)+_IO_BASE), (val))
59*4882a593Smuzhiyun #define inl(port)		in_be32((u32 *)((port)+_IO_BASE))
60*4882a593Smuzhiyun #define outl(val, port)		out_be32((u32 *)((port)+_IO_BASE), (val))
61*4882a593Smuzhiyun #else
62*4882a593Smuzhiyun #define inw(port)		in_le16((u16 *)((port)+_IO_BASE))
63*4882a593Smuzhiyun #define outw(val, port)		out_le16((u16 *)((port)+_IO_BASE), (val))
64*4882a593Smuzhiyun #define inl(port)		in_le32((u32 *)((port)+_IO_BASE))
65*4882a593Smuzhiyun #define outl(val, port)		out_le32((u32 *)((port)+_IO_BASE), (val))
66*4882a593Smuzhiyun #endif
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun #define mb() __asm__ __volatile__ ("" : : : "memory")
69*4882a593Smuzhiyun 
_insb(volatile u8 * port,void * buf,int ns)70*4882a593Smuzhiyun static inline void _insb(volatile u8 * port, void *buf, int ns)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	u8 *data = (u8 *) buf;
73*4882a593Smuzhiyun 	while (ns--)
74*4882a593Smuzhiyun 		*data++ = *port;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
_outsb(volatile u8 * port,const void * buf,int ns)77*4882a593Smuzhiyun static inline void _outsb(volatile u8 * port, const void *buf, int ns)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun 	u8 *data = (u8 *) buf;
80*4882a593Smuzhiyun 	while (ns--)
81*4882a593Smuzhiyun 		*port = *data++;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
_insw(volatile u16 * port,void * buf,int ns)84*4882a593Smuzhiyun static inline void _insw(volatile u16 * port, void *buf, int ns)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun 	u16 *data = (u16 *) buf;
87*4882a593Smuzhiyun 	while (ns--)
88*4882a593Smuzhiyun 		*data++ = __sw16(*port);
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun 
_outsw(volatile u16 * port,const void * buf,int ns)91*4882a593Smuzhiyun static inline void _outsw(volatile u16 * port, const void *buf, int ns)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun 	u16 *data = (u16 *) buf;
94*4882a593Smuzhiyun 	while (ns--) {
95*4882a593Smuzhiyun 		*port = __sw16(*data);
96*4882a593Smuzhiyun 		data++;
97*4882a593Smuzhiyun 	}
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun 
_insl(volatile u32 * port,void * buf,int nl)100*4882a593Smuzhiyun static inline void _insl(volatile u32 * port, void *buf, int nl)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun 	u32 *data = (u32 *) buf;
103*4882a593Smuzhiyun 	while (nl--)
104*4882a593Smuzhiyun 		*data++ = __sw32(*port);
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun 
_outsl(volatile u32 * port,const void * buf,int nl)107*4882a593Smuzhiyun static inline void _outsl(volatile u32 * port, const void *buf, int nl)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun 	u32 *data = (u32 *) buf;
110*4882a593Smuzhiyun 	while (nl--) {
111*4882a593Smuzhiyun 		*port = __sw32(*data);
112*4882a593Smuzhiyun 		data++;
113*4882a593Smuzhiyun 	}
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun 
_insw_ns(volatile u16 * port,void * buf,int ns)116*4882a593Smuzhiyun static inline void _insw_ns(volatile u16 * port, void *buf, int ns)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun 	u16 *data = (u16 *) buf;
119*4882a593Smuzhiyun 	while (ns--)
120*4882a593Smuzhiyun 		*data++ = *port;
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun 
_outsw_ns(volatile u16 * port,const void * buf,int ns)123*4882a593Smuzhiyun static inline void _outsw_ns(volatile u16 * port, const void *buf, int ns)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun 	u16 *data = (u16 *) buf;
126*4882a593Smuzhiyun 	while (ns--) {
127*4882a593Smuzhiyun 		*port = *data++;
128*4882a593Smuzhiyun 	}
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun 
_insl_ns(volatile u32 * port,void * buf,int nl)131*4882a593Smuzhiyun static inline void _insl_ns(volatile u32 * port, void *buf, int nl)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun 	u32 *data = (u32 *) buf;
134*4882a593Smuzhiyun 	while (nl--)
135*4882a593Smuzhiyun 		*data++ = *port;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun 
_outsl_ns(volatile u32 * port,const void * buf,int nl)138*4882a593Smuzhiyun static inline void _outsl_ns(volatile u32 * port, const void *buf, int nl)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun 	u32 *data = (u32 *) buf;
141*4882a593Smuzhiyun 	while (nl--) {
142*4882a593Smuzhiyun 		*port = *data;
143*4882a593Smuzhiyun 		data++;
144*4882a593Smuzhiyun 	}
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun /*
148*4882a593Smuzhiyun  * The *_ns versions below don't do byte-swapping.
149*4882a593Smuzhiyun  * Neither do the standard versions now, these are just here
150*4882a593Smuzhiyun  * for older code.
151*4882a593Smuzhiyun  */
152*4882a593Smuzhiyun #define insw_ns(port, buf, ns)	_insw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
153*4882a593Smuzhiyun #define outsw_ns(port, buf, ns)	_outsw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
154*4882a593Smuzhiyun #define insl_ns(port, buf, nl)	_insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
155*4882a593Smuzhiyun #define outsl_ns(port, buf, nl)	_outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun #define IO_SPACE_LIMIT ~0
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun /*
160*4882a593Smuzhiyun  * 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
161*4882a593Smuzhiyun  */
in_8(volatile u8 * addr)162*4882a593Smuzhiyun static inline int in_8(volatile u8 * addr)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun 	return (int)*addr;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun 
out_8(volatile u8 * addr,int val)167*4882a593Smuzhiyun static inline void out_8(volatile u8 * addr, int val)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun 	*addr = (u8) val;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun 
in_le16(volatile u16 * addr)172*4882a593Smuzhiyun static inline int in_le16(volatile u16 * addr)
173*4882a593Smuzhiyun {
174*4882a593Smuzhiyun 	return __sw16(*addr);
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun 
in_be16(volatile u16 * addr)177*4882a593Smuzhiyun static inline int in_be16(volatile u16 * addr)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun 	return (*addr & 0xFFFF);
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun 
out_le16(volatile u16 * addr,int val)182*4882a593Smuzhiyun static inline void out_le16(volatile u16 * addr, int val)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun 	*addr = __sw16(val);
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun 
out_be16(volatile u16 * addr,int val)187*4882a593Smuzhiyun static inline void out_be16(volatile u16 * addr, int val)
188*4882a593Smuzhiyun {
189*4882a593Smuzhiyun 	*addr = (u16) val;
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun 
in_le32(volatile u32 * addr)192*4882a593Smuzhiyun static inline unsigned in_le32(volatile u32 * addr)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun 	return __sw32(*addr);
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun 
in_be32(volatile u32 * addr)197*4882a593Smuzhiyun static inline unsigned in_be32(volatile u32 * addr)
198*4882a593Smuzhiyun {
199*4882a593Smuzhiyun 	return (*addr);
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun 
out_le32(volatile unsigned * addr,int val)202*4882a593Smuzhiyun static inline void out_le32(volatile unsigned *addr, int val)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	*addr = __sw32(val);
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun 
out_be32(volatile unsigned * addr,int val)207*4882a593Smuzhiyun static inline void out_be32(volatile unsigned *addr, int val)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun 	*addr = val;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun /* Clear and set bits in one shot. These macros can be used to clear and
213*4882a593Smuzhiyun  * set multiple bits in a register using a single call. These macros can
214*4882a593Smuzhiyun  * also be used to set a multiple-bit bit pattern using a mask, by
215*4882a593Smuzhiyun  * specifying the mask in the 'clear' parameter and the new bit pattern
216*4882a593Smuzhiyun  * in the 'set' parameter.
217*4882a593Smuzhiyun  */
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun #define clrbits(type, addr, clear) \
220*4882a593Smuzhiyun 	out_##type((addr), in_##type(addr) & ~(clear))
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun #define setbits(type, addr, set) \
223*4882a593Smuzhiyun 	out_##type((addr), in_##type(addr) | (set))
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun #define clrsetbits(type, addr, clear, set) \
226*4882a593Smuzhiyun 	out_##type((addr), (in_##type(addr) & ~(clear)) | (set))
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun #define clrbits_be32(addr, clear) clrbits(be32, addr, clear)
229*4882a593Smuzhiyun #define setbits_be32(addr, set) setbits(be32, addr, set)
230*4882a593Smuzhiyun #define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set)
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun #define clrbits_le32(addr, clear) clrbits(le32, addr, clear)
233*4882a593Smuzhiyun #define setbits_le32(addr, set) setbits(le32, addr, set)
234*4882a593Smuzhiyun #define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set)
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun #define clrbits_be16(addr, clear) clrbits(be16, addr, clear)
237*4882a593Smuzhiyun #define setbits_be16(addr, set) setbits(be16, addr, set)
238*4882a593Smuzhiyun #define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set)
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun #define clrbits_le16(addr, clear) clrbits(le16, addr, clear)
241*4882a593Smuzhiyun #define setbits_le16(addr, set) setbits(le16, addr, set)
242*4882a593Smuzhiyun #define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set)
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun #define clrbits_8(addr, clear) clrbits(8, addr, clear)
245*4882a593Smuzhiyun #define setbits_8(addr, set) setbits(8, addr, set)
246*4882a593Smuzhiyun #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
247*4882a593Smuzhiyun 
sync(void)248*4882a593Smuzhiyun static inline void sync(void)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun 	/* This sync function is for PowerPC or other architecture instruction
251*4882a593Smuzhiyun 	 * ColdFire does not have this instruction. Dummy function, added for
252*4882a593Smuzhiyun 	 * compatibility (CFI driver)
253*4882a593Smuzhiyun 	 */
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun /*
257*4882a593Smuzhiyun  * Given a physical address and a length, return a virtual address
258*4882a593Smuzhiyun  * that can be used to access the memory range with the caching
259*4882a593Smuzhiyun  * properties specified by "flags".
260*4882a593Smuzhiyun  */
261*4882a593Smuzhiyun #define MAP_NOCACHE	(0)
262*4882a593Smuzhiyun #define MAP_WRCOMBINE	(0)
263*4882a593Smuzhiyun #define MAP_WRBACK	(0)
264*4882a593Smuzhiyun #define MAP_WRTHROUGH	(0)
265*4882a593Smuzhiyun 
map_physmem(phys_addr_t paddr,unsigned long len,unsigned long flags)266*4882a593Smuzhiyun static inline void *map_physmem(phys_addr_t paddr, unsigned long len,
267*4882a593Smuzhiyun 				unsigned long flags)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun 	return (void *)paddr;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun /*
273*4882a593Smuzhiyun  * Take down a mapping set up by map_physmem().
274*4882a593Smuzhiyun  */
unmap_physmem(void * vaddr,unsigned long flags)275*4882a593Smuzhiyun static inline void unmap_physmem(void *vaddr, unsigned long flags)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun 
virt_to_phys(void * vaddr)280*4882a593Smuzhiyun static inline phys_addr_t virt_to_phys(void * vaddr)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun 	return (phys_addr_t)(vaddr);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun #endif				/* __ASM_M68K_IO_H__ */
286