xref: /freebsd/sys/dev/ppc/ppc.c (revision 11afcc8f9f96d657b8e6f7547c02c1957331fc96)
1 /*-
2  * Copyright (c) 1997, 1998 Nicolas Souchu
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  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *	$Id: ppc.c,v 1.3 1998/04/17 22:36:37 des Exp $
27  *
28  */
29 #include "ppc.h"
30 
31 #if NPPC > 0
32 
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/conf.h>
36 #include <sys/malloc.h>
37 
38 #include <machine/clock.h>
39 
40 #include <vm/vm.h>
41 #include <vm/vm_param.h>
42 #include <vm/pmap.h>
43 
44 #include <i386/isa/isa_device.h>
45 
46 #include <dev/ppbus/ppbconf.h>
47 #include <dev/ppbus/ppb_msq.h>
48 
49 #include <i386/isa/ppcreg.h>
50 
51 static int	ppcprobe(struct isa_device *);
52 static int	ppcattach(struct isa_device *);
53 
54 struct isa_driver ppcdriver = {
55 	ppcprobe, ppcattach, "ppc"
56 };
57 
58 static struct ppc_data *ppcdata[NPPC];
59 static int nppc = 0;
60 
61 static char *ppc_types[] = {
62 	"SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306",
63 	"82091AA", "Generic", "W83877F", "W83877AF", "Winbond", 0
64 };
65 
66 /* list of available modes */
67 static char *ppc_avms[] = {
68 	"COMPATIBLE", "NIBBLE-only", "PS2-only", "PS2/NIBBLE", "EPP-only",
69 	"EPP/NIBBLE", "EPP/PS2", "EPP/PS2/NIBBLE", "ECP-only",
70 	"ECP/NIBBLE", "ECP/PS2", "ECP/PS2/NIBBLE", "ECP/EPP",
71 	"ECP/EPP/NIBBLE", "ECP/EPP/PS2", "ECP/EPP/PS2/NIBBLE", 0
72 };
73 
74 /* list of current executing modes
75  * Note that few modes do not actually exist.
76  */
77 static char *ppc_modes[] = {
78 	"COMPATIBLE", "NIBBLE", "PS/2", "PS/2", "EPP",
79 	"EPP", "EPP", "EPP", "ECP",
80 	"ECP", "ECP+PS2", "ECP+PS2", "ECP+EPP",
81 	"ECP+EPP", "ECP+EPP", "ECP+EPP", 0
82 };
83 
84 static char *ppc_epp_protocol[] = { " (EPP 1.9)", " (EPP 1.7)", 0 };
85 
86 /*
87  * BIOS printer list - used by BIOS probe.
88  */
89 #define	BIOS_PPC_PORTS	0x408
90 #define	BIOS_PORTS	(short *)(KERNBASE+BIOS_PPC_PORTS)
91 #define	BIOS_MAX_PPC	4
92 
93 /*
94  * All these functions are default actions for IN/OUT operations.
95  * They may be redefined if needed.
96  */
97 static void ppc_outsb_epp(int unit, char *addr, int cnt) {
98 	outsb(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
99 static void ppc_outsw_epp(int unit, char *addr, int cnt) {
100 	outsw(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
101 static void ppc_outsl_epp(int unit, char *addr, int cnt) {
102 	outsl(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
103 static void ppc_insb_epp(int unit, char *addr, int cnt) {
104 	insb(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
105 static void ppc_insw_epp(int unit, char *addr, int cnt) {
106 	insw(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
107 static void ppc_insl_epp(int unit, char *addr, int cnt) {
108 	insl(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
109 
110 static char ppc_rdtr(int unit) { return r_dtr(ppcdata[unit]); }
111 static char ppc_rstr(int unit) { return r_str(ppcdata[unit]); }
112 static char ppc_rctr(int unit) { return r_ctr(ppcdata[unit]); }
113 static char ppc_repp(int unit) { return r_epp(ppcdata[unit]); }
114 static char ppc_recr(int unit) { return r_ecr(ppcdata[unit]); }
115 static char ppc_rfifo(int unit) { return r_fifo(ppcdata[unit]); }
116 
117 static void ppc_wdtr(int unit, char byte) { w_dtr(ppcdata[unit], byte); }
118 static void ppc_wstr(int unit, char byte) { w_str(ppcdata[unit], byte); }
119 static void ppc_wctr(int unit, char byte) { w_ctr(ppcdata[unit], byte); }
120 static void ppc_wepp(int unit, char byte) { w_epp(ppcdata[unit], byte); }
121 static void ppc_wecr(int unit, char byte) { w_ecr(ppcdata[unit], byte); }
122 static void ppc_wfifo(int unit, char byte) { w_fifo(ppcdata[unit], byte); }
123 
124 static void ppc_reset_epp_timeout(int);
125 static void ppc_ecp_sync(int);
126 
127 static int ppc_exec_microseq(int, struct ppb_microseq *, int *);
128 static int ppc_generic_setmode(int, int);
129 
130 static struct ppb_adapter ppc_adapter = {
131 
132 	0,	/* no intr handler, filled by chipset dependent code */
133 
134 	ppc_reset_epp_timeout, ppc_ecp_sync,
135 
136 	ppc_exec_microseq,
137 
138 	ppc_generic_setmode,
139 
140 	ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp,
141 	ppc_insb_epp, ppc_insw_epp, ppc_insl_epp,
142 
143 	ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp, ppc_recr, ppc_rfifo,
144 	ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp, ppc_wecr, ppc_wfifo
145 };
146 
147 /*
148  * ppc_ecp_sync()		XXX
149  */
150 static void
151 ppc_ecp_sync(int unit) {
152 
153 	struct ppc_data *ppc = ppcdata[unit];
154 	int i, r;
155 
156 	r = r_ecr(ppc);
157 	if ((r & 0xe0) != 0x80)
158 		return;
159 
160 	for (i = 0; i < 100; i++) {
161 		r = r_ecr(ppc);
162 		if (r & 0x1)
163 			return;
164 		DELAY(100);
165 	}
166 
167 	printf("ppc%d: ECP sync failed as data still " \
168 		"present in FIFO.\n", unit);
169 
170 	return;
171 }
172 
173 void
174 ppcintr(int unit)
175 {
176 	/* call directly upper code */
177 	ppb_intr(&ppcdata[unit]->ppc_link);
178 
179 	return;
180 }
181 
182 static void
183 ppc_ecp_config(struct ppc_data *ppc, int chipset_mode)
184 {
185 	/* XXX disable DMA, enable interrupts */
186 	if (chipset_mode & PPB_EPP)
187 		/* select EPP mode */
188 		w_ecr(ppc, 0x80);
189 	else if (chipset_mode & PPB_PS2)
190 			/* select PS2 mode with ECP */
191 			w_ecr(ppc, 0x20);
192 		else
193 			/* keep ECP mode alone, default for NIBBLE */
194 			w_ecr(ppc, 0x70);
195 
196 	return;
197 }
198 
199 static int
200 ppc_detect_port(struct ppc_data *ppc)
201 {
202 
203 	w_ctr(ppc, 0x0c);	/* To avoid missing PS2 ports */
204 	w_dtr(ppc, 0xaa);
205 	if (r_dtr(ppc) != (char) 0xaa)
206 		return (0);
207 
208 	return (1);
209 }
210 
211 /*
212  * ppc_pc873xx_detect
213  *
214  * Probe for a Natsemi PC873xx-family part.
215  *
216  * References in this function are to the National Semiconductor
217  * PC87332 datasheet TL/C/11930, May 1995 revision.
218  */
219 static int pc873xx_basetab[] = {0x0398, 0x026e, 0x015c, 0x002e, 0};
220 static int pc873xx_porttab[] = {0x0378, 0x03bc, 0x0278, 0};
221 
222 static int
223 ppc_pc873xx_detect(struct ppc_data *ppc, int chipset_mode)	/* XXX mode never forced */
224 {
225     static int	index = 0;
226     int		base, idport;
227     int		val;
228 
229     while ((idport = pc873xx_basetab[index++])) {
230 
231 	/* XXX should check first to see if this location is already claimed */
232 
233 	/*
234 	 * Pull the 873xx through the power-on ID cycle (2.2,1.).  We can't use this
235 	 * to locate the chip as it may already have been used by the BIOS.
236 	 */
237 	(void)inb(idport); (void)inb(idport); (void)inb(idport); (void)inb(idport);
238 
239 	/*
240 	 * Read the SID byte.  Possible values are :
241 	 *
242 	 * 0001xxxx	PC87332
243 	 * 01110xxx	PC87306
244 	 */
245 	outb(idport, PC873_SID);
246 	val = inb(idport + 1);
247 	if ((val & 0xf0) == 0x10) {
248 	    ppc->ppc_type = NS_PC87332;
249 	} else if ((val & 0xf8) == 0x70) {
250 	    ppc->ppc_type = NS_PC87306;
251 	} else {
252 	    if (bootverbose && (val != 0xff))
253 		printf("PC873xx probe at 0x%x got unknown ID 0x%x\n", idport, val);
254 	    continue ;		/* not recognised */
255 	}
256 
257 	/*
258 	 * We think we have one.  Is it enabled and where we want it to be?
259 	 */
260 	outb(idport, PC873_FER);
261 	val = inb(idport + 1);
262 	if (!(val & PC873_PPENABLE)) {
263 	    if (bootverbose)
264 		printf("PC873xx parallel port disabled\n");
265 	    continue;
266 	}
267 	outb(idport, PC873_FAR);
268 	val = inb(idport + 1) & 0x3;
269 	/* XXX we should create a driver instance for every port found */
270 	if (pc873xx_porttab[val] != ppc->ppc_base) {
271 	    if (bootverbose)
272 		printf("PC873xx at 0x%x not for driver at port 0x%x\n",
273 		       pc873xx_porttab[val], ppc->ppc_base);
274 	    continue;
275 	}
276 
277 	/*
278 	 * This is the port we want.  Can we dink with it to improve
279 	 * our chances?
280 	 */
281 	outb(idport, PC873_PTR);
282 	val = inb(idport + 1);
283 	if (val & PC873_CFGLOCK) {
284 	    if (bootverbose)
285 		printf("PC873xx locked\n");
286 
287 	    /* work out what mode we're in */
288 	    ppc->ppc_avm |= PPB_NIBBLE;		/* worst case */
289 
290 	    outb(idport, PC873_PCR);
291 	    val = inb(idport + 1);
292 	    if ((val & PC873_EPPEN) && (val & PC873_EPP19)) {
293 		outb(idport, PC873_PTR);
294 		val = inb(idport + 1);
295 		if (!(val & PC873_EPPRDIR)) {
296 		    ppc->ppc_avm |= PPB_EPP;	/* As we would have done it anwyay */
297 		}
298 	    } else if ((val & PC873_ECPEN) && (val & PC873_ECPCLK)) {
299 		ppc->ppc_avm |= PPB_PS2;	/* tolerable alternative */
300 	    }
301 	} else {
302 	    if (bootverbose)
303 		printf("PC873xx unlocked, ");
304 
305 #if 0	/* broken */
306 	    /*
307 	     * Frob the zero-wait-state option if possible; it causes
308 	     * unreliable operation.
309 	     */
310 	    outb(idport, PC873_FCR);
311 	    val = inb(idport + 1);
312 	    if ((ppc->ppc_type == NS_PC87306) ||	/* we are a '306 */
313 		!(val & PC873_ZWSPWDN)) {		/* or pin _is_ ZWS */
314 		val &= ~PC873_ZWS;
315 		outb(idport + 1, val);			/* must disable ZWS */
316 		outb(idport + 1, val);
317 
318 		if (bootverbose)
319 		    printf("ZWS %s, ", (val & PC873_ZWS) ? "enabled" : "disabled");
320 	    }
321 
322 #endif
323 	    if (bootverbose)
324 		printf("reconfiguring for ");
325 
326 	    /*
327 	     * if the chip is at 0x3bc, we can't use EPP as there's no room
328 	     * for the extra registers.
329 	     *
330 	     * XXX should we use ECP mode always and use the EPP submode?
331 	     */
332 	    if (ppc->ppc_base != 0x3bc) {
333 		if (bootverbose)
334 		    printf("EPP 1.9\n");
335 
336 		/* configure for EPP 1.9 operation XXX should be configurable */
337 		outb(idport, PC873_PCR);
338 		val = inb(idport + 1);
339 		val &= ~(PC873_ECPEN | PC873_ECPCLK);	/* disable ECP */
340 		val |= (PC873_EPPEN | PC873_EPP19);	/* enable EPP */
341 		outb(idport + 1, val);
342 		outb(idport + 1, val);
343 
344 		/* enable automatic direction turnover */
345 		outb(idport, PC873_PTR);
346 		val = inb(idport + 1);
347 		val &= ~PC873_EPPRDIR;			/* disable "regular" direction change */
348 		outb(idport + 1, val);
349 		outb(idport + 1, val);
350 
351 		/* we are an EPP-32 port */
352 		ppc->ppc_avm |= PPB_EPP;
353 	    } else {
354 		if (bootverbose)
355 		    printf("ECP\n");
356 
357 		/* configure as an ECP port to get bidirectional operation for now */
358 		outb(idport, PC873_PCR);
359 		outb(idport + 1, inb(idport + 1) | PC873_ECPEN | PC873_ECPCLK);
360 
361 		/* we look like a PS/2 port */
362 		ppc->ppc_avm |= PPB_PS2;
363 	    }
364 	}
365 
366 	return(chipset_mode);
367     }
368     return(-1);
369 }
370 
371 static int
372 ppc_check_epp_timeout(struct ppc_data *ppc)
373 {
374 	ppc_reset_epp_timeout(ppc->ppc_unit);
375 
376 	return (!(r_str(ppc) & TIMEOUT));
377 }
378 
379 /*
380  * ppc_smc37c66xgt_detect
381  *
382  * SMC FDC37C66xGT configuration.
383  */
384 static int
385 ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode)
386 {
387 	int s, i;
388 	char r;
389 	int type = -1;
390 	int csr = SMC66x_CSR;	/* initial value is 0x3F0 */
391 
392 	int port_address[] = { -1 /* disabled */ , 0x3bc, 0x378, 0x278 };
393 
394 
395 #define cio csr+1	/* config IO port is either 0x3F1 or 0x371 */
396 
397 	/*
398 	 * Detection: enter configuration mode and read CRD register.
399 	 */
400 
401 	s = splhigh();
402 	outb(csr, SMC665_iCODE);
403 	outb(csr, SMC665_iCODE);
404 	splx(s);
405 
406 	outb(csr, 0xd);
407 	if (inb(cio) == 0x65) {
408 		type = SMC_37C665GT;
409 		goto config;
410 	}
411 
412 	for (i = 0; i < 2; i++) {
413 		s = splhigh();
414 		outb(csr, SMC666_iCODE);
415 		outb(csr, SMC666_iCODE);
416 		splx(s);
417 
418 		outb(csr, 0xd);
419 		if (inb(cio) == 0x66) {
420 			type = SMC_37C666GT;
421 			break;
422 		}
423 
424 		/* Another chance, CSR may be hard-configured to be at 0x370 */
425 		csr = SMC666_CSR;
426 	}
427 
428 config:
429 	/*
430 	 * If chipset not found, do not continue.
431 	 */
432 	if (type == -1)
433 		return (-1);
434 
435 	/* select CR1 */
436 	outb(csr, 0x1);
437 
438 	/* read the port's address: bits 0 and 1 of CR1 */
439 	r = inb(cio) & SMC_CR1_ADDR;
440 	if (port_address[r] != ppc->ppc_base)
441 		return (-1);
442 
443 	ppc->ppc_type = type;
444 
445 	/*
446 	 * CR1 and CR4 registers bits 3 and 0/1 for mode configuration
447 	 * If SPP mode is detected, try to set ECP+EPP mode
448 	 */
449 
450 	if (bootverbose) {
451 		outb(csr, 0x1);
452 		printf("SMC registers CR1=0x%x", ppc->ppc_unit,
453 			inb(cio) & 0xff);
454 
455 		outb(csr, 0x4);
456 		printf(" CR4=0x%x", inb(cio) & 0xff);
457 	}
458 
459 	/* select CR1 */
460 	outb(csr, 0x1);
461 
462 	if (!chipset_mode) {
463 		/* autodetect mode */
464 
465 		/* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
466 		if (type == SMC_37C666GT) {
467 			ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
468 
469 		} else
470 		   if ((inb(cio) & SMC_CR1_MODE) == 0) {
471 			/* already in extended parallel port mode, read CR4 */
472 			outb(csr, 0x4);
473 			r = (inb(cio) & SMC_CR4_EMODE);
474 
475 			switch (r) {
476 			case SMC_SPP:
477 				ppc->ppc_avm |= PPB_SPP;
478 				break;
479 
480 			case SMC_EPPSPP:
481 				ppc->ppc_avm |= PPB_EPP | PPB_SPP;
482 				break;
483 
484 			case SMC_ECP:
485 				ppc->ppc_avm |= PPB_ECP | PPB_SPP;
486 				break;
487 
488 			case SMC_ECPEPP:
489 				ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
490 				break;
491 			}
492 		   } else {
493 			/* not an extended port mode */
494 			ppc->ppc_avm |= PPB_SPP;
495 		   }
496 
497 	} else {
498 		/* mode forced */
499 
500 		/* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
501 		if (type == SMC_37C666GT)
502 			goto end_detect;
503 
504 		r = inb(cio);
505 		if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) {
506 			/* do not use ECP when the mode is not forced to */
507 			outb(cio, r | SMC_CR1_MODE);
508 		} else {
509 			/* an extended mode is selected */
510 			outb(cio, r & ~SMC_CR1_MODE);
511 
512 			/* read CR4 register and reset mode field */
513 			outb(csr, 0x4);
514 			r = inb(cio) & ~SMC_CR4_EMODE;
515 
516 			if (chipset_mode & PPB_ECP) {
517 				if (chipset_mode & PPB_EPP) {
518 					outb(cio, r | SMC_ECPEPP);
519 				} else {
520 					outb(cio, r | SMC_ECP);
521 				}
522 			} else {
523 				/* PPB_EPP is set */
524 				outb(cio, r | SMC_EPPSPP);
525 			}
526 		}
527 		ppc->ppc_avm = chipset_mode;
528 	}
529 
530 end_detect:
531 
532 	if (bootverbose)
533 		printf ("\n");
534 
535 	if (chipset_mode & PPB_EPP) {
536 		/* select CR4 */
537 		outb(csr, 0x4);
538 		r = inb(cio);
539 
540 		/*
541 		 * Set the EPP protocol...
542 		 * Low=EPP 1.9 (1284 standard) and High=EPP 1.7
543 		 */
544 		if (ppc->ppc_epp == EPP_1_9)
545 			outb(cio, (r & ~SMC_CR4_EPPTYPE));
546 		else
547 			outb(cio, (r | SMC_CR4_EPPTYPE));
548 	}
549 
550 	/* end config mode */
551 	outb(csr, 0xaa);
552 
553 	if (ppc->ppc_avm & PPB_ECP)
554 		ppc_ecp_config(ppc, chipset_mode);
555 
556 	return (chipset_mode);
557 }
558 
559 /*
560  * Winbond W83877F stuff
561  *
562  * EFER: extended function enable register
563  * EFIR: extended function index register
564  * EFDR: extended function data register
565  */
566 #define efir ((efer == 0x250) ? 0x251 : 0x3f0)
567 #define efdr ((efer == 0x250) ? 0x252 : 0x3f1)
568 
569 static int w83877f_efers[] = { 0x250, 0x3f0, 0x3f0, 0x250 };
570 static int w83877f_keys[] = { 0x89, 0x86, 0x87, 0x88 };
571 static int w83877f_keyiter[] = { 1, 2, 2, 1 };
572 static int w83877f_hefs[] = { WINB_HEFERE, WINB_HEFRAS, WINB_HEFERE | WINB_HEFRAS, 0 };
573 
574 static int
575 ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode)
576 {
577 	int i, j, efer, base;
578 	unsigned char r, hefere, hefras;
579 
580 	for (i = 0; i < 4; i ++) {
581 		/* first try to enable configuration registers */
582 		efer = w83877f_efers[i];
583 
584 		/* write the key to the EFER */
585 		for (j = 0; j < w83877f_keyiter[i]; j ++)
586 			outb (efer, w83877f_keys[i]);
587 
588 		/* then check HEFERE and HEFRAS bits */
589 		outb (efir, 0x0c);
590 		hefere = inb(efdr) & WINB_HEFERE;
591 
592 		outb (efir, 0x16);
593 		hefras = inb(efdr) & WINB_HEFRAS;
594 
595 		/*
596 		 * HEFRAS	HEFERE
597 		 *   0		   1	write 89h to 250h (power-on default)
598 		 *   1		   0	write 86h twice to 3f0h
599 		 *   1		   1	write 87h twice to 3f0h
600 		 *   0		   0	write 88h to 250h
601 		 */
602 		if ((hefere | hefras) == w83877f_hefs[i])
603 			goto found;
604 	}
605 
606 	return (-1);	/* failed */
607 
608 found:
609 	/* check base port address - read from CR23 */
610 	outb(efir, 0x23);
611 	if (ppc->ppc_base != inb(efdr) * 4)		/* 4 bytes boundaries */
612 		return (-1);
613 
614 	/* read CHIP ID from CR9/bits0-3 */
615 	outb(efir, 0x9);
616 
617 	switch (inb(efdr) & WINB_CHIPID) {
618 		case WINB_W83877F_ID:
619 			ppc->ppc_type = WINB_W83877F;
620 			break;
621 
622 		case WINB_W83877AF_ID:
623 			ppc->ppc_type = WINB_W83877AF;
624 			break;
625 
626 		default:
627 			ppc->ppc_type = WINB_UNKNOWN;
628 	}
629 
630 	if (bootverbose) {
631 		/* dump of registers */
632 		printf("ppc%d: 0x%x - ", ppc->ppc_unit, w83877f_keys[i]);
633 		for (i = 0; i <= 0xd; i ++) {
634 			outb(efir, i);
635 			printf("0x%x ", inb(efdr));
636 		}
637 		for (i = 0x10; i <= 0x17; i ++) {
638 			outb(efir, i);
639 			printf("0x%x ", inb(efdr));
640 		}
641 		outb(efir, 0x1e);
642 		printf("0x%x ", inb(efdr));
643 		for (i = 0x20; i <= 0x29; i ++) {
644 			outb(efir, i);
645 			printf("0x%x ", inb(efdr));
646 		}
647 		printf("\n");
648 	}
649 
650 	if (!chipset_mode) {
651 		/* autodetect mode */
652 
653 		/* select CR0 */
654 		outb(efir, 0x0);
655 		r = inb(efdr) & (WINB_PRTMODS0 | WINB_PRTMODS1);
656 
657 		/* select CR9 */
658 		outb(efir, 0x9);
659 		r |= (inb(efdr) & WINB_PRTMODS2);
660 
661 		switch (r) {
662 		case WINB_W83757:
663 			if (bootverbose)
664 				printf("ppc%d: W83757 compatible mode\n",
665 					ppc->ppc_unit);
666 			return (-1);	/* generic or SMC-like */
667 
668 		case WINB_EXTFDC:
669 		case WINB_EXTADP:
670 		case WINB_EXT2FDD:
671 		case WINB_JOYSTICK:
672 			if (bootverbose)
673 				printf("ppc%d: not in parallel port mode\n",
674 					ppc->ppc_unit);
675 			return (-1);
676 
677 		case (WINB_PARALLEL | WINB_EPP_SPP):
678 			ppc->ppc_avm |= PPB_EPP | PPB_SPP;
679 			break;
680 
681 		case (WINB_PARALLEL | WINB_ECP):
682 			ppc->ppc_avm |= PPB_ECP | PPB_SPP;
683 			break;
684 
685 		case (WINB_PARALLEL | WINB_ECP_EPP):
686 			ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
687 			break;
688 		default:
689 			printf("%s: unknown case (0x%x)!\n", __FUNCTION__, r);
690 		}
691 
692 	} else {
693 		/* mode forced */
694 
695 		/* select CR9 and set PRTMODS2 bit */
696 		outb(efir, 0x9);
697 		outb(efdr, inb(efdr) & ~WINB_PRTMODS2);
698 
699 		/* select CR0 and reset PRTMODSx bits */
700 		outb(efir, 0x0);
701 		outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1));
702 
703 		if (chipset_mode & PPB_ECP) {
704 			if (chipset_mode & PPB_EPP)
705 				outb(efdr, inb(efdr) | WINB_ECP_EPP);
706 			else
707 				outb(efdr, inb(efdr) | WINB_ECP);
708 		} else {
709 			/* select EPP_SPP otherwise */
710 			outb(efdr, inb(efdr) | WINB_EPP_SPP);
711 		}
712 		ppc->ppc_avm = chipset_mode;
713 	}
714 
715 	/* exit configuration mode */
716 	outb(efer, 0xaa);
717 
718 	if (ppc->ppc_avm & PPB_ECP)
719 		ppc_ecp_config(ppc, chipset_mode);
720 
721 	return (chipset_mode);
722 }
723 
724 /*
725  * ppc_generic_detect
726  */
727 static int
728 ppc_generic_detect(struct ppc_data *ppc, int chipset_mode)
729 {
730 	char save_control;
731 
732 	if (!chipset_mode) {
733 		/* first, check for ECP */
734 		w_ecr(ppc, 0x20);
735 		if ((r_ecr(ppc) & 0xe0) == 0x20) {
736 			ppc->ppc_avm |= PPB_ECP | PPB_SPP;
737 
738 			/* search for SMC style ECP+EPP mode */
739 			w_ecr(ppc, 0x80);
740 		}
741 
742 		/* try to reset EPP timeout bit */
743 		if (ppc_check_epp_timeout(ppc)) {
744 			ppc->ppc_avm |= PPB_EPP;
745 
746 			if (ppc->ppc_avm & PPB_ECP)
747 				/* SMC like chipset found */
748 				ppc->ppc_type = SMC_LIKE;
749 		}
750 
751 		/* XXX try to detect NIBBLE mode */
752 		ppc->ppc_avm |= PPB_NIBBLE;
753 
754 	} else
755 		ppc->ppc_avm = chipset_mode;
756 
757 	if (ppc->ppc_avm & PPB_ECP)
758 		ppc_ecp_config(ppc, chipset_mode);
759 
760 	return (chipset_mode);
761 }
762 
763 /*
764  * ppc_detect()
765  *
766  * mode is the mode suggested at boot
767  */
768 static int
769 ppc_detect(struct ppc_data *ppc, int chipset_mode) {
770 
771 	int i, mode;
772 
773 	/* list of supported chipsets */
774 	int (*chipset_detect[])(struct ppc_data *, int) = {
775 		ppc_pc873xx_detect,
776 		ppc_smc37c66xgt_detect,
777 		ppc_w83877f_detect,
778 		ppc_generic_detect,
779 		NULL
780 	};
781 
782 	/* if can't find the port and mode not forced return error */
783 	if (!ppc_detect_port(ppc) && chipset_mode == 0)
784 		return (EIO);			/* failed, port not present */
785 
786 	/* assume centronics compatible mode is supported */
787 	ppc->ppc_avm = PPB_COMPATIBLE;
788 
789 	/* we have to differenciate available chipset modes,
790 	 * chipset running modes and IEEE-1284 operating modes
791 	 *
792 	 * after detection, the port must support running in compatible mode
793 	 */
794 	for (i=0; chipset_detect[i] != NULL; i++) {
795 		if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
796 			ppc->ppc_mode = mode;
797 			break;
798 		}
799 	}
800 
801 	return (0);
802 }
803 
804 /*
805  * ppc_exec_microseq()
806  *
807  * Execute a microsequence.
808  * Microsequence mechanism is supposed to handle fast I/O operations.
809  */
810 static int
811 ppc_exec_microseq(int unit, struct ppb_microseq *msq, int *ppbpc)
812 {
813 	struct ppc_data	*ppc = ppcdata[unit];
814 	struct ppb_microseq *pc;
815 	char cc, *p;
816 	int i, iter, reg;
817 	int error;
818 
819 	/* static to be reused after few ppc_exec_microseq()/return calls
820 	 * XXX should be in a context variable shared with ppb level */
821 	static int accum;
822 	static char *ptr;
823 
824 	struct ppb_microseq *microseq_stack = 0;
825 	struct ppb_microseq *pc_stack = 0;
826 
827 /* microsequence registers are equivalent to PC-like port registers */
828 #define r_reg(register,ppc) ((char)inb((ppc)->ppc_base + register))
829 #define w_reg(register,ppc,byte) outb((ppc)->ppc_base + register, byte)
830 
831 #define INCR_PC (pc ++)		/* increment program counter */
832 #define mi pc			/* microinstruction currently executed */
833 
834 	/* get the state of pc from ppb level of execution */
835 	pc = &msq[*ppbpc];
836 
837 	for (;;) {
838 
839 		switch (mi->opcode) {
840 		case MS_OP_RSET:
841 			cc = r_reg(mi->arg[0].i, ppc);
842 			cc &= mi->arg[2].c;		/* clear mask */
843 			cc |= mi->arg[1].c;		/* assert mask */
844                         w_reg(mi->arg[0].i, ppc, cc);
845 			INCR_PC;
846                         break;
847 
848 		case MS_OP_RASSERT_P:
849 			for (i=0; i<mi->arg[0].i; i++)
850 				w_reg(mi->arg[1].i, ppc, *ptr++);
851 			INCR_PC;
852 			break;
853 
854                 case MS_OP_RFETCH_P:
855 			for (i=0; i<mi->arg[0].i; i++)
856 				*ptr++ = r_reg(mi->arg[1].i, ppc) &
857 								mi->arg[2].c;
858 			INCR_PC;
859                         break;
860 
861                 case MS_OP_RFETCH:
862 			*((char *) mi->arg[2].p) = r_reg(mi->arg[0].i, ppc) &
863 							mi->arg[1].c;
864 			INCR_PC;
865                         break;
866 
867 		case MS_OP_RASSERT:
868 
869 		/* let's suppose the next instr. is the same */
870 		prefetch:
871 			for (;mi->opcode == MS_OP_RASSERT; INCR_PC)
872 				w_reg(mi->arg[0].i, ppc, mi->arg[1].c);
873 
874 			if (mi->opcode == MS_OP_DELAY) {
875 				DELAY(mi->arg[0].i);
876 				INCR_PC;
877 				goto prefetch;
878 			}
879 			break;
880 
881                 case MS_OP_DELAY:
882                         DELAY(mi->arg[0].i);
883 			INCR_PC;
884                         break;
885 
886 		case MS_OP_TRIG:
887 			reg = mi->arg[0].i;
888 			iter = mi->arg[1].i;
889 			p = (char *)mi->arg[2].p;
890 
891 			for (i=0; i<iter; i++) {
892 				w_reg(reg, ppc, *p++);
893 				DELAY((unsigned char)*p++);
894 			}
895 			INCR_PC;
896 			break;
897 
898                 case MS_OP_SET:
899                         accum = mi->arg[0].i;
900 			INCR_PC;
901                         break;
902 
903                 case MS_OP_DBRA:
904                         if (--accum > 0)
905                                 pc += mi->arg[0].i;
906 			else
907 				INCR_PC;
908                         break;
909 
910                 case MS_OP_BRSET:
911                         cc = r_str(ppc);
912                         if ((cc & mi->arg[0].c) == mi->arg[0].c)
913                                 pc += mi->arg[1].i;
914 			else
915 				INCR_PC;
916                         break;
917 
918                 case MS_OP_BRCLEAR:
919                         cc = r_str(ppc);
920                         if ((cc & mi->arg[0].c) == 0)
921                                 pc += mi->arg[1].i;
922 			else
923 				INCR_PC;
924                         break;
925 
926 		case MS_OP_C_CALL:
927 			/*
928 			 * If the C call returns !0 then end the microseq.
929 			 * The current state of ptr is passed to the C function
930 			 */
931 			if ((error = mi->arg[0].f(mi->arg[1].p, ptr)))
932 				return (error);
933 
934 			INCR_PC;
935 			break;
936 
937 		case MS_OP_PTR:
938 			ptr = (char *)mi->arg[0].p;
939 			INCR_PC;
940 			break;
941 
942 		case MS_OP_CALL:
943 			if (microseq_stack)
944 				panic("%s: too much calls", __FUNCTION__);
945 
946 			if (mi->arg[0].p) {
947 				/* store the state of the actual
948 				 * microsequence
949 				 */
950 				microseq_stack = msq;
951 				pc_stack = pc;
952 
953 				/* jump to the new microsequence */
954 				msq = (struct ppb_microseq *)mi->arg[0].p;
955 				pc = msq;
956 			} else
957 				INCR_PC;
958 
959 			break;
960 
961 		case MS_OP_SUBRET:
962 			/* retrieve microseq and pc state before the call */
963 			msq = microseq_stack;
964 			pc = pc_stack;
965 
966 			/* reset the stack */
967 			microseq_stack = 0;
968 
969 			/* XXX return code */
970 
971 			INCR_PC;
972 			break;
973 
974                 case MS_OP_PUT:
975                 case MS_OP_GET:
976                 case MS_OP_RET:
977 			/* can't return to ppb level during the execution
978 			 * of a submicrosequence */
979 			if (microseq_stack)
980 				panic("%s: can't return to ppb level",
981 								__FUNCTION__);
982 
983 			/* update pc for ppb level of execution */
984 			*ppbpc = (int)(pc - msq);
985 
986 			/* return to ppb level of execution */
987 			return (0);
988 
989                 default:
990                         panic("%s: unknown microsequence opcode 0x%x",
991                                 __FUNCTION__, mi->opcode);
992                 }
993 	}
994 
995 	/* unreached */
996 }
997 
998 /*
999  * Configure current operating mode
1000  */
1001 static int
1002 ppc_generic_setmode(int unit, int mode)
1003 {
1004 	struct ppc_data *ppc = ppcdata[unit];
1005 
1006 	/* back to compatible mode, XXX don't know yet what to do here */
1007 	if (mode == 0) {
1008 		ppc->ppc_mode = PPB_COMPATIBLE;
1009 		return (0);
1010 	}
1011 
1012 	/* check if mode is available */
1013 	if (!(ppc->ppc_avm & mode))
1014 		return (EOPNOTSUPP);
1015 
1016 	/* if ECP mode, configure ecr register */
1017 	if (ppc->ppc_avm & PPB_ECP)
1018 		ppc_ecp_config(ppc, mode);
1019 
1020 	ppc->ppc_mode = mode;
1021 
1022 	return (0);
1023 }
1024 
1025 /*
1026  * EPP timeout, according to the PC87332 manual
1027  * Semantics of clearing EPP timeout bit.
1028  * PC87332	- reading SPP_STR does it...
1029  * SMC		- write 1 to EPP timeout bit			XXX
1030  * Others	- (???) write 0 to EPP timeout bit
1031  */
1032 static void
1033 ppc_reset_epp_timeout(int unit)
1034 {
1035 	struct ppc_data *ppc = ppcdata[unit];
1036 	register char r;
1037 
1038 	r = r_str(ppc);
1039 	w_str(ppc, r | 0x1);
1040 	w_str(ppc, r & 0xfe);
1041 
1042 	return;
1043 }
1044 
1045 static int
1046 ppcprobe(struct isa_device *dvp)
1047 {
1048 	static short next_bios_ppc = 0;
1049 	struct ppc_data *ppc;
1050 	int error;
1051 
1052 	/*
1053 	 * If port not specified, use bios list.
1054 	 */
1055 	if(dvp->id_iobase < 0) {
1056 		if((next_bios_ppc < BIOS_MAX_PPC) &&
1057 				(*(BIOS_PORTS+next_bios_ppc) != 0) ) {
1058 			dvp->id_iobase = *(BIOS_PORTS+next_bios_ppc++);
1059 		} else
1060 			return (0);
1061 	}
1062 
1063 	/*
1064 	 * Port was explicitly specified.
1065 	 * This allows probing of ports unknown to the BIOS.
1066 	 */
1067 
1068 	/*
1069 	 * Allocate the ppc_data structure.
1070 	 */
1071 	ppc = malloc(sizeof(struct ppc_data), M_DEVBUF, M_NOWAIT);
1072 	if (!ppc) {
1073 		printf("ppc: cannot malloc!\n");
1074 		goto error;
1075 	}
1076 	bzero(ppc, sizeof(struct ppc_data));
1077 
1078 	ppc->ppc_base = dvp->id_iobase;
1079 	ppc->ppc_unit = dvp->id_unit;
1080 	ppc->ppc_type = GENERIC;
1081 
1082 	ppc->ppc_mode = PPB_COMPATIBLE;
1083 	ppc->ppc_epp = (dvp->id_flags & 0x10) >> 4;
1084 
1085 	/*
1086 	 * XXX
1087 	 * Try and detect if interrupts are working.
1088 	 */
1089 	if (!(dvp->id_flags & 0x20))
1090 		ppc->ppc_irq = (dvp->id_irq);
1091 
1092 	ppcdata[ppc->ppc_unit] = ppc;
1093 	nppc ++;
1094 
1095 	/*
1096 	 * Try to detect the chipset and its mode.
1097 	 */
1098 	if (ppc_detect(ppc, dvp->id_flags & 0xf))
1099 		goto error;
1100 
1101 end_probe:
1102 
1103 	return (1);
1104 
1105 error:
1106 	return (0);
1107 }
1108 
1109 static int
1110 ppcattach(struct isa_device *isdp)
1111 {
1112 	struct ppc_data *ppc = ppcdata[isdp->id_unit];
1113 	struct ppb_data *ppbus;
1114 	char * mode;
1115 
1116 	/*
1117 	 * Link the Parallel Port Chipset (adapter) to
1118 	 * the future ppbus.
1119 	 */
1120 	ppc->ppc_link.adapter_unit = ppc->ppc_unit;
1121 	ppc->ppc_link.adapter = &ppc_adapter;
1122 
1123 	printf("ppc%d: %s chipset (%s) in %s mode%s\n", ppc->ppc_unit,
1124 		ppc_types[ppc->ppc_type], ppc_avms[ppc->ppc_avm],
1125 		ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
1126 			ppc_epp_protocol[ppc->ppc_epp] : "");
1127 
1128 	/*
1129 	 * Prepare ppbus data area for upper level code.
1130 	 */
1131 	ppbus = ppb_alloc_bus();
1132 
1133 	if (!ppbus)
1134 		return (0);
1135 
1136 	ppc->ppc_link.ppbus = ppbus;
1137 	ppbus->ppb_link = &ppc->ppc_link;
1138 
1139 	/*
1140 	 * Probe the ppbus and attach devices found.
1141 	 */
1142 	ppb_attachdevs(ppbus);
1143 
1144 	return (1);
1145 }
1146 #endif
1147