xref: /netbsd-src/sys/arch/sparc/dev/zs.c (revision d20841bb642898112fe68f0ad3f7b26dddf56f07)
1 /*	$NetBSD: zs.c,v 1.99 2004/02/13 11:36:17 wiz Exp $	*/
2 
3 /*-
4  * Copyright (c) 1996 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Gordon W. Ross.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Zilog Z8530 Dual UART driver (machine-dependent part)
41  *
42  * Runs two serial lines per chip using slave drivers.
43  * Plain tty/async lines use the zs_async slave.
44  * Sun keyboard/mouse uses the zs_kbd/zs_ms slaves.
45  */
46 
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.99 2004/02/13 11:36:17 wiz Exp $");
49 
50 #include "opt_ddb.h"
51 #include "opt_kgdb.h"
52 #include "opt_sparc_arch.h"
53 
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/conf.h>
57 #include <sys/device.h>
58 #include <sys/file.h>
59 #include <sys/ioctl.h>
60 #include <sys/kernel.h>
61 #include <sys/proc.h>
62 #include <sys/tty.h>
63 #include <sys/time.h>
64 #include <sys/syslog.h>
65 
66 #include <machine/bsd_openprom.h>
67 #include <machine/autoconf.h>
68 #include <machine/intr.h>
69 #include <machine/eeprom.h>
70 #include <machine/psl.h>
71 #include <machine/z8530var.h>
72 
73 #include <dev/cons.h>
74 #include <dev/ic/z8530reg.h>
75 
76 #include <sparc/sparc/vaddrs.h>
77 #include <sparc/sparc/auxreg.h>
78 #include <sparc/sparc/auxiotwo.h>
79 #include <sparc/dev/cons.h>
80 
81 #include "kbd.h"	/* NKBD */
82 #include "zs.h" 	/* NZS */
83 
84 /* Make life easier for the initialized arrays here. */
85 #if NZS < 3
86 #undef  NZS
87 #define NZS 3
88 #endif
89 
90 /*
91  * Some warts needed by z8530tty.c -
92  * The default parity REALLY needs to be the same as the PROM uses,
93  * or you can not see messages done with printf during boot-up...
94  */
95 int zs_def_cflag = (CREAD | CS8 | HUPCL);
96 
97 /*
98  * The Sun provides a 4.9152 MHz clock to the ZS chips.
99  */
100 #define PCLK	(9600 * 512)	/* PCLK pin input clock rate */
101 
102 #define	ZS_DELAY()		(CPU_ISSUN4C ? (0) : delay(2))
103 
104 /* The layout of this is hardware-dependent (padding, order). */
105 struct zschan {
106 	volatile u_char	zc_csr;		/* ctrl,status, and indirect access */
107 	u_char		zc_xxx0;
108 	volatile u_char	zc_data;	/* data */
109 	u_char		zc_xxx1;
110 };
111 struct zsdevice {
112 	/* Yes, they are backwards. */
113 	struct	zschan zs_chan_b;
114 	struct	zschan zs_chan_a;
115 };
116 
117 /* ZS channel used as the console device (if any) */
118 void *zs_conschan_get, *zs_conschan_put;
119 
120 static u_char zs_init_reg[16] = {
121 	0,	/* 0: CMD (reset, etc.) */
122 	0,	/* 1: No interrupts yet. */
123 	0,	/* 2: IVECT */
124 	ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
125 	ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP,
126 	ZSWR5_TX_8 | ZSWR5_TX_ENABLE,
127 	0,	/* 6: TXSYNC/SYNCLO */
128 	0,	/* 7: RXSYNC/SYNCHI */
129 	0,	/* 8: alias for data port */
130 	ZSWR9_MASTER_IE | ZSWR9_NO_VECTOR,
131 	0,	/*10: Misc. TX/RX control bits */
132 	ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
133 	((PCLK/32)/9600)-2,	/*12: BAUDLO (default=9600) */
134 	0,			/*13: BAUDHI (default=9600) */
135 	ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK,
136 	ZSWR15_BREAK_IE,
137 };
138 
139 /* Console ops */
140 static int  zscngetc __P((dev_t));
141 static void zscnputc __P((dev_t, int));
142 static void zscnpollc __P((dev_t, int));
143 
144 struct consdev zs_consdev = {
145 	NULL,
146 	NULL,
147 	zscngetc,
148 	zscnputc,
149 	zscnpollc,
150 	NULL,
151 };
152 
153 
154 /****************************************************************
155  * Autoconfig
156  ****************************************************************/
157 
158 /* Definition of the driver for autoconfig. */
159 static int  zs_match_mainbus __P((struct device *, struct cfdata *, void *));
160 static int  zs_match_obio __P((struct device *, struct cfdata *, void *));
161 static void zs_attach_mainbus __P((struct device *, struct device *, void *));
162 static void zs_attach_obio __P((struct device *, struct device *, void *));
163 
164 #if defined(SUN4D)
165 #include <sparc/dev/bootbusvar.h>
166 
167 static int  zs_match_bootbus __P((struct device *, struct cfdata *, void *));
168 static void zs_attach_bootbus __P((struct device *, struct device *, void *));
169 
170 CFATTACH_DECL(zs_bootbus, sizeof(struct zsc_softc),
171     zs_match_bootbus, zs_attach_bootbus, NULL, NULL);
172 #endif /* SUN4D */
173 
174 static void zs_attach __P((struct zsc_softc *, struct zsdevice *, int));
175 static int  zs_print __P((void *, const char *name));
176 
177 CFATTACH_DECL(zs_mainbus, sizeof(struct zsc_softc),
178     zs_match_mainbus, zs_attach_mainbus, NULL, NULL);
179 
180 CFATTACH_DECL(zs_obio, sizeof(struct zsc_softc),
181     zs_match_obio, zs_attach_obio, NULL, NULL);
182 
183 extern struct cfdriver zs_cd;
184 
185 /* softintr(9) cookie, shared by all instances of this driver */
186 static void *zs_sicookie;
187 
188 /* Interrupt handlers. */
189 static int zshard __P((void *));
190 static void zssoft __P((void *));
191 
192 static int zs_get_speed __P((struct zs_chanstate *));
193 
194 /* Console device support */
195 static int zs_console_flags __P((int, int, int));
196 
197 /* Power management hooks */
198 int  zs_enable __P((struct zs_chanstate *));
199 void zs_disable __P((struct zs_chanstate *));
200 
201 
202 /*
203  * Is the zs chip present?
204  */
205 static int
206 zs_match_mainbus(parent, cf, aux)
207 	struct device *parent;
208 	struct cfdata *cf;
209 	void *aux;
210 {
211 	struct mainbus_attach_args *ma = aux;
212 
213 	if (strcmp(cf->cf_name, ma->ma_name) != 0)
214 		return (0);
215 
216 	return (1);
217 }
218 
219 static int
220 zs_match_obio(parent, cf, aux)
221 	struct device *parent;
222 	struct cfdata *cf;
223 	void *aux;
224 {
225 	union obio_attach_args *uoba = aux;
226 	struct obio4_attach_args *oba;
227 
228 	if (uoba->uoba_isobio4 == 0) {
229 		struct sbus_attach_args *sa = &uoba->uoba_sbus;
230 
231 		if (strcmp(cf->cf_name, sa->sa_name) != 0)
232 			return (0);
233 
234 		return (1);
235 	}
236 
237 	oba = &uoba->uoba_oba4;
238 	return (bus_space_probe(oba->oba_bustag, oba->oba_paddr,
239 			        1, 0, 0, NULL, NULL));
240 }
241 
242 #if defined(SUN4D)
243 static int
244 zs_match_bootbus(parent, cf, aux)
245 	struct device *parent;
246 	struct cfdata *cf;
247 	void *aux;
248 {
249 	struct bootbus_attach_args *baa = aux;
250 
251 	return (strcmp(cf->cf_name, baa->ba_name) == 0);
252 }
253 #endif /* SUN4D */
254 
255 static void
256 zs_attach_mainbus(parent, self, aux)
257 	struct device *parent;
258 	struct device *self;
259 	void *aux;
260 {
261 	struct zsc_softc *zsc = (void *) self;
262 	struct mainbus_attach_args *ma = aux;
263 
264 	zsc->zsc_bustag = ma->ma_bustag;
265 	zsc->zsc_dmatag = ma->ma_dmatag;
266 	zsc->zsc_promunit = PROM_getpropint(ma->ma_node, "slave", -2);
267 	zsc->zsc_node = ma->ma_node;
268 
269 	/*
270 	 * For machines with zs on mainbus (all sun4c models), we expect
271 	 * the device registers to be mapped by the PROM.
272 	 */
273 	zs_attach(zsc, ma->ma_promvaddr, ma->ma_pri);
274 }
275 
276 static void
277 zs_attach_obio(parent, self, aux)
278 	struct device *parent;
279 	struct device *self;
280 	void *aux;
281 {
282 	struct zsc_softc *zsc = (void *) self;
283 	union obio_attach_args *uoba = aux;
284 
285 	if (uoba->uoba_isobio4 == 0) {
286 		struct sbus_attach_args *sa = &uoba->uoba_sbus;
287 		void *va;
288 		struct zs_chanstate *cs;
289 		int channel;
290 
291 		if (sa->sa_nintr == 0) {
292 			printf(" no interrupt lines\n");
293 			return;
294 		}
295 
296 		/*
297 		 * Some sun4m models (Javastations) may not map the zs device.
298 		 */
299 		if (sa->sa_npromvaddrs > 0)
300 			va = (void *)sa->sa_promvaddr;
301 		else {
302 			bus_space_handle_t bh;
303 
304 			if (sbus_bus_map(sa->sa_bustag,
305 					 sa->sa_slot,
306 					 sa->sa_offset,
307 					 sa->sa_size,
308 					 BUS_SPACE_MAP_LINEAR, &bh) != 0) {
309 				printf(" cannot map zs registers\n");
310 				return;
311 			}
312 			va = (void *)bh;
313 		}
314 
315 		/*
316 		 * Check if power state can be set, e.g. Tadpole 3GX
317 		 */
318 		if (PROM_getpropint(sa->sa_node, "pwr-on-auxio2", 0))
319 		{
320 			printf (" powered via auxio2");
321 			for (channel = 0; channel < 2; channel++) {
322 				cs = &zsc->zsc_cs_store[channel];
323 				cs->enable = zs_enable;
324 				cs->disable = zs_disable;
325 			}
326 		}
327 
328 		zsc->zsc_bustag = sa->sa_bustag;
329 		zsc->zsc_dmatag = sa->sa_dmatag;
330 		zsc->zsc_promunit = PROM_getpropint(sa->sa_node, "slave", -2);
331 		zsc->zsc_node = sa->sa_node;
332 		zs_attach(zsc, va, sa->sa_pri);
333 	} else {
334 		struct obio4_attach_args *oba = &uoba->uoba_oba4;
335 		bus_space_handle_t bh;
336 		bus_addr_t paddr = oba->oba_paddr;
337 
338 		/*
339 		 * As for zs on mainbus, we require a PROM mapping.
340 		 */
341 		if (bus_space_map(oba->oba_bustag,
342 				  paddr,
343 				  sizeof(struct zsdevice),
344 				  BUS_SPACE_MAP_LINEAR | OBIO_BUS_MAP_USE_ROM,
345 				  &bh) != 0) {
346 			printf(" cannot map zs registers\n");
347 			return;
348 		}
349 		zsc->zsc_bustag = oba->oba_bustag;
350 		zsc->zsc_dmatag = oba->oba_dmatag;
351 		/*
352 		 * Find prom unit by physical address
353 		 * We're just comparing the address (not the iospace) here
354 		 */
355 		paddr = BUS_ADDR_PADDR(paddr);
356 		if (cpuinfo.cpu_type == CPUTYP_4_100)
357 			/*
358 			 * On the sun4/100, the top-most 4 bits are zero
359 			 * on obio addresses; force them to 1's for the
360 			 * sake of the comparison here.
361 			 */
362 			paddr |= 0xf0000000;
363 		zsc->zsc_promunit =
364 			(paddr == 0xf1000000) ? 0 :
365 			(paddr == 0xf0000000) ? 1 :
366 			(paddr == 0xe0000000) ? 2 : -2;
367 
368 		zs_attach(zsc, (void *)bh, oba->oba_pri);
369 	}
370 }
371 
372 #if defined(SUN4D)
373 static void
374 zs_attach_bootbus(parent, self, aux)
375 	struct device *parent;
376 	struct device *self;
377 	void *aux;
378 {
379 	struct zsc_softc *zsc = (void *) self;
380 	struct bootbus_attach_args *baa = aux;
381 	void *va;
382 
383 	if (baa->ba_nintr == 0) {
384 		printf(": no interrupt lines\n");
385 		return;
386 	}
387 
388 	if (baa->ba_npromvaddrs > 0)
389 		va = (void *) baa->ba_promvaddrs;
390 	else {
391 		bus_space_handle_t bh;
392 
393 		if (bus_space_map(baa->ba_bustag,
394 		    BUS_ADDR(baa->ba_slot, baa->ba_offset),
395 		    baa->ba_size, BUS_SPACE_MAP_LINEAR, &bh) != 0) {
396 			printf(": cannot map zs registers\n");
397 			return;
398 		}
399 		va = (void *) bh;
400 	}
401 
402 	zsc->zsc_bustag = baa->ba_bustag;
403 	zsc->zsc_promunit = PROM_getpropint(baa->ba_node, "slave", -2);
404 	zsc->zsc_node = baa->ba_node;
405 	zs_attach(zsc, va, baa->ba_intr[0].oi_pri);
406 }
407 #endif /* SUN4D */
408 
409 /*
410  * Attach a found zs.
411  *
412  * USE ROM PROPERTIES port-a-ignore-cd AND port-b-ignore-cd FOR
413  * SOFT CARRIER, AND keyboard PROPERTY FOR KEYBOARD/MOUSE?
414  */
415 static void
416 zs_attach(zsc, zsd, pri)
417 	struct zsc_softc *zsc;
418 	struct zsdevice *zsd;
419 	int pri;
420 {
421 	struct zsc_attach_args zsc_args;
422 	struct zs_chanstate *cs;
423 	int s, channel;
424 	static int didintr, prevpri;
425 
426 	if (zsd == NULL) {
427 		printf("configuration incomplete\n");
428 		return;
429 	}
430 
431 	if (!didintr) {
432 		zs_sicookie = softintr_establish(IPL_SOFTSERIAL, zssoft, NULL);
433 		if (zs_sicookie == NULL) {
434 			printf("\n%s: cannot establish soft int handler\n",
435 				zsc->zsc_dev.dv_xname);
436 			return;
437 		}
438 	}
439 	printf(" softpri %d\n", IPL_SOFTSERIAL);
440 
441 	/*
442 	 * Initialize software state for each channel.
443 	 */
444 	for (channel = 0; channel < 2; channel++) {
445 		struct zschan *zc;
446 
447 		zsc_args.channel = channel;
448 		cs = &zsc->zsc_cs_store[channel];
449 		zsc->zsc_cs[channel] = cs;
450 
451 		simple_lock_init(&cs->cs_lock);
452 		cs->cs_channel = channel;
453 		cs->cs_private = NULL;
454 		cs->cs_ops = &zsops_null;
455 		cs->cs_brg_clk = PCLK / 16;
456 
457 		zc = (channel == 0) ? &zsd->zs_chan_a : &zsd->zs_chan_b;
458 
459 		zsc_args.hwflags = zs_console_flags(zsc->zsc_promunit,
460 						    zsc->zsc_node,
461 						    channel);
462 
463 		if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) {
464 			zsc_args.hwflags |= ZS_HWFLAG_USE_CONSDEV;
465 			zsc_args.consdev = &zs_consdev;
466 		}
467 
468 		if ((zsc_args.hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) {
469 			zs_conschan_get = zc;
470 		}
471 		if ((zsc_args.hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) {
472 			zs_conschan_put = zc;
473 		}
474 		/* Childs need to set cn_dev, etc */
475 
476 		cs->cs_reg_csr  = &zc->zc_csr;
477 		cs->cs_reg_data = &zc->zc_data;
478 
479 		bcopy(zs_init_reg, cs->cs_creg, 16);
480 		bcopy(zs_init_reg, cs->cs_preg, 16);
481 
482 		/* XXX: Consult PROM properties for this?! */
483 		cs->cs_defspeed = zs_get_speed(cs);
484 		cs->cs_defcflag = zs_def_cflag;
485 
486 		/* Make these correspond to cs_defcflag (-crtscts) */
487 		cs->cs_rr0_dcd = ZSRR0_DCD;
488 		cs->cs_rr0_cts = 0;
489 		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
490 		cs->cs_wr5_rts = 0;
491 
492 		/*
493 		 * Clear the master interrupt enable.
494 		 * The INTENA is common to both channels,
495 		 * so just do it on the A channel.
496 		 */
497 		if (channel == 0) {
498 			zs_write_reg(cs, 9, 0);
499 		}
500 
501 		/*
502 		 * Look for a child driver for this channel.
503 		 * The child attach will setup the hardware.
504 		 */
505 		if (!config_found(&zsc->zsc_dev, (void *)&zsc_args, zs_print)) {
506 			/* No sub-driver.  Just reset it. */
507 			u_char reset = (channel == 0) ?
508 				ZSWR9_A_RESET : ZSWR9_B_RESET;
509 			s = splzs();
510 			zs_write_reg(cs,  9, reset);
511 			splx(s);
512 		}
513 	}
514 
515 	/*
516 	 * Now safe to install interrupt handlers.  Note the arguments
517 	 * to the interrupt handlers aren't used.  Note, we only do this
518 	 * once since both SCCs interrupt at the same level and vector.
519 	 */
520 	if (!didintr) {
521 		didintr = 1;
522 		prevpri = pri;
523 		bus_intr_establish(zsc->zsc_bustag, pri, IPL_SERIAL,
524 				   zshard, NULL);
525 	} else if (pri != prevpri)
526 		panic("broken zs interrupt scheme");
527 
528 	evcnt_attach_dynamic(&zsc->zsc_intrcnt, EVCNT_TYPE_INTR, NULL,
529 	    zsc->zsc_dev.dv_xname, "intr");
530 
531 	/*
532 	 * Set the master interrupt enable and interrupt vector.
533 	 * (common to both channels, do it on A)
534 	 */
535 	cs = zsc->zsc_cs[0];
536 	s = splhigh();
537 	/* interrupt vector */
538 	zs_write_reg(cs, 2, zs_init_reg[2]);
539 	/* master interrupt control (enable) */
540 	zs_write_reg(cs, 9, zs_init_reg[9]);
541 	splx(s);
542 
543 #if 0
544 	/*
545 	 * XXX: L1A hack - We would like to be able to break into
546 	 * the debugger during the rest of autoconfiguration, so
547 	 * lower interrupts just enough to let zs interrupts in.
548 	 * This is done after both zs devices are attached.
549 	 */
550 	if (zsc->zsc_promunit == 1) {
551 		printf("zs1: enabling zs interrupts\n");
552 		(void)splfd(); /* XXX: splzs - 1 */
553 	}
554 #endif
555 }
556 
557 static int
558 zs_print(aux, name)
559 	void *aux;
560 	const char *name;
561 {
562 	struct zsc_attach_args *args = aux;
563 
564 	if (name != NULL)
565 		aprint_normal("%s: ", name);
566 
567 	if (args->channel != -1)
568 		aprint_normal(" channel %d", args->channel);
569 
570 	return (UNCONF);
571 }
572 
573 static volatile int zssoftpending;
574 
575 /*
576  * Our ZS chips all share a common, autovectored interrupt,
577  * so we have to look at all of them on each interrupt.
578  */
579 static int
580 zshard(arg)
581 	void *arg;
582 {
583 	struct zsc_softc *zsc;
584 	int unit, rr3, rval, softreq;
585 
586 	rval = softreq = 0;
587 	for (unit = 0; unit < zs_cd.cd_ndevs; unit++) {
588 		struct zs_chanstate *cs;
589 
590 		zsc = zs_cd.cd_devs[unit];
591 		if (zsc == NULL)
592 			continue;
593 		rr3 = zsc_intr_hard(zsc);
594 		/* Count up the interrupts. */
595 		if (rr3) {
596 			rval |= rr3;
597 			zsc->zsc_intrcnt.ev_count++;
598 		}
599 		if ((cs = zsc->zsc_cs[0]) != NULL)
600 			softreq |= cs->cs_softreq;
601 		if ((cs = zsc->zsc_cs[1]) != NULL)
602 			softreq |= cs->cs_softreq;
603 	}
604 
605 	/* We are at splzs here, so no need to lock. */
606 	if (softreq && (zssoftpending == 0)) {
607 		zssoftpending = 1;
608 		softintr_schedule(zs_sicookie);
609 	}
610 	return (rval);
611 }
612 
613 /*
614  * Similar scheme as for zshard (look at all of them)
615  */
616 static void
617 zssoft(arg)
618 	void *arg;
619 {
620 	struct zsc_softc *zsc;
621 	int s, unit;
622 
623 	/* This is not the only ISR on this IPL. */
624 	if (zssoftpending == 0)
625 		return;
626 
627 	/*
628 	 * The soft intr. bit will be set by zshard only if
629 	 * the variable zssoftpending is zero.  The order of
630 	 * these next two statements prevents our clearing
631 	 * the soft intr bit just after zshard has set it.
632 	 */
633 	/* ienab_bic(IE_ZSSOFT); */
634 	zssoftpending = 0;
635 
636 	/* Make sure we call the tty layer at spltty. */
637 	s = spltty();
638 	for (unit = 0; unit < zs_cd.cd_ndevs; unit++) {
639 		zsc = zs_cd.cd_devs[unit];
640 		if (zsc == NULL)
641 			continue;
642 		(void)zsc_intr_soft(zsc);
643 	}
644 	splx(s);
645 }
646 
647 
648 /*
649  * Compute the current baud rate given a ZS channel.
650  */
651 static int
652 zs_get_speed(cs)
653 	struct zs_chanstate *cs;
654 {
655 	int tconst;
656 
657 	tconst = zs_read_reg(cs, 12);
658 	tconst |= zs_read_reg(cs, 13) << 8;
659 	return (TCONST_TO_BPS(cs->cs_brg_clk, tconst));
660 }
661 
662 /*
663  * MD functions for setting the baud rate and control modes.
664  */
665 int
666 zs_set_speed(cs, bps)
667 	struct zs_chanstate *cs;
668 	int bps;	/* bits per second */
669 {
670 	int tconst, real_bps;
671 
672 	if (bps == 0)
673 		return (0);
674 
675 #ifdef	DIAGNOSTIC
676 	if (cs->cs_brg_clk == 0)
677 		panic("zs_set_speed");
678 #endif
679 
680 	tconst = BPS_TO_TCONST(cs->cs_brg_clk, bps);
681 	if (tconst < 0)
682 		return (EINVAL);
683 
684 	/* Convert back to make sure we can do it. */
685 	real_bps = TCONST_TO_BPS(cs->cs_brg_clk, tconst);
686 
687 	/* XXX - Allow some tolerance here? */
688 	if (real_bps != bps)
689 		return (EINVAL);
690 
691 	cs->cs_preg[12] = tconst;
692 	cs->cs_preg[13] = tconst >> 8;
693 
694 	/* Caller will stuff the pending registers. */
695 	return (0);
696 }
697 
698 int
699 zs_set_modes(cs, cflag)
700 	struct zs_chanstate *cs;
701 	int cflag;	/* bits per second */
702 {
703 	int s;
704 
705 	/*
706 	 * Output hardware flow control on the chip is horrendous:
707 	 * if carrier detect drops, the receiver is disabled, and if
708 	 * CTS drops, the transmitter is stoped IN MID CHARACTER!
709 	 * Therefore, NEVER set the HFC bit, and instead use the
710 	 * status interrupt to detect CTS changes.
711 	 */
712 	s = splzs();
713 	cs->cs_rr0_pps = 0;
714 	if ((cflag & (CLOCAL | MDMBUF)) != 0) {
715 		cs->cs_rr0_dcd = 0;
716 		if ((cflag & MDMBUF) == 0)
717 			cs->cs_rr0_pps = ZSRR0_DCD;
718 	} else
719 		cs->cs_rr0_dcd = ZSRR0_DCD;
720 	if ((cflag & CRTSCTS) != 0) {
721 		cs->cs_wr5_dtr = ZSWR5_DTR;
722 		cs->cs_wr5_rts = ZSWR5_RTS;
723 		cs->cs_rr0_cts = ZSRR0_CTS;
724 	} else if ((cflag & CDTRCTS) != 0) {
725 		cs->cs_wr5_dtr = 0;
726 		cs->cs_wr5_rts = ZSWR5_DTR;
727 		cs->cs_rr0_cts = ZSRR0_CTS;
728 	} else if ((cflag & MDMBUF) != 0) {
729 		cs->cs_wr5_dtr = 0;
730 		cs->cs_wr5_rts = ZSWR5_DTR;
731 		cs->cs_rr0_cts = ZSRR0_DCD;
732 	} else {
733 		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
734 		cs->cs_wr5_rts = 0;
735 		cs->cs_rr0_cts = 0;
736 	}
737 	splx(s);
738 
739 	/* Caller will stuff the pending registers. */
740 	return (0);
741 }
742 
743 
744 /*
745  * Read or write the chip with suitable delays.
746  */
747 
748 u_char
749 zs_read_reg(cs, reg)
750 	struct zs_chanstate *cs;
751 	u_char reg;
752 {
753 	u_char val;
754 
755 	*cs->cs_reg_csr = reg;
756 	ZS_DELAY();
757 	val = *cs->cs_reg_csr;
758 	ZS_DELAY();
759 	return (val);
760 }
761 
762 void
763 zs_write_reg(cs, reg, val)
764 	struct zs_chanstate *cs;
765 	u_char reg, val;
766 {
767 	*cs->cs_reg_csr = reg;
768 	ZS_DELAY();
769 	*cs->cs_reg_csr = val;
770 	ZS_DELAY();
771 }
772 
773 u_char
774 zs_read_csr(cs)
775 	struct zs_chanstate *cs;
776 {
777 	u_char val;
778 
779 	val = *cs->cs_reg_csr;
780 	ZS_DELAY();
781 	return (val);
782 }
783 
784 void
785 zs_write_csr(cs, val)
786 	struct zs_chanstate *cs;
787 	u_char val;
788 {
789 	*cs->cs_reg_csr = val;
790 	ZS_DELAY();
791 }
792 
793 u_char
794 zs_read_data(cs)
795 	struct zs_chanstate *cs;
796 {
797 	u_char val;
798 
799 	val = *cs->cs_reg_data;
800 	ZS_DELAY();
801 	return (val);
802 }
803 
804 void  zs_write_data(cs, val)
805 	struct zs_chanstate *cs;
806 	u_char val;
807 {
808 	*cs->cs_reg_data = val;
809 	ZS_DELAY();
810 }
811 
812 /****************************************************************
813  * Console support functions (Sun specific!)
814  * Note: this code is allowed to know about the layout of
815  * the chip registers, and uses that to keep things simple.
816  * XXX - I think I like the mvme167 code better. -gwr
817  ****************************************************************/
818 
819 /*
820  * Handle user request to enter kernel debugger.
821  */
822 void
823 zs_abort(cs)
824 	struct zs_chanstate *cs;
825 {
826 	struct zschan *zc = zs_conschan_get;
827 	int rr0;
828 
829 	/* Wait for end of break to avoid PROM abort. */
830 	/* XXX - Limit the wait? */
831 	do {
832 		rr0 = zc->zc_csr;
833 		ZS_DELAY();
834 	} while (rr0 & ZSRR0_BREAK);
835 
836 #if defined(KGDB)
837 	zskgdb(cs);
838 #elif defined(DDB)
839 	Debugger();
840 #else
841 	printf("stopping on keyboard abort\n");
842 	callrom();
843 #endif
844 }
845 
846 int  zs_getc __P((void *arg));
847 void zs_putc __P((void *arg, int c));
848 
849 /*
850  * Polled input char.
851  */
852 int
853 zs_getc(arg)
854 	void *arg;
855 {
856 	struct zschan *zc = arg;
857 	int s, c, rr0;
858 	u_int omid;
859 
860 	/* Temporarily direct interrupts at ourselves */
861 	s = splhigh();
862 	omid = setitr(cpuinfo.mid);
863 
864 	/* Wait for a character to arrive. */
865 	do {
866 		rr0 = zc->zc_csr;
867 		ZS_DELAY();
868 	} while ((rr0 & ZSRR0_RX_READY) == 0);
869 
870 	c = zc->zc_data;
871 	ZS_DELAY();
872 	setitr(omid);
873 	splx(s);
874 
875 	/*
876 	 * This is used by the kd driver to read scan codes,
877 	 * so don't translate '\r' ==> '\n' here...
878 	 */
879 	return (c);
880 }
881 
882 /*
883  * Polled output char.
884  */
885 void
886 zs_putc(arg, c)
887 	void *arg;
888 	int c;
889 {
890 	struct zschan *zc = arg;
891 	int s, rr0;
892 	u_int omid;
893 
894 	/* Temporarily direct interrupts at ourselves */
895 	s = splhigh();
896 	omid = setitr(cpuinfo.mid);
897 
898 	/* Wait for transmitter to become ready. */
899 	do {
900 		rr0 = zc->zc_csr;
901 		ZS_DELAY();
902 	} while ((rr0 & ZSRR0_TX_READY) == 0);
903 
904 	/*
905 	 * Send the next character.
906 	 * Now you'd think that this could be followed by a ZS_DELAY()
907 	 * just like all the other chip accesses, but it turns out that
908 	 * the `transmit-ready' interrupt isn't de-asserted until
909 	 * some period of time after the register write completes
910 	 * (more than a couple instructions).  So to avoid stray
911 	 * interrupts we put in the 2us delay regardless of CPU model.
912 	 */
913 	zc->zc_data = c;
914 	delay(2);
915 
916 	setitr(omid);
917 	splx(s);
918 }
919 
920 /*****************************************************************/
921 /*
922  * Polled console input putchar.
923  */
924 int
925 zscngetc(dev)
926 	dev_t dev;
927 {
928 	return (zs_getc(zs_conschan_get));
929 }
930 
931 /*
932  * Polled console output putchar.
933  */
934 void
935 zscnputc(dev, c)
936 	dev_t dev;
937 	int c;
938 {
939 	zs_putc(zs_conschan_put, c);
940 }
941 
942 void
943 zscnpollc(dev, on)
944 	dev_t dev;
945 	int on;
946 {
947 	/* No action needed */
948 }
949 
950 int
951 zs_console_flags(promunit, node, channel)
952 	int promunit;
953 	int node;
954 	int channel;
955 {
956 	int cookie, flags = 0;
957 
958 	switch (prom_version()) {
959 	case PROM_OLDMON:
960 	case PROM_OBP_V0:
961 		/*
962 		 * Use `promunit' and `channel' to derive the PROM
963 		 * stdio handles that correspond to this device.
964 		 */
965 		if (promunit == 0)
966 			cookie = PROMDEV_TTYA + channel;
967 		else if (promunit == 1 && channel == 0)
968 			cookie = PROMDEV_KBD;
969 		else
970 			cookie = -1;
971 
972 		if (cookie == prom_stdin())
973 			flags |= ZS_HWFLAG_CONSOLE_INPUT;
974 
975 		/*
976 		 * Prevent the keyboard from matching the output device
977 		 * (note that PROMDEV_KBD == PROMDEV_SCREEN == 0!).
978 		 */
979 		if (cookie != PROMDEV_KBD && cookie == prom_stdout())
980 			flags |= ZS_HWFLAG_CONSOLE_OUTPUT;
981 
982 		break;
983 
984 	case PROM_OBP_V2:
985 	case PROM_OBP_V3:
986 	case PROM_OPENFIRM:
987 
988 		/*
989 		 * Match the nodes and device arguments prepared by
990 		 * consinit() against our device node and channel.
991 		 * (The device argument is the part of the OBP path
992 		 * following the colon, as in `/obio/zs@0,100000:a')
993 		 */
994 
995 		/* Default to channel 0 if there are no explicit prom args */
996 		cookie = 0;
997 
998 		if (node == prom_stdin_node) {
999 			if (prom_stdin_args[0] != '\0')
1000 				/* Translate (a,b) -> (0,1) */
1001 				cookie = prom_stdin_args[0] - 'a';
1002 
1003 			if (channel == cookie)
1004 				flags |= ZS_HWFLAG_CONSOLE_INPUT;
1005 		}
1006 
1007 		if (node == prom_stdout_node) {
1008 			if (prom_stdout_args[0] != '\0')
1009 				/* Translate (a,b) -> (0,1) */
1010 				cookie = prom_stdout_args[0] - 'a';
1011 
1012 			if (channel == cookie)
1013 				flags |= ZS_HWFLAG_CONSOLE_OUTPUT;
1014 		}
1015 
1016 		break;
1017 
1018 	default:
1019 		break;
1020 	}
1021 
1022 	return (flags);
1023 }
1024 
1025 /*
1026  * Power management hooks for zsopen() and zsclose().
1027  * We use them to power on/off the ports, if necessary.
1028  */
1029 int
1030 zs_enable(cs)
1031 	struct zs_chanstate *cs;
1032 {
1033 	auxiotwoserialendis (ZS_ENABLE);
1034 	cs->enabled = 1;
1035 	return(0);
1036 }
1037 
1038 void
1039 zs_disable(cs)
1040 	struct zs_chanstate *cs;
1041 {
1042 	auxiotwoserialendis (ZS_DISABLE);
1043 	cs->enabled = 0;
1044 }
1045