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