zs.c revision 1.100 1 /* $NetBSD: zs.c,v 1.100 2004/03/17 17:04:59 pk 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.100 2004/03/17 17:04:59 pk 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