xref: /netbsd-src/sys/arch/amiga/dev/wstsc.c (revision ae1bfcddc410612bc8c58b807e1830becb69a24c)
1 /*
2  * Copyright (c) 1982, 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *	@(#)supradma.c
34  *	$Id: wstsc.c,v 1.1 1994/05/08 05:53:50 chopps Exp $
35  */
36 
37 /*
38  * dummy Supra 5380 DMA driver
39  */
40 
41 #include "suprascsi.h"
42 
43 #if NSUPRASCSI > 0
44 
45 #include <sys/param.h>
46 
47 #include <amiga/dev/device.h>
48 #include <amiga/dev/scivar.h>
49 #include <amiga/dev/scireg.h>
50 
51 int supradma_pseudo = 0;	/* 0=none, 1=byte, 2=word */
52 
53 #ifdef DEBUG
54 extern int sci_debug;
55 #define QUASEL
56 #endif
57 #define	HIST(h,w)
58 
59 #ifdef QUASEL
60 #define QPRINTF(a) if (sci_debug > 1) printf a
61 #else
62 #define QPRINTF
63 #endif
64 
65 extern int sci_data_wait;
66 
67 static int dma_xfer_in __P((struct sci_softc *dev, int len,
68     register u_char *buf, int phase));
69 static int dma_xfer_out __P((struct sci_softc *dev, int len,
70     register u_char *buf, int phase));
71 static int dma_xfer_in2 __P((struct sci_softc *dev, int len,
72     register u_short *buf, int phase));
73 static int dma_xfer_out2 __P((struct sci_softc *dev, int len,
74     register u_short *buf, int phase));
75 static int supra_intr __P((struct sci_softc *dev));
76 
77 void
78 supradmainit (dev)
79 	struct sci_softc *dev;
80 {
81 	if (supradma_pseudo == 2) {
82 		dev->dma_xfer_in = dma_xfer_in2;
83 		dev->dma_xfer_out = dma_xfer_out2;
84 	} else if (supradma_pseudo == 1) {
85 		dev->dma_xfer_in = dma_xfer_in;
86 		dev->dma_xfer_out = dma_xfer_out;
87 	}
88 	dev->dma_intr = supra_intr;
89 }
90 
91 static int
92 dma_xfer_in (dev, len, buf, phase)
93 	struct sci_softc *dev;
94 	int len;
95 	register u_char *buf;
96 	int phase;
97 {
98 	int wait = sci_data_wait;
99 	u_char csr;
100 	u_char *obp = (u_char *) buf;
101 	volatile register u_char *sci_dma = dev->sci_idata;
102 	volatile register u_char *sci_csr = dev->sci_csr;
103 
104 	QPRINTF(("supradma_in %d, csr=%02x\n", len, *dev->sci_bus_csr));
105 
106 	*dev->sci_tcmd = phase;
107 	*dev->sci_icmd = 0;
108 	*dev->sci_mode = SCI_MODE_DMA;
109 	*dev->sci_irecv = 0;
110 
111 	while (len >= 128) {
112 		wait = sci_data_wait;
113 		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
114 		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
115 			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
116 			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
117 			  || --wait < 0) {
118 #ifdef DEBUG
119 				if (sci_debug | 1)
120 					printf("supradma2_in fail: l%d i%x w%d\n",
121 					len, *dev->sci_bus_csr, wait);
122 #endif
123 				HIST(ixin_wait, wait)
124 				*dev->sci_mode = 0;
125 				return 0;
126 			}
127 		}
128 
129 		*buf++ = *sci_dma; *buf++ = *sci_dma;
130 		*buf++ = *sci_dma; *buf++ = *sci_dma;
131 		*buf++ = *sci_dma; *buf++ = *sci_dma;
132 		*buf++ = *sci_dma; *buf++ = *sci_dma;
133 		*buf++ = *sci_dma; *buf++ = *sci_dma;
134 		*buf++ = *sci_dma; *buf++ = *sci_dma;
135 		*buf++ = *sci_dma; *buf++ = *sci_dma;
136 		*buf++ = *sci_dma; *buf++ = *sci_dma;
137 		*buf++ = *sci_dma; *buf++ = *sci_dma;
138 		*buf++ = *sci_dma; *buf++ = *sci_dma;
139 		*buf++ = *sci_dma; *buf++ = *sci_dma;
140 		*buf++ = *sci_dma; *buf++ = *sci_dma;
141 		*buf++ = *sci_dma; *buf++ = *sci_dma;
142 		*buf++ = *sci_dma; *buf++ = *sci_dma;
143 		*buf++ = *sci_dma; *buf++ = *sci_dma;
144 		*buf++ = *sci_dma; *buf++ = *sci_dma;
145 		*buf++ = *sci_dma; *buf++ = *sci_dma;
146 		*buf++ = *sci_dma; *buf++ = *sci_dma;
147 		*buf++ = *sci_dma; *buf++ = *sci_dma;
148 		*buf++ = *sci_dma; *buf++ = *sci_dma;
149 		*buf++ = *sci_dma; *buf++ = *sci_dma;
150 		*buf++ = *sci_dma; *buf++ = *sci_dma;
151 		*buf++ = *sci_dma; *buf++ = *sci_dma;
152 		*buf++ = *sci_dma; *buf++ = *sci_dma;
153 		*buf++ = *sci_dma; *buf++ = *sci_dma;
154 		*buf++ = *sci_dma; *buf++ = *sci_dma;
155 		*buf++ = *sci_dma; *buf++ = *sci_dma;
156 		*buf++ = *sci_dma; *buf++ = *sci_dma;
157 		*buf++ = *sci_dma; *buf++ = *sci_dma;
158 		*buf++ = *sci_dma; *buf++ = *sci_dma;
159 		*buf++ = *sci_dma; *buf++ = *sci_dma;
160 		*buf++ = *sci_dma; *buf++ = *sci_dma;
161 		*buf++ = *sci_dma; *buf++ = *sci_dma;
162 		*buf++ = *sci_dma; *buf++ = *sci_dma;
163 		*buf++ = *sci_dma; *buf++ = *sci_dma;
164 		*buf++ = *sci_dma; *buf++ = *sci_dma;
165 		*buf++ = *sci_dma; *buf++ = *sci_dma;
166 		*buf++ = *sci_dma; *buf++ = *sci_dma;
167 		*buf++ = *sci_dma; *buf++ = *sci_dma;
168 		*buf++ = *sci_dma; *buf++ = *sci_dma;
169 		*buf++ = *sci_dma; *buf++ = *sci_dma;
170 		*buf++ = *sci_dma; *buf++ = *sci_dma;
171 		*buf++ = *sci_dma; *buf++ = *sci_dma;
172 		*buf++ = *sci_dma; *buf++ = *sci_dma;
173 		*buf++ = *sci_dma; *buf++ = *sci_dma;
174 		*buf++ = *sci_dma; *buf++ = *sci_dma;
175 		*buf++ = *sci_dma; *buf++ = *sci_dma;
176 		*buf++ = *sci_dma; *buf++ = *sci_dma;
177 		*buf++ = *sci_dma; *buf++ = *sci_dma;
178 		*buf++ = *sci_dma; *buf++ = *sci_dma;
179 		*buf++ = *sci_dma; *buf++ = *sci_dma;
180 		*buf++ = *sci_dma; *buf++ = *sci_dma;
181 		*buf++ = *sci_dma; *buf++ = *sci_dma;
182 		*buf++ = *sci_dma; *buf++ = *sci_dma;
183 		*buf++ = *sci_dma; *buf++ = *sci_dma;
184 		*buf++ = *sci_dma; *buf++ = *sci_dma;
185 		*buf++ = *sci_dma; *buf++ = *sci_dma;
186 		*buf++ = *sci_dma; *buf++ = *sci_dma;
187 		*buf++ = *sci_dma; *buf++ = *sci_dma;
188 		*buf++ = *sci_dma; *buf++ = *sci_dma;
189 		*buf++ = *sci_dma; *buf++ = *sci_dma;
190 		*buf++ = *sci_dma; *buf++ = *sci_dma;
191 		*buf++ = *sci_dma; *buf++ = *sci_dma;
192 		*buf++ = *sci_dma; *buf++ = *sci_dma;
193 		len -= 128;
194 	}
195 
196 	while (len > 0) {
197 		wait = sci_data_wait;
198 		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
199 		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
200 			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
201 			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
202 			  || --wait < 0) {
203 #ifdef DEBUG
204 				if (sci_debug | 1)
205 					printf("supradma1_in fail: l%d i%x w%d\n",
206 					len, *dev->sci_bus_csr, wait);
207 #endif
208 				HIST(ixin_wait, wait)
209 				*dev->sci_mode = 0;
210 				return 0;
211 			}
212 		}
213 
214 		*buf++ = *sci_dma;
215 		len--;
216 	}
217 
218 	QPRINTF(("supradma_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
219 	  len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
220 	  obp[6], obp[7], obp[8], obp[9]));
221 
222 	HIST(ixin_wait, wait)
223 	*dev->sci_mode = 0;
224 	return 0;
225 }
226 
227 static int
228 dma_xfer_out (dev, len, buf, phase)
229 	struct sci_softc *dev;
230 	int len;
231 	register u_char *buf;
232 	int phase;
233 {
234 	int wait = sci_data_wait;
235 	u_char csr;
236 	u_char *obp = buf;
237 	volatile register u_char *sci_dma = dev->sci_data;
238 	volatile register u_char *sci_csr = dev->sci_csr;
239 
240 	QPRINTF(("supradma_out %d, csr=%02x\n", len, *dev->sci_bus_csr));
241 
242 	QPRINTF(("supradma_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
243   	 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
244 	 buf[6], buf[7], buf[8], buf[9]));
245 
246 	*dev->sci_tcmd = phase;
247 	*dev->sci_mode = SCI_MODE_DMA;
248 	*dev->sci_icmd = SCI_ICMD_DATA;
249 	*dev->sci_dma_send = 0;
250 	while (len > 0) {
251 		wait = sci_data_wait;
252 		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
253 		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
254 			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
255 			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
256 			  || --wait < 0) {
257 #ifdef DEBUG
258 				if (sci_debug)
259 					printf("supradma_out fail: l%d i%x w%d\n",
260 					len, csr, wait);
261 #endif
262 				HIST(ixin_wait, wait)
263 				*dev->sci_mode = 0;
264 				return 0;
265 			}
266 		}
267 
268 		*sci_dma = *buf++;
269 		len--;
270 	}
271 
272 	wait = sci_data_wait;
273 	while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) ==
274 	  SCI_CSR_PHASE_MATCH && --wait);
275 
276 
277 	HIST(ixin_wait, wait)
278 	*dev->sci_mode = 0;
279 	*dev->sci_icmd = 0;
280 	return 0;
281 }
282 
283 
284 static int
285 dma_xfer_in2 (dev, len, buf, phase)
286 	struct sci_softc *dev;
287 	int len;
288 	register u_short *buf;
289 	int phase;
290 {
291 	int wait = sci_data_wait;
292 	u_char csr;
293 	u_char *obp = (u_char *) buf;
294 	volatile register u_short *sci_dma = (u_short *)(dev->sci_idata + 0x10);
295 	volatile register u_char *sci_csr = dev->sci_csr + 0x10;
296 
297 	QPRINTF(("supradma_in2 %d, csr=%02x\n", len, *dev->sci_bus_csr));
298 
299 	*dev->sci_tcmd = phase;
300 	*dev->sci_mode = SCI_MODE_DMA;
301 	*dev->sci_icmd = 0;
302 	*(dev->sci_irecv + 16) = 0;
303 	while (len >= 128) {
304 #if 0
305 		wait = sci_data_wait;
306 		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
307 		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
308 			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
309 			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
310 			  || --wait < 0) {
311 #ifdef DEBUG
312 				if (sci_debug | 1)
313 					printf("supradma2_in2 fail: l%d i%x w%d\n",
314 					len, *dev->sci_bus_csr, wait);
315 #endif
316 				HIST(ixin_wait, wait)
317 				*dev->sci_mode &= ~SCI_MODE_DMA;
318 				return 0;
319 			}
320 		}
321 #else
322 		while (!(*sci_csr & SCI_CSR_DREQ))
323 			;
324 #endif
325 
326 		*buf++ = *sci_dma; *buf++ = *sci_dma;
327 		*buf++ = *sci_dma; *buf++ = *sci_dma;
328 		*buf++ = *sci_dma; *buf++ = *sci_dma;
329 		*buf++ = *sci_dma; *buf++ = *sci_dma;
330 		*buf++ = *sci_dma; *buf++ = *sci_dma;
331 		*buf++ = *sci_dma; *buf++ = *sci_dma;
332 		*buf++ = *sci_dma; *buf++ = *sci_dma;
333 		*buf++ = *sci_dma; *buf++ = *sci_dma;
334 		*buf++ = *sci_dma; *buf++ = *sci_dma;
335 		*buf++ = *sci_dma; *buf++ = *sci_dma;
336 		*buf++ = *sci_dma; *buf++ = *sci_dma;
337 		*buf++ = *sci_dma; *buf++ = *sci_dma;
338 		*buf++ = *sci_dma; *buf++ = *sci_dma;
339 		*buf++ = *sci_dma; *buf++ = *sci_dma;
340 		*buf++ = *sci_dma; *buf++ = *sci_dma;
341 		*buf++ = *sci_dma; *buf++ = *sci_dma;
342 		*buf++ = *sci_dma; *buf++ = *sci_dma;
343 		*buf++ = *sci_dma; *buf++ = *sci_dma;
344 		*buf++ = *sci_dma; *buf++ = *sci_dma;
345 		*buf++ = *sci_dma; *buf++ = *sci_dma;
346 		*buf++ = *sci_dma; *buf++ = *sci_dma;
347 		*buf++ = *sci_dma; *buf++ = *sci_dma;
348 		*buf++ = *sci_dma; *buf++ = *sci_dma;
349 		*buf++ = *sci_dma; *buf++ = *sci_dma;
350 		*buf++ = *sci_dma; *buf++ = *sci_dma;
351 		*buf++ = *sci_dma; *buf++ = *sci_dma;
352 		*buf++ = *sci_dma; *buf++ = *sci_dma;
353 		*buf++ = *sci_dma; *buf++ = *sci_dma;
354 		*buf++ = *sci_dma; *buf++ = *sci_dma;
355 		*buf++ = *sci_dma; *buf++ = *sci_dma;
356 		*buf++ = *sci_dma; *buf++ = *sci_dma;
357 		*buf++ = *sci_dma; *buf++ = *sci_dma;
358 		len -= 128;
359 	}
360 	while (len > 0) {
361 #if 0
362 		wait = sci_data_wait;
363 		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
364 		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
365 			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
366 			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
367 			  || --wait < 0) {
368 #ifdef DEBUG
369 				if (sci_debug | 1)
370 					printf("supradma1_in2 fail: l%d i%x w%d\n",
371 					len, *dev->sci_bus_csr, wait);
372 #endif
373 				HIST(ixin_wait, wait)
374 				*dev->sci_mode &= ~SCI_MODE_DMA;
375 				return 0;
376 			}
377 		}
378 #else
379 		while (!(*sci_csr * SCI_CSR_DREQ))
380 			;
381 #endif
382 
383 		*buf++ = *sci_dma;
384 		len -= 2;
385 	}
386 
387 	QPRINTF(("supradma_in2 {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
388 	  len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
389 	  obp[6], obp[7], obp[8], obp[9]));
390 
391 	HIST(ixin_wait, wait)
392 	*dev->sci_irecv = 0;
393 	*dev->sci_mode = 0;
394 	return 0;
395 }
396 
397 static int
398 dma_xfer_out2 (dev, len, buf, phase)
399 	struct sci_softc *dev;
400 	int len;
401 	register u_short *buf;
402 	int phase;
403 {
404 	int wait = sci_data_wait;
405 	u_char csr;
406 	u_char *obp = (u_char *) buf;
407 	volatile register u_short *sci_dma = (ushort *)(dev->sci_data + 0x10);
408 	volatile register u_char *sci_bus_csr = dev->sci_bus_csr;
409 
410 	QPRINTF(("supradma_out2 %d, csr=%02x\n", len, *dev->sci_bus_csr));
411 
412 	QPRINTF(("supradma_out2 {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
413   	 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
414 	 obp[6], obp[7], obp[8], obp[9]));
415 
416 	*dev->sci_tcmd = phase;
417 	*dev->sci_mode = SCI_MODE_DMA;
418 	*dev->sci_icmd = SCI_ICMD_DATA;
419 	*dev->sci_dma_send = 0;
420 	while (len > 0) {
421 #if 0
422 		wait = sci_data_wait;
423 		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
424 		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
425 			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
426 			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
427 			  || --wait < 0) {
428 #ifdef DEBUG
429 				if (sci_debug)
430 					printf("supradma_out2 fail: l%d i%x w%d\n",
431 					len, csr, wait);
432 #endif
433 				HIST(ixin_wait, wait)
434 				*dev->sci_mode = 0;
435 				return 0;
436 			}
437 		}
438 #else
439 		*dev->sci_mode = 0;
440 		*dev->sci_icmd &= ~SCI_ICMD_ACK;
441 		while (!(*sci_bus_csr & SCI_BUS_REQ))
442 			;
443 		*dev->sci_mode = SCI_MODE_DMA;
444 		*dev->sci_dma_send = 0;
445 #endif
446 
447 		*sci_dma = *buf++; *sci_dma = *buf++;
448 		*sci_dma = *buf++; *sci_dma = *buf++;
449 		*sci_dma = *buf++; *sci_dma = *buf++;
450 		*sci_dma = *buf++; *sci_dma = *buf++;
451 		*sci_dma = *buf++; *sci_dma = *buf++;
452 		*sci_dma = *buf++; *sci_dma = *buf++;
453 		*sci_dma = *buf++; *sci_dma = *buf++;
454 		*sci_dma = *buf++; *sci_dma = *buf++;
455 		*sci_dma = *buf++; *sci_dma = *buf++;
456 		*sci_dma = *buf++; *sci_dma = *buf++;
457 		*sci_dma = *buf++; *sci_dma = *buf++;
458 		*sci_dma = *buf++; *sci_dma = *buf++;
459 		*sci_dma = *buf++; *sci_dma = *buf++;
460 		*sci_dma = *buf++; *sci_dma = *buf++;
461 		*sci_dma = *buf++; *sci_dma = *buf++;
462 		*sci_dma = *buf++; *sci_dma = *buf++;
463 		if (*(sci_bus_csr + 0x10) & SCI_BUS_REQ)
464 			;
465 		len -= 64;
466 	}
467 
468 #if 0
469 	wait = sci_data_wait;
470 	while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) ==
471 	  SCI_CSR_PHASE_MATCH && --wait);
472 #endif
473 
474 
475 	HIST(ixin_wait, wait)
476 	*dev->sci_irecv = 0;
477 	*dev->sci_icmd &= ~SCI_ICMD_ACK;
478 	*dev->sci_mode = 0;
479 	*dev->sci_icmd = 0;
480 	return 0;
481 }
482 
483 static int
484 supra_intr (dev)
485 	struct sci_softc *dev;
486 {
487 	if (*(dev->sci_csr + 0x10) & SCI_CSR_INT) {
488 		char dummy;
489 #if 0
490 printf ("supra_intr\n");
491 #endif
492 		dummy = *(dev->sci_iack + 0x10);
493 		return (1);
494 	}
495 	return (0);
496 }
497 #endif
498