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