1 /* $NetBSD: intio_dmac.c,v 1.33 2010/06/06 04:50:08 mrg Exp $ */ 2 3 /*- 4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Minoura Makoto. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Hitachi HD63450 (= Motorola MC68450) DMAC driver for x68k. 34 */ 35 36 #include "opt_m68k_arch.h" 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: intio_dmac.c,v 1.33 2010/06/06 04:50:08 mrg Exp $"); 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/device.h> 44 #include <uvm/uvm_extern.h> 45 46 #include <machine/bus.h> 47 #include <machine/cpu.h> 48 #include <machine/frame.h> 49 50 #include <arch/x68k/dev/intiovar.h> 51 #include <arch/x68k/dev/dmacvar.h> 52 53 #ifdef DMAC_DEBUG 54 #define DPRINTF(n,x) if (dmacdebug>((n)&0x0f)) printf x 55 #define DDUMPREGS(n,x) if (dmacdebug>((n)&0x0f)) {printf x; dmac_dump_regs();} 56 int dmacdebug = 0; 57 #else 58 #define DPRINTF(n,x) 59 #define DDUMPREGS(n,x) 60 #endif 61 62 static void dmac_init_channels(struct dmac_softc *); 63 #ifdef DMAC_ARRAYCHAIN 64 static int dmac_program_arraychain(device_t, struct dmac_dma_xfer *, 65 u_int, u_int); 66 #endif 67 static int dmac_done(void *); 68 static int dmac_error(void *); 69 70 #ifdef DMAC_DEBUG 71 static int dmac_dump_regs(void); 72 #endif 73 74 /* 75 * autoconf stuff 76 */ 77 static int dmac_match(device_t, cfdata_t, void *); 78 static void dmac_attach(device_t, device_t, void *); 79 80 CFATTACH_DECL_NEW(dmac, sizeof(struct dmac_softc), 81 dmac_match, dmac_attach, NULL, NULL); 82 83 static int dmac_attached; 84 85 static int 86 dmac_match(device_t parent, cfdata_t cf, void *aux) 87 { 88 struct intio_attach_args *ia = aux; 89 90 if (strcmp(ia->ia_name, "dmac") != 0) 91 return (0); 92 if (dmac_attached) 93 return (0); 94 95 if (ia->ia_addr == INTIOCF_ADDR_DEFAULT) 96 ia->ia_addr = DMAC_ADDR; 97 98 /* fixed address */ 99 if (ia->ia_addr != DMAC_ADDR) 100 return (0); 101 if (ia->ia_intr != INTIOCF_INTR_DEFAULT) 102 return (0); 103 104 return 1; 105 } 106 107 static void 108 dmac_attach(device_t parent, device_t self, void *aux) 109 { 110 struct dmac_softc *sc = device_private(self); 111 struct intio_attach_args *ia = aux; 112 struct intio_softc *intio; 113 int r; 114 115 sc->sc_dev = self; 116 dmac_attached = 1; 117 118 ia->ia_size = DMAC_CHAN_SIZE * DMAC_NCHAN; 119 r = intio_map_allocate_region(parent, ia, INTIO_MAP_ALLOCATE); 120 #ifdef DIAGNOSTIC 121 if (r) 122 panic("IO map for DMAC corruption??"); 123 #endif 124 125 intio = device_private(parent); 126 intio->sc_dmac = self; 127 sc->sc_bst = ia->ia_bst; 128 bus_space_map(sc->sc_bst, ia->ia_addr, ia->ia_size, 0, &sc->sc_bht); 129 dmac_init_channels(sc); 130 131 aprint_normal(": HD63450 DMAC\n"); 132 aprint_normal_dev(self, "4 channels available.\n"); 133 } 134 135 static void 136 dmac_init_channels(struct dmac_softc *sc) 137 { 138 int i; 139 140 DPRINTF(3, ("dmac_init_channels\n")); 141 for (i=0; i<DMAC_NCHAN; i++) { 142 sc->sc_channels[i].ch_channel = i; 143 sc->sc_channels[i].ch_name[0] = 0; 144 sc->sc_channels[i].ch_softc = sc; 145 bus_space_subregion(sc->sc_bst, sc->sc_bht, 146 DMAC_CHAN_SIZE*i, DMAC_CHAN_SIZE, 147 &sc->sc_channels[i].ch_bht); 148 sc->sc_channels[i].ch_xfer.dx_dmamap = 0; 149 /* reset the status register */ 150 bus_space_write_1(sc->sc_bst, sc->sc_channels[i].ch_bht, 151 DMAC_REG_CSR, 0xff); 152 } 153 154 return; 155 } 156 157 158 /* 159 * Channel initialization/deinitialization per user device. 160 */ 161 struct dmac_channel_stat * 162 dmac_alloc_channel(device_t self, int ch, const char *name, int normalv, 163 dmac_intr_handler_t normal, void *normalarg, int errorv, 164 dmac_intr_handler_t error, void *errorarg) 165 { 166 struct intio_softc *intio = device_private(self); 167 struct dmac_softc *dmac = device_private(intio->sc_dmac); 168 struct dmac_channel_stat *chan = &dmac->sc_channels[ch]; 169 #ifdef DMAC_ARRAYCHAIN 170 int r, dummy; 171 #endif 172 173 aprint_normal_dev(dmac->sc_dev, "allocating ch %d for %s.\n", 174 ch, name); 175 DPRINTF(3, ("dmamap=%p\n", (void *)chan->ch_xfer.dx_dmamap)); 176 #ifdef DIAGNOSTIC 177 if (ch < 0 || ch >= DMAC_NCHAN) 178 panic("Invalid DMAC channel."); 179 if (chan->ch_name[0]) 180 panic("DMAC: channel in use."); 181 if (strlen(name) > 8) 182 panic("DMAC: wrong user name."); 183 #endif 184 185 #ifdef DMAC_ARRAYCHAIN 186 /* allocate the DMAC arraychaining map */ 187 r = bus_dmamem_alloc(intio->sc_dmat, 188 sizeof(struct dmac_sg_array) * DMAC_MAPSIZE, 189 4, 0, &chan->ch_seg[0], 1, &dummy, 190 BUS_DMA_NOWAIT); 191 if (r) 192 panic("DMAC: cannot alloc DMA safe memory"); 193 r = bus_dmamem_map(intio->sc_dmat, 194 &chan->ch_seg[0], 1, 195 sizeof(struct dmac_sg_array) * DMAC_MAPSIZE, 196 (void **) &chan->ch_map, 197 BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 198 if (r) 199 panic("DMAC: cannot map DMA safe memory"); 200 #endif 201 202 /* fill the channel status structure by the default values. */ 203 strcpy(chan->ch_name, name); 204 chan->ch_dcr = (DMAC_DCR_XRM_CSWH | DMAC_DCR_OTYP_EASYNC | 205 DMAC_DCR_OPS_8BIT); 206 chan->ch_ocr = (DMAC_OCR_SIZE_BYTE | DMAC_OCR_REQG_EXTERNAL); 207 chan->ch_normalv = normalv; 208 chan->ch_errorv = errorv; 209 chan->ch_normal = normal; 210 chan->ch_error = error; 211 chan->ch_normalarg = normalarg; 212 chan->ch_errorarg = errorarg; 213 chan->ch_xfer.dx_dmamap = 0; 214 215 /* setup the device-specific registers */ 216 bus_space_write_1(dmac->sc_bst, chan->ch_bht, DMAC_REG_CSR, 0xff); 217 bus_space_write_1(dmac->sc_bst, chan->ch_bht, 218 DMAC_REG_DCR, chan->ch_dcr); 219 bus_space_write_1(dmac->sc_bst, chan->ch_bht, DMAC_REG_CPR, 0); 220 221 /* 222 * X68k physical user space is a subset of the kernel space; 223 * the memory is always included in the physical user space, 224 * while the device is not. 225 */ 226 bus_space_write_1(dmac->sc_bst, chan->ch_bht, 227 DMAC_REG_BFCR, DMAC_FC_USER_DATA); 228 bus_space_write_1(dmac->sc_bst, chan->ch_bht, 229 DMAC_REG_MFCR, DMAC_FC_USER_DATA); 230 bus_space_write_1(dmac->sc_bst, chan->ch_bht, 231 DMAC_REG_DFCR, DMAC_FC_KERNEL_DATA); 232 233 /* setup the interrupt handlers */ 234 bus_space_write_1(dmac->sc_bst, chan->ch_bht, DMAC_REG_NIVR, normalv); 235 bus_space_write_1(dmac->sc_bst, chan->ch_bht, DMAC_REG_EIVR, errorv); 236 237 intio_intr_establish_ext(normalv, name, "dma", dmac_done, chan); 238 intio_intr_establish_ext(errorv, name, "dmaerr", dmac_error, chan); 239 240 return chan; 241 } 242 243 int 244 dmac_free_channel(device_t self, int ch, void *channel) 245 { 246 struct intio_softc *intio = device_private(self); 247 struct dmac_softc *dmac = device_private(intio->sc_dmac); 248 struct dmac_channel_stat *chan = &dmac->sc_channels[ch]; 249 250 DPRINTF(3, ("dmac_free_channel, %d\n", ch)); 251 DPRINTF(3, ("dmamap=%p\n", (void *)chan->ch_xfer.dx_dmamap)); 252 if (chan != channel) 253 return -1; 254 if (ch != chan->ch_channel) 255 return -1; 256 257 #ifdef DMAC_ARRAYCHAIN 258 bus_dmamem_unmap(intio->sc_dmat, (void *)chan->ch_map, 259 sizeof(struct dmac_sg_array) * DMAC_MAPSIZE); 260 bus_dmamem_free(intio->sc_dmat, &chan->ch_seg[0], 1); 261 #endif 262 chan->ch_name[0] = 0; 263 intio_intr_disestablish(chan->ch_normalv, channel); 264 intio_intr_disestablish(chan->ch_errorv, channel); 265 266 return 0; 267 } 268 269 /* 270 * Initialization / deinitialization per transfer. 271 */ 272 struct dmac_dma_xfer * 273 dmac_alloc_xfer(struct dmac_channel_stat *chan, bus_dma_tag_t dmat, 274 bus_dmamap_t dmamap) 275 { 276 struct dmac_dma_xfer *xf = &chan->ch_xfer; 277 278 DPRINTF(3, ("dmac_alloc_xfer\n")); 279 xf->dx_channel = chan; 280 xf->dx_dmamap = dmamap; 281 xf->dx_tag = dmat; 282 #ifdef DMAC_ARRAYCHAIN 283 xf->dx_array = chan->ch_map; 284 xf->dx_done = 0; 285 #endif 286 xf->dx_nextoff = xf->dx_nextsize = -1; 287 return xf; 288 } 289 290 int 291 dmac_load_xfer(struct dmac_softc *dmac, struct dmac_dma_xfer *xf) 292 { 293 struct dmac_channel_stat *chan = xf->dx_channel; 294 295 DPRINTF(3, ("dmac_load_xfer\n")); 296 297 xf->dx_ocr &= ~DMAC_OCR_CHAIN_MASK; 298 if (xf->dx_dmamap->dm_nsegs == 1) 299 xf->dx_ocr |= DMAC_OCR_CHAIN_DISABLED; 300 else { 301 xf->dx_ocr |= DMAC_OCR_CHAIN_ARRAY; 302 xf->dx_nextoff = ~0; 303 xf->dx_nextsize = ~0; 304 } 305 306 bus_space_write_1(dmac->sc_bst, chan->ch_bht, DMAC_REG_CSR, 0xff); 307 bus_space_write_1(dmac->sc_bst, chan->ch_bht, DMAC_REG_SCR, xf->dx_scr); 308 bus_space_write_1(dmac->sc_bst, chan->ch_bht, 309 DMAC_REG_OCR, (xf->dx_ocr | chan->ch_ocr)); 310 bus_space_write_4(dmac->sc_bst, chan->ch_bht, 311 DMAC_REG_DAR, (int) xf->dx_device); 312 313 return 0; 314 } 315 316 struct dmac_dma_xfer * 317 dmac_prepare_xfer(struct dmac_channel_stat *chan, bus_dma_tag_t dmat, 318 bus_dmamap_t dmamap, int dir, int scr, void *dar) 319 { 320 struct dmac_dma_xfer *xf; 321 struct dmac_softc *dmac = chan->ch_softc; 322 323 xf = dmac_alloc_xfer(chan, dmat, dmamap); 324 325 xf->dx_ocr = dir & DMAC_OCR_DIR_MASK; 326 xf->dx_scr = scr & (DMAC_SCR_MAC_MASK|DMAC_SCR_DAC_MASK); 327 xf->dx_device = dar; 328 329 dmac_load_xfer(dmac, xf); 330 331 return xf; 332 } 333 334 #ifdef DMAC_DEBUG 335 static struct dmac_channel_stat *debugchan = 0; 336 #endif 337 338 /* 339 * Do the actual transfer. 340 */ 341 int 342 dmac_start_xfer(struct dmac_softc *dmac, struct dmac_dma_xfer *xf) 343 { 344 return dmac_start_xfer_offset(dmac, xf, 0, 0); 345 } 346 347 int 348 dmac_start_xfer_offset(struct dmac_softc *dmac, struct dmac_dma_xfer *xf, 349 u_int offset, u_int size) 350 { 351 struct dmac_channel_stat *chan = xf->dx_channel; 352 struct x68k_bus_dmamap *dmamap = xf->dx_dmamap; 353 int go = DMAC_CCR_STR|DMAC_CCR_INT; 354 #ifdef DMAC_ARRAYCHAIN 355 int c; 356 #endif 357 358 DPRINTF(3, ("dmac_start_xfer\n")); 359 #ifdef DMAC_DEBUG 360 debugchan=chan; 361 #endif 362 363 if (size == 0) { 364 #ifdef DIAGNOSTIC 365 if (offset != 0) 366 panic("dmac_start_xfer_offset: invalid offset %x", 367 offset); 368 #endif 369 size = dmamap->dm_mapsize; 370 } 371 372 #ifdef DMAC_ARRAYCHAIN 373 #ifdef DIAGNOSTIC 374 if (xf->dx_done) 375 panic("dmac_start_xfer: DMA transfer in progress"); 376 #endif 377 #endif 378 DPRINTF(3, ("First program:\n")); 379 #ifdef DIAGNOSTIC 380 if ((offset >= dmamap->dm_mapsize) || 381 (offset + size > dmamap->dm_mapsize)) 382 panic("dmac_start_xfer_offset: invalid offset: " 383 "offset=%d, size=%d, mapsize=%ld", 384 offset, size, dmamap->dm_mapsize); 385 #endif 386 /* program DMAC in single block mode or array chainning mode */ 387 if (dmamap->dm_nsegs == 1) { 388 DPRINTF(3, ("single block mode\n")); 389 #ifdef DIAGNOSTIC 390 if (dmamap->dm_mapsize != dmamap->dm_segs[0].ds_len) 391 panic("dmac_start_xfer_offset: dmamap curruption"); 392 #endif 393 if (offset == xf->dx_nextoff && 394 size == xf->dx_nextsize) { 395 /* Use continued operation */ 396 go |= DMAC_CCR_CNT; 397 xf->dx_nextoff += size; 398 } else { 399 bus_space_write_4(dmac->sc_bst, chan->ch_bht, 400 DMAC_REG_MAR, 401 (int) dmamap->dm_segs[0].ds_addr 402 + offset); 403 bus_space_write_2(dmac->sc_bst, chan->ch_bht, 404 DMAC_REG_MTCR, (int) size); 405 xf->dx_nextoff = offset; 406 xf->dx_nextsize = size; 407 } 408 #ifdef DMAC_ARRAYCHAIN 409 xf->dx_done = 1; 410 #endif 411 } else { 412 #ifdef DMAC_ARRAYCHAIN 413 c = dmac_program_arraychain(self, xf, offset, size); 414 bus_space_write_4(dmac->sc_bst, chan->ch_bht, 415 DMAC_REG_BAR, (int) chan->ch_seg[0].ds_addr); 416 bus_space_write_2(dmac->sc_bst, chan->ch_bht, 417 DMAC_REG_BTCR, c); 418 #else 419 panic("DMAC: unexpected use of arraychaining mode"); 420 #endif 421 } 422 423 bus_space_write_1(dmac->sc_bst, chan->ch_bht, DMAC_REG_CSR, 0xff); 424 425 /* START!! */ 426 DDUMPREGS(3, ("first start\n")); 427 428 #ifdef DMAC_ARRAYCHAIN 429 #if defined(M68040) || defined(M68060) 430 /* flush data cache for the map */ 431 if (dmamap->dm_nsegs != 1 && mmutype == MMU_68040) 432 dma_cachectl((void *) xf->dx_array, 433 sizeof(struct dmac_sg_array) * c); 434 #endif 435 #endif 436 bus_space_write_1(dmac->sc_bst, chan->ch_bht, DMAC_REG_CCR, go); 437 438 if (xf->dx_nextoff != ~0) { 439 bus_space_write_4(dmac->sc_bst, chan->ch_bht, 440 DMAC_REG_BAR, xf->dx_nextoff); 441 bus_space_write_2(dmac->sc_bst, chan->ch_bht, 442 DMAC_REG_BTCR, xf->dx_nextsize); 443 } 444 445 return 0; 446 } 447 448 #ifdef DMAC_ARRAYCHAIN 449 static int 450 dmac_program_arraychain(device_t self, struct dmac_dma_xfer *xf, 451 u_int offset, u_int size) 452 { 453 struct dmac_channel_stat *chan = xf->dx_channel; 454 int ch = chan->ch_channel; 455 struct x68k_bus_dmamap *map = xf->dx_dmamap; 456 int i, j; 457 458 /* XXX not yet!! */ 459 if (offset != 0 || size != map->dm_mapsize) 460 panic("dmac_program_arraychain: unsupported offset/size"); 461 462 DPRINTF(3, ("dmac_program_arraychain\n")); 463 for (i=0, j=xf->dx_done; i<DMAC_MAPSIZE && j<map->dm_nsegs; 464 i++, j++) { 465 xf->dx_array[i].da_addr = map->dm_segs[j].ds_addr; 466 #ifdef DIAGNOSTIC 467 if (map->dm_segs[j].ds_len > DMAC_MAXSEGSZ) 468 panic("dmac_program_arraychain: wrong map: %ld", 469 map->dm_segs[j].ds_len); 470 #endif 471 xf->dx_array[i].da_count = map->dm_segs[j].ds_len; 472 } 473 xf->dx_done = j; 474 475 return i; 476 } 477 #endif 478 479 /* 480 * interrupt handlers. 481 */ 482 static int 483 dmac_done(void *arg) 484 { 485 struct dmac_channel_stat *chan = arg; 486 struct dmac_softc *sc = chan->ch_softc; 487 #ifdef DMAC_ARRAYCHAIN 488 struct dmac_dma_xfer *xf = &chan->ch_xfer; 489 struct x68k_bus_dmamap *map = xf->dx_dmamap; 490 int c; 491 #endif 492 493 DPRINTF(3, ("dmac_done\n")); 494 495 bus_space_write_1(sc->sc_bst, chan->ch_bht, DMAC_REG_CSR, 0xff); 496 497 #ifdef DMAC_ARRAYCHAIN 498 if (xf->dx_done == map->dm_nsegs) { 499 xf->dx_done = 0; 500 #endif 501 /* Done */ 502 return (*chan->ch_normal)(chan->ch_normalarg); 503 #ifdef DMAC_ARRAYCHAIN 504 } 505 #endif 506 507 #ifdef DMAC_ARRAYCHAIN 508 /* Continue transfer */ 509 DPRINTF(3, ("reprograming\n")); 510 c = dmac_program_arraychain(sc->sc_dev, xf, 0, map->dm_mapsize); 511 512 bus_space_write_1(sc->sc_bst, chan->ch_bht, DMAC_REG_CSR, 0xff); 513 bus_space_write_4(sc->sc_bst, chan->ch_bht, 514 DMAC_REG_BAR, (int) chan->ch_map); 515 bus_space_write_4(sc->sc_bst, chan->ch_bht, 516 DMAC_REG_DAR, (int) xf->dx_device); 517 bus_space_write_2(sc->sc_bst, chan->ch_bht, DMAC_REG_BTCR, c); 518 519 /* START!! */ 520 DDUMPREGS(3, ("restart\n")); 521 bus_space_write_1(sc->sc_bst, chan->ch_bht, 522 DMAC_REG_CCR, DMAC_CCR_STR|DMAC_CCR_INT); 523 524 return 1; 525 #endif 526 } 527 528 static int 529 dmac_error(void *arg) 530 { 531 struct dmac_channel_stat *chan = arg; 532 struct dmac_softc *sc = chan->ch_softc; 533 534 printf("DMAC transfer error CSR=%02x, CER=%02x\n", 535 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_CSR), 536 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_CER)); 537 DDUMPREGS(3, ("registers were:\n")); 538 539 /* Clear the status bits */ 540 bus_space_write_1(sc->sc_bst, chan->ch_bht, DMAC_REG_CSR, 0xff); 541 542 #ifdef DMAC_ARRAYCHAIN 543 chan->ch_xfer.dx_done = 0; 544 #endif 545 546 return (*chan->ch_error)(chan->ch_errorarg); 547 } 548 549 int 550 dmac_abort_xfer(struct dmac_softc *dmac, struct dmac_dma_xfer *xf) 551 { 552 struct dmac_channel_stat *chan = xf->dx_channel; 553 554 bus_space_write_1(dmac->sc_bst, chan->ch_bht, DMAC_REG_CCR, 555 DMAC_CCR_INT | DMAC_CCR_HLT); 556 bus_space_write_1(dmac->sc_bst, chan->ch_bht, DMAC_REG_CSR, 0xff); 557 xf->dx_nextoff = xf->dx_nextsize = -1; 558 559 return 0; 560 } 561 562 #ifdef DMAC_DEBUG 563 static int 564 dmac_dump_regs(void) 565 { 566 struct dmac_channel_stat *chan = debugchan; 567 struct dmac_softc *sc; 568 569 if ((chan == 0) || (dmacdebug & 0xf0)) 570 return 0; 571 sc = chan->ch_softc; 572 573 printf("DMAC channel %d registers\n", chan->ch_channel); 574 printf("CSR=%02x, CER=%02x, DCR=%02x, OCR=%02x, SCR=%02x, " 575 "CCR=%02x, CPR=%02x, GCR=%02x\n", 576 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_CSR), 577 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_CER), 578 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_DCR), 579 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_OCR), 580 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_SCR), 581 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_CCR), 582 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_CPR), 583 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_GCR)); 584 printf("NIVR=%02x, EIVR=%02x, MTCR=%04x, BTCR=%04x, DFCR=%02x, " 585 "MFCR=%02x, BFCR=%02x\n", 586 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_NIVR), 587 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_EIVR), 588 bus_space_read_2(sc->sc_bst, chan->ch_bht, DMAC_REG_MTCR), 589 bus_space_read_2(sc->sc_bst, chan->ch_bht, DMAC_REG_BTCR), 590 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_DFCR), 591 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_MFCR), 592 bus_space_read_1(sc->sc_bst, chan->ch_bht, DMAC_REG_BFCR)); 593 printf("DAR=%08x, MAR=%08x, BAR=%08x\n", 594 bus_space_read_4(sc->sc_bst, chan->ch_bht, DMAC_REG_DAR), 595 bus_space_read_4(sc->sc_bst, chan->ch_bht, DMAC_REG_MAR), 596 bus_space_read_4(sc->sc_bst, chan->ch_bht, DMAC_REG_BAR)); 597 598 return 0; 599 } 600 #endif 601