xref: /openbmc/u-boot/arch/mips/include/asm/io.h (revision 819833af39a91fa1c1e8252862bbda6f5a602f7b)
1*819833afSPeter Tyser /*
2*819833afSPeter Tyser  * This file is subject to the terms and conditions of the GNU General Public
3*819833afSPeter Tyser  * License.  See the file "COPYING" in the main directory of this archive
4*819833afSPeter Tyser  * for more details.
5*819833afSPeter Tyser  *
6*819833afSPeter Tyser  * Copyright (C) 1994, 1995 Waldorf GmbH
7*819833afSPeter Tyser  * Copyright (C) 1994 - 2000 Ralf Baechle
8*819833afSPeter Tyser  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9*819833afSPeter Tyser  * Copyright (C) 2000 FSMLabs, Inc.
10*819833afSPeter Tyser  */
11*819833afSPeter Tyser #ifndef _ASM_IO_H
12*819833afSPeter Tyser #define _ASM_IO_H
13*819833afSPeter Tyser 
14*819833afSPeter Tyser #include <linux/config.h>
15*819833afSPeter Tyser #if 0
16*819833afSPeter Tyser #include <linux/pagemap.h>
17*819833afSPeter Tyser #endif
18*819833afSPeter Tyser #include <asm/addrspace.h>
19*819833afSPeter Tyser #include <asm/byteorder.h>
20*819833afSPeter Tyser 
21*819833afSPeter Tyser /*
22*819833afSPeter Tyser  * Slowdown I/O port space accesses for antique hardware.
23*819833afSPeter Tyser  */
24*819833afSPeter Tyser #undef CONF_SLOWDOWN_IO
25*819833afSPeter Tyser 
26*819833afSPeter Tyser /*
27*819833afSPeter Tyser  * Sane hardware offers swapping of I/O space accesses in hardware; less
28*819833afSPeter Tyser  * sane hardware forces software to fiddle with this ...
29*819833afSPeter Tyser  */
30*819833afSPeter Tyser #if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
31*819833afSPeter Tyser 
32*819833afSPeter Tyser #define __ioswab8(x) (x)
33*819833afSPeter Tyser #define __ioswab16(x) swab16(x)
34*819833afSPeter Tyser #define __ioswab32(x) swab32(x)
35*819833afSPeter Tyser 
36*819833afSPeter Tyser #else
37*819833afSPeter Tyser 
38*819833afSPeter Tyser #define __ioswab8(x) (x)
39*819833afSPeter Tyser #define __ioswab16(x) (x)
40*819833afSPeter Tyser #define __ioswab32(x) (x)
41*819833afSPeter Tyser 
42*819833afSPeter Tyser #endif
43*819833afSPeter Tyser 
44*819833afSPeter Tyser /*
45*819833afSPeter Tyser  * This file contains the definitions for the MIPS counterpart of the
46*819833afSPeter Tyser  * x86 in/out instructions. This heap of macros and C results in much
47*819833afSPeter Tyser  * better code than the approach of doing it in plain C.  The macros
48*819833afSPeter Tyser  * result in code that is to fast for certain hardware.  On the other
49*819833afSPeter Tyser  * side the performance of the string functions should be improved for
50*819833afSPeter Tyser  * sake of certain devices like EIDE disks that do highspeed polled I/O.
51*819833afSPeter Tyser  *
52*819833afSPeter Tyser  *   Ralf
53*819833afSPeter Tyser  *
54*819833afSPeter Tyser  * This file contains the definitions for the x86 IO instructions
55*819833afSPeter Tyser  * inb/inw/inl/outb/outw/outl and the "string versions" of the same
56*819833afSPeter Tyser  * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
57*819833afSPeter Tyser  * versions of the single-IO instructions (inb_p/inw_p/..).
58*819833afSPeter Tyser  *
59*819833afSPeter Tyser  * This file is not meant to be obfuscating: it's just complicated
60*819833afSPeter Tyser  * to (a) handle it all in a way that makes gcc able to optimize it
61*819833afSPeter Tyser  * as well as possible and (b) trying to avoid writing the same thing
62*819833afSPeter Tyser  * over and over again with slight variations and possibly making a
63*819833afSPeter Tyser  * mistake somewhere.
64*819833afSPeter Tyser  */
65*819833afSPeter Tyser 
66*819833afSPeter Tyser /*
67*819833afSPeter Tyser  * On MIPS I/O ports are memory mapped, so we access them using normal
68*819833afSPeter Tyser  * load/store instructions. mips_io_port_base is the virtual address to
69*819833afSPeter Tyser  * which all ports are being mapped.  For sake of efficiency some code
70*819833afSPeter Tyser  * assumes that this is an address that can be loaded with a single lui
71*819833afSPeter Tyser  * instruction, so the lower 16 bits must be zero.  Should be true on
72*819833afSPeter Tyser  * on any sane architecture; generic code does not use this assumption.
73*819833afSPeter Tyser  */
74*819833afSPeter Tyser extern const unsigned long mips_io_port_base;
75*819833afSPeter Tyser 
76*819833afSPeter Tyser /*
77*819833afSPeter Tyser  * Gcc will generate code to load the value of mips_io_port_base after each
78*819833afSPeter Tyser  * function call which may be fairly wasteful in some cases.  So we don't
79*819833afSPeter Tyser  * play quite by the book.  We tell gcc mips_io_port_base is a long variable
80*819833afSPeter Tyser  * which solves the code generation issue.  Now we need to violate the
81*819833afSPeter Tyser  * aliasing rules a little to make initialization possible and finally we
82*819833afSPeter Tyser  * will need the barrier() to fight side effects of the aliasing chat.
83*819833afSPeter Tyser  * This trickery will eventually collapse under gcc's optimizer.  Oh well.
84*819833afSPeter Tyser  */
85*819833afSPeter Tyser static inline void set_io_port_base(unsigned long base)
86*819833afSPeter Tyser {
87*819833afSPeter Tyser 	* (unsigned long *) &mips_io_port_base = base;
88*819833afSPeter Tyser }
89*819833afSPeter Tyser 
90*819833afSPeter Tyser /*
91*819833afSPeter Tyser  * Thanks to James van Artsdalen for a better timing-fix than
92*819833afSPeter Tyser  * the two short jumps: using outb's to a nonexistent port seems
93*819833afSPeter Tyser  * to guarantee better timings even on fast machines.
94*819833afSPeter Tyser  *
95*819833afSPeter Tyser  * On the other hand, I'd like to be sure of a non-existent port:
96*819833afSPeter Tyser  * I feel a bit unsafe about using 0x80 (should be safe, though)
97*819833afSPeter Tyser  *
98*819833afSPeter Tyser  *		Linus
99*819833afSPeter Tyser  *
100*819833afSPeter Tyser  */
101*819833afSPeter Tyser 
102*819833afSPeter Tyser #define __SLOW_DOWN_IO \
103*819833afSPeter Tyser 	__asm__ __volatile__( \
104*819833afSPeter Tyser 		"sb\t$0,0x80(%0)" \
105*819833afSPeter Tyser 		: : "r" (mips_io_port_base));
106*819833afSPeter Tyser 
107*819833afSPeter Tyser #ifdef CONF_SLOWDOWN_IO
108*819833afSPeter Tyser #ifdef REALLY_SLOW_IO
109*819833afSPeter Tyser #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
110*819833afSPeter Tyser #else
111*819833afSPeter Tyser #define SLOW_DOWN_IO __SLOW_DOWN_IO
112*819833afSPeter Tyser #endif
113*819833afSPeter Tyser #else
114*819833afSPeter Tyser #define SLOW_DOWN_IO
115*819833afSPeter Tyser #endif
116*819833afSPeter Tyser 
117*819833afSPeter Tyser /*
118*819833afSPeter Tyser  * Change virtual addresses to physical addresses and vv.
119*819833afSPeter Tyser  * These are trivial on the 1:1 Linux/MIPS mapping
120*819833afSPeter Tyser  */
121*819833afSPeter Tyser extern inline phys_addr_t virt_to_phys(volatile void * address)
122*819833afSPeter Tyser {
123*819833afSPeter Tyser 	return CPHYSADDR(address);
124*819833afSPeter Tyser }
125*819833afSPeter Tyser 
126*819833afSPeter Tyser extern inline void * phys_to_virt(unsigned long address)
127*819833afSPeter Tyser {
128*819833afSPeter Tyser 	return (void *)KSEG0ADDR(address);
129*819833afSPeter Tyser }
130*819833afSPeter Tyser 
131*819833afSPeter Tyser /*
132*819833afSPeter Tyser  * IO bus memory addresses are also 1:1 with the physical address
133*819833afSPeter Tyser  */
134*819833afSPeter Tyser extern inline unsigned long virt_to_bus(volatile void * address)
135*819833afSPeter Tyser {
136*819833afSPeter Tyser 	return CPHYSADDR(address);
137*819833afSPeter Tyser }
138*819833afSPeter Tyser 
139*819833afSPeter Tyser extern inline void * bus_to_virt(unsigned long address)
140*819833afSPeter Tyser {
141*819833afSPeter Tyser 	return (void *)KSEG0ADDR(address);
142*819833afSPeter Tyser }
143*819833afSPeter Tyser 
144*819833afSPeter Tyser /*
145*819833afSPeter Tyser  * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped
146*819833afSPeter Tyser  * for the processor.
147*819833afSPeter Tyser  */
148*819833afSPeter Tyser extern unsigned long isa_slot_offset;
149*819833afSPeter Tyser 
150*819833afSPeter Tyser extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
151*819833afSPeter Tyser 
152*819833afSPeter Tyser #if 0
153*819833afSPeter Tyser extern inline void *ioremap(unsigned long offset, unsigned long size)
154*819833afSPeter Tyser {
155*819833afSPeter Tyser 	return __ioremap(offset, size, _CACHE_UNCACHED);
156*819833afSPeter Tyser }
157*819833afSPeter Tyser 
158*819833afSPeter Tyser extern inline void *ioremap_nocache(unsigned long offset, unsigned long size)
159*819833afSPeter Tyser {
160*819833afSPeter Tyser 	return __ioremap(offset, size, _CACHE_UNCACHED);
161*819833afSPeter Tyser }
162*819833afSPeter Tyser 
163*819833afSPeter Tyser extern void iounmap(void *addr);
164*819833afSPeter Tyser #endif
165*819833afSPeter Tyser 
166*819833afSPeter Tyser /*
167*819833afSPeter Tyser  * XXX We need system specific versions of these to handle EISA address bits
168*819833afSPeter Tyser  * 24-31 on SNI.
169*819833afSPeter Tyser  * XXX more SNI hacks.
170*819833afSPeter Tyser  */
171*819833afSPeter Tyser #define readb(addr) (*(volatile unsigned char *)(addr))
172*819833afSPeter Tyser #define readw(addr) __ioswab16((*(volatile unsigned short *)(addr)))
173*819833afSPeter Tyser #define readl(addr) __ioswab32((*(volatile unsigned int *)(addr)))
174*819833afSPeter Tyser #define __raw_readb readb
175*819833afSPeter Tyser #define __raw_readw readw
176*819833afSPeter Tyser #define __raw_readl readl
177*819833afSPeter Tyser 
178*819833afSPeter Tyser #define writeb(b,addr) (*(volatile unsigned char *)(addr)) = (b)
179*819833afSPeter Tyser #define writew(b,addr) (*(volatile unsigned short *)(addr)) = (__ioswab16(b))
180*819833afSPeter Tyser #define writel(b,addr) (*(volatile unsigned int *)(addr)) = (__ioswab32(b))
181*819833afSPeter Tyser #define __raw_writeb writeb
182*819833afSPeter Tyser #define __raw_writew writew
183*819833afSPeter Tyser #define __raw_writel writel
184*819833afSPeter Tyser 
185*819833afSPeter Tyser #define memset_io(a,b,c)	memset((void *)(a),(b),(c))
186*819833afSPeter Tyser #define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
187*819833afSPeter Tyser #define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
188*819833afSPeter Tyser 
189*819833afSPeter Tyser /* END SNI HACKS ... */
190*819833afSPeter Tyser 
191*819833afSPeter Tyser /*
192*819833afSPeter Tyser  * ISA space is 'always mapped' on currently supported MIPS systems, no need
193*819833afSPeter Tyser  * to explicitly ioremap() it. The fact that the ISA IO space is mapped
194*819833afSPeter Tyser  * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
195*819833afSPeter Tyser  * are physical addresses. The following constant pointer can be
196*819833afSPeter Tyser  * used as the IO-area pointer (it can be iounmapped as well, so the
197*819833afSPeter Tyser  * analogy with PCI is quite large):
198*819833afSPeter Tyser  */
199*819833afSPeter Tyser #define __ISA_IO_base ((char *)(PAGE_OFFSET))
200*819833afSPeter Tyser 
201*819833afSPeter Tyser #define isa_readb(a) readb(a)
202*819833afSPeter Tyser #define isa_readw(a) readw(a)
203*819833afSPeter Tyser #define isa_readl(a) readl(a)
204*819833afSPeter Tyser #define isa_writeb(b,a) writeb(b,a)
205*819833afSPeter Tyser #define isa_writew(w,a) writew(w,a)
206*819833afSPeter Tyser #define isa_writel(l,a) writel(l,a)
207*819833afSPeter Tyser 
208*819833afSPeter Tyser #define isa_memset_io(a,b,c)     memset_io((a),(b),(c))
209*819833afSPeter Tyser #define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),(b),(c))
210*819833afSPeter Tyser #define isa_memcpy_toio(a,b,c)   memcpy_toio((a),(b),(c))
211*819833afSPeter Tyser 
212*819833afSPeter Tyser /*
213*819833afSPeter Tyser  * We don't have csum_partial_copy_fromio() yet, so we cheat here and
214*819833afSPeter Tyser  * just copy it. The net code will then do the checksum later.
215*819833afSPeter Tyser  */
216*819833afSPeter Tyser #define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len))
217*819833afSPeter Tyser #define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(b),(c),(d))
218*819833afSPeter Tyser 
219*819833afSPeter Tyser static inline int check_signature(unsigned long io_addr,
220*819833afSPeter Tyser 				  const unsigned char *signature, int length)
221*819833afSPeter Tyser {
222*819833afSPeter Tyser 	int retval = 0;
223*819833afSPeter Tyser 	do {
224*819833afSPeter Tyser 		if (readb(io_addr) != *signature)
225*819833afSPeter Tyser 			goto out;
226*819833afSPeter Tyser 		io_addr++;
227*819833afSPeter Tyser 		signature++;
228*819833afSPeter Tyser 		length--;
229*819833afSPeter Tyser 	} while (length);
230*819833afSPeter Tyser 	retval = 1;
231*819833afSPeter Tyser out:
232*819833afSPeter Tyser 	return retval;
233*819833afSPeter Tyser }
234*819833afSPeter Tyser #define isa_check_signature(io, s, l) check_signature(i,s,l)
235*819833afSPeter Tyser 
236*819833afSPeter Tyser /*
237*819833afSPeter Tyser  * Talk about misusing macros..
238*819833afSPeter Tyser  */
239*819833afSPeter Tyser 
240*819833afSPeter Tyser #define __OUT1(s) \
241*819833afSPeter Tyser extern inline void __out##s(unsigned int value, unsigned int port) {
242*819833afSPeter Tyser 
243*819833afSPeter Tyser #define __OUT2(m) \
244*819833afSPeter Tyser __asm__ __volatile__ ("s" #m "\t%0,%1(%2)"
245*819833afSPeter Tyser 
246*819833afSPeter Tyser #define __OUT(m,s,w) \
247*819833afSPeter Tyser __OUT1(s) __OUT2(m) : : "r" (__ioswab##w(value)), "i" (0), "r" (mips_io_port_base+port)); } \
248*819833afSPeter Tyser __OUT1(s##c) __OUT2(m) : : "r" (__ioswab##w(value)), "ir" (port), "r" (mips_io_port_base)); } \
249*819833afSPeter Tyser __OUT1(s##_p) __OUT2(m) : : "r" (__ioswab##w(value)), "i" (0), "r" (mips_io_port_base+port)); \
250*819833afSPeter Tyser 	SLOW_DOWN_IO; } \
251*819833afSPeter Tyser __OUT1(s##c_p) __OUT2(m) : : "r" (__ioswab##w(value)), "ir" (port), "r" (mips_io_port_base)); \
252*819833afSPeter Tyser 	SLOW_DOWN_IO; }
253*819833afSPeter Tyser 
254*819833afSPeter Tyser #define __IN1(t,s) \
255*819833afSPeter Tyser extern __inline__ t __in##s(unsigned int port) { t _v;
256*819833afSPeter Tyser 
257*819833afSPeter Tyser /*
258*819833afSPeter Tyser  * Required nops will be inserted by the assembler
259*819833afSPeter Tyser  */
260*819833afSPeter Tyser #define __IN2(m) \
261*819833afSPeter Tyser __asm__ __volatile__ ("l" #m "\t%0,%1(%2)"
262*819833afSPeter Tyser 
263*819833afSPeter Tyser #define __IN(t,m,s,w) \
264*819833afSPeter Tyser __IN1(t,s) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); return __ioswab##w(_v); } \
265*819833afSPeter Tyser __IN1(t,s##c) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); return __ioswab##w(_v); } \
266*819833afSPeter Tyser __IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); SLOW_DOWN_IO; return __ioswab##w(_v); } \
267*819833afSPeter Tyser __IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return __ioswab##w(_v); }
268*819833afSPeter Tyser 
269*819833afSPeter Tyser #define __INS1(s) \
270*819833afSPeter Tyser extern inline void __ins##s(unsigned int port, void * addr, unsigned long count) {
271*819833afSPeter Tyser 
272*819833afSPeter Tyser #define __INS2(m) \
273*819833afSPeter Tyser if (count) \
274*819833afSPeter Tyser __asm__ __volatile__ ( \
275*819833afSPeter Tyser 	".set\tnoreorder\n\t" \
276*819833afSPeter Tyser 	".set\tnoat\n" \
277*819833afSPeter Tyser 	"1:\tl" #m "\t$1,%4(%5)\n\t" \
278*819833afSPeter Tyser 	"subu\t%1,1\n\t" \
279*819833afSPeter Tyser 	"s" #m "\t$1,(%0)\n\t" \
280*819833afSPeter Tyser 	"bne\t$0,%1,1b\n\t" \
281*819833afSPeter Tyser 	"addiu\t%0,%6\n\t" \
282*819833afSPeter Tyser 	".set\tat\n\t" \
283*819833afSPeter Tyser 	".set\treorder"
284*819833afSPeter Tyser 
285*819833afSPeter Tyser #define __INS(m,s,i) \
286*819833afSPeter Tyser __INS1(s) __INS2(m) \
287*819833afSPeter Tyser 	: "=r" (addr), "=r" (count) \
288*819833afSPeter Tyser 	: "0" (addr), "1" (count), "i" (0), \
289*819833afSPeter Tyser 	  "r" (mips_io_port_base+port), "I" (i) \
290*819833afSPeter Tyser 	: "$1");} \
291*819833afSPeter Tyser __INS1(s##c) __INS2(m) \
292*819833afSPeter Tyser 	: "=r" (addr), "=r" (count) \
293*819833afSPeter Tyser 	: "0" (addr), "1" (count), "ir" (port), \
294*819833afSPeter Tyser 	  "r" (mips_io_port_base), "I" (i) \
295*819833afSPeter Tyser 	: "$1");}
296*819833afSPeter Tyser 
297*819833afSPeter Tyser #define __OUTS1(s) \
298*819833afSPeter Tyser extern inline void __outs##s(unsigned int port, const void * addr, unsigned long count) {
299*819833afSPeter Tyser 
300*819833afSPeter Tyser #define __OUTS2(m) \
301*819833afSPeter Tyser if (count) \
302*819833afSPeter Tyser __asm__ __volatile__ ( \
303*819833afSPeter Tyser 	".set\tnoreorder\n\t" \
304*819833afSPeter Tyser 	".set\tnoat\n" \
305*819833afSPeter Tyser 	"1:\tl" #m "\t$1,(%0)\n\t" \
306*819833afSPeter Tyser 	"subu\t%1,1\n\t" \
307*819833afSPeter Tyser 	"s" #m "\t$1,%4(%5)\n\t" \
308*819833afSPeter Tyser 	"bne\t$0,%1,1b\n\t" \
309*819833afSPeter Tyser 	"addiu\t%0,%6\n\t" \
310*819833afSPeter Tyser 	".set\tat\n\t" \
311*819833afSPeter Tyser 	".set\treorder"
312*819833afSPeter Tyser 
313*819833afSPeter Tyser #define __OUTS(m,s,i) \
314*819833afSPeter Tyser __OUTS1(s) __OUTS2(m) \
315*819833afSPeter Tyser 	: "=r" (addr), "=r" (count) \
316*819833afSPeter Tyser 	: "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \
317*819833afSPeter Tyser 	: "$1");} \
318*819833afSPeter Tyser __OUTS1(s##c) __OUTS2(m) \
319*819833afSPeter Tyser 	: "=r" (addr), "=r" (count) \
320*819833afSPeter Tyser 	: "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \
321*819833afSPeter Tyser 	: "$1");}
322*819833afSPeter Tyser 
323*819833afSPeter Tyser __IN(unsigned char,b,b,8)
324*819833afSPeter Tyser __IN(unsigned short,h,w,16)
325*819833afSPeter Tyser __IN(unsigned int,w,l,32)
326*819833afSPeter Tyser 
327*819833afSPeter Tyser __OUT(b,b,8)
328*819833afSPeter Tyser __OUT(h,w,16)
329*819833afSPeter Tyser __OUT(w,l,32)
330*819833afSPeter Tyser 
331*819833afSPeter Tyser __INS(b,b,1)
332*819833afSPeter Tyser __INS(h,w,2)
333*819833afSPeter Tyser __INS(w,l,4)
334*819833afSPeter Tyser 
335*819833afSPeter Tyser __OUTS(b,b,1)
336*819833afSPeter Tyser __OUTS(h,w,2)
337*819833afSPeter Tyser __OUTS(w,l,4)
338*819833afSPeter Tyser 
339*819833afSPeter Tyser 
340*819833afSPeter Tyser /*
341*819833afSPeter Tyser  * Note that due to the way __builtin_constant_p() works, you
342*819833afSPeter Tyser  *  - can't use it inside an inline function (it will never be true)
343*819833afSPeter Tyser  *  - you don't have to worry about side effects within the __builtin..
344*819833afSPeter Tyser  */
345*819833afSPeter Tyser #define outb(val,port) \
346*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
347*819833afSPeter Tyser 	__outbc((val),(port)) : \
348*819833afSPeter Tyser 	__outb((val),(port)))
349*819833afSPeter Tyser 
350*819833afSPeter Tyser #define inb(port) \
351*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
352*819833afSPeter Tyser 	__inbc(port) : \
353*819833afSPeter Tyser 	__inb(port))
354*819833afSPeter Tyser 
355*819833afSPeter Tyser #define outb_p(val,port) \
356*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
357*819833afSPeter Tyser 	__outbc_p((val),(port)) : \
358*819833afSPeter Tyser 	__outb_p((val),(port)))
359*819833afSPeter Tyser 
360*819833afSPeter Tyser #define inb_p(port) \
361*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
362*819833afSPeter Tyser 	__inbc_p(port) : \
363*819833afSPeter Tyser 	__inb_p(port))
364*819833afSPeter Tyser 
365*819833afSPeter Tyser #define outw(val,port) \
366*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
367*819833afSPeter Tyser 	__outwc((val),(port)) : \
368*819833afSPeter Tyser 	__outw((val),(port)))
369*819833afSPeter Tyser 
370*819833afSPeter Tyser #define inw(port) \
371*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
372*819833afSPeter Tyser 	__inwc(port) : \
373*819833afSPeter Tyser 	__inw(port))
374*819833afSPeter Tyser 
375*819833afSPeter Tyser #define outw_p(val,port) \
376*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
377*819833afSPeter Tyser 	__outwc_p((val),(port)) : \
378*819833afSPeter Tyser 	__outw_p((val),(port)))
379*819833afSPeter Tyser 
380*819833afSPeter Tyser #define inw_p(port) \
381*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
382*819833afSPeter Tyser 	__inwc_p(port) : \
383*819833afSPeter Tyser 	__inw_p(port))
384*819833afSPeter Tyser 
385*819833afSPeter Tyser #define outl(val,port) \
386*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
387*819833afSPeter Tyser 	__outlc((val),(port)) : \
388*819833afSPeter Tyser 	__outl((val),(port)))
389*819833afSPeter Tyser 
390*819833afSPeter Tyser #define inl(port) \
391*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
392*819833afSPeter Tyser 	__inlc(port) : \
393*819833afSPeter Tyser 	__inl(port))
394*819833afSPeter Tyser 
395*819833afSPeter Tyser #define outl_p(val,port) \
396*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
397*819833afSPeter Tyser 	__outlc_p((val),(port)) : \
398*819833afSPeter Tyser 	__outl_p((val),(port)))
399*819833afSPeter Tyser 
400*819833afSPeter Tyser #define inl_p(port) \
401*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
402*819833afSPeter Tyser 	__inlc_p(port) : \
403*819833afSPeter Tyser 	__inl_p(port))
404*819833afSPeter Tyser 
405*819833afSPeter Tyser 
406*819833afSPeter Tyser #define outsb(port,addr,count) \
407*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
408*819833afSPeter Tyser 	__outsbc((port),(addr),(count)) : \
409*819833afSPeter Tyser 	__outsb ((port),(addr),(count)))
410*819833afSPeter Tyser 
411*819833afSPeter Tyser #define insb(port,addr,count) \
412*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
413*819833afSPeter Tyser 	__insbc((port),(addr),(count)) : \
414*819833afSPeter Tyser 	__insb((port),(addr),(count)))
415*819833afSPeter Tyser 
416*819833afSPeter Tyser #define outsw(port,addr,count) \
417*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
418*819833afSPeter Tyser 	__outswc((port),(addr),(count)) : \
419*819833afSPeter Tyser 	__outsw ((port),(addr),(count)))
420*819833afSPeter Tyser 
421*819833afSPeter Tyser #define insw(port,addr,count) \
422*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
423*819833afSPeter Tyser 	__inswc((port),(addr),(count)) : \
424*819833afSPeter Tyser 	__insw((port),(addr),(count)))
425*819833afSPeter Tyser 
426*819833afSPeter Tyser #define outsl(port,addr,count) \
427*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
428*819833afSPeter Tyser 	__outslc((port),(addr),(count)) : \
429*819833afSPeter Tyser 	__outsl ((port),(addr),(count)))
430*819833afSPeter Tyser 
431*819833afSPeter Tyser #define insl(port,addr,count) \
432*819833afSPeter Tyser ((__builtin_constant_p((port)) && (port) < 32768) ? \
433*819833afSPeter Tyser 	__inslc((port),(addr),(count)) : \
434*819833afSPeter Tyser 	__insl((port),(addr),(count)))
435*819833afSPeter Tyser 
436*819833afSPeter Tyser #define IO_SPACE_LIMIT 0xffff
437*819833afSPeter Tyser 
438*819833afSPeter Tyser /*
439*819833afSPeter Tyser  * The caches on some architectures aren't dma-coherent and have need to
440*819833afSPeter Tyser  * handle this in software.  There are three types of operations that
441*819833afSPeter Tyser  * can be applied to dma buffers.
442*819833afSPeter Tyser  *
443*819833afSPeter Tyser  *  - dma_cache_wback_inv(start, size) makes caches and coherent by
444*819833afSPeter Tyser  *    writing the content of the caches back to memory, if necessary.
445*819833afSPeter Tyser  *    The function also invalidates the affected part of the caches as
446*819833afSPeter Tyser  *    necessary before DMA transfers from outside to memory.
447*819833afSPeter Tyser  *  - dma_cache_wback(start, size) makes caches and coherent by
448*819833afSPeter Tyser  *    writing the content of the caches back to memory, if necessary.
449*819833afSPeter Tyser  *    The function also invalidates the affected part of the caches as
450*819833afSPeter Tyser  *    necessary before DMA transfers from outside to memory.
451*819833afSPeter Tyser  *  - dma_cache_inv(start, size) invalidates the affected parts of the
452*819833afSPeter Tyser  *    caches.  Dirty lines of the caches may be written back or simply
453*819833afSPeter Tyser  *    be discarded.  This operation is necessary before dma operations
454*819833afSPeter Tyser  *    to the memory.
455*819833afSPeter Tyser  */
456*819833afSPeter Tyser extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
457*819833afSPeter Tyser extern void (*_dma_cache_wback)(unsigned long start, unsigned long size);
458*819833afSPeter Tyser extern void (*_dma_cache_inv)(unsigned long start, unsigned long size);
459*819833afSPeter Tyser 
460*819833afSPeter Tyser #define dma_cache_wback_inv(start,size)	_dma_cache_wback_inv(start,size)
461*819833afSPeter Tyser #define dma_cache_wback(start,size)	_dma_cache_wback(start,size)
462*819833afSPeter Tyser #define dma_cache_inv(start,size)	_dma_cache_inv(start,size)
463*819833afSPeter Tyser 
464*819833afSPeter Tyser static inline void sync(void)
465*819833afSPeter Tyser {
466*819833afSPeter Tyser }
467*819833afSPeter Tyser 
468*819833afSPeter Tyser /*
469*819833afSPeter Tyser  * Given a physical address and a length, return a virtual address
470*819833afSPeter Tyser  * that can be used to access the memory range with the caching
471*819833afSPeter Tyser  * properties specified by "flags".
472*819833afSPeter Tyser  */
473*819833afSPeter Tyser #define MAP_NOCACHE	(0)
474*819833afSPeter Tyser #define MAP_WRCOMBINE	(0)
475*819833afSPeter Tyser #define MAP_WRBACK	(0)
476*819833afSPeter Tyser #define MAP_WRTHROUGH	(0)
477*819833afSPeter Tyser 
478*819833afSPeter Tyser static inline void *
479*819833afSPeter Tyser map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
480*819833afSPeter Tyser {
481*819833afSPeter Tyser 	return (void *)paddr;
482*819833afSPeter Tyser }
483*819833afSPeter Tyser 
484*819833afSPeter Tyser /*
485*819833afSPeter Tyser  * Take down a mapping set up by map_physmem().
486*819833afSPeter Tyser  */
487*819833afSPeter Tyser static inline void unmap_physmem(void *vaddr, unsigned long flags)
488*819833afSPeter Tyser {
489*819833afSPeter Tyser 
490*819833afSPeter Tyser }
491*819833afSPeter Tyser 
492*819833afSPeter Tyser #endif /* _ASM_IO_H */
493