xref: /netbsd-src/sys/arch/hp300/dev/dma.c (revision ce0bb6e8d2e560ecacbe865a848624f94498063b)
1 /*	$NetBSD: dma.c,v 1.5 1994/10/26 07:23:40 cgd Exp $	*/
2 
3 /*
4  * Copyright (c) 1982, 1990, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)dma.c	8.1 (Berkeley) 6/10/93
36  */
37 
38 /*
39  * DMA driver
40  */
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/time.h>
45 #include <sys/kernel.h>
46 #include <sys/proc.h>
47 
48 #include <machine/cpu.h>
49 
50 #include <hp300/dev/device.h>
51 #include <hp300/dev/dmareg.h>
52 #include <hp300/dev/dmavar.h>
53 
54 #include <hp300/hp300/isr.h>
55 
56 extern void isrlink();
57 extern void _insque();
58 extern void _remque();
59 extern u_int kvtop();
60 extern void PCIA();
61 
62 /*
63  * The largest single request will be MAXPHYS bytes which will require
64  * at most MAXPHYS/NBPG+1 chain elements to describe, i.e. if none of
65  * the buffer pages are physically contiguous (MAXPHYS/NBPG) and the
66  * buffer is not page aligned (+1).
67  */
68 #define	DMAMAXIO	(MAXPHYS/NBPG+1)
69 
70 struct	dma_chain {
71 	int	dc_count;
72 	char	*dc_addr;
73 };
74 
75 struct	dma_softc {
76 	struct	dmadevice *sc_hwaddr;
77 	struct	dmaBdevice *sc_Bhwaddr;
78 	char	sc_type;
79 	char	sc_flags;
80 	u_short	sc_cmd;
81 	struct	dma_chain *sc_cur;
82 	struct	dma_chain *sc_last;
83 	struct	dma_chain sc_chain[DMAMAXIO];
84 } dma_softc[NDMA];
85 
86 /* types */
87 #define	DMA_B	0
88 #define DMA_C	1
89 
90 /* flags */
91 #define DMAF_PCFLUSH	0x01
92 #define DMAF_VCFLUSH	0x02
93 #define DMAF_NOINTR	0x04
94 
95 struct	devqueue dmachan[NDMA + 1];
96 int	dmaintr();
97 
98 #ifdef DEBUG
99 int	dmadebug = 0;
100 #define DDB_WORD	0x01	/* same as DMAGO_WORD */
101 #define DDB_LWORD	0x02	/* same as DMAGO_LWORD */
102 #define	DDB_FOLLOW	0x04
103 #define DDB_IO		0x08
104 
105 void	dmatimeout __P((void *));
106 int	dmatimo[NDMA];
107 
108 long	dmahits[NDMA];
109 long	dmamisses[NDMA];
110 long	dmabyte[NDMA];
111 long	dmaword[NDMA];
112 long	dmalword[NDMA];
113 #endif
114 
115 void
116 dmainit()
117 {
118 	register struct dmareg *dma = (struct dmareg *)DMA_BASE;
119 	register struct dma_softc *dc;
120 	register int i;
121 	char rev;
122 
123 	/*
124 	 * Determine the DMA type.
125 	 * Don't know how to easily differentiate the A and B cards,
126 	 * so we just hope nobody has an A card (A cards will work if
127 	 * DMAINTLVL is set to 3).
128 	 */
129 	if (!badbaddr((char *)&dma->dma_id[2]))
130 		rev = dma->dma_id[2];
131 	else {
132 		rev = 'B';
133 #if !defined(HP320)
134 		panic("dmainit: DMA card requires hp320 support");
135 #endif
136 	}
137 
138 	dc = &dma_softc[0];
139 	for (i = 0; i < NDMA; i++) {
140 		dc->sc_hwaddr = (i & 1) ? &dma->dma_chan1 : &dma->dma_chan0;
141 		dc->sc_Bhwaddr = (i & 1) ? &dma->dma_Bchan1 : &dma->dma_Bchan0;
142 		dc->sc_type = rev == 'B' ? DMA_B : DMA_C;
143 		dc++;
144 		dmachan[i].dq_forw = dmachan[i].dq_back = &dmachan[i];
145 	}
146 	dmachan[i].dq_forw = dmachan[i].dq_back = &dmachan[i];
147 #ifdef DEBUG
148 	/* make sure timeout is really not needed */
149 	timeout(dmatimeout, (void *)0, 30 * hz);
150 #endif
151 
152 	printf("dma: 98620%c with 2 channels, %d bit DMA\n",
153 	       rev, rev == 'B' ? 16 : 32);
154 }
155 
156 int
157 dmareq(dq)
158 	register struct devqueue *dq;
159 {
160 	register int i;
161 	register int chan;
162 	register int s = splbio();
163 
164 	chan = dq->dq_ctlr;
165 	i = NDMA;
166 	while (--i >= 0) {
167 		if ((chan & (1 << i)) == 0)
168 			continue;
169 		if (dmachan[i].dq_forw != &dmachan[i])
170 			continue;
171 		insque(dq, &dmachan[i]);
172 		dq->dq_ctlr = i;
173 		splx(s);
174 		return(1);
175 	}
176 	insque(dq, dmachan[NDMA].dq_back);
177 	splx(s);
178 	return(0);
179 }
180 
181 void
182 dmafree(dq)
183 	register struct devqueue *dq;
184 {
185 	int unit = dq->dq_ctlr;
186 	register struct dma_softc *dc = &dma_softc[unit];
187 	register struct devqueue *dn;
188 	register int chan, s;
189 
190 	s = splbio();
191 #ifdef DEBUG
192 	dmatimo[unit] = 0;
193 #endif
194 	DMA_CLEAR(dc);
195 #if defined(HP360) || defined(HP370) || defined(HP380)
196 	/*
197 	 * XXX we may not always go thru the flush code in dmastop()
198 	 */
199 	if (dc->sc_flags & DMAF_PCFLUSH) {
200 		PCIA();
201 		dc->sc_flags &= ~DMAF_PCFLUSH;
202 	}
203 #endif
204 #if defined(HP320) || defined(HP350)
205 	if (dc->sc_flags & DMAF_VCFLUSH) {
206 		/*
207 		 * 320/350s have VACs that may also need flushing.
208 		 * In our case we only flush the supervisor side
209 		 * because we know that if we are DMAing to user
210 		 * space, the physical pages will also be mapped
211 		 * in kernel space (via vmapbuf) and hence cache-
212 		 * inhibited by the pmap module due to the multiple
213 		 * mapping.
214 		 */
215 		DCIS();
216 		dc->sc_flags &= ~DMAF_VCFLUSH;
217 	}
218 #endif
219 	remque(dq);
220 	chan = 1 << unit;
221 	for (dn = dmachan[NDMA].dq_forw;
222 	     dn != &dmachan[NDMA]; dn = dn->dq_forw) {
223 		if (dn->dq_ctlr & chan) {
224 			remque((caddr_t)dn);
225 			insque((caddr_t)dn, (caddr_t)dq->dq_back);
226 			splx(s);
227 			dn->dq_ctlr = dq->dq_ctlr;
228 			(dn->dq_driver->d_start)(dn->dq_unit);
229 			return;
230 		}
231 	}
232 	splx(s);
233 }
234 
235 void
236 dmago(unit, addr, count, flags)
237 	int unit;
238 	register char *addr;
239 	register int count;
240 	register int flags;
241 {
242 	register struct dma_softc *dc = &dma_softc[unit];
243 	register struct dma_chain *dcp;
244 	register char *dmaend = NULL;
245 	register int tcount;
246 
247 	if (count > MAXPHYS)
248 		panic("dmago: count > MAXPHYS");
249 #if defined(HP320)
250 	if (dc->sc_type == DMA_B && (flags & DMAGO_LWORD))
251 		panic("dmago: no can do 32-bit DMA");
252 #endif
253 #ifdef DEBUG
254 	if (dmadebug & DDB_FOLLOW)
255 		printf("dmago(%d, %x, %x, %x)\n",
256 		       unit, addr, count, flags);
257 	if (flags & DMAGO_LWORD)
258 		dmalword[unit]++;
259 	else if (flags & DMAGO_WORD)
260 		dmaword[unit]++;
261 	else
262 		dmabyte[unit]++;
263 #endif
264 	/*
265 	 * Build the DMA chain
266 	 */
267 	for (dcp = dc->sc_chain; count > 0; dcp++) {
268 		dcp->dc_addr = (char *) kvtop(addr);
269 #if defined(HP380)
270 		/*
271 		 * Push back dirty cache lines
272 		 */
273 		if (mmutype == MMU_68040)
274 			DCFP(dcp->dc_addr);
275 #endif
276 		if (count < (tcount = NBPG - ((int)addr & PGOFSET)))
277 			tcount = count;
278 		dcp->dc_count = tcount;
279 		addr += tcount;
280 		count -= tcount;
281 		if (flags & DMAGO_LWORD)
282 			tcount >>= 2;
283 		else if (flags & DMAGO_WORD)
284 			tcount >>= 1;
285 		if (dcp->dc_addr == dmaend
286 #if defined(HP320)
287 		    /* only 16-bit count on 98620B */
288 		    && (dc->sc_type != DMA_B ||
289 			(dcp-1)->dc_count + tcount <= 65536)
290 #endif
291 		) {
292 #ifdef DEBUG
293 			dmahits[unit]++;
294 #endif
295 			dmaend += dcp->dc_count;
296 			(--dcp)->dc_count += tcount;
297 		} else {
298 #ifdef DEBUG
299 			dmamisses[unit]++;
300 #endif
301 			dmaend = dcp->dc_addr + dcp->dc_count;
302 			dcp->dc_count = tcount;
303 		}
304 	}
305 	dc->sc_cur = dc->sc_chain;
306 	dc->sc_last = --dcp;
307 	dc->sc_flags = 0;
308 	/*
309 	 * Set up the command word based on flags
310 	 */
311 	dc->sc_cmd = DMA_ENAB | DMA_IPL(DMAINTLVL) | DMA_START;
312 	if ((flags & DMAGO_READ) == 0)
313 		dc->sc_cmd |= DMA_WRT;
314 	if (flags & DMAGO_LWORD)
315 		dc->sc_cmd |= DMA_LWORD;
316 	else if (flags & DMAGO_WORD)
317 		dc->sc_cmd |= DMA_WORD;
318 	if (flags & DMAGO_PRI)
319 		dc->sc_cmd |= DMA_PRI;
320 #if defined(HP380)
321 	/*
322 	 * On the 68040 we need to flush (push) the data cache before a
323 	 * DMA (already done above) and flush again after DMA completes.
324 	 * In theory we should only need to flush prior to a write DMA
325 	 * and purge after a read DMA but if the entire page is not
326 	 * involved in the DMA we might purge some valid data.
327 	 */
328 	if (mmutype == MMU_68040 && (flags & DMAGO_READ))
329 		dc->sc_flags |= DMAF_PCFLUSH;
330 #endif
331 #if defined(HP360) || defined(HP370)
332 	/*
333 	 * Remember if we need to flush external physical cache when
334 	 * DMA is done.  We only do this if we are reading (writing memory).
335 	 */
336 	if (ectype == EC_PHYS && (flags & DMAGO_READ))
337 		dc->sc_flags |= DMAF_PCFLUSH;
338 #endif
339 #if defined(HP320) || defined(HP350)
340 	if (ectype == EC_VIRT && (flags & DMAGO_READ))
341 		dc->sc_flags |= DMAF_VCFLUSH;
342 #endif
343 	/*
344 	 * Remember if we can skip the dma completion interrupt on
345 	 * the last segment in the chain.
346 	 */
347 	if (flags & DMAGO_NOINT) {
348 		if (dc->sc_cur == dc->sc_last)
349 			dc->sc_cmd &= ~DMA_ENAB;
350 		else
351 			dc->sc_flags |= DMAF_NOINTR;
352 	}
353 #ifdef DEBUG
354 	if (dmadebug & DDB_IO)
355 		if ((dmadebug&DDB_WORD) && (dc->sc_cmd&DMA_WORD) ||
356 		    (dmadebug&DDB_LWORD) && (dc->sc_cmd&DMA_LWORD)) {
357 			printf("dmago: cmd %x, flags %x\n",
358 			       dc->sc_cmd, dc->sc_flags);
359 			for (dcp = dc->sc_chain; dcp <= dc->sc_last; dcp++)
360 				printf("  %d: %d@%x\n", dcp-dc->sc_chain,
361 				       dcp->dc_count, dcp->dc_addr);
362 		}
363 	dmatimo[unit] = 1;
364 #endif
365 	DMA_ARM(dc);
366 }
367 
368 void
369 dmastop(unit)
370 	register int unit;
371 {
372 	register struct dma_softc *dc = &dma_softc[unit];
373 	register struct devqueue *dq;
374 
375 #ifdef DEBUG
376 	if (dmadebug & DDB_FOLLOW)
377 		printf("dmastop(%d)\n", unit);
378 	dmatimo[unit] = 0;
379 #endif
380 	DMA_CLEAR(dc);
381 #if defined(HP360) || defined(HP370) || defined(HP380)
382 	if (dc->sc_flags & DMAF_PCFLUSH) {
383 		PCIA();
384 		dc->sc_flags &= ~DMAF_PCFLUSH;
385 	}
386 #endif
387 #if defined(HP320) || defined(HP350)
388 	if (dc->sc_flags & DMAF_VCFLUSH) {
389 		/*
390 		 * 320/350s have VACs that may also need flushing.
391 		 * In our case we only flush the supervisor side
392 		 * because we know that if we are DMAing to user
393 		 * space, the physical pages will also be mapped
394 		 * in kernel space (via vmapbuf) and hence cache-
395 		 * inhibited by the pmap module due to the multiple
396 		 * mapping.
397 		 */
398 		DCIS();
399 		dc->sc_flags &= ~DMAF_VCFLUSH;
400 	}
401 #endif
402 	/*
403 	 * We may get this interrupt after a device service routine
404 	 * has freed the dma channel.  So, ignore the intr if there's
405 	 * nothing on the queue.
406 	 */
407 	dq = dmachan[unit].dq_forw;
408 	if (dq != &dmachan[unit])
409 		(dq->dq_driver->d_done)(dq->dq_unit);
410 }
411 
412 int
413 dmaintr()
414 {
415 	register struct dma_softc *dc;
416 	register int i, stat;
417 	int found = 0;
418 
419 #ifdef DEBUG
420 	if (dmadebug & DDB_FOLLOW)
421 		printf("dmaintr\n");
422 #endif
423 	for (i = 0, dc = dma_softc; i < NDMA; i++, dc++) {
424 		stat = DMA_STAT(dc);
425 		if ((stat & DMA_INTR) == 0)
426 			continue;
427 		found++;
428 #ifdef DEBUG
429 		if (dmadebug & DDB_IO) {
430 			if ((dmadebug&DDB_WORD) && (dc->sc_cmd&DMA_WORD) ||
431 			    (dmadebug&DDB_LWORD) && (dc->sc_cmd&DMA_LWORD))
432 				printf("dmaintr: unit %d stat %x next %d\n",
433 				       i, stat, (dc->sc_cur-dc->sc_chain)+1);
434 		}
435 		if (stat & DMA_ARMED)
436 			printf("dma%d: intr when armed\n", i);
437 #endif
438 		if (++dc->sc_cur <= dc->sc_last) {
439 #ifdef DEBUG
440 			dmatimo[i] = 1;
441 #endif
442 			/*
443 			 * Last chain segment, disable DMA interrupt.
444 			 */
445 			if (dc->sc_cur == dc->sc_last &&
446 			    (dc->sc_flags & DMAF_NOINTR))
447 				dc->sc_cmd &= ~DMA_ENAB;
448 			DMA_CLEAR(dc);
449 			DMA_ARM(dc);
450 		} else
451 			dmastop(i);
452 	}
453 	return(found);
454 }
455 
456 #ifdef DEBUG
457 void
458 dmatimeout(arg)
459 	void *arg;
460 {
461 	register int i, s;
462 
463 	for (i = 0; i < NDMA; i++) {
464 		s = splbio();
465 		if (dmatimo[i]) {
466 			if (dmatimo[i] > 1)
467 				printf("dma%d: timeout #%d\n",
468 				       i, dmatimo[i]-1);
469 			dmatimo[i]++;
470 		}
471 		splx(s);
472 	}
473 	timeout(dmatimeout, (void *)0, 30 * hz);
474 }
475 #endif
476