File: /usr/src/linux/include/asm-mips64/io.h

1     /*
2      * This file is subject to the terms and conditions of the GNU General Public
3      * License.  See the file "COPYING" in the main directory of this archive
4      * for more details.
5      *
6      * Copyright (C) 1994, 1995 Waldorf GmbH
7      * Copyright (C) 1994 - 2000 Ralf Baechle
8      * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9      */
10     #ifndef _ASM_IO_H
11     #define _ASM_IO_H
12     
13     #include <linux/config.h>
14     #include <asm/addrspace.h>
15     #include <asm/page.h>
16     
17     #ifdef CONFIG_SGI_IP22
18     #include <asm/sgi/io.h>
19     #endif
20     
21     #ifdef CONFIG_SGI_IP27
22     #include <asm/sn/io.h>
23     #endif
24     
25     extern unsigned long bus_to_baddr[256];
26     
27     /*
28      * Slowdown I/O port space accesses for antique hardware.
29      */
30     #undef CONF_SLOWDOWN_IO
31     
32     /*
33      * On MIPS, we have the whole physical address space mapped at all
34      * times, so "ioremap()" and "iounmap()" do not need to do anything.
35      *
36      * We cheat a bit and always return uncachable areas until we've fixed
37      * the drivers to handle caching properly.
38      */
39     extern inline void *
40     ioremap(unsigned long offset, unsigned long size)
41     {
42     	return (void *) (IO_SPACE_BASE | offset);
43     }
44     
45     /* This one maps high address device memory and turns off caching for that
46      *  area.  It's useful if some control registers are in such an area and write
47      * combining or read caching is not desirable.
48      */
49     extern inline void *
50     ioremap_nocache (unsigned long offset, unsigned long size)
51     {
52     	return (void *) (IO_SPACE_BASE | offset);
53     }
54     
55     extern inline void iounmap(void *addr)
56     {
57     }
58     
59     /*
60      * This assumes sane hardware.  The Origin is.
61      */
62     #define readb(addr)		(*(volatile unsigned char *) (addr))
63     #define readw(addr)		(*(volatile unsigned short *) (addr))
64     #define readl(addr)		(*(volatile unsigned int *) (addr))
65     
66     #define writeb(b,addr)		(*(volatile unsigned char *) (addr) = (b))
67     #define writew(b,addr)		(*(volatile unsigned short *) (addr) = (b))
68     #define writel(b,addr)		(*(volatile unsigned int *) (addr) = (b))
69     
70     #define memset_io(a,b,c)	memset((void *) a,(b),(c))
71     #define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
72     #define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
73     
74     /* The ISA versions are supplied by system specific code */
75     
76     /*
77      * On MIPS I/O ports are memory mapped, so we access them using normal
78      * load/store instructions. mips_io_port_base is the virtual address to
79      * which all ports are being mapped.  For sake of efficiency some code
80      * assumes that this is an address that can be loaded with a single lui
81      * instruction, so the lower 16 bits must be zero.  Should be true on
82      * on any sane architecture; generic code does not use this assumption.
83      */
84     extern unsigned long mips_io_port_base;
85     
86     #define __SLOW_DOWN_IO \
87     	__asm__ __volatile__( \
88     		"sb\t$0,0x80(%0)" \
89     		: : "r" (mips_io_port_base));
90     
91     #ifdef CONF_SLOWDOWN_IO
92     #ifdef REALLY_SLOW_IO
93     #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
94     #else
95     #define SLOW_DOWN_IO __SLOW_DOWN_IO
96     #endif
97     #else
98     #define SLOW_DOWN_IO
99     #endif
100     
101     /*
102      * Change virtual addresses to physical addresses and vv.
103      * These are trivial on the 1:1 Linux/MIPS mapping
104      */
105     extern inline unsigned long virt_to_phys(volatile void * address)
106     {
107     	return (unsigned long)address - PAGE_OFFSET;
108     }
109     
110     extern inline void * phys_to_virt(unsigned long address)
111     {
112     	return (void *)(address + PAGE_OFFSET);
113     }
114     
115     /*
116      * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped
117      * for the processor.  This implies the assumption that there is only
118      * one of these busses.
119      */
120     extern unsigned long isa_slot_offset;
121     
122     /*
123      * We don't have csum_partial_copy_fromio() yet, so we cheat here and
124      * just copy it. The net code will then do the checksum later.
125      */
126     #define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len))
127     
128     static inline int
129     check_signature(unsigned long io_addr, const unsigned char *signature,
130                     int length)
131     {
132     	int retval = 0;
133     	do {
134     		if (readb(io_addr) != *signature)
135     			goto out;
136     		io_addr++;
137     		signature++;
138     		length--;
139     	} while (length);
140     	retval = 1;
141     out:
142     	return retval;
143     }
144     
145     /*
146      * Talk about misusing macros..
147      */
148     
149     #define __OUT1(s) \
150     extern inline void __out##s(unsigned int value, unsigned long port) {
151     
152     #define __OUT2(m) \
153     __asm__ __volatile__ ("s" #m "\t%0,%1(%2)"
154     
155     #define __OUT(m,s) \
156     __OUT1(s) __OUT2(m) : : "r" (value), "i" (0), "r" (mips_io_port_base+port)); } \
157     __OUT1(s##c) __OUT2(m) : : "r" (value), "ir" (port), "r" (mips_io_port_base)); } \
158     __OUT1(s##_p) __OUT2(m) : : "r" (value), "i" (0), "r" (mips_io_port_base+port)); \
159     	SLOW_DOWN_IO; } \
160     __OUT1(s##c_p) __OUT2(m) : : "r" (value), "ir" (port), "r" (mips_io_port_base)); \
161     	SLOW_DOWN_IO; }
162     
163     #define __IN1(t,s) \
164     extern __inline__ t __in##s(unsigned long port) { t _v;
165     
166     /*
167      * Required nops will be inserted by the assembler
168      */
169     #define __IN2(m) \
170     __asm__ __volatile__ ("l" #m "\t%0,%1(%2)"
171     
172     #define __IN(t,m,s) \
173     __IN1(t,s) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); return _v; } \
174     __IN1(t,s##c) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); return _v; } \
175     __IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); SLOW_DOWN_IO; return _v; } \
176     __IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return _v; }
177     
178     #define __INS1(s) \
179     extern inline void __ins##s(unsigned long port, void * addr, unsigned long count) {
180     
181     #define __INS2(m) \
182     if (count) \
183     __asm__ __volatile__ ( \
184     	".set\tnoreorder\n\t" \
185     	".set\tnoat\n" \
186     	"1:\tl" #m "\t$1, %4(%5)\n\t" \
187     	"dsubu\t%1, 1\n\t" \
188     	"s" #m "\t$1,(%0)\n\t" \
189     	"bnez\t%1, 1b\n\t" \
190     	"daddiu\t%0, %6\n\t" \
191     	".set\tat\n\t" \
192     	".set\treorder"
193     
194     #define __INS(m,s,i) \
195     __INS1(s) __INS2(m) \
196     	: "=r" (addr), "=r" (count) \
197     	: "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \
198     	: "$1");} \
199     __INS1(s##c) __INS2(m) \
200     	: "=r" (addr), "=r" (count) \
201     	: "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \
202     	: "$1");}
203     
204     #define __OUTS1(s) \
205     extern inline void __outs##s(unsigned long port, const void * addr, unsigned long count) {
206     
207     #define __OUTS2(m) \
208     if (count) \
209     __asm__ __volatile__ ( \
210     	".set\tnoreorder\n\t" \
211     	".set\tnoat\n" \
212     	"1:\tl" #m "\t$1, (%0)\n\t" \
213     	"dsubu\t%1, 1\n\t" \
214     	"s" #m "\t$1, %4(%5)\n\t" \
215     	"bnez\t%1, 1b\n\t" \
216     	"daddiu\t%0, %6\n\t" \
217     	".set\tat\n\t" \
218     	".set\treorder"
219     
220     #define __OUTS(m,s,i) \
221     __OUTS1(s) __OUTS2(m) \
222     	: "=r" (addr), "=r" (count) \
223     	: "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \
224     	: "$1");} \
225     __OUTS1(s##c) __OUTS2(m) \
226     	: "=r" (addr), "=r" (count) \
227     	: "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \
228     	: "$1");}
229     
230     __IN(unsigned char,b,b)
231     __IN(unsigned short,h,w)
232     __IN(unsigned int,w,l)
233     
234     __OUT(b,b)
235     __OUT(h,w)
236     __OUT(w,l)
237     
238     __INS(b,b,1)
239     __INS(h,w,2)
240     __INS(w,l,4)
241     
242     __OUTS(b,b,1)
243     __OUTS(h,w,2)
244     __OUTS(w,l,4)
245     
246     /*
247      * Note that due to the way __builtin_constant_p() works, you
248      *  - can't use it inside an inline function (it will never be true)
249      *  - you don't have to worry about side effects within the __builtin..
250      */
251     #define outb(val,port) \
252     ((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \
253     	__outbc((val),(port)^(3)) : \
254     	__outb((val),(port)^(3)))
255     
256     #define inb(port) \
257     ((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \
258     	__inbc((port)^(3)) : \
259     	__inb((port)^(3)))
260     
261     #define outb_p(val,port) \
262     ((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \
263     	__outbc_p((val),(port)^(3)) : \
264     	__outb_p((val),(port)^(3)))
265     
266     #define inb_p(port) \
267     ((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \
268     	__inbc_p((port)^(3)) : \
269     	__inb_p((port)^(3)))
270     
271     #define outw(val,port) \
272     ((__builtin_constant_p(((port)^(2))) && ((port)^(2)) < 32768) ? \
273     	__outwc((val),((port)^(2))) : \
274     	__outw((val),((port)^(2))))
275     
276     #define inw(port) \
277     ((__builtin_constant_p(((port)^(2))) && ((port)^(2)) < 32768) ? \
278     	__inwc((port)^(2)) : \
279     	__inw((port)^(2)))
280     
281     #define outw_p(val,port) \
282     ((__builtin_constant_p((port)^(2)) && ((port)^(2)) < 32768) ? \
283     	__outwc_p((val),(port)^(2)) : \
284     	__outw_p((val),(port)^(2)))
285     
286     #define inw_p(port) \
287     ((__builtin_constant_p((port)^(2)) && ((port)^(2)) < 32768) ? \
288     	__inwc_p((port)^(2)) : \
289     	__inw_p((port)^(2)))
290     
291     #define outl(val,port) \
292     ((__builtin_constant_p((port)) && (port) < 32768) ? \
293     	__outlc((val),(port)) : \
294     	__outl((val),(port)))
295     
296     #define inl(port) \
297     ((__builtin_constant_p((port)) && (port) < 32768) ? \
298     	__inlc(port) : \
299     	__inl(port))
300     
301     #define outl_p(val,port) \
302     ((__builtin_constant_p((port)) && (port) < 32768) ? \
303     	__outlc_p((val),(port)) : \
304     	__outl_p((val),(port)))
305     
306     #define inl_p(port) \
307     ((__builtin_constant_p((port)) && (port) < 32768) ? \
308     	__inlc_p(port) : \
309     	__inl_p(port))
310     
311     
312     #define outsb(port,addr,count) \
313     ((__builtin_constant_p((port)) && (port) < 32768) ? \
314     	__outsbc((port),(addr),(count)) : \
315     	__outsb ((port),(addr),(count)))
316     
317     #define insb(port,addr,count) \
318     ((__builtin_constant_p((port)) && (port) < 32768) ? \
319     	__insbc((port),(addr),(count)) : \
320     	__insb((port),(addr),(count)))
321     
322     #define outsw(port,addr,count) \
323     ((__builtin_constant_p((port)) && (port) < 32768) ? \
324     	__outswc((port),(addr),(count)) : \
325     	__outsw ((port),(addr),(count)))
326     
327     #define insw(port,addr,count) \
328     ((__builtin_constant_p((port)) && (port) < 32768) ? \
329     	__inswc((port),(addr),(count)) : \
330     	__insw((port),(addr),(count)))
331     
332     #define outsl(port,addr,count) \
333     ((__builtin_constant_p((port)) && (port) < 32768) ? \
334     	__outslc((port),(addr),(count)) : \
335     	__outsl ((port),(addr),(count)))
336     
337     #define insl(port,addr,count) \
338     ((__builtin_constant_p((port)) && (port) < 32768) ? \
339     	__inslc((port),(addr),(count)) : \
340     	__insl((port),(addr),(count)))
341     
342     /*
343      * The caches on some architectures aren't dma-coherent and have need to
344      * handle this in software.  There are three types of operations that
345      * can be applied to dma buffers.
346      *
347      *  - dma_cache_wback_inv(start, size) makes caches and coherent by
348      *    writing the content of the caches back to memory, if necessary.
349      *    The function also invalidates the affected part of the caches as
350      *    necessary before DMA transfers from outside to memory.
351      *  - dma_cache_wback(start, size) makes caches and coherent by
352      *    writing the content of the caches back to memory, if necessary.
353      *    The function also invalidates the affected part of the caches as
354      *    necessary before DMA transfers from outside to memory.
355      *  - dma_cache_inv(start, size) invalidates the affected parts of the
356      *    caches.  Dirty lines of the caches may be written back or simply
357      *    be discarded.  This operation is necessary before dma operations
358      *    to the memory.
359      */
360     #ifdef CONFIG_COHERENT_IO
361     
362     /* This is for example for IP27.  */
363     extern inline void dma_cache_wback_inv(unsigned long start, unsigned long size)
364     {
365     }
366     
367     extern inline void dma_cache_wback(unsigned long start, unsigned long size)
368     {
369     }
370     
371     extern inline void dma_cache_inv(unsigned long start, unsigned long size)
372     {
373     }
374     
375     #else
376     
377     extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
378     extern void (*_dma_cache_wback)(unsigned long start, unsigned long size);
379     extern void (*_dma_cache_inv)(unsigned long start, unsigned long size);
380     
381     #define dma_cache_wback_inv(start,size)	_dma_cache_wback_inv(start,size)
382     #define dma_cache_wback(start,size)	_dma_cache_wback(start,size)
383     #define dma_cache_inv(start,size)	_dma_cache_inv(start,size)
384     
385     #endif
386     
387     #endif /* _ASM_IO_H */
388