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