1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * linux/include/asm-m68k/raw_io.h
4  *
5  * 10/20/00 RZ: - created from bits of io.h and ide.h to cleanup namespace
6  *
7  */
8 
9 #ifndef _RAW_IO_H
10 #define _RAW_IO_H
11 
12 #ifdef __KERNEL__
13 
14 #include <asm/byteorder.h>
15 
16 /* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
17  * two accesses to memory, which may be undesirable for some devices.
18  */
19 #define in_8(addr) \
20     ({ u8 __v = (*(__force volatile u8 *) (addr)); __v; })
21 #define in_be16(addr) \
22     ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; })
23 #define in_be32(addr) \
24     ({ u32 __v = (*(__force volatile u32 *) (addr)); __v; })
25 #define in_le16(addr) \
26     ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (addr)); __v; })
27 #define in_le32(addr) \
28     ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (addr)); __v; })
29 
30 #define out_8(addr,b) (void)((*(__force volatile u8 *) (addr)) = (b))
31 #define out_be16(addr,w) (void)((*(__force volatile u16 *) (addr)) = (w))
32 #define out_be32(addr,l) (void)((*(__force volatile u32 *) (addr)) = (l))
33 #define out_le16(addr,w) (void)((*(__force volatile __le16 *) (addr)) = cpu_to_le16(w))
34 #define out_le32(addr,l) (void)((*(__force volatile __le32 *) (addr)) = cpu_to_le32(l))
35 
36 #define raw_inb in_8
37 #define raw_inw in_be16
38 #define raw_inl in_be32
39 #define __raw_readb in_8
40 #define __raw_readw in_be16
41 #define __raw_readl in_be32
42 
43 #define raw_outb(val,port) out_8((port),(val))
44 #define raw_outw(val,port) out_be16((port),(val))
45 #define raw_outl(val,port) out_be32((port),(val))
46 #define __raw_writeb(val,addr) out_8((addr),(val))
47 #define __raw_writew(val,addr) out_be16((addr),(val))
48 #define __raw_writel(val,addr) out_be32((addr),(val))
49 
50 /*
51  * Atari ROM port (cartridge port) ISA adapter, used for the EtherNEC NE2000
52  * network card driver.
53  * The ISA adapter connects address lines A9-A13 to ISA address lines A0-A4,
54  * and hardwires the rest of the ISA addresses for a base address of 0x300.
55  *
56  * Data lines D8-D15 are connected to ISA data lines D0-D7 for reading.
57  * For writes, address lines A1-A8 are latched to ISA data lines D0-D7
58  * (meaning the bit pattern on A1-A8 can be read back as byte).
59  *
60  * Read and write operations are distinguished by the base address used:
61  * reads are from the ROM A side range, writes are through the B side range
62  * addresses (A side base + 0x10000).
63  *
64  * Reads and writes are byte only.
65  *
66  * 16 bit reads and writes are necessary for the NetUSBee adapter's USB
67  * chipset - 16 bit words are read straight off the ROM port while 16 bit
68  * reads are split into two byte writes. The low byte is latched to the
69  * NetUSBee buffer by a read from the _read_ window (with the data pattern
70  * asserted as A1-A8 address pattern). The high byte is then written to the
71  * write range as usual, completing the write cycle.
72  */
73 
74 #if defined(CONFIG_ATARI_ROM_ISA)
75 #define rom_in_8(addr) \
76 	({ u16 __v = (*(__force volatile u16 *) (addr)); __v >>= 8; __v; })
77 #define rom_in_be16(addr) \
78 	({ u16 __v = (*(__force volatile u16 *) (addr)); __v; })
79 #define rom_in_le16(addr) \
80 	({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v; })
81 
82 #define rom_out_8(addr, b)	\
83 	({u8 __w, __v = (b);  u32 _addr = ((u32) (addr)); \
84 	__w = ((*(__force volatile u8 *)  ((_addr | 0x10000) + (__v<<1)))); })
85 #define rom_out_be16(addr, w)	\
86 	({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \
87 	__w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v & 0xFF)<<1)))); \
88 	__w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v >> 8)<<1)))); })
89 #define rom_out_le16(addr, w)	\
90 	({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \
91 	__w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v >> 8)<<1)))); \
92 	__w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v & 0xFF)<<1)))); })
93 
94 #define raw_rom_inb rom_in_8
95 #define raw_rom_inw rom_in_be16
96 
97 #define raw_rom_outb(val, port) rom_out_8((port), (val))
98 #define raw_rom_outw(val, port) rom_out_be16((port), (val))
99 #endif /* CONFIG_ATARI_ROM_ISA */
100 
raw_insb(volatile u8 __iomem * port,u8 * buf,unsigned int len)101 static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
102 {
103 	unsigned int i;
104 
105         for (i = 0; i < len; i++)
106 		*buf++ = in_8(port);
107 }
108 
raw_outsb(volatile u8 __iomem * port,const u8 * buf,unsigned int len)109 static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf,
110 			     unsigned int len)
111 {
112 	unsigned int i;
113 
114         for (i = 0; i < len; i++)
115 		out_8(port, *buf++);
116 }
117 
raw_insw(volatile u16 __iomem * port,u16 * buf,unsigned int nr)118 static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr)
119 {
120 	unsigned int tmp;
121 
122 	if (nr & 15) {
123 		tmp = (nr & 15) - 1;
124 		asm volatile (
125 			"1: movew %2@,%0@+; dbra %1,1b"
126 			: "=a" (buf), "=d" (tmp)
127 			: "a" (port), "0" (buf),
128 			  "1" (tmp));
129 	}
130 	if (nr >> 4) {
131 		tmp = (nr >> 4) - 1;
132 		asm volatile (
133 			"1: "
134 			"movew %2@,%0@+; "
135 			"movew %2@,%0@+; "
136 			"movew %2@,%0@+; "
137 			"movew %2@,%0@+; "
138 			"movew %2@,%0@+; "
139 			"movew %2@,%0@+; "
140 			"movew %2@,%0@+; "
141 			"movew %2@,%0@+; "
142 			"movew %2@,%0@+; "
143 			"movew %2@,%0@+; "
144 			"movew %2@,%0@+; "
145 			"movew %2@,%0@+; "
146 			"movew %2@,%0@+; "
147 			"movew %2@,%0@+; "
148 			"movew %2@,%0@+; "
149 			"movew %2@,%0@+; "
150 			"dbra %1,1b"
151 			: "=a" (buf), "=d" (tmp)
152 			: "a" (port), "0" (buf),
153 			  "1" (tmp));
154 	}
155 }
156 
raw_outsw(volatile u16 __iomem * port,const u16 * buf,unsigned int nr)157 static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf,
158 			     unsigned int nr)
159 {
160 	unsigned int tmp;
161 
162 	if (nr & 15) {
163 		tmp = (nr & 15) - 1;
164 		asm volatile (
165 			"1: movew %0@+,%2@; dbra %1,1b"
166 			: "=a" (buf), "=d" (tmp)
167 			: "a" (port), "0" (buf),
168 			  "1" (tmp));
169 	}
170 	if (nr >> 4) {
171 		tmp = (nr >> 4) - 1;
172 		asm volatile (
173 			"1: "
174 			"movew %0@+,%2@; "
175 			"movew %0@+,%2@; "
176 			"movew %0@+,%2@; "
177 			"movew %0@+,%2@; "
178 			"movew %0@+,%2@; "
179 			"movew %0@+,%2@; "
180 			"movew %0@+,%2@; "
181 			"movew %0@+,%2@; "
182 			"movew %0@+,%2@; "
183 			"movew %0@+,%2@; "
184 			"movew %0@+,%2@; "
185 			"movew %0@+,%2@; "
186 			"movew %0@+,%2@; "
187 			"movew %0@+,%2@; "
188 			"movew %0@+,%2@; "
189 			"movew %0@+,%2@; "
190 			"dbra %1,1b"
191 			: "=a" (buf), "=d" (tmp)
192 			: "a" (port), "0" (buf),
193 			  "1" (tmp));
194 	}
195 }
196 
raw_insl(volatile u32 __iomem * port,u32 * buf,unsigned int nr)197 static inline void raw_insl(volatile u32 __iomem *port, u32 *buf, unsigned int nr)
198 {
199 	unsigned int tmp;
200 
201 	if (nr & 15) {
202 		tmp = (nr & 15) - 1;
203 		asm volatile (
204 			"1: movel %2@,%0@+; dbra %1,1b"
205 			: "=a" (buf), "=d" (tmp)
206 			: "a" (port), "0" (buf),
207 			  "1" (tmp));
208 	}
209 	if (nr >> 4) {
210 		tmp = (nr >> 4) - 1;
211 		asm volatile (
212 			"1: "
213 			"movel %2@,%0@+; "
214 			"movel %2@,%0@+; "
215 			"movel %2@,%0@+; "
216 			"movel %2@,%0@+; "
217 			"movel %2@,%0@+; "
218 			"movel %2@,%0@+; "
219 			"movel %2@,%0@+; "
220 			"movel %2@,%0@+; "
221 			"movel %2@,%0@+; "
222 			"movel %2@,%0@+; "
223 			"movel %2@,%0@+; "
224 			"movel %2@,%0@+; "
225 			"movel %2@,%0@+; "
226 			"movel %2@,%0@+; "
227 			"movel %2@,%0@+; "
228 			"movel %2@,%0@+; "
229 			"dbra %1,1b"
230 			: "=a" (buf), "=d" (tmp)
231 			: "a" (port), "0" (buf),
232 			  "1" (tmp));
233 	}
234 }
235 
raw_outsl(volatile u32 __iomem * port,const u32 * buf,unsigned int nr)236 static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf,
237 			     unsigned int nr)
238 {
239 	unsigned int tmp;
240 
241 	if (nr & 15) {
242 		tmp = (nr & 15) - 1;
243 		asm volatile (
244 			"1: movel %0@+,%2@; dbra %1,1b"
245 			: "=a" (buf), "=d" (tmp)
246 			: "a" (port), "0" (buf),
247 			  "1" (tmp));
248 	}
249 	if (nr >> 4) {
250 		tmp = (nr >> 4) - 1;
251 		asm volatile (
252 			"1: "
253 			"movel %0@+,%2@; "
254 			"movel %0@+,%2@; "
255 			"movel %0@+,%2@; "
256 			"movel %0@+,%2@; "
257 			"movel %0@+,%2@; "
258 			"movel %0@+,%2@; "
259 			"movel %0@+,%2@; "
260 			"movel %0@+,%2@; "
261 			"movel %0@+,%2@; "
262 			"movel %0@+,%2@; "
263 			"movel %0@+,%2@; "
264 			"movel %0@+,%2@; "
265 			"movel %0@+,%2@; "
266 			"movel %0@+,%2@; "
267 			"movel %0@+,%2@; "
268 			"movel %0@+,%2@; "
269 			"dbra %1,1b"
270 			: "=a" (buf), "=d" (tmp)
271 			: "a" (port), "0" (buf),
272 			  "1" (tmp));
273 	}
274 }
275 
276 
raw_insw_swapw(volatile u16 __iomem * port,u16 * buf,unsigned int nr)277 static inline void raw_insw_swapw(volatile u16 __iomem *port, u16 *buf,
278 				  unsigned int nr)
279 {
280     if ((nr) % 8)
281 	__asm__ __volatile__
282 	       ("\tmovel %0,%/a0\n\t"
283 		"movel %1,%/a1\n\t"
284 		"movel %2,%/d6\n\t"
285 		"subql #1,%/d6\n"
286 		"1:\tmovew %/a0@,%/d0\n\t"
287 		"rolw  #8,%/d0\n\t"
288 		"movew %/d0,%/a1@+\n\t"
289 		"dbra %/d6,1b"
290 		:
291 		: "g" (port), "g" (buf), "g" (nr)
292 		: "d0", "a0", "a1", "d6");
293     else
294 	__asm__ __volatile__
295 	       ("movel %0,%/a0\n\t"
296 		"movel %1,%/a1\n\t"
297 		"movel %2,%/d6\n\t"
298 		"lsrl  #3,%/d6\n\t"
299 		"subql #1,%/d6\n"
300 		"1:\tmovew %/a0@,%/d0\n\t"
301 		"rolw  #8,%/d0\n\t"
302 		"movew %/d0,%/a1@+\n\t"
303 		"movew %/a0@,%/d0\n\t"
304 		"rolw  #8,%/d0\n\t"
305 		"movew %/d0,%/a1@+\n\t"
306 		"movew %/a0@,%/d0\n\t"
307 		"rolw  #8,%/d0\n\t"
308 		"movew %/d0,%/a1@+\n\t"
309 		"movew %/a0@,%/d0\n\t"
310 		"rolw  #8,%/d0\n\t"
311 		"movew %/d0,%/a1@+\n\t"
312 		"movew %/a0@,%/d0\n\t"
313 		"rolw  #8,%/d0\n\t"
314 		"movew %/d0,%/a1@+\n\t"
315 		"movew %/a0@,%/d0\n\t"
316 		"rolw  #8,%/d0\n\t"
317 		"movew %/d0,%/a1@+\n\t"
318 		"movew %/a0@,%/d0\n\t"
319 		"rolw  #8,%/d0\n\t"
320 		"movew %/d0,%/a1@+\n\t"
321 		"movew %/a0@,%/d0\n\t"
322 		"rolw  #8,%/d0\n\t"
323 		"movew %/d0,%/a1@+\n\t"
324 		"dbra %/d6,1b"
325                 :
326 		: "g" (port), "g" (buf), "g" (nr)
327 		: "d0", "a0", "a1", "d6");
328 }
329 
raw_outsw_swapw(volatile u16 __iomem * port,const u16 * buf,unsigned int nr)330 static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
331 				   unsigned int nr)
332 {
333     if ((nr) % 8)
334 	__asm__ __volatile__
335 	       ("movel %0,%/a0\n\t"
336 		"movel %1,%/a1\n\t"
337 		"movel %2,%/d6\n\t"
338 		"subql #1,%/d6\n"
339 		"1:\tmovew %/a1@+,%/d0\n\t"
340 		"rolw  #8,%/d0\n\t"
341 		"movew %/d0,%/a0@\n\t"
342 		"dbra %/d6,1b"
343                 :
344 		: "g" (port), "g" (buf), "g" (nr)
345 		: "d0", "a0", "a1", "d6");
346     else
347 	__asm__ __volatile__
348 	       ("movel %0,%/a0\n\t"
349 		"movel %1,%/a1\n\t"
350 		"movel %2,%/d6\n\t"
351 		"lsrl  #3,%/d6\n\t"
352 		"subql #1,%/d6\n"
353 		"1:\tmovew %/a1@+,%/d0\n\t"
354 		"rolw  #8,%/d0\n\t"
355 		"movew %/d0,%/a0@\n\t"
356 		"movew %/a1@+,%/d0\n\t"
357 		"rolw  #8,%/d0\n\t"
358 		"movew %/d0,%/a0@\n\t"
359 		"movew %/a1@+,%/d0\n\t"
360 		"rolw  #8,%/d0\n\t"
361 		"movew %/d0,%/a0@\n\t"
362 		"movew %/a1@+,%/d0\n\t"
363 		"rolw  #8,%/d0\n\t"
364 		"movew %/d0,%/a0@\n\t"
365 		"movew %/a1@+,%/d0\n\t"
366 		"rolw  #8,%/d0\n\t"
367 		"movew %/d0,%/a0@\n\t"
368 		"movew %/a1@+,%/d0\n\t"
369 		"rolw  #8,%/d0\n\t"
370 		"movew %/d0,%/a0@\n\t"
371 		"movew %/a1@+,%/d0\n\t"
372 		"rolw  #8,%/d0\n\t"
373 		"movew %/d0,%/a0@\n\t"
374 		"movew %/a1@+,%/d0\n\t"
375 		"rolw  #8,%/d0\n\t"
376 		"movew %/d0,%/a0@\n\t"
377 		"dbra %/d6,1b"
378                 :
379 		: "g" (port), "g" (buf), "g" (nr)
380 		: "d0", "a0", "a1", "d6");
381 }
382 
383 
384 #if defined(CONFIG_ATARI_ROM_ISA)
raw_rom_insb(volatile u8 __iomem * port,u8 * buf,unsigned int len)385 static inline void raw_rom_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
386 {
387 	unsigned int i;
388 
389 	for (i = 0; i < len; i++)
390 		*buf++ = rom_in_8(port);
391 }
392 
raw_rom_outsb(volatile u8 __iomem * port,const u8 * buf,unsigned int len)393 static inline void raw_rom_outsb(volatile u8 __iomem *port, const u8 *buf,
394 			     unsigned int len)
395 {
396 	unsigned int i;
397 
398 	for (i = 0; i < len; i++)
399 		rom_out_8(port, *buf++);
400 }
401 
raw_rom_insw(volatile u16 __iomem * port,u16 * buf,unsigned int nr)402 static inline void raw_rom_insw(volatile u16 __iomem *port, u16 *buf,
403 				   unsigned int nr)
404 {
405 	unsigned int i;
406 
407 	for (i = 0; i < nr; i++)
408 		*buf++ = rom_in_be16(port);
409 }
410 
raw_rom_outsw(volatile u16 __iomem * port,const u16 * buf,unsigned int nr)411 static inline void raw_rom_outsw(volatile u16 __iomem *port, const u16 *buf,
412 				   unsigned int nr)
413 {
414 	unsigned int i;
415 
416 	for (i = 0; i < nr; i++)
417 		rom_out_be16(port, *buf++);
418 }
419 
raw_rom_insw_swapw(volatile u16 __iomem * port,u16 * buf,unsigned int nr)420 static inline void raw_rom_insw_swapw(volatile u16 __iomem *port, u16 *buf,
421 				   unsigned int nr)
422 {
423 	unsigned int i;
424 
425 	for (i = 0; i < nr; i++)
426 		*buf++ = rom_in_le16(port);
427 }
428 
raw_rom_outsw_swapw(volatile u16 __iomem * port,const u16 * buf,unsigned int nr)429 static inline void raw_rom_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
430 				   unsigned int nr)
431 {
432 	unsigned int i;
433 
434 	for (i = 0; i < nr; i++)
435 		rom_out_le16(port, *buf++);
436 }
437 #endif /* CONFIG_ATARI_ROM_ISA */
438 
439 #endif /* __KERNEL__ */
440 
441 #endif /* _RAW_IO_H */
442