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