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