xref: /linux/arch/arm/mach-rpc/include/mach/io.h (revision 367b8112fe2ea5c39a7bb4d263dcdd9b612fae18)
1 /*
2  *  arch/arm/mach-rpc/include/mach/io.h
3  *
4  *  Copyright (C) 1997 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Modifications:
11  *  06-Dec-1997	RMK	Created.
12  */
13 #ifndef __ASM_ARM_ARCH_IO_H
14 #define __ASM_ARM_ARCH_IO_H
15 
16 #include <mach/hardware.h>
17 
18 #define IO_SPACE_LIMIT 0xffffffff
19 
20 /*
21  * GCC is totally crap at loading/storing data.  We try to persuade it
22  * to do the right thing by using these whereever possible instead of
23  * the above.
24  */
25 #define __arch_base_getb(b,o)			\
26  ({						\
27 	unsigned int __v, __r = (b);		\
28 	__asm__ __volatile__(			\
29 		"ldrb	%0, [%1, %2]"		\
30 		: "=r" (__v)			\
31 		: "r" (__r), "Ir" (o));		\
32 	__v;					\
33  })
34 
35 #define __arch_base_getl(b,o)			\
36  ({						\
37 	unsigned int __v, __r = (b);		\
38 	__asm__ __volatile__(			\
39 		"ldr	%0, [%1, %2]"		\
40 		: "=r" (__v)			\
41 		: "r" (__r), "Ir" (o));		\
42 	__v;					\
43  })
44 
45 #define __arch_base_putb(v,b,o)			\
46  ({						\
47 	unsigned int __r = (b);			\
48 	__asm__ __volatile__(			\
49 		"strb	%0, [%1, %2]"		\
50 		:				\
51 		: "r" (v), "r" (__r), "Ir" (o));\
52  })
53 
54 #define __arch_base_putl(v,b,o)			\
55  ({						\
56 	unsigned int __r = (b);			\
57 	__asm__ __volatile__(			\
58 		"str	%0, [%1, %2]"		\
59 		:				\
60 		: "r" (v), "r" (__r), "Ir" (o));\
61  })
62 
63 /*
64  * We use two different types of addressing - PC style addresses, and ARM
65  * addresses.  PC style accesses the PC hardware with the normal PC IO
66  * addresses, eg 0x3f8 for serial#1.  ARM addresses are 0x80000000+
67  * and are translated to the start of IO.  Note that all addresses are
68  * shifted left!
69  */
70 #define __PORT_PCIO(x)	(!((x) & 0x80000000))
71 
72 /*
73  * Dynamic IO functions.
74  */
75 static inline void __outb (unsigned int value, unsigned int port)
76 {
77 	unsigned long temp;
78 	__asm__ __volatile__(
79 	"tst	%2, #0x80000000\n\t"
80 	"mov	%0, %4\n\t"
81 	"addeq	%0, %0, %3\n\t"
82 	"strb	%1, [%0, %2, lsl #2]	@ outb"
83 	: "=&r" (temp)
84 	: "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
85 	: "cc");
86 }
87 
88 static inline void __outw (unsigned int value, unsigned int port)
89 {
90 	unsigned long temp;
91 	__asm__ __volatile__(
92 	"tst	%2, #0x80000000\n\t"
93 	"mov	%0, %4\n\t"
94 	"addeq	%0, %0, %3\n\t"
95 	"str	%1, [%0, %2, lsl #2]	@ outw"
96 	: "=&r" (temp)
97 	: "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
98 	: "cc");
99 }
100 
101 static inline void __outl (unsigned int value, unsigned int port)
102 {
103 	unsigned long temp;
104 	__asm__ __volatile__(
105 	"tst	%2, #0x80000000\n\t"
106 	"mov	%0, %4\n\t"
107 	"addeq	%0, %0, %3\n\t"
108 	"str	%1, [%0, %2, lsl #2]	@ outl"
109 	: "=&r" (temp)
110 	: "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
111 	: "cc");
112 }
113 
114 #define DECLARE_DYN_IN(sz,fnsuffix,instr)					\
115 static inline unsigned sz __in##fnsuffix (unsigned int port)		\
116 {										\
117 	unsigned long temp, value;						\
118 	__asm__ __volatile__(							\
119 	"tst	%2, #0x80000000\n\t"						\
120 	"mov	%0, %4\n\t"							\
121 	"addeq	%0, %0, %3\n\t"							\
122 	"ldr" instr "	%1, [%0, %2, lsl #2]	@ in" #fnsuffix			\
123 	: "=&r" (temp), "=r" (value)						\
124 	: "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)		\
125 	: "cc");								\
126 	return (unsigned sz)value;						\
127 }
128 
129 static inline void __iomem *__deprecated __ioaddr(unsigned int port)
130 {
131 	void __iomem *ret;
132 	if (__PORT_PCIO(port))
133 		ret = PCIO_BASE;
134 	else
135 		ret = IO_BASE;
136 	return ret + (port << 2);
137 }
138 
139 #define DECLARE_IO(sz,fnsuffix,instr)	\
140 	DECLARE_DYN_IN(sz,fnsuffix,instr)
141 
142 DECLARE_IO(char,b,"b")
143 DECLARE_IO(short,w,"")
144 DECLARE_IO(int,l,"")
145 
146 #undef DECLARE_IO
147 #undef DECLARE_DYN_IN
148 
149 /*
150  * Constant address IO functions
151  *
152  * These have to be macros for the 'J' constraint to work -
153  * +/-4096 immediate operand.
154  */
155 #define __outbc(value,port)							\
156 ({										\
157 	if (__PORT_PCIO((port)))						\
158 		__asm__ __volatile__(						\
159 		"strb	%0, [%1, %2]	@ outbc"				\
160 		: : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2));		\
161 	else									\
162 		__asm__ __volatile__(						\
163 		"strb	%0, [%1, %2]	@ outbc"				\
164 		: : "r" (value), "r" (IO_BASE), "r" ((port) << 2));		\
165 })
166 
167 #define __inbc(port)								\
168 ({										\
169 	unsigned char result;							\
170 	if (__PORT_PCIO((port)))						\
171 		__asm__ __volatile__(						\
172 		"ldrb	%0, [%1, %2]	@ inbc"					\
173 		: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));		\
174 	else									\
175 		__asm__ __volatile__(						\
176 		"ldrb	%0, [%1, %2]	@ inbc"					\
177 		: "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));		\
178 	result;									\
179 })
180 
181 #define __outwc(value,port)							\
182 ({										\
183 	unsigned long __v = value;						\
184 	if (__PORT_PCIO((port)))						\
185 		__asm__ __volatile__(						\
186 		"str	%0, [%1, %2]	@ outwc"				\
187 		: : "r" (__v|__v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2));	\
188 	else									\
189 		__asm__ __volatile__(						\
190 		"str	%0, [%1, %2]	@ outwc"				\
191 		: : "r" (__v|__v<<16), "r" (IO_BASE), "r" ((port) << 2));		\
192 })
193 
194 #define __inwc(port)								\
195 ({										\
196 	unsigned short result;							\
197 	if (__PORT_PCIO((port)))						\
198 		__asm__ __volatile__(						\
199 		"ldr	%0, [%1, %2]	@ inwc"					\
200 		: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));		\
201 	else									\
202 		__asm__ __volatile__(						\
203 		"ldr	%0, [%1, %2]	@ inwc"					\
204 		: "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));		\
205 	result & 0xffff;							\
206 })
207 
208 #define __outlc(value,port)							\
209 ({										\
210 	unsigned long __v = value;						\
211 	if (__PORT_PCIO((port)))						\
212 		__asm__ __volatile__(						\
213 		"str	%0, [%1, %2]	@ outlc"				\
214 		: : "r" (__v), "r" (PCIO_BASE), "Jr" ((port) << 2));		\
215 	else									\
216 		__asm__ __volatile__(						\
217 		"str	%0, [%1, %2]	@ outlc"				\
218 		: : "r" (__v), "r" (IO_BASE), "r" ((port) << 2));		\
219 })
220 
221 #define __inlc(port)								\
222 ({										\
223 	unsigned long result;							\
224 	if (__PORT_PCIO((port)))						\
225 		__asm__ __volatile__(						\
226 		"ldr	%0, [%1, %2]	@ inlc"					\
227 		: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));		\
228 	else									\
229 		__asm__ __volatile__(						\
230 		"ldr	%0, [%1, %2]	@ inlc"					\
231 		: "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));		\
232 	result;									\
233 })
234 
235 #define __ioaddrc(port)		__ioaddr(port)
236 
237 #define inb(p)	 	(__builtin_constant_p((p)) ? __inbc(p)    : __inb(p))
238 #define inw(p)	 	(__builtin_constant_p((p)) ? __inwc(p)    : __inw(p))
239 #define inl(p)	 	(__builtin_constant_p((p)) ? __inlc(p)    : __inl(p))
240 #define outb(v,p)	(__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
241 #define outw(v,p)	(__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
242 #define outl(v,p)	(__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
243 #define __ioaddr(p)	(__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
244 /* the following macro is deprecated */
245 #define ioaddr(port)	((unsigned long)__ioaddr((port)))
246 
247 #define insb(p,d,l)	__raw_readsb(__ioaddr(p),d,l)
248 #define insw(p,d,l)	__raw_readsw(__ioaddr(p),d,l)
249 
250 #define outsb(p,d,l)	__raw_writesb(__ioaddr(p),d,l)
251 #define outsw(p,d,l)	__raw_writesw(__ioaddr(p),d,l)
252 
253 /*
254  * 1:1 mapping for ioremapped regions.
255  */
256 #define __mem_pci(x)	(x)
257 
258 #endif
259