1 /* $NetBSD: zs.c,v 1.18 2008/04/28 20:23:37 martin Exp $ */
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Zilog Z8530 Dual UART driver (machine-dependent part)
35 * Runs two serial lines per chip using slave drivers.
36 * Plain tty/async lines use the zs_async slave.
37 * Sun keyboard/mouse uses the zs_kbd/zs_ms slaves.
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.18 2008/04/28 20:23:37 martin Exp $");
46 #include <sys/param.h>
47 #include <sys/systm.h>
49 #include <sys/device.h>
51 #include <sys/ioctl.h>
52 #include <sys/kernel.h>
56 #include <sys/syslog.h>
59 #include <machine/autoconf.h>
60 #include <machine/promlib.h>
61 #include <machine/cpu.h>
62 #include <machine/eeprom.h>
63 #include <machine/psl.h>
64 #include <machine/z8530var.h>
67 #include <dev/ic/z8530reg.h>
68 #include <dev/sun/kbd_ms_ttyvar.h>
69 #include <ddb/db_output.h>
71 #include <sun2/dev/cons.h>
74 #include "kbd.h" /* NKBD */
75 #include "ms.h" /* NMS */
78 * Some warts needed by z8530tty.c -
79 * The default parity REALLY needs to be the same as the PROM uses,
80 * or you can not see messages done with printf during boot-up...
82 int zs_def_cflag
= (CREAD
| CS8
| HUPCL
);
84 /* ZS channel used as the console device (if any) */
85 void *zs_conschan_get
, *zs_conschan_put
;
87 static uint8_t zs_init_reg
[16] = {
88 0, /* 0: CMD (reset, etc.) */
89 0, /* 1: No interrupts yet. */
91 ZS_INIT_IVECT
, /* 2: IVECT */
95 ZSWR3_RX_8
| ZSWR3_RX_ENABLE
,
96 ZSWR4_CLK_X16
| ZSWR4_ONESB
| ZSWR4_EVENP
,
97 ZSWR5_TX_8
| ZSWR5_TX_ENABLE
,
98 0, /* 6: TXSYNC/SYNCLO */
99 0, /* 7: RXSYNC/SYNCHI */
100 0, /* 8: alias for data port */
104 ZSWR9_MASTER_IE
| ZSWR9_NO_VECTOR
,
106 0, /*10: Misc. TX/RX control bits */
107 ZSWR11_TXCLK_BAUD
| ZSWR11_RXCLK_BAUD
,
108 ((PCLK
/32)/9600)-2, /*12: BAUDLO (default=9600) */
109 0, /*13: BAUDHI (default=9600) */
110 ZSWR14_BAUD_ENA
| ZSWR14_BAUD_FROM_PCLK
,
115 static int zscngetc(dev_t
);
116 static void zscnputc(dev_t
, int);
117 static void zscnpollc(dev_t
, int);
119 struct consdev zs_consdev
= {
129 /****************************************************************
131 ****************************************************************/
133 static int zs_print(void *, const char *name
);
135 /* Interrupt handlers. */
136 int zscheckintr(void *);
137 static int zshard(void *);
138 static void zssoft(void *);
140 static int zs_get_speed(struct zs_chanstate
*);
145 * USE ROM PROPERTIES port-a-ignore-cd AND port-b-ignore-cd FOR
146 * SOFT CARRIER, AND keyboard PROPERTY FOR KEYBOARD/MOUSE?
149 zs_attach(struct zsc_softc
*zsc
, struct zsdevice
*zsd
, int pri
)
151 struct zsc_attach_args zsc_args
;
152 struct zs_chanstate
*cs
;
156 aprint_error(": configuration incomplete\n");
161 /* we should use ipl2si(softpri) but it isn't exported */
162 aprint_normal(" softpri %d\n", _IPL_SOFT_LEVEL3
);
168 * Initialize software state for each channel.
170 for (channel
= 0; channel
< 2; channel
++) {
172 struct device
*child
;
174 zsc_args
.channel
= channel
;
175 cs
= &zsc
->zsc_cs_store
[channel
];
176 zsc
->zsc_cs
[channel
] = cs
;
179 cs
->cs_channel
= channel
;
180 cs
->cs_private
= NULL
;
181 cs
->cs_ops
= &zsops_null
;
182 cs
->cs_brg_clk
= PCLK
/ 16;
184 zc
= (channel
== 0) ? &zsd
->zs_chan_a
: &zsd
->zs_chan_b
;
186 zsc_args
.consdev
= NULL
;
187 zsc_args
.hwflags
= zs_console_flags(zsc
->zsc_promunit
,
191 if (zsc_args
.hwflags
& ZS_HWFLAG_CONSOLE
) {
192 zsc_args
.hwflags
|= ZS_HWFLAG_USE_CONSDEV
;
193 zsc_args
.consdev
= &zs_consdev
;
196 if ((zsc_args
.hwflags
& ZS_HWFLAG_CONSOLE_INPUT
) != 0) {
197 zs_conschan_get
= zc
;
199 if ((zsc_args
.hwflags
& ZS_HWFLAG_CONSOLE_OUTPUT
) != 0) {
200 zs_conschan_put
= zc
;
203 /* Children need to set cn_dev, etc */
204 cs
->cs_reg_csr
= &zc
->zc_csr
;
205 cs
->cs_reg_data
= &zc
->zc_data
;
207 memcpy(cs
->cs_creg
, zs_init_reg
, 16);
208 memcpy(cs
->cs_preg
, zs_init_reg
, 16);
210 /* XXX: Consult PROM properties for this?! */
211 cs
->cs_defspeed
= zs_get_speed(cs
);
212 cs
->cs_defcflag
= zs_def_cflag
;
214 /* Make these correspond to cs_defcflag (-crtscts) */
215 cs
->cs_rr0_dcd
= ZSRR0_DCD
;
217 cs
->cs_wr5_dtr
= ZSWR5_DTR
| ZSWR5_RTS
;
221 * Clear the master interrupt enable.
222 * The INTENA is common to both channels,
223 * so just do it on the A channel.
226 zs_write_reg(cs
, 9, 0);
230 * Look for a child driver for this channel.
231 * The child attach will setup the hardware.
233 if ((child
= config_found(zsc
->zsc_dev
, (void *)&zsc_args
,
234 zs_print
)) == NULL
) {
235 /* No sub-driver. Just reset it. */
236 uint8_t reset
= (channel
== 0) ?
237 ZSWR9_A_RESET
: ZSWR9_B_RESET
;
239 zs_write_reg(cs
, 9, reset
);
242 #if (NKBD > 0) || (NMS > 0)
244 * If this was a zstty it has a keyboard
245 * property on it we need to attach the
246 * sunkbd and sunms line disciplines.
249 && device_is_a(child
, "zstty")) {
250 struct kbd_ms_tty_attach_args kma
;
253 * The following are the only fields
258 struct zs_chanstate
*zst_cs
;
259 } *zst
= device_private(child
);
262 kma
.kmta_tp
= tp
= zst
->zst_tty
;
264 kma
.kmta_dev
= tp
->t_dev
;
265 kma
.kmta_consdev
= zsc_args
.consdev
;
267 /* Attach 'em if we got 'em. */
268 switch(zs_peripheral_type(zsc
->zsc_promunit
,
271 case ZS_PERIPHERAL_SUNKBD
:
273 kma
.kmta_name
= "keyboard";
274 config_found(child
, (void *)&kma
, NULL
);
277 case ZS_PERIPHERAL_SUNMS
:
279 kma
.kmta_name
= "mouse";
280 config_found(child
, (void *)&kma
, NULL
);
292 * Now safe to install interrupt handlers.
294 bus_intr_establish(zsc
->zsc_bustag
, pri
, IPL_SERIAL
, 0, zshard
, zsc
);
295 if ((zsc
->zsc_softintr
= softint_establish(SOFTINT_SERIAL
,
296 zssoft
, zsc
)) == NULL
)
297 panic("%s: could not establish soft interrupt", __func__
);
299 evcnt_attach_dynamic(&zsc
->zsc_intrcnt
, EVCNT_TYPE_INTR
, NULL
,
300 device_xname(zsc
->zsc_dev
), "intr");
304 * Set the master interrupt enable and interrupt vector.
305 * (common to both channels, do it on A)
309 /* interrupt vector */
310 zs_write_reg(cs
, 2, zs_init_reg
[2]);
311 /* master interrupt control (enable) */
312 zs_write_reg(cs
, 9, zs_init_reg
[9]);
318 zs_print(void *aux
, const char *name
)
320 struct zsc_attach_args
*args
= aux
;
323 aprint_normal("%s: ", name
);
325 if (args
->channel
!= -1)
326 aprint_normal(" channel %d", args
->channel
);
334 struct zsc_softc
*zsc
= arg
;
339 while ((rr3
= zsc_intr_hard(zsc
))) {
340 /* Count up the interrupts. */
342 zsc
->zsc_intrcnt
.ev_count
++;
344 if (((zsc
->zsc_cs
[0] && zsc
->zsc_cs
[0]->cs_softreq
) ||
345 (zsc
->zsc_cs
[1] && zsc
->zsc_cs
[1]->cs_softreq
)) &&
347 softint_schedule(zsc
->zsc_softintr
);
353 zscheckintr(void *arg
)
355 struct zsc_softc
*zsc
;
359 for (unit
= 0; unit
< zs_cd
.cd_ndevs
; unit
++) {
361 zsc
= device_lookup_private(&zs_cd
, unit
);
364 rval
= (zshard((void *)zsc
) || rval
);
371 * We need this only for TTY_DEBUG purposes.
376 struct zsc_softc
*zsc
= arg
;
379 /* Make sure we call the tty layer at spltty. */
381 (void)zsc_intr_soft(zsc
);
384 struct zstty_softc
*zst0
= zsc
->zsc_cs
[0]->cs_private
;
385 struct zstty_softc
*zst1
= zsc
->zsc_cs
[1]->cs_private
;
386 if (zst0
->zst_overflows
|| zst1
->zst_overflows
) {
387 struct trapframe
*frame
= arg
; /* XXX */
389 printf("zs silo overflow from %p\n",
399 * Compute the current baud rate given a ZS channel.
402 zs_get_speed(struct zs_chanstate
*cs
)
406 tconst
= zs_read_reg(cs
, 12);
407 tconst
|= zs_read_reg(cs
, 13) << 8;
408 return (TCONST_TO_BPS(cs
->cs_brg_clk
, tconst
));
412 * MD functions for setting the baud rate and control modes.
415 zs_set_speed(struct zs_chanstate
*cs
, int bps
)
417 int tconst
, real_bps
;
423 if (cs
->cs_brg_clk
== 0)
424 panic("zs_set_speed");
427 tconst
= BPS_TO_TCONST(cs
->cs_brg_clk
, bps
);
431 /* Convert back to make sure we can do it. */
432 real_bps
= TCONST_TO_BPS(cs
->cs_brg_clk
, tconst
);
434 /* XXX - Allow some tolerance here? */
438 cs
->cs_preg
[12] = tconst
;
439 cs
->cs_preg
[13] = tconst
>> 8;
441 /* Caller will stuff the pending registers. */
446 zs_set_modes(struct zs_chanstate
*cs
, int cflag
/* bits per second */)
451 * Output hardware flow control on the chip is horrendous:
452 * if carrier detect drops, the receiver is disabled, and if
453 * CTS drops, the transmitter is stoped IN MID CHARACTER!
454 * Therefore, NEVER set the HFC bit, and instead use the
455 * status interrupt to detect CTS changes.
459 if ((cflag
& (CLOCAL
| MDMBUF
)) != 0) {
461 if ((cflag
& MDMBUF
) == 0)
462 cs
->cs_rr0_pps
= ZSRR0_DCD
;
464 cs
->cs_rr0_dcd
= ZSRR0_DCD
;
465 if ((cflag
& CRTSCTS
) != 0) {
466 cs
->cs_wr5_dtr
= ZSWR5_DTR
;
467 cs
->cs_wr5_rts
= ZSWR5_RTS
;
468 cs
->cs_rr0_cts
= ZSRR0_CTS
;
469 } else if ((cflag
& CDTRCTS
) != 0) {
471 cs
->cs_wr5_rts
= ZSWR5_DTR
;
472 cs
->cs_rr0_cts
= ZSRR0_CTS
;
473 } else if ((cflag
& MDMBUF
) != 0) {
475 cs
->cs_wr5_rts
= ZSWR5_DTR
;
476 cs
->cs_rr0_cts
= ZSRR0_DCD
;
478 cs
->cs_wr5_dtr
= ZSWR5_DTR
| ZSWR5_RTS
;
484 /* Caller will stuff the pending registers. */
490 * Read or write the chip with suitable delays.
494 zs_read_reg(struct zs_chanstate
*cs
, uint8_t reg
)
498 *cs
->cs_reg_csr
= reg
;
500 val
= *cs
->cs_reg_csr
;
506 zs_write_reg(struct zs_chanstate
*cs
, uint8_t reg
, uint8_t val
)
508 *cs
->cs_reg_csr
= reg
;
510 *cs
->cs_reg_csr
= val
;
515 zs_read_csr(struct zs_chanstate
*cs
)
519 val
= *cs
->cs_reg_csr
;
525 zs_write_csr(struct zs_chanstate
*cs
, uint8_t val
)
527 *cs
->cs_reg_csr
= val
;
532 zs_read_data(struct zs_chanstate
*cs
)
536 val
= *cs
->cs_reg_data
;
542 zs_write_data(struct zs_chanstate
*cs
, uint8_t val
)
544 *cs
->cs_reg_data
= val
;
548 /****************************************************************
549 * Console support functions (Sun specific!)
550 * Note: this code is allowed to know about the layout of
551 * the chip registers, and uses that to keep things simple.
552 * XXX - I think I like the mvme167 code better. -gwr
553 ****************************************************************/
555 extern void Debugger(void);
558 * Handle user request to enter kernel debugger.
561 zs_abort(struct zs_chanstate
*cs
)
563 volatile struct zschan
*zc
= zs_conschan_get
;
566 /* Wait for end of break to avoid PROM abort. */
567 /* XXX - Limit the wait? */
571 } while (rr0
& ZSRR0_BREAK
);
577 extern int db_active
;
582 /* Debugger is probably hozed */
586 printf("stopping on keyboard abort\n");
598 volatile struct zschan
*zc
= arg
;
602 /* Wait for a character to arrive. */
606 } while ((rr0
& ZSRR0_RX_READY
) == 0);
613 * This is used by the kd driver to read scan codes,
614 * so don't translate '\r' ==> '\n' here...
620 * Polled output char.
623 zs_putc(void *arg
, int c
)
625 volatile struct zschan
*zc
= arg
;
630 /* Wait for transmitter to become ready. */
634 } while ((rr0
& ZSRR0_TX_READY
) == 0);
637 * Send the next character.
638 * Now you'd think that this could be followed by a ZS_DELAY()
639 * just like all the other chip accesses, but it turns out that
640 * the `transmit-ready' interrupt isn't de-asserted until
641 * some period of time after the register write completes
642 * (more than a couple instructions). So to avoid stray
643 * interrupts we put in the 2us delay regardless of CPU model.
651 /*****************************************************************/
657 * Polled console input putchar.
662 return (zs_getc(zs_conschan_get
));
666 * Polled console output putchar.
669 zscnputc(dev_t dev
, int c
)
671 zs_putc(zs_conschan_put
, c
);
677 zscnpollc(dev_t dev
, int on
)
680 * Need to tell zs driver to acknowledge all interrupts or we get
681 * annoying spurious interrupt messages. This is because mucking
682 * with spl() levels during polling does not prevent interrupts from
686 if (on
) swallow_zsintrs
++;
687 else swallow_zsintrs
--;