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