dma.c revision 1.29 1 /* $NetBSD: dma.c,v 1.29 2003/04/01 20:41:36 thorpej Exp $ */
2
3 /*-
4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe.
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 * Copyright (c) 1982, 1990, 1993
41 * The Regents of the University of California. All rights reserved.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution.
51 * 3. All advertising materials mentioning features or use of this software
52 * must display the following acknowledgement:
53 * This product includes software developed by the University of
54 * California, Berkeley and its contributors.
55 * 4. Neither the name of the University nor the names of its contributors
56 * may be used to endorse or promote products derived from this software
57 * without specific prior written permission.
58 *
59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * SUCH DAMAGE.
70 *
71 * @(#)dma.c 8.1 (Berkeley) 6/10/93
72 */
73
74 /*
75 * DMA driver
76 */
77
78 #include <sys/cdefs.h>
79 __KERNEL_RCSID(0, "$NetBSD: dma.c,v 1.29 2003/04/01 20:41:36 thorpej Exp $");
80
81 #include <machine/hp300spu.h> /* XXX param.h includes cpu.h */
82
83 #include <sys/param.h>
84 #include <sys/systm.h>
85 #include <sys/callout.h>
86 #include <sys/device.h>
87 #include <sys/kernel.h>
88 #include <sys/proc.h>
89
90 #include <uvm/uvm_extern.h>
91
92 #include <machine/bus.h>
93
94 #include <m68k/cacheops.h>
95
96 #include <hp300/dev/intiovar.h>
97 #include <hp300/dev/dmareg.h>
98 #include <hp300/dev/dmavar.h>
99
100 /*
101 * The largest single request will be MAXPHYS bytes which will require
102 * at most MAXPHYS/PAGE_SIZE+1 chain elements to describe, i.e. if none of
103 * the buffer pages are physically contiguous (MAXPHYS/PAGE_SIZE) and the
104 * buffer is not page aligned (+1).
105 */
106 #define DMAMAXIO (MAXPHYS/PAGE_SIZE+1)
107
108 struct dma_chain {
109 int dc_count;
110 char *dc_addr;
111 };
112
113 struct dma_channel {
114 struct dmaqueue *dm_job; /* current job */
115 struct dmadevice *dm_hwaddr; /* registers if DMA_C */
116 struct dmaBdevice *dm_Bhwaddr; /* registers if not DMA_C */
117 char dm_flags; /* misc. flags */
118 u_short dm_cmd; /* DMA controller command */
119 int dm_cur; /* current segment */
120 int dm_last; /* last segment */
121 struct dma_chain dm_chain[DMAMAXIO]; /* all segments */
122 };
123
124 struct dma_softc {
125 struct device sc_dev;
126 bus_space_tag_t sc_bst;
127 bus_space_handle_t sc_bsh;
128
129 struct dmareg *sc_dmareg; /* pointer to our hardware */
130 struct dma_channel sc_chan[NDMACHAN]; /* 2 channels */
131 TAILQ_HEAD(, dmaqueue) sc_queue; /* job queue */
132 struct callout sc_debug_ch;
133 char sc_type; /* A, B, or C */
134 int sc_ipl; /* our interrupt level */
135 void *sc_ih; /* interrupt cookie */
136 };
137
138 /* types */
139 #define DMA_B 0
140 #define DMA_C 1
141
142 /* flags */
143 #define DMAF_PCFLUSH 0x01
144 #define DMAF_VCFLUSH 0x02
145 #define DMAF_NOINTR 0x04
146
147 int dmamatch(struct device *, struct cfdata *, void *);
148 void dmaattach(struct device *, struct device *, void *);
149
150 CFATTACH_DECL(dma, sizeof(struct dma_softc),
151 dmamatch, dmaattach, NULL, NULL);
152
153 int dmaintr __P((void *));
154
155 #ifdef DEBUG
156 int dmadebug = 0;
157 #define DDB_WORD 0x01 /* same as DMAGO_WORD */
158 #define DDB_LWORD 0x02 /* same as DMAGO_LWORD */
159 #define DDB_FOLLOW 0x04
160 #define DDB_IO 0x08
161
162 void dmatimeout __P((void *));
163 int dmatimo[NDMACHAN];
164
165 long dmahits[NDMACHAN];
166 long dmamisses[NDMACHAN];
167 long dmabyte[NDMACHAN];
168 long dmaword[NDMACHAN];
169 long dmalword[NDMACHAN];
170 #endif
171
172 static struct dma_softc *dma_softc;
173
174 int
175 dmamatch(parent, match, aux)
176 struct device *parent;
177 struct cfdata *match;
178 void *aux;
179 {
180 struct intio_attach_args *ia = aux;
181 static int dmafound = 0; /* can only have one */
182
183 if (strcmp("dma", ia->ia_modname) != 0 || dmafound)
184 return (0);
185
186 dmafound = 1;
187 return (1);
188 }
189
190
191
192 void
193 dmaattach(parent, self, aux)
194 struct device *parent, *self;
195 void *aux;
196 {
197 struct dma_softc *sc = (struct dma_softc *)self;
198 struct intio_attach_args *ia = aux;
199 struct dma_channel *dc;
200 struct dmareg *dma;
201 int i;
202 char rev;
203
204 /* There's just one. */
205 dma_softc = sc;
206
207 sc->sc_bst = ia->ia_bst;
208 if (bus_space_map(sc->sc_bst, ia->ia_iobase, INTIO_DEVSIZE, 0,
209 &sc->sc_bsh)) {
210 printf("%s: can't map registers\n", sc->sc_dev.dv_xname);
211 return;
212 }
213
214 dma = (struct dmareg *)bus_space_vaddr(sc->sc_bst, sc->sc_bsh);
215 sc->sc_dmareg = dma;
216
217 /*
218 * Determine the DMA type. A DMA_A or DMA_B will fail the
219 * following probe.
220 *
221 * XXX Don't know how to easily differentiate the A and B cards,
222 * so we just hope nobody has an A card (A cards will work if
223 * splbio works out to ipl 3).
224 */
225 if (badbaddr((char *)&dma->dma_id[2])) {
226 rev = 'B';
227 #if !defined(HP320)
228 panic("dmainit: DMA card requires hp320 support");
229 #endif
230 } else
231 rev = dma->dma_id[2];
232
233 sc->sc_type = (rev == 'B') ? DMA_B : DMA_C;
234
235 TAILQ_INIT(&sc->sc_queue);
236 callout_init(&sc->sc_debug_ch);
237
238 for (i = 0; i < NDMACHAN; i++) {
239 dc = &sc->sc_chan[i];
240 dc->dm_job = NULL;
241 switch (i) {
242 case 0:
243 dc->dm_hwaddr = &dma->dma_chan0;
244 dc->dm_Bhwaddr = &dma->dma_Bchan0;
245 break;
246
247 case 1:
248 dc->dm_hwaddr = &dma->dma_chan1;
249 dc->dm_Bhwaddr = &dma->dma_Bchan1;
250 break;
251
252 default:
253 panic("dmainit: more than 2 channels?");
254 /* NOTREACHED */
255 }
256 }
257
258 #ifdef DEBUG
259 /* make sure timeout is really not needed */
260 callout_reset(&sc->sc_debug_ch, 30 * hz, dmatimeout, sc);
261 #endif
262
263 printf(": 98620%c, 2 channels, %d-bit DMA\n",
264 rev, (rev == 'B') ? 16 : 32);
265
266 /*
267 * Defer hooking up our interrupt until the first
268 * DMA-using controller has hooked up theirs.
269 */
270 sc->sc_ih = NULL;
271 }
272
273 /*
274 * Compute the ipl and (re)establish the interrupt handler
275 * for the DMA controller.
276 */
277 void
278 dmacomputeipl()
279 {
280 struct dma_softc *sc = dma_softc;
281
282 if (sc->sc_ih != NULL)
283 intr_disestablish(sc->sc_ih);
284
285 /*
286 * Our interrupt level must be as high as the highest
287 * device using DMA (i.e. splbio).
288 */
289 sc->sc_ipl = PSLTOIPL(hp300_ipls[HP300_IPL_BIO]);
290 sc->sc_ih = intr_establish(dmaintr, sc, sc->sc_ipl, IPL_BIO);
291 }
292
293 int
294 dmareq(dq)
295 struct dmaqueue *dq;
296 {
297 struct dma_softc *sc = dma_softc;
298 int i, chan, s;
299
300 #if 1
301 s = splhigh(); /* XXXthorpej */
302 #else
303 s = splbio();
304 #endif
305
306 chan = dq->dq_chan;
307 for (i = NDMACHAN - 1; i >= 0; i--) {
308 /*
309 * Can we use this channel?
310 */
311 if ((chan & (1 << i)) == 0)
312 continue;
313
314 /*
315 * We can use it; is it busy?
316 */
317 if (sc->sc_chan[i].dm_job != NULL)
318 continue;
319
320 /*
321 * Not busy; give the caller this channel.
322 */
323 sc->sc_chan[i].dm_job = dq;
324 dq->dq_chan = i;
325 splx(s);
326 return (1);
327 }
328
329 /*
330 * Couldn't get a channel now; put this in the queue.
331 */
332 TAILQ_INSERT_TAIL(&sc->sc_queue, dq, dq_list);
333 splx(s);
334 return (0);
335 }
336
337 void
338 dmafree(dq)
339 struct dmaqueue *dq;
340 {
341 int unit = dq->dq_chan;
342 struct dma_softc *sc = dma_softc;
343 struct dma_channel *dc = &sc->sc_chan[unit];
344 struct dmaqueue *dn;
345 int chan, s;
346
347 #if 1
348 s = splhigh(); /* XXXthorpej */
349 #else
350 s = splbio();
351 #endif
352
353 #ifdef DEBUG
354 dmatimo[unit] = 0;
355 #endif
356
357 DMA_CLEAR(dc);
358
359 #if defined(CACHE_HAVE_PAC) || defined(M68040)
360 /*
361 * XXX we may not always go thru the flush code in dmastop()
362 */
363 if (dc->dm_flags & DMAF_PCFLUSH) {
364 PCIA();
365 dc->dm_flags &= ~DMAF_PCFLUSH;
366 }
367 #endif
368
369 #if defined(CACHE_HAVE_VAC)
370 if (dc->dm_flags & DMAF_VCFLUSH) {
371 /*
372 * 320/350s have VACs that may also need flushing.
373 * In our case we only flush the supervisor side
374 * because we know that if we are DMAing to user
375 * space, the physical pages will also be mapped
376 * in kernel space (via vmapbuf) and hence cache-
377 * inhibited by the pmap module due to the multiple
378 * mapping.
379 */
380 DCIS();
381 dc->dm_flags &= ~DMAF_VCFLUSH;
382 }
383 #endif
384
385 /*
386 * Channel is now free. Look for another job to run on this
387 * channel.
388 */
389 dc->dm_job = NULL;
390 chan = 1 << unit;
391 for (dn = sc->sc_queue.tqh_first; dn != NULL;
392 dn = dn->dq_list.tqe_next) {
393 if (dn->dq_chan & chan) {
394 /* Found one... */
395 TAILQ_REMOVE(&sc->sc_queue, dn, dq_list);
396 dc->dm_job = dn;
397 dn->dq_chan = dq->dq_chan;
398 splx(s);
399
400 /* Start the initiator. */
401 (*dn->dq_start)(dn->dq_softc);
402 return;
403 }
404 }
405 splx(s);
406 }
407
408 void
409 dmago(unit, addr, count, flags)
410 int unit;
411 char *addr;
412 int count;
413 int flags;
414 {
415 struct dma_softc *sc = dma_softc;
416 struct dma_channel *dc = &sc->sc_chan[unit];
417 char *dmaend = NULL;
418 int seg, tcount;
419
420 if (count > MAXPHYS)
421 panic("dmago: count > MAXPHYS");
422
423 #if defined(HP320)
424 if (sc->sc_type == DMA_B && (flags & DMAGO_LWORD))
425 panic("dmago: no can do 32-bit DMA");
426 #endif
427
428 #ifdef DEBUG
429 if (dmadebug & DDB_FOLLOW)
430 printf("dmago(%d, %p, %x, %x)\n",
431 unit, addr, count, flags);
432 if (flags & DMAGO_LWORD)
433 dmalword[unit]++;
434 else if (flags & DMAGO_WORD)
435 dmaword[unit]++;
436 else
437 dmabyte[unit]++;
438 #endif
439 /*
440 * Build the DMA chain
441 */
442 for (seg = 0; count > 0; seg++) {
443 dc->dm_chain[seg].dc_addr = (char *) kvtop(addr);
444 #if defined(M68040)
445 /*
446 * Push back dirty cache lines
447 */
448 if (mmutype == MMU_68040)
449 DCFP((paddr_t)dc->dm_chain[seg].dc_addr);
450 #endif
451 if (count < (tcount = PAGE_SIZE - ((int)addr & PGOFSET)))
452 tcount = count;
453 dc->dm_chain[seg].dc_count = tcount;
454 addr += tcount;
455 count -= tcount;
456 if (flags & DMAGO_LWORD)
457 tcount >>= 2;
458 else if (flags & DMAGO_WORD)
459 tcount >>= 1;
460
461 /*
462 * Try to compact the DMA transfer if the pages are adjacent.
463 * Note: this will never happen on the first iteration.
464 */
465 if (dc->dm_chain[seg].dc_addr == dmaend
466 #if defined(HP320)
467 /* only 16-bit count on 98620B */
468 && (sc->sc_type != DMA_B ||
469 dc->dm_chain[seg - 1].dc_count + tcount <= 65536)
470 #endif
471 ) {
472 #ifdef DEBUG
473 dmahits[unit]++;
474 #endif
475 dmaend += dc->dm_chain[seg].dc_count;
476 dc->dm_chain[--seg].dc_count += tcount;
477 } else {
478 #ifdef DEBUG
479 dmamisses[unit]++;
480 #endif
481 dmaend = dc->dm_chain[seg].dc_addr +
482 dc->dm_chain[seg].dc_count;
483 dc->dm_chain[seg].dc_count = tcount;
484 }
485 }
486 dc->dm_cur = 0;
487 dc->dm_last = --seg;
488 dc->dm_flags = 0;
489 /*
490 * Set up the command word based on flags
491 */
492 dc->dm_cmd = DMA_ENAB | DMA_IPL(sc->sc_ipl) | DMA_START;
493 if ((flags & DMAGO_READ) == 0)
494 dc->dm_cmd |= DMA_WRT;
495 if (flags & DMAGO_LWORD)
496 dc->dm_cmd |= DMA_LWORD;
497 else if (flags & DMAGO_WORD)
498 dc->dm_cmd |= DMA_WORD;
499 if (flags & DMAGO_PRI)
500 dc->dm_cmd |= DMA_PRI;
501
502 #if defined(M68040)
503 /*
504 * On the 68040 we need to flush (push) the data cache before a
505 * DMA (already done above) and flush again after DMA completes.
506 * In theory we should only need to flush prior to a write DMA
507 * and purge after a read DMA but if the entire page is not
508 * involved in the DMA we might purge some valid data.
509 */
510 if (mmutype == MMU_68040 && (flags & DMAGO_READ))
511 dc->dm_flags |= DMAF_PCFLUSH;
512 #endif
513
514 #if defined(CACHE_HAVE_PAC)
515 /*
516 * Remember if we need to flush external physical cache when
517 * DMA is done. We only do this if we are reading (writing memory).
518 */
519 if (ectype == EC_PHYS && (flags & DMAGO_READ))
520 dc->dm_flags |= DMAF_PCFLUSH;
521 #endif
522
523 #if defined(CACHE_HAVE_VAC)
524 if (ectype == EC_VIRT && (flags & DMAGO_READ))
525 dc->dm_flags |= DMAF_VCFLUSH;
526 #endif
527
528 /*
529 * Remember if we can skip the dma completion interrupt on
530 * the last segment in the chain.
531 */
532 if (flags & DMAGO_NOINT) {
533 if (dc->dm_cur == dc->dm_last)
534 dc->dm_cmd &= ~DMA_ENAB;
535 else
536 dc->dm_flags |= DMAF_NOINTR;
537 }
538 #ifdef DEBUG
539 if (dmadebug & DDB_IO) {
540 if (((dmadebug&DDB_WORD) && (dc->dm_cmd&DMA_WORD)) ||
541 ((dmadebug&DDB_LWORD) && (dc->dm_cmd&DMA_LWORD))) {
542 printf("dmago: cmd %x, flags %x\n",
543 dc->dm_cmd, dc->dm_flags);
544 for (seg = 0; seg <= dc->dm_last; seg++)
545 printf(" %d: %d@%p\n", seg,
546 dc->dm_chain[seg].dc_count,
547 dc->dm_chain[seg].dc_addr);
548 }
549 }
550 dmatimo[unit] = 1;
551 #endif
552 DMA_ARM(sc, dc);
553 }
554
555 void
556 dmastop(unit)
557 int unit;
558 {
559 struct dma_softc *sc = dma_softc;
560 struct dma_channel *dc = &sc->sc_chan[unit];
561
562 #ifdef DEBUG
563 if (dmadebug & DDB_FOLLOW)
564 printf("dmastop(%d)\n", unit);
565 dmatimo[unit] = 0;
566 #endif
567 DMA_CLEAR(dc);
568
569 #if defined(CACHE_HAVE_PAC) || defined(M68040)
570 if (dc->dm_flags & DMAF_PCFLUSH) {
571 PCIA();
572 dc->dm_flags &= ~DMAF_PCFLUSH;
573 }
574 #endif
575
576 #if defined(CACHE_HAVE_VAC)
577 if (dc->dm_flags & DMAF_VCFLUSH) {
578 /*
579 * 320/350s have VACs that may also need flushing.
580 * In our case we only flush the supervisor side
581 * because we know that if we are DMAing to user
582 * space, the physical pages will also be mapped
583 * in kernel space (via vmapbuf) and hence cache-
584 * inhibited by the pmap module due to the multiple
585 * mapping.
586 */
587 DCIS();
588 dc->dm_flags &= ~DMAF_VCFLUSH;
589 }
590 #endif
591
592 /*
593 * We may get this interrupt after a device service routine
594 * has freed the dma channel. So, ignore the intr if there's
595 * nothing on the queue.
596 */
597 if (dc->dm_job != NULL)
598 (*dc->dm_job->dq_done)(dc->dm_job->dq_softc);
599 }
600
601 int
602 dmaintr(arg)
603 void *arg;
604 {
605 struct dma_softc *sc = arg;
606 struct dma_channel *dc;
607 int i, stat;
608 int found = 0;
609
610 #ifdef DEBUG
611 if (dmadebug & DDB_FOLLOW)
612 printf("dmaintr\n");
613 #endif
614 for (i = 0; i < NDMACHAN; i++) {
615 dc = &sc->sc_chan[i];
616 stat = DMA_STAT(dc);
617 if ((stat & DMA_INTR) == 0)
618 continue;
619 found++;
620 #ifdef DEBUG
621 if (dmadebug & DDB_IO) {
622 if (((dmadebug&DDB_WORD) && (dc->dm_cmd&DMA_WORD)) ||
623 ((dmadebug&DDB_LWORD) && (dc->dm_cmd&DMA_LWORD)))
624 printf("dmaintr: flags %x unit %d stat %x next %d\n",
625 dc->dm_flags, i, stat, dc->dm_cur + 1);
626 }
627 if (stat & DMA_ARMED)
628 printf("dma channel %d: intr when armed\n", i);
629 #endif
630 /*
631 * Load the next segemnt, or finish up if we're done.
632 */
633 dc->dm_cur++;
634 if (dc->dm_cur <= dc->dm_last) {
635 #ifdef DEBUG
636 dmatimo[i] = 1;
637 #endif
638 /*
639 * If we're the last segment, disable the
640 * completion interrupt, if necessary.
641 */
642 if (dc->dm_cur == dc->dm_last &&
643 (dc->dm_flags & DMAF_NOINTR))
644 dc->dm_cmd &= ~DMA_ENAB;
645 DMA_CLEAR(dc);
646 DMA_ARM(sc, dc);
647 } else
648 dmastop(i);
649 }
650 return(found);
651 }
652
653 #ifdef DEBUG
654 void
655 dmatimeout(arg)
656 void *arg;
657 {
658 int i, s;
659 struct dma_softc *sc = arg;
660
661 for (i = 0; i < NDMACHAN; i++) {
662 s = splbio();
663 if (dmatimo[i]) {
664 if (dmatimo[i] > 1)
665 printf("dma channel %d timeout #%d\n",
666 i, dmatimo[i]-1);
667 dmatimo[i]++;
668 }
669 splx(s);
670 }
671 callout_reset(&sc->sc_debug_ch, 30 * hz, dmatimeout, sc);
672 }
673 #endif
674