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