ppc.c revision 38505
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.4 1998/08/03 19:14:32 msmith 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
51static int	ppcprobe(struct isa_device *);
52static int	ppcattach(struct isa_device *);
53
54struct isa_driver ppcdriver = {
55	ppcprobe, ppcattach, "ppc"
56};
57
58static struct ppc_data *ppcdata[NPPC];
59static int nppc = 0;
60
61static 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 */
67static 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 */
77static 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
84static 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 */
97static void ppc_outsb_epp(int unit, char *addr, int cnt) {
98	outsb(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
99static void ppc_outsw_epp(int unit, char *addr, int cnt) {
100	outsw(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
101static void ppc_outsl_epp(int unit, char *addr, int cnt) {
102	outsl(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
103static void ppc_insb_epp(int unit, char *addr, int cnt) {
104	insb(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
105static void ppc_insw_epp(int unit, char *addr, int cnt) {
106	insw(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
107static void ppc_insl_epp(int unit, char *addr, int cnt) {
108	insl(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
109
110static char ppc_rdtr(int unit) { return r_dtr(ppcdata[unit]); }
111static char ppc_rstr(int unit) { return r_str(ppcdata[unit]); }
112static char ppc_rctr(int unit) { return r_ctr(ppcdata[unit]); }
113static char ppc_repp(int unit) { return r_epp(ppcdata[unit]); }
114static char ppc_recr(int unit) { return r_ecr(ppcdata[unit]); }
115static char ppc_rfifo(int unit) { return r_fifo(ppcdata[unit]); }
116
117static void ppc_wdtr(int unit, char byte) { w_dtr(ppcdata[unit], byte); }
118static void ppc_wstr(int unit, char byte) { w_str(ppcdata[unit], byte); }
119static void ppc_wctr(int unit, char byte) { w_ctr(ppcdata[unit], byte); }
120static void ppc_wepp(int unit, char byte) { w_epp(ppcdata[unit], byte); }
121static void ppc_wecr(int unit, char byte) { w_ecr(ppcdata[unit], byte); }
122static void ppc_wfifo(int unit, char byte) { w_fifo(ppcdata[unit], byte); }
123
124static void ppc_reset_epp_timeout(int);
125static void ppc_ecp_sync(int);
126
127static int ppc_exec_microseq(int, struct ppb_microseq *, int *);
128static int ppc_generic_setmode(int, int);
129
130static 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 */
150static void
151ppc_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
173void
174ppcintr(int unit)
175{
176	/* call directly upper code */
177	ppb_intr(&ppcdata[unit]->ppc_link);
178
179	return;
180}
181
182static void
183ppc_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
199static int
200ppc_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 */
219static int pc873xx_basetab[] = {0x0398, 0x026e, 0x015c, 0x002e, 0};
220static int pc873xx_porttab[] = {0x0378, 0x03bc, 0x0278, 0};
221
222static int
223ppc_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
371static int
372ppc_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 */
384static int
385ppc_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
428config:
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", inb(cio) & 0xff);
453
454		outb(csr, 0x4);
455		printf(" CR4=0x%x", inb(cio) & 0xff);
456	}
457
458	/* select CR1 */
459	outb(csr, 0x1);
460
461	if (!chipset_mode) {
462		/* autodetect mode */
463
464		/* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
465		if (type == SMC_37C666GT) {
466			ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
467
468		} else
469		   if ((inb(cio) & SMC_CR1_MODE) == 0) {
470			/* already in extended parallel port mode, read CR4 */
471			outb(csr, 0x4);
472			r = (inb(cio) & SMC_CR4_EMODE);
473
474			switch (r) {
475			case SMC_SPP:
476				ppc->ppc_avm |= PPB_SPP;
477				break;
478
479			case SMC_EPPSPP:
480				ppc->ppc_avm |= PPB_EPP | PPB_SPP;
481				break;
482
483			case SMC_ECP:
484				ppc->ppc_avm |= PPB_ECP | PPB_SPP;
485				break;
486
487			case SMC_ECPEPP:
488				ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
489				break;
490			}
491		   } else {
492			/* not an extended port mode */
493			ppc->ppc_avm |= PPB_SPP;
494		   }
495
496	} else {
497		/* mode forced */
498
499		/* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
500		if (type == SMC_37C666GT)
501			goto end_detect;
502
503		r = inb(cio);
504		if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) {
505			/* do not use ECP when the mode is not forced to */
506			outb(cio, r | SMC_CR1_MODE);
507		} else {
508			/* an extended mode is selected */
509			outb(cio, r & ~SMC_CR1_MODE);
510
511			/* read CR4 register and reset mode field */
512			outb(csr, 0x4);
513			r = inb(cio) & ~SMC_CR4_EMODE;
514
515			if (chipset_mode & PPB_ECP) {
516				if (chipset_mode & PPB_EPP) {
517					outb(cio, r | SMC_ECPEPP);
518				} else {
519					outb(cio, r | SMC_ECP);
520				}
521			} else {
522				/* PPB_EPP is set */
523				outb(cio, r | SMC_EPPSPP);
524			}
525		}
526		ppc->ppc_avm = chipset_mode;
527	}
528
529end_detect:
530
531	if (bootverbose)
532		printf ("\n");
533
534	if (chipset_mode & PPB_EPP) {
535		/* select CR4 */
536		outb(csr, 0x4);
537		r = inb(cio);
538
539		/*
540		 * Set the EPP protocol...
541		 * Low=EPP 1.9 (1284 standard) and High=EPP 1.7
542		 */
543		if (ppc->ppc_epp == EPP_1_9)
544			outb(cio, (r & ~SMC_CR4_EPPTYPE));
545		else
546			outb(cio, (r | SMC_CR4_EPPTYPE));
547	}
548
549	/* end config mode */
550	outb(csr, 0xaa);
551
552	if (ppc->ppc_avm & PPB_ECP)
553		ppc_ecp_config(ppc, chipset_mode);
554
555	return (chipset_mode);
556}
557
558/*
559 * Winbond W83877F stuff
560 *
561 * EFER: extended function enable register
562 * EFIR: extended function index register
563 * EFDR: extended function data register
564 */
565#define efir ((efer == 0x250) ? 0x251 : 0x3f0)
566#define efdr ((efer == 0x250) ? 0x252 : 0x3f1)
567
568static int w83877f_efers[] = { 0x250, 0x3f0, 0x3f0, 0x250 };
569static int w83877f_keys[] = { 0x89, 0x86, 0x87, 0x88 };
570static int w83877f_keyiter[] = { 1, 2, 2, 1 };
571static int w83877f_hefs[] = { WINB_HEFERE, WINB_HEFRAS, WINB_HEFERE | WINB_HEFRAS, 0 };
572
573static int
574ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode)
575{
576	int i, j, efer, base;
577	unsigned char r, hefere, hefras;
578
579	for (i = 0; i < 4; i ++) {
580		/* first try to enable configuration registers */
581		efer = w83877f_efers[i];
582
583		/* write the key to the EFER */
584		for (j = 0; j < w83877f_keyiter[i]; j ++)
585			outb (efer, w83877f_keys[i]);
586
587		/* then check HEFERE and HEFRAS bits */
588		outb (efir, 0x0c);
589		hefere = inb(efdr) & WINB_HEFERE;
590
591		outb (efir, 0x16);
592		hefras = inb(efdr) & WINB_HEFRAS;
593
594		/*
595		 * HEFRAS	HEFERE
596		 *   0		   1	write 89h to 250h (power-on default)
597		 *   1		   0	write 86h twice to 3f0h
598		 *   1		   1	write 87h twice to 3f0h
599		 *   0		   0	write 88h to 250h
600		 */
601		if ((hefere | hefras) == w83877f_hefs[i])
602			goto found;
603	}
604
605	return (-1);	/* failed */
606
607found:
608	/* check base port address - read from CR23 */
609	outb(efir, 0x23);
610	if (ppc->ppc_base != inb(efdr) * 4)		/* 4 bytes boundaries */
611		return (-1);
612
613	/* read CHIP ID from CR9/bits0-3 */
614	outb(efir, 0x9);
615
616	switch (inb(efdr) & WINB_CHIPID) {
617		case WINB_W83877F_ID:
618			ppc->ppc_type = WINB_W83877F;
619			break;
620
621		case WINB_W83877AF_ID:
622			ppc->ppc_type = WINB_W83877AF;
623			break;
624
625		default:
626			ppc->ppc_type = WINB_UNKNOWN;
627	}
628
629	if (bootverbose) {
630		/* dump of registers */
631		printf("ppc%d: 0x%x - ", ppc->ppc_unit, w83877f_keys[i]);
632		for (i = 0; i <= 0xd; i ++) {
633			outb(efir, i);
634			printf("0x%x ", inb(efdr));
635		}
636		for (i = 0x10; i <= 0x17; i ++) {
637			outb(efir, i);
638			printf("0x%x ", inb(efdr));
639		}
640		outb(efir, 0x1e);
641		printf("0x%x ", inb(efdr));
642		for (i = 0x20; i <= 0x29; i ++) {
643			outb(efir, i);
644			printf("0x%x ", inb(efdr));
645		}
646		printf("\n");
647	}
648
649	if (!chipset_mode) {
650		/* autodetect mode */
651
652		/* select CR0 */
653		outb(efir, 0x0);
654		r = inb(efdr) & (WINB_PRTMODS0 | WINB_PRTMODS1);
655
656		/* select CR9 */
657		outb(efir, 0x9);
658		r |= (inb(efdr) & WINB_PRTMODS2);
659
660		switch (r) {
661		case WINB_W83757:
662			if (bootverbose)
663				printf("ppc%d: W83757 compatible mode\n",
664					ppc->ppc_unit);
665			return (-1);	/* generic or SMC-like */
666
667		case WINB_EXTFDC:
668		case WINB_EXTADP:
669		case WINB_EXT2FDD:
670		case WINB_JOYSTICK:
671			if (bootverbose)
672				printf("ppc%d: not in parallel port mode\n",
673					ppc->ppc_unit);
674			return (-1);
675
676		case (WINB_PARALLEL | WINB_EPP_SPP):
677			ppc->ppc_avm |= PPB_EPP | PPB_SPP;
678			break;
679
680		case (WINB_PARALLEL | WINB_ECP):
681			ppc->ppc_avm |= PPB_ECP | PPB_SPP;
682			break;
683
684		case (WINB_PARALLEL | WINB_ECP_EPP):
685			ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
686			break;
687		default:
688			printf("%s: unknown case (0x%x)!\n", __FUNCTION__, r);
689		}
690
691	} else {
692		/* mode forced */
693
694		/* select CR9 and set PRTMODS2 bit */
695		outb(efir, 0x9);
696		outb(efdr, inb(efdr) & ~WINB_PRTMODS2);
697
698		/* select CR0 and reset PRTMODSx bits */
699		outb(efir, 0x0);
700		outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1));
701
702		if (chipset_mode & PPB_ECP) {
703			if (chipset_mode & PPB_EPP)
704				outb(efdr, inb(efdr) | WINB_ECP_EPP);
705			else
706				outb(efdr, inb(efdr) | WINB_ECP);
707		} else {
708			/* select EPP_SPP otherwise */
709			outb(efdr, inb(efdr) | WINB_EPP_SPP);
710		}
711		ppc->ppc_avm = chipset_mode;
712	}
713
714	/* exit configuration mode */
715	outb(efer, 0xaa);
716
717	if (ppc->ppc_avm & PPB_ECP)
718		ppc_ecp_config(ppc, chipset_mode);
719
720	return (chipset_mode);
721}
722
723/*
724 * ppc_generic_detect
725 */
726static int
727ppc_generic_detect(struct ppc_data *ppc, int chipset_mode)
728{
729	char save_control;
730
731	if (!chipset_mode) {
732		/* first, check for ECP */
733		w_ecr(ppc, 0x20);
734		if ((r_ecr(ppc) & 0xe0) == 0x20) {
735			ppc->ppc_avm |= PPB_ECP | PPB_SPP;
736
737			/* search for SMC style ECP+EPP mode */
738			w_ecr(ppc, 0x80);
739		}
740
741		/* try to reset EPP timeout bit */
742		if (ppc_check_epp_timeout(ppc)) {
743			ppc->ppc_avm |= PPB_EPP;
744
745			if (ppc->ppc_avm & PPB_ECP)
746				/* SMC like chipset found */
747				ppc->ppc_type = SMC_LIKE;
748		}
749
750		/* XXX try to detect NIBBLE mode */
751		ppc->ppc_avm |= PPB_NIBBLE;
752
753	} else
754		ppc->ppc_avm = chipset_mode;
755
756	if (ppc->ppc_avm & PPB_ECP)
757		ppc_ecp_config(ppc, chipset_mode);
758
759	return (chipset_mode);
760}
761
762/*
763 * ppc_detect()
764 *
765 * mode is the mode suggested at boot
766 */
767static int
768ppc_detect(struct ppc_data *ppc, int chipset_mode) {
769
770	int i, mode;
771
772	/* list of supported chipsets */
773	int (*chipset_detect[])(struct ppc_data *, int) = {
774		ppc_pc873xx_detect,
775		ppc_smc37c66xgt_detect,
776		ppc_w83877f_detect,
777		ppc_generic_detect,
778		NULL
779	};
780
781	/* if can't find the port and mode not forced return error */
782	if (!ppc_detect_port(ppc) && chipset_mode == 0)
783		return (EIO);			/* failed, port not present */
784
785	/* assume centronics compatible mode is supported */
786	ppc->ppc_avm = PPB_COMPATIBLE;
787
788	/* we have to differenciate available chipset modes,
789	 * chipset running modes and IEEE-1284 operating modes
790	 *
791	 * after detection, the port must support running in compatible mode
792	 */
793	for (i=0; chipset_detect[i] != NULL; i++) {
794		if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
795			ppc->ppc_mode = mode;
796			break;
797		}
798	}
799
800	return (0);
801}
802
803/*
804 * ppc_exec_microseq()
805 *
806 * Execute a microsequence.
807 * Microsequence mechanism is supposed to handle fast I/O operations.
808 */
809static int
810ppc_exec_microseq(int unit, struct ppb_microseq *msq, int *ppbpc)
811{
812	struct ppc_data	*ppc = ppcdata[unit];
813	struct ppb_microseq *pc;
814	char cc, *p;
815	int i, iter, reg;
816	int error;
817
818	/* static to be reused after few ppc_exec_microseq()/return calls
819	 * XXX should be in a context variable shared with ppb level */
820	static int accum;
821	static char *ptr;
822
823	struct ppb_microseq *microseq_stack = 0;
824	struct ppb_microseq *pc_stack = 0;
825
826/* microsequence registers are equivalent to PC-like port registers */
827#define r_reg(register,ppc) ((char)inb((ppc)->ppc_base + register))
828#define w_reg(register,ppc,byte) outb((ppc)->ppc_base + register, byte)
829
830#define INCR_PC (pc ++)		/* increment program counter */
831#define mi pc			/* microinstruction currently executed */
832
833	/* get the state of pc from ppb level of execution */
834	pc = &msq[*ppbpc];
835
836	for (;;) {
837
838		switch (mi->opcode) {
839		case MS_OP_RSET:
840			cc = r_reg(mi->arg[0].i, ppc);
841			cc &= mi->arg[2].c;		/* clear mask */
842			cc |= mi->arg[1].c;		/* assert mask */
843                        w_reg(mi->arg[0].i, ppc, cc);
844			INCR_PC;
845                        break;
846
847		case MS_OP_RASSERT_P:
848			for (i=0; i<mi->arg[0].i; i++)
849				w_reg(mi->arg[1].i, ppc, *ptr++);
850			INCR_PC;
851			break;
852
853                case MS_OP_RFETCH_P:
854			for (i=0; i<mi->arg[0].i; i++)
855				*ptr++ = r_reg(mi->arg[1].i, ppc) &
856								mi->arg[2].c;
857			INCR_PC;
858                        break;
859
860                case MS_OP_RFETCH:
861			*((char *) mi->arg[2].p) = r_reg(mi->arg[0].i, ppc) &
862							mi->arg[1].c;
863			INCR_PC;
864                        break;
865
866		case MS_OP_RASSERT:
867
868		/* let's suppose the next instr. is the same */
869		prefetch:
870			for (;mi->opcode == MS_OP_RASSERT; INCR_PC)
871				w_reg(mi->arg[0].i, ppc, mi->arg[1].c);
872
873			if (mi->opcode == MS_OP_DELAY) {
874				DELAY(mi->arg[0].i);
875				INCR_PC;
876				goto prefetch;
877			}
878			break;
879
880                case MS_OP_DELAY:
881                        DELAY(mi->arg[0].i);
882			INCR_PC;
883                        break;
884
885		case MS_OP_TRIG:
886			reg = mi->arg[0].i;
887			iter = mi->arg[1].i;
888			p = (char *)mi->arg[2].p;
889
890			for (i=0; i<iter; i++) {
891				w_reg(reg, ppc, *p++);
892				DELAY((unsigned char)*p++);
893			}
894			INCR_PC;
895			break;
896
897                case MS_OP_SET:
898                        accum = mi->arg[0].i;
899			INCR_PC;
900                        break;
901
902                case MS_OP_DBRA:
903                        if (--accum > 0)
904                                pc += mi->arg[0].i;
905			else
906				INCR_PC;
907                        break;
908
909                case MS_OP_BRSET:
910                        cc = r_str(ppc);
911                        if ((cc & mi->arg[0].c) == mi->arg[0].c)
912                                pc += mi->arg[1].i;
913			else
914				INCR_PC;
915                        break;
916
917                case MS_OP_BRCLEAR:
918                        cc = r_str(ppc);
919                        if ((cc & mi->arg[0].c) == 0)
920                                pc += mi->arg[1].i;
921			else
922				INCR_PC;
923                        break;
924
925		case MS_OP_C_CALL:
926			/*
927			 * If the C call returns !0 then end the microseq.
928			 * The current state of ptr is passed to the C function
929			 */
930			if ((error = mi->arg[0].f(mi->arg[1].p, ptr)))
931				return (error);
932
933			INCR_PC;
934			break;
935
936		case MS_OP_PTR:
937			ptr = (char *)mi->arg[0].p;
938			INCR_PC;
939			break;
940
941		case MS_OP_CALL:
942			if (microseq_stack)
943				panic("%s: too much calls", __FUNCTION__);
944
945			if (mi->arg[0].p) {
946				/* store the state of the actual
947				 * microsequence
948				 */
949				microseq_stack = msq;
950				pc_stack = pc;
951
952				/* jump to the new microsequence */
953				msq = (struct ppb_microseq *)mi->arg[0].p;
954				pc = msq;
955			} else
956				INCR_PC;
957
958			break;
959
960		case MS_OP_SUBRET:
961			/* retrieve microseq and pc state before the call */
962			msq = microseq_stack;
963			pc = pc_stack;
964
965			/* reset the stack */
966			microseq_stack = 0;
967
968			/* XXX return code */
969
970			INCR_PC;
971			break;
972
973                case MS_OP_PUT:
974                case MS_OP_GET:
975                case MS_OP_RET:
976			/* can't return to ppb level during the execution
977			 * of a submicrosequence */
978			if (microseq_stack)
979				panic("%s: can't return to ppb level",
980								__FUNCTION__);
981
982			/* update pc for ppb level of execution */
983			*ppbpc = (int)(pc - msq);
984
985			/* return to ppb level of execution */
986			return (0);
987
988                default:
989                        panic("%s: unknown microsequence opcode 0x%x",
990                                __FUNCTION__, mi->opcode);
991                }
992	}
993
994	/* unreached */
995}
996
997/*
998 * Configure current operating mode
999 */
1000static int
1001ppc_generic_setmode(int unit, int mode)
1002{
1003	struct ppc_data *ppc = ppcdata[unit];
1004
1005	/* back to compatible mode, XXX don't know yet what to do here */
1006	if (mode == 0) {
1007		ppc->ppc_mode = PPB_COMPATIBLE;
1008		return (0);
1009	}
1010
1011	/* check if mode is available */
1012	if (!(ppc->ppc_avm & mode))
1013		return (EOPNOTSUPP);
1014
1015	/* if ECP mode, configure ecr register */
1016	if (ppc->ppc_avm & PPB_ECP)
1017		ppc_ecp_config(ppc, mode);
1018
1019	ppc->ppc_mode = mode;
1020
1021	return (0);
1022}
1023
1024/*
1025 * EPP timeout, according to the PC87332 manual
1026 * Semantics of clearing EPP timeout bit.
1027 * PC87332	- reading SPP_STR does it...
1028 * SMC		- write 1 to EPP timeout bit			XXX
1029 * Others	- (???) write 0 to EPP timeout bit
1030 */
1031static void
1032ppc_reset_epp_timeout(int unit)
1033{
1034	struct ppc_data *ppc = ppcdata[unit];
1035	register char r;
1036
1037	r = r_str(ppc);
1038	w_str(ppc, r | 0x1);
1039	w_str(ppc, r & 0xfe);
1040
1041	return;
1042}
1043
1044static int
1045ppcprobe(struct isa_device *dvp)
1046{
1047	static short next_bios_ppc = 0;
1048	struct ppc_data *ppc;
1049	int error;
1050
1051	/*
1052	 * If port not specified, use bios list.
1053	 */
1054	if(dvp->id_iobase < 0) {
1055		if((next_bios_ppc < BIOS_MAX_PPC) &&
1056				(*(BIOS_PORTS+next_bios_ppc) != 0) ) {
1057			dvp->id_iobase = *(BIOS_PORTS+next_bios_ppc++);
1058		} else
1059			return (0);
1060	}
1061
1062	/*
1063	 * Port was explicitly specified.
1064	 * This allows probing of ports unknown to the BIOS.
1065	 */
1066
1067	/*
1068	 * Allocate the ppc_data structure.
1069	 */
1070	ppc = malloc(sizeof(struct ppc_data), M_DEVBUF, M_NOWAIT);
1071	if (!ppc) {
1072		printf("ppc: cannot malloc!\n");
1073		goto error;
1074	}
1075	bzero(ppc, sizeof(struct ppc_data));
1076
1077	ppc->ppc_base = dvp->id_iobase;
1078	ppc->ppc_unit = dvp->id_unit;
1079	ppc->ppc_type = GENERIC;
1080
1081	ppc->ppc_mode = PPB_COMPATIBLE;
1082	ppc->ppc_epp = (dvp->id_flags & 0x10) >> 4;
1083
1084	/*
1085	 * XXX
1086	 * Try and detect if interrupts are working.
1087	 */
1088	if (!(dvp->id_flags & 0x20))
1089		ppc->ppc_irq = (dvp->id_irq);
1090
1091	ppcdata[ppc->ppc_unit] = ppc;
1092	nppc ++;
1093
1094	/*
1095	 * Try to detect the chipset and its mode.
1096	 */
1097	if (ppc_detect(ppc, dvp->id_flags & 0xf))
1098		goto error;
1099
1100end_probe:
1101
1102	return (1);
1103
1104error:
1105	return (0);
1106}
1107
1108static int
1109ppcattach(struct isa_device *isdp)
1110{
1111	struct ppc_data *ppc = ppcdata[isdp->id_unit];
1112	struct ppb_data *ppbus;
1113	char * mode;
1114
1115	/*
1116	 * Link the Parallel Port Chipset (adapter) to
1117	 * the future ppbus.
1118	 */
1119	ppc->ppc_link.adapter_unit = ppc->ppc_unit;
1120	ppc->ppc_link.adapter = &ppc_adapter;
1121
1122	printf("ppc%d: %s chipset (%s) in %s mode%s\n", ppc->ppc_unit,
1123		ppc_types[ppc->ppc_type], ppc_avms[ppc->ppc_avm],
1124		ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
1125			ppc_epp_protocol[ppc->ppc_epp] : "");
1126
1127	/*
1128	 * Prepare ppbus data area for upper level code.
1129	 */
1130	ppbus = ppb_alloc_bus();
1131
1132	if (!ppbus)
1133		return (0);
1134
1135	ppc->ppc_link.ppbus = ppbus;
1136	ppbus->ppb_link = &ppc->ppc_link;
1137
1138	/*
1139	 * Probe the ppbus and attach devices found.
1140	 */
1141	ppb_attachdevs(ppbus);
1142
1143	return (1);
1144}
1145#endif
1146