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) 2000-2003 Silicon Graphics, Inc. All rights reserved.
7  */
8 
9 #ifndef _ASM_SN_SN2_IO_H
10 #define _ASM_SN_SN2_IO_H
11 
12 extern void * sn_io_addr(unsigned long port) __attribute__ ((__const__)); /* Forward definition */
13 extern void sn_mmiob(void); /* Forward definition */
14 
15 #define __sn_mf_a()   __asm__ __volatile__ ("mf.a" ::: "memory")
16 
17 extern void sn_dma_flush(unsigned long);
18 
19 /*
20  * The following routines are SN Platform specific, called when
21  * a reference is made to inX/outX set macros.  SN Platform
22  * inX set of macros ensures that Posted DMA writes on the
23  * Bridge is flushed.
24  *
25  * The routines should be self explainatory.
26  */
27 
28 static inline unsigned int
__sn_inb(unsigned long port)29 __sn_inb (unsigned long port)
30 {
31 	volatile unsigned char *addr;
32 	unsigned char ret = -1;
33 
34 	if ((addr = sn_io_addr(port))) {
35 		ret = *addr;
36 		__sn_mf_a();
37 		sn_dma_flush((unsigned long)addr);
38 	}
39 	return ret;
40 }
41 
42 static inline unsigned int
__sn_inw(unsigned long port)43 __sn_inw (unsigned long port)
44 {
45 	volatile unsigned short *addr;
46 	unsigned short ret = -1;
47 
48 	if ((addr = sn_io_addr(port))) {
49 		ret = *addr;
50 		__sn_mf_a();
51 		sn_dma_flush((unsigned long)addr);
52 	}
53 	return ret;
54 }
55 
56 static inline unsigned int
__sn_inl(unsigned long port)57 __sn_inl (unsigned long port)
58 {
59 	volatile unsigned int *addr;
60 	unsigned int ret = -1;
61 
62 	if ((addr = sn_io_addr(port))) {
63 		ret = *addr;
64 		__sn_mf_a();
65 		sn_dma_flush((unsigned long)addr);
66 	}
67 	return ret;
68 }
69 
70 static inline void
__sn_outb(unsigned char val,unsigned long port)71 __sn_outb (unsigned char val, unsigned long port)
72 {
73 	volatile unsigned char *addr;
74 
75 	if ((addr = sn_io_addr(port))) {
76 		*addr = val;
77 		sn_mmiob();
78 	}
79 }
80 
81 static inline void
__sn_outw(unsigned short val,unsigned long port)82 __sn_outw (unsigned short val, unsigned long port)
83 {
84 	volatile unsigned short *addr;
85 
86 	if ((addr = sn_io_addr(port))) {
87 		*addr = val;
88 		sn_mmiob();
89 	}
90 }
91 
92 static inline void
__sn_outl(unsigned int val,unsigned long port)93 __sn_outl (unsigned int val, unsigned long port)
94 {
95 	volatile unsigned int *addr;
96 
97 	if ((addr = sn_io_addr(port))) {
98 		*addr = val;
99 		sn_mmiob();
100 	}
101 }
102 
103 /*
104  * The following routines are SN Platform specific, called when
105  * a reference is made to readX/writeX set macros.  SN Platform
106  * readX set of macros ensures that Posted DMA writes on the
107  * Bridge is flushed.
108  *
109  * The routines should be self explainatory.
110  */
111 
112 static inline unsigned char
__sn_readb(void * addr)113 __sn_readb (void *addr)
114 {
115 	unsigned char val;
116 
117 	val = *(volatile unsigned char *)addr;
118 	__sn_mf_a();
119 	sn_dma_flush((unsigned long)addr);
120         return val;
121 }
122 
123 static inline unsigned short
__sn_readw(void * addr)124 __sn_readw (void *addr)
125 {
126 	unsigned short val;
127 
128 	val = *(volatile unsigned short *)addr;
129 	__sn_mf_a();
130 	sn_dma_flush((unsigned long)addr);
131         return val;
132 }
133 
134 static inline unsigned int
__sn_readl(void * addr)135 __sn_readl (void *addr)
136 {
137 	unsigned int val;
138 
139 	val = *(volatile unsigned int *) addr;
140 	__sn_mf_a();
141 	sn_dma_flush((unsigned long)addr);
142         return val;
143 }
144 
145 static inline unsigned long
__sn_readq(void * addr)146 __sn_readq (void *addr)
147 {
148 	unsigned long val;
149 
150 	val = *(volatile unsigned long *) addr;
151 	__sn_mf_a();
152 	sn_dma_flush((unsigned long)addr);
153         return val;
154 }
155 
156 /*
157  * For generic and SN2 kernels, we have a set of fast access
158  * PIO macros.	These macros are provided on SN Platform
159  * because the normal inX and readX macros perform an
160  * additional task of flushing Post DMA request on the Bridge.
161  *
162  * These routines should be self explainatory.
163  */
164 
165 static inline unsigned int
sn_inb_fast(unsigned long port)166 sn_inb_fast (unsigned long port)
167 {
168 	volatile unsigned char *addr = (unsigned char *)port;
169 	unsigned char ret;
170 
171 	ret = *addr;
172 	__sn_mf_a();
173 	return ret;
174 }
175 
176 static inline unsigned int
sn_inw_fast(unsigned long port)177 sn_inw_fast (unsigned long port)
178 {
179 	volatile unsigned short *addr = (unsigned short *)port;
180 	unsigned short ret;
181 
182 	ret = *addr;
183 	__sn_mf_a();
184 	return ret;
185 }
186 
187 static inline unsigned int
sn_inl_fast(unsigned long port)188 sn_inl_fast (unsigned long port)
189 {
190 	volatile unsigned int *addr = (unsigned int *)port;
191 	unsigned int ret;
192 
193 	ret = *addr;
194 	__sn_mf_a();
195 	return ret;
196 }
197 
198 static inline unsigned char
sn_readb_fast(void * addr)199 sn_readb_fast (void *addr)
200 {
201 	return *(volatile unsigned char *)addr;
202 }
203 
204 static inline unsigned short
sn_readw_fast(void * addr)205 sn_readw_fast (void *addr)
206 {
207 	return *(volatile unsigned short *)addr;
208 }
209 
210 static inline unsigned int
sn_readl_fast(void * addr)211 sn_readl_fast (void *addr)
212 {
213 	return *(volatile unsigned int *) addr;
214 }
215 
216 static inline unsigned long
sn_readq_fast(void * addr)217 sn_readq_fast (void *addr)
218 {
219 	return *(volatile unsigned long *) addr;
220 }
221 
222 #endif
223