Home | History | Annotate | Line # | Download | only in dev
zs.c revision 1.41
      1 /*	$NetBSD: zs.c,v 1.41 2008/06/13 12:26:02 cegger 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  *
     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.
     30  */
     31 
     32 /*
     33  * Zilog Z8530 Dual UART driver (machine-dependent part)
     34  *
     35  * Runs two serial lines per chip using slave drivers.
     36  * Plain tty/async lines use the zs_async slave.
     37  *
     38  * Modified for NetBSD/mvme68k by Jason R. Thorpe <thorpej (at) NetBSD.org>
     39  */
     40 
     41 #include <sys/cdefs.h>
     42 __KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.41 2008/06/13 12:26:02 cegger Exp $");
     43 
     44 #include <sys/param.h>
     45 #include <sys/systm.h>
     46 #include <sys/conf.h>
     47 #include <sys/device.h>
     48 #include <sys/file.h>
     49 #include <sys/ioctl.h>
     50 #include <sys/kernel.h>
     51 #include <sys/proc.h>
     52 #include <sys/tty.h>
     53 #include <sys/time.h>
     54 #include <sys/syslog.h>
     55 #include <sys/cpu.h>
     56 #include <sys/bus.h>
     57 #include <sys/intr.h>
     58 
     59 #include <dev/cons.h>
     60 #include <dev/ic/z8530reg.h>
     61 #include <machine/z8530var.h>
     62 
     63 #include <mvme68k/dev/zsvar.h>
     64 
     65 #include "ioconf.h"
     66 
     67 /*
     68  * Some warts needed by z8530tty.c -
     69  * The default parity REALLY needs to be the same as the PROM uses,
     70  * or you can not see messages done with printf during boot-up...
     71  */
     72 int zs_def_cflag = (CREAD | CS8 | HUPCL);
     73 
     74 /* Flags from zscnprobe() */
     75 static int zs_hwflags[NZSC][2];
     76 
     77 /* Default speed for each channel */
     78 static int zs_defspeed[NZSC][2] = {
     79 	{ 9600, 	/* port 1 */
     80 	  9600 },	/* port 2 */
     81 	{ 9600, 	/* port 3 */
     82 	  9600 },	/* port 4 */
     83 };
     84 
     85 static struct zs_chanstate zs_conschan_store;
     86 static struct zs_chanstate *zs_conschan;
     87 
     88 uint8_t zs_init_reg[16] = {
     89 	0,	/* 0: CMD (reset, etc.) */
     90 	0,	/* 1: No interrupts yet. */
     91 	0x18 + ZSHARD_PRI,	/* IVECT */
     92 	ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
     93 	ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP,
     94 	ZSWR5_TX_8 | ZSWR5_TX_ENABLE,
     95 	0,	/* 6: TXSYNC/SYNCLO */
     96 	0,	/* 7: RXSYNC/SYNCHI */
     97 	0,	/* 8: alias for data port */
     98 	ZSWR9_MASTER_IE,
     99 	0,	/*10: Misc. TX/RX control bits */
    100 	ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
    101 	0,			/*12: BAUDLO (default=9600) */
    102 	0,			/*13: BAUDHI (default=9600) */
    103 	ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK,
    104 	ZSWR15_BREAK_IE,
    105 };
    106 
    107 
    108 /****************************************************************
    109  * Autoconfig
    110  ****************************************************************/
    111 
    112 /* Definition of the driver for autoconfig. */
    113 static int	zsc_print(void *, const char *name);
    114 int	zs_getc(void *);
    115 void	zs_putc(void *, int);
    116 
    117 #if 0
    118 static int zs_get_speed(struct zs_chanstate *);
    119 #endif
    120 
    121 cons_decl(zsc_pcc);
    122 
    123 
    124 /*
    125  * Configure children of an SCC.
    126  */
    127 void
    128 zs_config(struct zsc_softc *zsc, struct zsdevice *zs, int vector, int pclk)
    129 {
    130 	struct zsc_attach_args zsc_args;
    131 	volatile struct zschan *zc;
    132 	struct zs_chanstate *cs;
    133 	int zsc_unit, channel, s;
    134 
    135 	zsc_unit = device_unit(zsc->zsc_dev);
    136 	printf(": Zilog 8530 SCC at vector 0x%x\n", vector);
    137 
    138 	/*
    139 	 * Initialize software state for each channel.
    140 	 */
    141 	for (channel = 0; channel < 2; channel++) {
    142 		zsc_args.channel = channel;
    143 		zsc_args.hwflags = zs_hwflags[zsc_unit][channel];
    144 		cs = &zsc->zsc_cs_store[channel];
    145 		zsc->zsc_cs[channel] = cs;
    146 		zs_lock_init(cs);
    147 
    148 		/*
    149 		 * If we're the console, copy the channel state, and
    150 		 * adjust the console channel pointer.
    151 		 */
    152 		if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) {
    153 			memcpy(cs, zs_conschan, sizeof(struct zs_chanstate));
    154 			zs_conschan = cs;
    155 		} else {
    156 			zc = (channel == 0) ? &zs->zs_chan_a : &zs->zs_chan_b;
    157 			cs->cs_reg_csr  = zc->zc_csr;
    158 			cs->cs_reg_data = zc->zc_data;
    159 			memcpy(cs->cs_creg, zs_init_reg, 16);
    160 			memcpy(cs->cs_preg, zs_init_reg, 16);
    161 			cs->cs_defspeed = zs_defspeed[zsc_unit][channel];
    162 		}
    163 
    164 		cs->cs_brg_clk = pclk / 16;
    165 		cs->cs_creg[2] = cs->cs_preg[2] = vector;
    166 		zs_set_speed(cs, cs->cs_defspeed);
    167 		cs->cs_creg[12] = cs->cs_preg[12];
    168 		cs->cs_creg[13] = cs->cs_preg[13];
    169 		cs->cs_defcflag = zs_def_cflag;
    170 
    171 		/* Make these correspond to cs_defcflag (-crtscts) */
    172 		cs->cs_rr0_dcd = ZSRR0_DCD;
    173 		cs->cs_rr0_cts = 0;
    174 		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
    175 		cs->cs_wr5_rts = 0;
    176 
    177 		cs->cs_channel = channel;
    178 		cs->cs_private = NULL;
    179 		cs->cs_ops = &zsops_null;
    180 
    181 		/*
    182 		 * Clear the master interrupt enable.
    183 		 * The INTENA is common to both channels,
    184 		 * so just do it on the A channel.
    185 		 * Write the interrupt vector while we're at it.
    186 		 */
    187 		if (channel == 0) {
    188 			zs_write_reg(cs, 9, 0);
    189 			zs_write_reg(cs, 2, vector);
    190 		}
    191 
    192 		/*
    193 		 * Look for a child driver for this channel.
    194 		 * The child attach will setup the hardware.
    195 		 */
    196 		if (!config_found(zsc->zsc_dev, (void *)&zsc_args,
    197 		    zsc_print)) {
    198 			/* No sub-driver.  Just reset it. */
    199 			uint8_t reset = (channel == 0) ?
    200 				ZSWR9_A_RESET : ZSWR9_B_RESET;
    201 			s = splzs();
    202 			zs_write_reg(cs,  9, reset);
    203 			splx(s);
    204 		}
    205 	}
    206 
    207 	/*
    208 	 * Allocate a software interrupt cookie.
    209 	 */
    210 	zsc->zsc_softintr_cookie = softint_establish(SOFTINT_SERIAL,
    211 	    (void (*)(void *)) zsc_intr_soft, zsc);
    212 #ifdef DEBUG
    213 	assert(zsc->zsc_softintr_cookie);
    214 #endif
    215 }
    216 
    217 static int
    218 zsc_print(void *aux, const char *name)
    219 {
    220 	struct zsc_attach_args *args = aux;
    221 
    222 	if (name != NULL)
    223 		aprint_normal("%s: ", name);
    224 
    225 	if (args->channel != -1)
    226 		aprint_normal(" channel %d", args->channel);
    227 
    228 	return UNCONF;
    229 }
    230 
    231 #if defined(MVME162) || defined(MVME172)
    232 /*
    233  * Our ZS chips each have their own interrupt vector.
    234  */
    235 int
    236 zshard_unshared(void *arg)
    237 {
    238 	struct zsc_softc *zsc = arg;
    239 	int rval;
    240 
    241 	rval = zsc_intr_hard(zsc);
    242 
    243 	if (rval) {
    244 		if ((zsc->zsc_cs[0]->cs_softreq) ||
    245 		    (zsc->zsc_cs[1]->cs_softreq))
    246 			softint_schedule(zsc->zsc_softintr_cookie);
    247 		zsc->zsc_evcnt.ev_count++;
    248 	}
    249 
    250 	return rval;
    251 }
    252 #endif
    253 
    254 #ifdef MVME147
    255 /*
    256  * Our ZS chips all share a common, PCC-vectored interrupt,
    257  * so we have to look at all of them on each interrupt.
    258  */
    259 int
    260 zshard_shared(void *arg)
    261 {
    262 	struct zsc_softc *zsc;
    263 	int unit, rval;
    264 
    265 	rval = 0;
    266 	for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) {
    267 		zsc = device_lookup_private(&zsc_cd, unit);
    268 		if (zsc != NULL && zsc_intr_hard(zsc)) {
    269 			if ((zsc->zsc_cs[0]->cs_softreq) ||
    270 			    (zsc->zsc_cs[1]->cs_softreq))
    271 				softint_schedule(zsc->zsc_softintr_cookie);
    272 			zsc->zsc_evcnt.ev_count++;
    273 			rval++;
    274 		}
    275 	}
    276 	return rval;
    277 }
    278 #endif
    279 
    280 
    281 #if 0
    282 /*
    283  * Compute the current baud rate given a ZSCC channel.
    284  */
    285 static int
    286 zs_get_speed(struct zs_chanstate *cs)
    287 {
    288 	int tconst;
    289 
    290 	tconst = zs_read_reg(cs, 12);
    291 	tconst |= zs_read_reg(cs, 13) << 8;
    292 	return TCONST_TO_BPS(cs->cs_brg_clk, tconst);
    293 }
    294 #endif
    295 
    296 /*
    297  * MD functions for setting the baud rate and control modes.
    298  */
    299 int
    300 zs_set_speed(struct zs_chanstate *cs, int bps)
    301 {
    302 	int tconst, real_bps;
    303 
    304 	if (bps == 0)
    305 		return 0;
    306 
    307 #ifdef	DIAGNOSTIC
    308 	if (cs->cs_brg_clk == 0)
    309 		panic("zs_set_speed");
    310 #endif
    311 
    312 	tconst = BPS_TO_TCONST(cs->cs_brg_clk, bps);
    313 	if (tconst < 0)
    314 		return EINVAL;
    315 
    316 	/* Convert back to make sure we can do it. */
    317 	real_bps = TCONST_TO_BPS(cs->cs_brg_clk, tconst);
    318 
    319 	/* Allow 2% tolerance WRT the required bps */
    320 	if (((abs(real_bps - bps) * 1000) / bps) > 20)
    321 		return EINVAL;
    322 
    323 	cs->cs_preg[12] = tconst;
    324 	cs->cs_preg[13] = tconst >> 8;
    325 
    326 	/* Caller will stuff the pending registers. */
    327 	return 0;
    328 }
    329 
    330 int
    331 zs_set_modes(struct zs_chanstate *cs, int cflag)
    332 {
    333 	int s;
    334 
    335 	/*
    336 	 * Output hardware flow control on the chip is horrendous:
    337 	 * if carrier detect drops, the receiver is disabled, and if
    338 	 * CTS drops, the transmitter is stoped IN MID CHARACTER!
    339 	 * Therefore, NEVER set the HFC bit, and instead use the
    340 	 * status interrupt to detect CTS changes.
    341 	 */
    342 	s = splzs();
    343 	cs->cs_rr0_pps = 0;
    344 	if ((cflag & (CLOCAL | MDMBUF)) != 0) {
    345 		cs->cs_rr0_dcd = 0;
    346 		if ((cflag & MDMBUF) == 0)
    347 			cs->cs_rr0_pps = ZSRR0_DCD;
    348 	} else
    349 		cs->cs_rr0_dcd = ZSRR0_DCD;
    350 	if ((cflag & CRTSCTS) != 0) {
    351 		cs->cs_wr5_dtr = ZSWR5_DTR;
    352 		cs->cs_wr5_rts = ZSWR5_RTS;
    353 		cs->cs_rr0_cts = ZSRR0_CTS;
    354 	} else if ((cflag & MDMBUF) != 0) {
    355 		cs->cs_wr5_dtr = 0;
    356 		cs->cs_wr5_rts = ZSWR5_DTR;
    357 		cs->cs_rr0_cts = ZSRR0_DCD;
    358 	} else {
    359 		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
    360 		cs->cs_wr5_rts = 0;
    361 		cs->cs_rr0_cts = 0;
    362 	}
    363 	splx(s);
    364 
    365 	/* Caller will stuff the pending registers. */
    366 	return 0;
    367 }
    368 
    369 
    370 /*
    371  * Read or write the chip with suitable delays.
    372  */
    373 
    374 uint8_t
    375 zs_read_reg(struct zs_chanstate *cs, uint8_t reg)
    376 {
    377 	uint8_t val;
    378 
    379 	*cs->cs_reg_csr = reg;
    380 	ZS_DELAY();
    381 	val = *cs->cs_reg_csr;
    382 	ZS_DELAY();
    383 	return val;
    384 }
    385 
    386 void
    387 zs_write_reg(struct zs_chanstate *cs, uint8_t reg, uint8_t val)
    388 {
    389 
    390 	*cs->cs_reg_csr = reg;
    391 	ZS_DELAY();
    392 	*cs->cs_reg_csr = val;
    393 	ZS_DELAY();
    394 }
    395 
    396 uint8_t
    397 zs_read_csr(struct zs_chanstate *cs)
    398 {
    399 	uint8_t val;
    400 
    401 	val = *cs->cs_reg_csr;
    402 	ZS_DELAY();
    403 	return val;
    404 }
    405 
    406 void
    407 zs_write_csr(struct zs_chanstate *cs, uint8_t val)
    408 {
    409 
    410 	*cs->cs_reg_csr = val;
    411 	ZS_DELAY();
    412 }
    413 
    414 uint8_t
    415 zs_read_data(struct zs_chanstate *cs)
    416 {
    417 	uint8_t val;
    418 
    419 	val = *cs->cs_reg_data;
    420 	ZS_DELAY();
    421 	return val;
    422 }
    423 
    424 void
    425 zs_write_data(struct zs_chanstate *cs, uint8_t val)
    426 {
    427 
    428 	*cs->cs_reg_data = val;
    429 	ZS_DELAY();
    430 }
    431 
    432 /****************************************************************
    433  * Console support functions (MVME specific!)
    434  ****************************************************************/
    435 
    436 /*
    437  * Polled input char.
    438  */
    439 int
    440 zs_getc(void *arg)
    441 {
    442 	struct zs_chanstate *cs = arg;
    443 	int s, c, rr0, stat;
    444 
    445 	s = splhigh();
    446  top:
    447 	/* Wait for a character to arrive. */
    448 	do {
    449 		rr0 = *cs->cs_reg_csr;
    450 		ZS_DELAY();
    451 	} while ((rr0 & ZSRR0_RX_READY) == 0);
    452 
    453 	/* Read error register. */
    454 	stat = zs_read_reg(cs, 1) & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE);
    455 	if (stat) {
    456 		zs_write_csr(cs, ZSM_RESET_ERR);
    457 		goto top;
    458 	}
    459 
    460 	/* Read character. */
    461 	c = *cs->cs_reg_data;
    462 	ZS_DELAY();
    463 	splx(s);
    464 
    465 	return c;
    466 }
    467 
    468 /*
    469  * Polled output char.
    470  */
    471 void
    472 zs_putc(void *arg, int c)
    473 {
    474 	struct zs_chanstate *cs = arg;
    475 	int s, rr0;
    476 
    477 	s = splhigh();
    478 	/* Wait for transmitter to become ready. */
    479 	do {
    480 		rr0 = *cs->cs_reg_csr;
    481 		ZS_DELAY();
    482 	} while ((rr0 & ZSRR0_TX_READY) == 0);
    483 
    484 	*cs->cs_reg_data = c;
    485 	ZS_DELAY();
    486 	splx(s);
    487 }
    488 
    489 /*
    490  * Common parts of console init.
    491  */
    492 void
    493 zs_cnconfig(int zsc_unit, int channel, struct zsdevice *zs, int pclk)
    494 {
    495 	struct zs_chanstate *cs;
    496 	struct zschan *zc;
    497 
    498 	zc = (channel == 0) ? &zs->zs_chan_a : &zs->zs_chan_b;
    499 
    500 	/*
    501 	 * Pointer to channel state.  Later, the console channel
    502 	 * state is copied into the softc, and the console channel
    503 	 * pointer adjusted to point to the new copy.
    504 	 */
    505 	zs_conschan = cs = &zs_conschan_store;
    506 	zs_hwflags[zsc_unit][channel] = ZS_HWFLAG_CONSOLE;
    507 
    508 	/* Setup temporary chanstate. */
    509 	cs->cs_brg_clk = pclk / 16;
    510 	cs->cs_reg_csr  = zc->zc_csr;
    511 	cs->cs_reg_data = zc->zc_data;
    512 
    513 	/* Initialize the pending registers. */
    514 	memcpy(cs->cs_preg, zs_init_reg, 16);
    515 	cs->cs_preg[5] |= (ZSWR5_DTR | ZSWR5_RTS);
    516 
    517 #if 0
    518 	/* XXX: Preserve BAUD rate from boot loader. */
    519 	/* XXX: Also, why reset the chip here? -gwr */
    520 	cs->cs_defspeed = zs_get_speed(cs);
    521 #else
    522 	cs->cs_defspeed = 9600;	/* XXX */
    523 #endif
    524 	zs_set_speed(cs, cs->cs_defspeed);
    525 	cs->cs_creg[12] = cs->cs_preg[12];
    526 	cs->cs_creg[13] = cs->cs_preg[13];
    527 
    528 	/* Clear the master interrupt enable. */
    529 	zs_write_reg(cs, 9, 0);
    530 
    531 	/* Reset the whole SCC chip. */
    532 	zs_write_reg(cs, 9, ZSWR9_HARD_RESET);
    533 
    534 	/* Copy "pending" to "current" and H/W. */
    535 	zs_loadchannelregs(cs);
    536 }
    537 
    538 /*
    539  * Polled console input putchar.
    540  */
    541 int
    542 zsc_pcccngetc(dev_t dev)
    543 {
    544 	struct zs_chanstate *cs = zs_conschan;
    545 	int c;
    546 
    547 	c = zs_getc(cs);
    548 	return c;
    549 }
    550 
    551 /*
    552  * Polled console output putchar.
    553  */
    554 void
    555 zsc_pcccnputc(dev_t dev, int c)
    556 {
    557 	struct zs_chanstate *cs = zs_conschan;
    558 
    559 	zs_putc(cs, c);
    560 }
    561 
    562 /*
    563  * Handle user request to enter kernel debugger.
    564  */
    565 void
    566 zs_abort(struct zs_chanstate *cs)
    567 {
    568 	int rr0;
    569 
    570 	/* Wait for end of break to avoid PROM abort. */
    571 	/* XXX - Limit the wait? */
    572 	do {
    573 		rr0 = *cs->cs_reg_csr;
    574 		ZS_DELAY();
    575 	} while (rr0 & ZSRR0_BREAK);
    576 
    577 	mvme68k_abort("SERIAL LINE ABORT");
    578 }
    579