ppc.c revision 38061
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
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", 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
530end_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
569static int w83877f_efers[] = { 0x250, 0x3f0, 0x3f0, 0x250 };
570static int w83877f_keys[] = { 0x89, 0x86, 0x87, 0x88 };
571static int w83877f_keyiter[] = { 1, 2, 2, 1 };
572static int w83877f_hefs[] = { WINB_HEFERE, WINB_HEFRAS, WINB_HEFERE | WINB_HEFRAS, 0 };
573
574static int
575ppc_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
608found:
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 */
727static int
728ppc_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 */
768static int
769ppc_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 */
810static int
811ppc_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 */
1001static int
1002ppc_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 */
1032static void
1033ppc_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
1045static int
1046ppcprobe(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
1101end_probe:
1102
1103	return (1);
1104
1105error:
1106	return (0);
1107}
1108
1109static int
1110ppcattach(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