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