xref: /netbsd/sys/arch/x68k/include/bus.h (revision 8a06b90d)
1 /*	$NetBSD: bus.h,v 1.26 2019/09/23 16:17:58 skrll Exp $	*/
2 
3 /*-
4  * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * bus_space(9) and bus_dma(9) interface for NetBSD/x68k.
35  */
36 
37 #ifndef _X68K_BUS_H_
38 #define _X68K_BUS_H_
39 
40 /*
41  * Bus address and size types
42  */
43 typedef u_long	bus_addr_t;
44 typedef u_long	bus_size_t;
45 typedef	u_long	bus_space_handle_t;
46 
47 #define PRIxBUSADDR	"lx"
48 #define PRIxBUSSIZE	"lx"
49 #define PRIuBUSSIZE	"lu"
50 #define PRIxBSH		"lx"
51 
52 /*
53  * Bus space descripter
54  */
55 typedef struct x68k_bus_space *bus_space_tag_t;
56 
57 struct x68k_bus_space {
58 #if 0
59 	enum {
60 		X68K_INTIO_BUS,
61 		X68K_PCI_BUS,
62 		X68K_NEPTUNE_BUS
63 	}	x68k_bus_type;
64 #endif
65 
66 	int	(*x68k_bus_space_map)(
67 				bus_space_tag_t,
68 				bus_addr_t,
69 				bus_size_t,
70 				int,			/* flags */
71 				bus_space_handle_t *);
72 	void	(*x68k_bus_space_unmap)(
73 				bus_space_tag_t,
74 				bus_space_handle_t,
75 				bus_size_t);
76 	int	(*x68k_bus_space_subregion)(
77 				bus_space_tag_t,
78 				bus_space_handle_t,
79 				bus_size_t,		/* offset */
80 				bus_size_t,		/* size */
81 				bus_space_handle_t *);
82 
83 	int	(*x68k_bus_space_alloc)(
84 				bus_space_tag_t,
85 				bus_addr_t,		/* reg_start */
86 				bus_addr_t,		/* reg_end */
87 				bus_size_t,
88 				bus_size_t,		/* alignment */
89 				bus_size_t,		/* boundary */
90 				int,			/* flags */
91 				bus_addr_t *,
92 				bus_space_handle_t *);
93 	void	(*x68k_bus_space_free)(
94 				bus_space_tag_t,
95 				bus_space_handle_t,
96 				bus_size_t);
97 
98 #if 0
99 	void	(*x68k_bus_space_barrier)(
100 				bus_space_tag_t,
101 				bus_space_handle_t,
102 				bus_size_t,		/* offset */
103 				bus_size_t,		/* length */
104 				int);			/* flags */
105 #endif
106 
107 	device_t x68k_bus_device;
108 };
109 
110 int x68k_bus_space_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t, bus_size_t,
111     bus_size_t, bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
112 void x68k_bus_space_free(bus_space_tag_t, bus_space_handle_t, bus_size_t);
113 
114 /*
115  * bus_space(9) interface
116  */
117 
118 #define bus_space_map(t, a, s, f, h) \
119 		((*((t)->x68k_bus_space_map)) ((t), (a), (s), (f), (h)))
120 #define bus_space_unmap(t, h, s) \
121 		((*((t)->x68k_bus_space_unmap)) ((t), (h), (s)))
122 #define bus_space_subregion(t, h, o, s, p) \
123 		((*((t)->x68k_bus_space_subregion)) ((t), (h), (o), (s), (p)))
124 #define BUS_SPACE_MAP_CACHEABLE		0x0001
125 #define BUS_SPACE_MAP_LINEAR		0x0002
126 #define BUS_SPACE_MAP_PREFETCHABLE	0x0004
127 /*
128  * For simpler hardware, many x68k devices are mapped with shifted address
129  * i.e. only on even or odd addresses.
130  */
131 #define BUS_SPACE_MAP_SHIFTED_MASK	0x1001
132 #define BUS_SPACE_MAP_SHIFTED_ODD	0x1001
133 #define BUS_SPACE_MAP_SHIFTED_EVEN	0x1000
134 #define BUS_SPACE_MAP_SHIFTED		BUS_SPACE_MAP_SHIFTED_ODD
135 
136 #define bus_space_alloc(t, rs, re, s, a, b, f, r, h)			\
137 		((*((t)->x68k_bus_space_alloc)) ((t),			\
138 		    (rs), (re), (s), (a), (b), (f), (r), (h)))
139 #define bus_space_free(t, h, s) \
140 		((*((t)->x68k_bus_space_free)) ((t), (h), (s)))
141 
142 /*
143  * Note: the 680x0 does not currently require barriers, but we must
144  * provide the flags to MI code.
145  */
146 #define	bus_space_barrier(t, h, o, l, f)	\
147 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
148 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
149 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
150 
151 #define bus_space_read_1(t,h,o) _bus_space_read_1(t,h,o)
152 #define bus_space_read_2(t,h,o) _bus_space_read_2(t,h,o)
153 #define bus_space_read_4(t,h,o) _bus_space_read_4(t,h,o)
154 
155 #define bus_space_read_multi_1(t,h,o,p,c) _bus_space_read_multi_1(t,h,o,p,c)
156 #define bus_space_read_multi_2(t,h,o,p,c) _bus_space_read_multi_2(t,h,o,p,c)
157 #define bus_space_read_multi_4(t,h,o,p,c) _bus_space_read_multi_4(t,h,o,p,c)
158 
159 #define bus_space_read_region_1(t,h,o,p,c) _bus_space_read_region_1(t,h,o,p,c)
160 #define bus_space_read_region_2(t,h,o,p,c) _bus_space_read_region_2(t,h,o,p,c)
161 #define bus_space_read_region_4(t,h,o,p,c) _bus_space_read_region_4(t,h,o,p,c)
162 
163 #define bus_space_write_1(t,h,o,v) _bus_space_write_1(t,h,o,v)
164 #define bus_space_write_2(t,h,o,v) _bus_space_write_2(t,h,o,v)
165 #define bus_space_write_4(t,h,o,v) _bus_space_write_4(t,h,o,v)
166 
167 #define bus_space_write_multi_1(t,h,o,p,c) _bus_space_write_multi_1(t,h,o,p,c)
168 #define bus_space_write_multi_2(t,h,o,p,c) _bus_space_write_multi_2(t,h,o,p,c)
169 #define bus_space_write_multi_4(t,h,o,p,c) _bus_space_write_multi_4(t,h,o,p,c)
170 
171 #define bus_space_write_region_1(t,h,o,p,c) \
172 		_bus_space_write_region_1(t,h,o,p,c)
173 #define bus_space_write_region_2(t,h,o,p,c) \
174 		_bus_space_write_region_2(t,h,o,p,c)
175 #define bus_space_write_region_4(t,h,o,p,c) \
176 		_bus_space_write_region_4(t,h,o,p,c)
177 
178 #define bus_space_set_region_1(t,h,o,v,c) _bus_space_set_region_1(t,h,o,v,c)
179 #define bus_space_set_region_2(t,h,o,v,c) _bus_space_set_region_2(t,h,o,v,c)
180 #define bus_space_set_region_4(t,h,o,v,c) _bus_space_set_region_4(t,h,o,v,c)
181 
182 #define bus_space_copy_region_1(t,sh,so,dh,do,c) \
183 		_bus_space_copy_region_1(t,sh,so,dh,do,c)
184 #define bus_space_copy_region_2(t,sh,so,dh,do,c) \
185 		_bus_space_copy_region_2(t,sh,so,dh,do,c)
186 #define bus_space_copy_region_4(t,sh,so,dh,do,c) \
187 		_bus_space_copy_region_4(t,sh,so,dh,do,c)
188 
189 static __inline uint8_t _bus_space_read_1
190 	(bus_space_tag_t, bus_space_handle_t bsh, bus_size_t offset);
191 static __inline uint16_t _bus_space_read_2
192 	(bus_space_tag_t, bus_space_handle_t, bus_size_t);
193 static __inline uint32_t _bus_space_read_4
194 	(bus_space_tag_t, bus_space_handle_t, bus_size_t);
195 
196 static __inline void _bus_space_read_multi_1
197 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
198 	     uint8_t *, bus_size_t);
199 static __inline void _bus_space_read_multi_2
200 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
201 	     uint16_t *, bus_size_t);
202 static __inline void _bus_space_read_multi_4
203 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
204 	     uint32_t *, bus_size_t);
205 
206 static __inline void _bus_space_read_region_1
207 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
208 	     uint8_t *, bus_size_t);
209 static __inline void _bus_space_read_region_2
210 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
211 	     uint16_t *, bus_size_t);
212 static __inline void _bus_space_read_region_4
213 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
214 	     uint32_t *, bus_size_t);
215 
216 static __inline void _bus_space_write_1
217 	(bus_space_tag_t, bus_space_handle_t, bus_size_t, uint8_t);
218 static __inline void _bus_space_write_2
219 	(bus_space_tag_t, bus_space_handle_t, bus_size_t, uint16_t);
220 static __inline void _bus_space_write_4
221 	(bus_space_tag_t, bus_space_handle_t, bus_size_t, uint32_t);
222 
223 static __inline void _bus_space_write_multi_1
224 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
225 	     const uint8_t *, bus_size_t);
226 static __inline void _bus_space_write_multi_2
227 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
228 	     const uint16_t *, bus_size_t);
229 static __inline void _bus_space_write_multi_4
230 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
231 	     const uint32_t *, bus_size_t);
232 
233 static __inline void _bus_space_write_region_1
234 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
235 	     const uint8_t *, bus_size_t);
236 static __inline void _bus_space_write_region_2
237 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
238 	     const uint16_t *, bus_size_t);
239 static __inline void _bus_space_write_region_4
240 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
241 	     const uint32_t *, bus_size_t);
242 
243 static __inline void _bus_space_set_region_1
244 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
245 	     uint8_t, bus_size_t);
246 static __inline void _bus_space_set_region_2
247 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
248 	     uint16_t, bus_size_t);
249 static __inline void _bus_space_set_region_4
250 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
251 	     uint32_t, bus_size_t);
252 
253 static __inline void _bus_space_copy_region_1
254 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
255 	     bus_space_handle_t, bus_size_t, bus_size_t);
256 static __inline void _bus_space_copy_region_2
257 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
258 	     bus_space_handle_t, bus_size_t, bus_size_t);
259 static __inline void _bus_space_copy_region_4
260 	(bus_space_tag_t, bus_space_handle_t, bus_size_t,
261 	     bus_space_handle_t, bus_size_t, bus_size_t);
262 
263 
264 #define __X68K_BUS_ADDR(tag, handle, offset)	\
265 	(((long)(handle) < 0 ? (offset) * 2 : (offset))	\
266 		+ ((handle) & 0x7fffffff))
267 
268 static __inline uint8_t
_bus_space_read_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset)269 _bus_space_read_1(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset)
270 {
271 
272 	return *((volatile uint8_t *) __X68K_BUS_ADDR(t, bsh, offset));
273 }
274 
275 static __inline uint16_t
_bus_space_read_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset)276 _bus_space_read_2(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset)
277 {
278 
279 	return *((volatile uint16_t *) __X68K_BUS_ADDR(t, bsh, offset));
280 }
281 
282 static __inline uint32_t
_bus_space_read_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset)283 _bus_space_read_4(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset)
284 {
285 
286 	return *((volatile uint32_t *) __X68K_BUS_ADDR(t, bsh, offset));
287 }
288 
289 static __inline void
_bus_space_read_multi_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint8_t * datap,bus_size_t count)290 _bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t bsh,
291     bus_size_t offset, uint8_t *datap, bus_size_t count)
292 {
293 	volatile uint8_t *regadr;
294 
295 	regadr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset);
296 
297 	for (; count; count--)
298 		*datap++ = *regadr;
299 }
300 
301 static __inline void
_bus_space_read_multi_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint16_t * datap,bus_size_t count)302 _bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t bsh,
303     bus_size_t offset, uint16_t *datap, bus_size_t count)
304 {
305 	volatile uint16_t *regadr;
306 
307 	regadr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset);
308 
309 	for (; count; count--)
310 		*datap++ = *regadr;
311 }
312 
313 static __inline void
_bus_space_read_multi_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint32_t * datap,bus_size_t count)314 _bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t bsh,
315     bus_size_t offset, uint32_t *datap, bus_size_t count)
316 {
317 	volatile uint32_t *regadr;
318 
319 	regadr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset);
320 
321 	for (; count; count--)
322 		*datap++ = *regadr;
323 }
324 
325 static __inline void
_bus_space_read_region_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint8_t * datap,bus_size_t count)326 _bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t bsh,
327     bus_size_t offset, uint8_t *datap, bus_size_t count)
328 {
329 	volatile uint8_t *addr;
330 
331 	addr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset);
332 
333 	for (; count; count--)
334 		*datap++ = *addr++;
335 }
336 
337 static __inline void
_bus_space_read_region_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint16_t * datap,bus_size_t count)338 _bus_space_read_region_2(bus_space_tag_t t, bus_space_handle_t bsh,
339     bus_size_t offset, uint16_t *datap, bus_size_t count)
340 {
341 	volatile uint16_t *addr;
342 
343 	addr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset);
344 
345 	for (; count; count--)
346 		*datap++ = *addr++;
347 }
348 
349 static __inline void
_bus_space_read_region_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint32_t * datap,bus_size_t count)350 _bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t bsh,
351     bus_size_t offset, uint32_t *datap, bus_size_t count)
352 {
353 	volatile uint32_t *addr;
354 
355 	addr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset);
356 
357 	for (; count; count--)
358 		*datap++ = *addr++;
359 }
360 
361 static __inline void
_bus_space_write_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint8_t value)362 _bus_space_write_1(bus_space_tag_t t, bus_space_handle_t bsh,
363     bus_size_t offset, uint8_t value)
364 {
365 
366 	*(volatile uint8_t *) __X68K_BUS_ADDR(t, bsh, offset) = value;
367 }
368 
369 static __inline void
_bus_space_write_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint16_t value)370 _bus_space_write_2(bus_space_tag_t t, bus_space_handle_t bsh,
371     bus_size_t offset, uint16_t value)
372 {
373 
374 	*(volatile uint16_t *) __X68K_BUS_ADDR(t, bsh, offset) = value;
375 }
376 
377 static __inline void
_bus_space_write_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint32_t value)378 _bus_space_write_4(bus_space_tag_t t, bus_space_handle_t bsh,
379     bus_size_t offset, uint32_t value)
380 {
381 
382 	*(volatile uint32_t *) __X68K_BUS_ADDR(t, bsh, offset) = value;
383 }
384 
385 static __inline void
_bus_space_write_multi_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,const uint8_t * datap,bus_size_t count)386 _bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t bsh,
387     bus_size_t offset, const uint8_t *datap, bus_size_t count)
388 {
389 	volatile uint8_t *regadr;
390 
391 	regadr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset);
392 
393 	for (; count; count--)
394 		*regadr = *datap++;
395 }
396 
397 static __inline void
_bus_space_write_multi_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,const uint16_t * datap,bus_size_t count)398 _bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t bsh,
399     bus_size_t offset, const uint16_t *datap, bus_size_t count)
400 {
401 	volatile uint16_t *regadr;
402 
403 	regadr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset);
404 
405 	for (; count; count--)
406 		*regadr = *datap++;
407 }
408 
409 static __inline void
_bus_space_write_multi_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,const uint32_t * datap,bus_size_t count)410 _bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t bsh,
411     bus_size_t offset, const uint32_t *datap, bus_size_t count)
412 {
413 	volatile uint32_t *regadr;
414 
415 	regadr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset);
416 
417 	for (; count; count--)
418 		*regadr = *datap++;
419 }
420 
421 static __inline void
_bus_space_write_region_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,const uint8_t * datap,bus_size_t count)422 _bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t bsh,
423     bus_size_t offset, const uint8_t *datap, bus_size_t count)
424 {
425 	volatile uint8_t *addr;
426 
427 	addr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset);
428 
429 	for (; count; count--)
430 		*addr++ = *datap++;
431 }
432 
433 static __inline void
_bus_space_write_region_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,const uint16_t * datap,bus_size_t count)434 _bus_space_write_region_2(bus_space_tag_t t, bus_space_handle_t bsh,
435     bus_size_t offset, const uint16_t *datap, bus_size_t count)
436 {
437 	volatile uint16_t *addr;
438 
439 	addr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset);
440 
441 	for (; count; count--)
442 		*addr++ = *datap++;
443 }
444 
445 static __inline void
_bus_space_write_region_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,const uint32_t * datap,bus_size_t count)446 _bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t bsh,
447     bus_size_t offset, const uint32_t *datap, bus_size_t count)
448 {
449 	volatile uint32_t *addr;
450 
451 	addr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset);
452 
453 	for (; count; count--)
454 		*addr++ = *datap++;
455 }
456 
457 static __inline void
_bus_space_set_region_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint8_t value,bus_size_t count)458 _bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t bsh,
459     bus_size_t offset, uint8_t value, bus_size_t count)
460 {
461 	volatile uint8_t *addr;
462 
463 	addr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset);
464 
465 	for (; count; count--)
466 		*addr++ = value;
467 }
468 
469 static __inline void
_bus_space_set_region_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint16_t value,bus_size_t count)470 _bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t bsh,
471     bus_size_t offset, uint16_t value, bus_size_t count)
472 {
473 	volatile uint16_t *addr;
474 
475 	addr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset);
476 
477 	for (; count; count--)
478 		*addr++ = value;
479 }
480 
481 static __inline void
_bus_space_set_region_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint32_t value,bus_size_t count)482 _bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t bsh,
483     bus_size_t offset, uint32_t value, bus_size_t count)
484 {
485 	volatile uint32_t *addr;
486 
487 	addr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset);
488 
489 	for (; count; count--)
490 		*addr++ = value;
491 }
492 
493 static __inline void
_bus_space_copy_region_1(bus_space_tag_t t,bus_space_handle_t sbsh,bus_size_t soffset,bus_space_handle_t dbsh,bus_size_t doffset,bus_size_t count)494 _bus_space_copy_region_1(bus_space_tag_t t,
495     bus_space_handle_t sbsh, bus_size_t soffset,
496     bus_space_handle_t dbsh, bus_size_t doffset,
497     bus_size_t count)
498 {
499 	volatile uint8_t *saddr = (void *) (sbsh + soffset);
500 	volatile uint8_t *daddr = (void *) (dbsh + doffset);
501 
502 	if ((uint32_t) saddr >= (uint32_t) daddr)
503 		while (count-- > 0)
504 			*daddr++ = *saddr++;
505 	else {
506 		saddr += count;
507 		daddr += count;
508 		while (count-- > 0)
509 			*--daddr = *--saddr;
510 	}
511 }
512 
513 static __inline void
_bus_space_copy_region_2(bus_space_tag_t t,bus_space_handle_t sbsh,bus_size_t soffset,bus_space_handle_t dbsh,bus_size_t doffset,bus_size_t count)514 _bus_space_copy_region_2(bus_space_tag_t t,
515     bus_space_handle_t sbsh, bus_size_t soffset,
516     bus_space_handle_t dbsh, bus_size_t doffset,
517     bus_size_t count)
518 {
519 	volatile uint16_t *saddr = (void *) (sbsh + soffset);
520 	volatile uint16_t *daddr = (void *) (dbsh + doffset);
521 
522 	if ((uint32_t) saddr >= (uint32_t) daddr)
523 		while (count-- > 0)
524 			*daddr++ = *saddr++;
525 	else {
526 		saddr += count;
527 		daddr += count;
528 		while (count-- > 0)
529 			*--daddr = *--saddr;
530 	}
531 }
532 
533 static __inline void
_bus_space_copy_region_4(bus_space_tag_t t,bus_space_handle_t sbsh,bus_size_t soffset,bus_space_handle_t dbsh,bus_size_t doffset,bus_size_t count)534 _bus_space_copy_region_4(bus_space_tag_t t,
535     bus_space_handle_t sbsh, bus_size_t soffset,
536     bus_space_handle_t dbsh, bus_size_t doffset,
537     bus_size_t count)
538 {
539 	volatile uint32_t *saddr = (void *) (sbsh + soffset);
540 	volatile uint32_t *daddr = (void *) (dbsh + doffset);
541 
542 	if ((uint32_t) saddr >= (uint32_t) daddr)
543 		while (count-- > 0)
544 			*daddr++ = *saddr++;
545 	else {
546 		saddr += count;
547 		daddr += count;
548 		while (count-- > 0)
549 			*--daddr = *--saddr;
550 	}
551 }
552 
553 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
554 
555 /*
556  * DMA segment
557  */
558 struct x68k_bus_dma_segment {
559 	bus_addr_t	ds_addr;
560 	bus_size_t	ds_len;
561 };
562 typedef struct x68k_bus_dma_segment	bus_dma_segment_t;
563 
564 /*
565  * DMA descriptor
566  */
567 /* Forwards needed by prototypes below. */
568 struct mbuf;
569 struct uio;
570 
571 typedef struct x68k_bus_dma		*bus_dma_tag_t;
572 typedef struct x68k_bus_dmamap		*bus_dmamap_t;
573 
574 #define BUS_DMA_TAG_VALID(t)    ((t) != (bus_dma_tag_t)0)
575 
576 struct x68k_bus_dma {
577 	/*
578 	 * The `bounce threshold' is checked while we are loading
579 	 * the DMA map.  If the physical address of the segment
580 	 * exceeds the threshold, an error will be returned.  The
581 	 * caller can then take whatever action is necessary to
582 	 * bounce the transfer.  If this value is 0, it will be
583 	 * ignored.
584 	 */
585 	bus_addr_t _bounce_thresh;
586 
587 	/*
588 	 * DMA mapping methods.
589 	 */
590 	int	(*x68k_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
591 		    bus_size_t, bus_size_t, int, bus_dmamap_t *);
592 	void	(*x68k_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
593 	int	(*x68k_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
594 		    bus_size_t, struct proc *, int);
595 	int	(*x68k_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
596 		    struct mbuf *, int);
597 	int	(*x68k_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
598 		    struct uio *, int);
599 	int	(*x68k_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
600 		    bus_dma_segment_t *, int, bus_size_t, int);
601 	void	(*x68k_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
602 	void	(*x68k_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
603 		    bus_addr_t, bus_size_t, int);
604 
605 	/*
606 	 * DMA memory utility functions.
607 	 */
608 	int	(*x68k_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
609 		    bus_size_t, bus_dma_segment_t *, int, int *, int);
610 	void	(*x68k_dmamem_free)(bus_dma_tag_t,
611 		    bus_dma_segment_t *, int);
612 	int	(*x68k_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
613 		    int, size_t, void **, int);
614 	void	(*x68k_dmamem_unmap)(bus_dma_tag_t, void *, size_t);
615 	paddr_t	(*x68k_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
616 		    int, off_t, int, int);
617 };
618 
619 /*
620  *	bus_dmamap_t
621  *
622  *	Describes a DMA mapping.
623  */
624 struct x68k_bus_dmamap {
625 	/*
626 	 * PRIVATE MEMBERS: not for use my machine-independent code.
627 	 */
628 	bus_size_t	x68k_dm_size;	/* largest DMA transfer mappable */
629 	int		x68k_dm_segcnt;	/* number of segs this map can map */
630 	bus_size_t	x68k_dm_maxmaxsegsz; /* fixed largest possible segment*/
631 	bus_size_t	x68k_dm_boundary; /* don't cross this */
632 	bus_addr_t	x68k_dm_bounce_thresh; /* bounce threshold */
633 	int		x68k_dm_flags;	/* misc. flags */
634 
635 	void		*x68k_dm_cookie; /* cookie for bus-specific functions */
636 
637 	/*
638 	 * PUBLIC MEMBERS: these are used by machine-independent code.
639 	 */
640 	bus_size_t	dm_maxsegsz;	/* largest possible segment */
641 	bus_size_t	dm_mapsize;	/* size of the mapping */
642 	int		dm_nsegs;	/* # valid segments in mapping */
643 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
644 };
645 
646 int	x68k_bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
647 	    bus_size_t, int, bus_dmamap_t *);
648 void	x68k_bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
649 int	x68k_bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
650 	    bus_size_t, struct proc *, int);
651 int	x68k_bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t,
652 	    struct mbuf *, int);
653 int	x68k_bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t,
654 	    struct uio *, int);
655 int	x68k_bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
656 	    bus_dma_segment_t *, int, bus_size_t, int);
657 void	x68k_bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
658 void	x68k_bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
659 	    bus_size_t, int);
660 
661 int	x68k_bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size,
662 	    bus_size_t alignment, bus_size_t boundary,
663 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
664 void	x68k_bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs,
665 	    int nsegs);
666 int	x68k_bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs,
667 	    int nsegs, size_t size, void **kvap, int flags);
668 void	x68k_bus_dmamem_unmap(bus_dma_tag_t tag, void *kva,
669 	    size_t size);
670 paddr_t	x68k_bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
671 	    int nsegs, off_t off, int prot, int flags);
672 
673 int	x68k_bus_dmamap_load_buffer(bus_dmamap_t, void *,
674 	    bus_size_t buflen, struct proc *, int, paddr_t *, int *, int);
675 int	x68k_bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
676 	    bus_size_t alignment, bus_size_t boundary,
677 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
678 	    paddr_t low, paddr_t high);
679 
680 #define	bus_dmamap_create(t,s,n,m,b,f,p) \
681 	((*((t)->x68k_dmamap_create)) ((t),(s),(n),(m),(b),(f),(p)))
682 #define	bus_dmamap_destroy(t,p) \
683 	((*((t)->x68k_dmamap_destroy)) ((t),(p)))
684 #define	bus_dmamap_load(t,m,b,s,p,f) \
685 	((*((t)->x68k_dmamap_load)) ((t),(m),(b),(s),(p),(f)))
686 #define	bus_dmamap_load_mbuf(t,m,b,f) \
687 	((*((t)->x68k_dmamap_load_mbuf)) ((t),(m),(b),(f)))
688 #define	bus_dmamap_load_uio(t,m,u,f) \
689 	((*((t)->x68k_dmamap_load_uio)) ((t),(m),(u),(f)))
690 #define	bus_dmamap_load_raw(t,m,sg,n,s,f) \
691 	((*((t)->x68k_dmamap_load_raw)) ((t),(m),(sg),(n),(s),(f)))
692 #define	bus_dmamap_unload(t,p) \
693 	((*((t)->x68k_dmamap_unload)) ((t),(p)))
694 #define	bus_dmamap_sync(t,p,o,l,ops) \
695 	((*((t)->x68k_dmamap_sync)) ((t),(p),(o),(l),(ops)))
696 
697 #define	bus_dmamem_alloc(t,s,a,b,sg,n,r,f) \
698 	((*((t)->x68k_dmamem_alloc)) ((t),(s),(a),(b),(sg),(n),(r),(f)))
699 #define	bus_dmamem_free(t,sg,n) \
700 	((*((t)->x68k_dmamem_free)) ((t),(sg),(n)))
701 #define	bus_dmamem_map(t,sg,n,s,k,f) \
702 	((*((t)->x68k_dmamem_map)) ((t),(sg),(n),(s),(k),(f)))
703 #define	bus_dmamem_unmap(t,k,s) \
704 	((*((t)->x68k_dmamem_unmap)) ((t),(k),(s)))
705 #define	bus_dmamem_mmap(t,sg,n,o,p,f) \
706 	((*((t)->x68k_dmamem_mmap)) ((t),(sg),(n),(o),(p),(f)))
707 
708 #define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
709 #define bus_dmatag_destroy(t)
710 
711 /*
712  * Flags used in various bus DMA methods.
713  */
714 #define	BUS_DMA_WAITOK		0x000	/* safe to sleep (pseudo-flag) */
715 #define	BUS_DMA_NOWAIT		0x001	/* not safe to sleep */
716 #define	BUS_DMA_ALLOCNOW	0x002	/* perform resource allocation now */
717 #define	BUS_DMA_COHERENT	0x004	/* hint: map memory DMA coherent */
718 #define	BUS_DMA_STREAMING	0x008	/* hint: sequential, unidirectional */
719 #define	BUS_DMA_BUS1		0x010	/* placeholders for bus functions... */
720 #define	BUS_DMA_BUS2		0x020
721 #define	BUS_DMA_BUS3		0x040
722 #define	BUS_DMA_BUS4		0x080
723 #define	BUS_DMA_READ		0x100	/* mapping is device -> memory only */
724 #define	BUS_DMA_WRITE		0x200	/* mapping is memory -> device only */
725 #define	BUS_DMA_NOCACHE		0x400	/* hint: map non-cached memory */
726 
727 /*
728  * Operations performed by bus_dmamap_sync().
729  */
730 #define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
731 #define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
732 #define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
733 #define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
734 
735 #endif /* _X68K_BUS_H_ */
736