1 /* $NetBSD: zs.c,v 1.18 1997/12/16 17:53:12 wrstuden Exp $ */ 2 3 /* 4 * Copyright (c) 1996 Bill Studenmund 5 * Copyright (c) 1995 Gordon W. Ross 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 4. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by Gordon Ross 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Zilog Z8530 Dual UART driver (machine-dependent part) 36 * 37 * Runs two serial lines per chip using slave drivers. 38 * Plain tty/async lines use the zs_async slave. 39 * Sun keyboard/mouse uses the zs_kbd/zs_ms slaves. 40 * Other ports use their own mice & keyboard slaves. 41 * 42 * Credits & history: 43 * 44 * With NetBSD 1.1, port-mac68k started using a port of the port-sparc 45 * (port-sun3?) zs.c driver (which was in turn based on code in the 46 * Berkeley 4.4 Lite release). Bill Studenmund did the port, with 47 * help from Allen Briggs and Gordon Ross <gwr@netbsd.org>. Noud de 48 * Brouwer field-tested the driver at a local ISP. 49 * 50 * Bill Studenmund and Gordon Ross then ported the machine-independant 51 * z8530 driver to work with port-mac68k. NetBSD 1.2 contained an 52 * intermediate version (mac68k using a local, patched version of 53 * the m.i. drivers), with NetBSD 1.3 containing a full version. 54 */ 55 56 #include <sys/param.h> 57 #include <sys/systm.h> 58 #include <sys/proc.h> 59 #include <sys/device.h> 60 #include <sys/conf.h> 61 #include <sys/file.h> 62 #include <sys/ioctl.h> 63 #include <sys/tty.h> 64 #include <sys/time.h> 65 #include <sys/kernel.h> 66 #include <sys/syslog.h> 67 68 #include <dev/cons.h> 69 70 #include <dev/ic/z8530reg.h> 71 #include <machine/z8530var.h> 72 73 #include <machine/autoconf.h> 74 #include <machine/cpu.h> 75 #include <machine/viareg.h> 76 77 /* Are these in a header file anywhere? */ 78 /* Booter flags interface */ 79 #define ZSMAC_RAW 0x01 80 #define ZSMAC_LOCALTALK 0x02 81 #define ZS_STD_BRG (57600*4) 82 83 #include "zsc.h" /* get the # of zs chips defined */ 84 85 /* 86 * Some warts needed by z8530tty.c - 87 */ 88 int zs_def_cflag = (CREAD | CS8 | HUPCL); 89 int zs_major = 12; 90 91 /* 92 * abort detection on console will now timeout after iterating on a loop 93 * the following # of times. Cheep hack. Also, abort detection is turned 94 * off after a timeout (i.e. maybe there's not a terminal hooked up). 95 */ 96 #define ZSABORT_DELAY 3000000 97 98 /* 99 * Define interrupt levels. 100 */ 101 #define ZSHARD_PRI 4 /* Wired on the CPU board... */ 102 /* 103 * Serial port cards with zs chips on them are actually at the 104 * NuBus interrupt level, which is lower than 4. But blocking 105 * level 4 interrupts will block those interrupts too, so level 106 * 4 is fine. 107 */ 108 109 /* The layout of this is hardware-dependent (padding, order). */ 110 struct zschan { 111 volatile u_char zc_csr; /* ctrl,status, and indirect access */ 112 u_char zc_xxx0; 113 u_char zc_xxx1; /* part of the other channel lives here! */ 114 u_char zc_xxx2; /* Yea Apple! */ 115 volatile u_char zc_data; /* data */ 116 u_char zc_xxx3; 117 u_char zc_xxx4; 118 u_char zc_xxx5; 119 }; 120 121 /* Saved PROM mappings */ 122 static char *zsaddr[NZSC]; /* See zs_init() */ 123 /* Flags from cninit() */ 124 static int zs_hwflags[NZSC][2]; 125 /* Default speed for each channel */ 126 static int zs_defspeed[NZSC][2] = { 127 { 9600, /* tty00 */ 128 9600 }, /* tty01 */ 129 }; 130 /* console stuff */ 131 void *zs_conschan = 0; 132 int zs_consunit; 133 #ifdef ZS_CONSOLE_ABORT 134 int zs_cons_canabort = 1; 135 #else 136 int zs_cons_canabort = 0; 137 #endif /* ZS_CONSOLE_ABORT*/ 138 /* device to which the console is attached--if serial. */ 139 dev_t mac68k_zsdev; 140 /* Mac stuff */ 141 volatile unsigned char *sccA = 0; 142 143 static struct zschan *zs_get_chan_addr __P((int zsc_unit, int channel)); 144 void zs_init __P((void)); 145 int zs_cn_check_speed __P((int bps)); 146 147 /* 148 * Even though zsparam will set up the clock multiples, etc., we 149 * still set them here as: 1) mice & keyboards don't use zsparam, 150 * and 2) the console stuff uses these defaults before device 151 * attach. 152 */ 153 154 static u_char zs_init_reg[16] = { 155 0, /* 0: CMD (reset, etc.) */ 156 0, /* 1: No interrupts yet. */ 157 0x18 + ZSHARD_PRI, /* IVECT */ 158 ZSWR3_RX_8 | ZSWR3_RX_ENABLE, 159 ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP, 160 ZSWR5_TX_8 | ZSWR5_TX_ENABLE, 161 0, /* 6: TXSYNC/SYNCLO */ 162 0, /* 7: RXSYNC/SYNCHI */ 163 0, /* 8: alias for data port */ 164 ZSWR9_MASTER_IE, 165 0, /*10: Misc. TX/RX control bits */ 166 ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD, 167 14, /*12: BAUDLO (default=9600) */ 168 0, /*13: BAUDHI (default=9600) */ 169 ZSWR14_BAUD_ENA, 170 ZSWR15_BREAK_IE | ZSWR15_DCD_IE, 171 }; 172 173 static struct zschan * 174 zs_get_chan_addr(zsc_unit, channel) 175 int zsc_unit, channel; 176 { 177 char *addr; 178 struct zschan *zc; 179 180 if (zsc_unit >= NZSC) 181 return NULL; 182 addr = zsaddr[zsc_unit]; 183 if (addr == NULL) 184 return NULL; 185 if (channel == 0) { 186 zc = (struct zschan *)(addr +2); 187 /* handle the fact the ports are intertwined. */ 188 } else { 189 zc = (struct zschan *)(addr); 190 } 191 return (zc); 192 } 193 194 195 /* Find PROM mappings (for console support). */ 196 int zsinited = 0; /* 0 = not, 1 = inited, not attached, 2= attached */ 197 198 void 199 zs_init() 200 { 201 if ((zsinited == 2)&&(zsaddr[0] != (char *) sccA)) 202 panic("Moved zs0 address after attached!"); 203 zsaddr[0] = (char *) sccA; 204 zsinited = 1; 205 if (zs_conschan != 0){ /* we might have moved io under the console */ 206 zs_conschan = zs_get_chan_addr(0, zs_consunit); 207 /* so recalc the console port */ 208 } 209 } 210 211 212 /**************************************************************** 213 * Autoconfig 214 ****************************************************************/ 215 216 /* Definition of the driver for autoconfig. */ 217 static int zsc_match __P((struct device *, struct cfdata *, void *)); 218 static void zsc_attach __P((struct device *, struct device *, void *)); 219 static int zsc_print __P((void *, const char *name)); 220 221 struct cfattach zsc_ca = { 222 sizeof(struct zsc_softc), zsc_match, zsc_attach 223 }; 224 225 struct cfdriver zsc_cd = { 226 NULL, "zsc", DV_DULL 227 }; 228 229 int zshard __P((void *)); 230 int zssoft __P((void *)); 231 232 233 /* 234 * Is the zs chip present? 235 */ 236 static int 237 zsc_match(parent, cf, aux) 238 struct device *parent; 239 struct cfdata *cf; 240 void *aux; 241 { 242 return 1; 243 } 244 245 /* 246 * Attach a found zs. 247 * 248 * Match slave number to zs unit number, so that misconfiguration will 249 * not set up the keyboard as ttya, etc. 250 */ 251 static void 252 zsc_attach(parent, self, aux) 253 struct device *parent; 254 struct device *self; 255 void *aux; 256 { 257 struct zsc_softc *zsc = (void *) self; 258 struct zsc_attach_args zsc_args; 259 volatile struct zschan *zc; 260 struct xzs_chanstate *xcs; 261 struct zs_chanstate *cs; 262 int zsc_unit, channel; 263 int s, chip, theflags; 264 265 if (!zsinited) 266 zs_init(); 267 zsinited = 2; 268 269 zsc_unit = zsc->zsc_dev.dv_unit; 270 271 /* Make sure everything's inited ok. */ 272 if (zsaddr[zsc_unit] == NULL) 273 panic("zs_attach: zs%d not mapped\n", zsc_unit); 274 275 chip = 0; /* We'll deal with chip types post 1.2 */ 276 printf(" chip type %d \n",chip); 277 278 /* 279 * Initialize software state for each channel. 280 */ 281 for (channel = 0; channel < 2; channel++) { 282 zsc_args.channel = channel; 283 zsc_args.hwflags = zs_hwflags[zsc_unit][channel]; 284 xcs = &zsc->xzsc_xcs_store[channel]; 285 cs = &xcs->xzs_cs; 286 zsc->zsc_cs[channel] = cs; 287 288 cs->cs_channel = channel; 289 cs->cs_private = NULL; 290 cs->cs_ops = &zsops_null; 291 292 zc = zs_get_chan_addr(zsc_unit, channel); 293 cs->cs_reg_csr = &zc->zc_csr; 294 cs->cs_reg_data = &zc->zc_data; 295 296 bcopy(zs_init_reg, cs->cs_creg, 16); 297 bcopy(zs_init_reg, cs->cs_preg, 16); 298 299 /* Current BAUD rate generator clock. */ 300 cs->cs_brg_clk = ZS_STD_BRG; /* RTxC is 230400*16, so use 230400 */ 301 cs->cs_defspeed = zs_defspeed[zsc_unit][channel]; 302 cs->cs_defcflag = zs_def_cflag; 303 304 /* Make these correspond to cs_defcflag (-crtscts) */ 305 cs->cs_rr0_dcd = ZSRR0_DCD; 306 cs->cs_rr0_cts = 0; 307 cs->cs_wr5_dtr = ZSWR5_DTR; 308 cs->cs_wr5_rts = 0; 309 310 #ifdef __notyet__ 311 cs->cs_slave_type = ZS_SLAVE_NONE; 312 #endif 313 314 /* Define BAUD rate stuff. */ 315 xcs->cs_clocks[0].clk = ZS_STD_BRG * 16; 316 xcs->cs_clocks[0].flags = ZSC_RTXBRG; 317 xcs->cs_clocks[1].flags = 318 ZSC_RTXBRG | ZSC_RTXDIV | ZSC_VARIABLE | ZSC_EXTERN; 319 xcs->cs_clocks[2].flags = ZSC_TRXDIV | ZSC_VARIABLE; 320 xcs->cs_clock_count = 3; 321 if (channel == 0) { 322 theflags = mac68k_machine.modem_flags; 323 xcs->cs_clocks[1].clk = mac68k_machine.modem_dcd_clk; 324 xcs->cs_clocks[2].clk = mac68k_machine.modem_cts_clk; 325 } else { 326 theflags = mac68k_machine.print_flags; 327 xcs->cs_clocks[1].flags = ZSC_VARIABLE; 328 /* 329 * Yes, we aren't defining ANY clock source enables for the 330 * printer's DCD clock in. The hardware won't let us 331 * use it. But a clock will freak out the chip, so we 332 * let you set it, telling us to bar interrupts on the line. 333 */ 334 xcs->cs_clocks[1].clk = mac68k_machine.print_dcd_clk; 335 xcs->cs_clocks[2].clk = mac68k_machine.print_cts_clk; 336 } 337 if (xcs->cs_clocks[1].clk) 338 zsc_args.hwflags |= ZS_HWFLAG_NO_DCD; 339 if (xcs->cs_clocks[2].clk) 340 zsc_args.hwflags |= ZS_HWFLAG_NO_CTS; 341 342 printf("zsc%d channel %d: d_speed %6d DCD clk %ld CTS clk %ld", 343 zsc_unit, channel, cs->cs_defspeed, 344 xcs->cs_clocks[1].clk, xcs->cs_clocks[2].clk); 345 346 /* Set defaults in our "extended" chanstate. */ 347 xcs->cs_csource = 0; 348 xcs->cs_psource = 0; 349 xcs->cs_cclk_flag = 0; /* Nothing fancy by default */ 350 xcs->cs_pclk_flag = 0; 351 352 if (theflags & ZSMAC_RAW) { 353 zsc_args.hwflags |= ZS_HWFLAG_RAW; 354 printf(" (raw defaults)"); 355 } 356 357 /* 358 * XXX - This might be better done with a "stub" driver 359 * (to replace zstty) that ignores LocalTalk for now. 360 */ 361 if (theflags & ZSMAC_LOCALTALK) { 362 printf(" shielding from LocalTalk"); 363 cs->cs_defspeed = 1; 364 cs->cs_creg[ZSRR_BAUDLO] = cs->cs_preg[ZSRR_BAUDLO] = 0xff; 365 cs->cs_creg[ZSRR_BAUDHI] = cs->cs_preg[ZSRR_BAUDHI] = 0xff; 366 zs_write_reg(cs, ZSRR_BAUDLO, 0xff); 367 zs_write_reg(cs, ZSRR_BAUDHI, 0xff); 368 /* 369 * If we might have LocalTalk, then make sure we have the 370 * Baud rate low-enough to not do any damage. 371 */ 372 } 373 374 /* 375 * We used to disable chip interrupts here, but we now 376 * do that in zscnprobe, just in case MacOS left the chip on. 377 */ 378 379 xcs->cs_chip = chip; 380 381 /* Stash away a copy of the final H/W flags. */ 382 xcs->cs_hwflags = zsc_args.hwflags; 383 384 printf("\n"); 385 386 /* 387 * Look for a child driver for this channel. 388 * The child attach will setup the hardware. 389 */ 390 if (!config_found(self, (void *)&zsc_args, zsc_print)) { 391 /* No sub-driver. Just reset it. */ 392 u_char reset = (channel == 0) ? 393 ZSWR9_A_RESET : ZSWR9_B_RESET; 394 s = splzs(); 395 zs_write_reg(cs, 9, reset); 396 splx(s); 397 } 398 } 399 400 /* XXX - Now safe to install interrupt handlers. */ 401 402 /* 403 * Set the master interrupt enable and interrupt vector. 404 * (common to both channels, do it on A) 405 */ 406 cs = zsc->zsc_cs[0]; 407 s = splzs(); 408 /* interrupt vector */ 409 zs_write_reg(cs, 2, zs_init_reg[2]); 410 /* master interrupt control (enable) */ 411 zs_write_reg(cs, 9, zs_init_reg[9]); 412 splx(s); 413 } 414 415 static int 416 zsc_print(aux, name) 417 void *aux; 418 const char *name; 419 { 420 struct zsc_attach_args *args = aux; 421 422 if (name != NULL) 423 printf("%s: ", name); 424 425 if (args->channel != -1) 426 printf(" channel %d", args->channel); 427 428 return UNCONF; 429 } 430 431 int 432 zsmdioctl(cs, cmd, data) 433 struct zs_chanstate *cs; 434 u_long cmd; 435 caddr_t data; 436 { 437 switch (cmd) { 438 default: 439 return (-1); 440 } 441 return (0); 442 } 443 444 void 445 zsmd_setclock(cs) 446 struct zs_chanstate *cs; 447 { 448 struct xzs_chanstate *xcs = (void *)cs; 449 450 if (cs->cs_channel != 0) 451 return; 452 453 /* 454 * If the new clock has the external bit set, then select the 455 * external source. 456 */ 457 via_set_modem((xcs->cs_pclk_flag & ZSC_EXTERN) ? 1 : 0); 458 } 459 460 static int zssoftpending; 461 462 /* 463 * Our ZS chips all share a common, autovectored interrupt, 464 * so we have to look at all of them on each interrupt. 465 */ 466 int 467 zshard(arg) 468 void *arg; 469 { 470 register struct zsc_softc *zsc; 471 register int unit, rval; 472 473 rval = 0; 474 for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) { 475 zsc = zsc_cd.cd_devs[unit]; 476 if (zsc == NULL) 477 continue; 478 rval |= zsc_intr_hard(zsc); 479 if ((zsc->zsc_cs[0]->cs_softreq) || 480 (zsc->zsc_cs[1]->cs_softreq)) 481 { 482 /* zsc_req_softint(zsc); */ 483 /* We are at splzs here, so no need to lock. */ 484 if (zssoftpending == 0) { 485 zssoftpending = 1; 486 setsoftserial(); 487 } 488 } 489 } 490 return (rval); 491 } 492 493 /* 494 * Similar scheme as for zshard (look at all of them) 495 */ 496 int 497 zssoft(arg) 498 void *arg; 499 { 500 register struct zsc_softc *zsc; 501 register int unit; 502 503 /* This is not the only ISR on this IPL. */ 504 if (zssoftpending == 0) 505 return (0); 506 507 /* 508 * The soft intr. bit will be set by zshard only if 509 * the variable zssoftpending is zero. 510 */ 511 zssoftpending = 0; 512 513 for (unit = 0; unit < zsc_cd.cd_ndevs; ++unit) { 514 zsc = zsc_cd.cd_devs[unit]; 515 if (zsc == NULL) 516 continue; 517 (void) zsc_intr_soft(zsc); 518 } 519 return (1); 520 } 521 522 523 #ifndef ZS_TOLERANCE 524 #define ZS_TOLERANCE 51 525 /* 5% in tenths of a %, plus 1 so that exactly 5% will be ok. */ 526 #endif 527 528 /* 529 * check out a rate for acceptability from the internal clock 530 * source. Used in console config to validate a requested 531 * default speed. Placed here so that all the speed checking code is 532 * in one place. 533 * 534 * != 0 means ok. 535 */ 536 int 537 zs_cn_check_speed(bps) 538 int bps; /* target rate */ 539 { 540 int tc, rate; 541 542 tc = BPS_TO_TCONST(ZS_STD_BRG, bps); 543 if (tc < 0) 544 return 0; 545 rate = TCONST_TO_BPS(ZS_STD_BRG, tc); 546 if (ZS_TOLERANCE > abs(((rate - bps)*1000)/bps)) 547 return 1; 548 else 549 return 0; 550 } 551 552 /* 553 * Search through the signal sources in the channel, and 554 * pick the best one for the baud rate requested. Return 555 * a -1 if not achievable in tolerance. Otherwise return 0 556 * and fill in the values. 557 * 558 * This routine draws inspiration from the Atari port's zs.c 559 * driver in NetBSD 1.1 which did the same type of source switching. 560 * Tolerance code inspired by comspeed routine in isa/com.c. 561 * 562 * By Bill Studenmund, 1996-05-12 563 */ 564 int 565 zs_set_speed(cs, bps) 566 struct zs_chanstate *cs; 567 int bps; /* bits per second */ 568 { 569 struct xzs_chanstate *xcs = (void *) cs; 570 int i, tc, tc0 = 0, tc1, s, sf = 0; 571 int src, rate0, rate1, err, tol; 572 573 if (bps == 0) 574 return (0); 575 576 src = -1; /* no valid source yet */ 577 tol = ZS_TOLERANCE; 578 579 /* 580 * Step through all the sources and see which one matches 581 * the best. A source has to match BETTER than tol to be chosen. 582 * Thus if two sources give the same error, the first one will be 583 * chosen. Also, allow for the possability that one source might run 584 * both the BRG and the direct divider (i.e. RTxC). 585 */ 586 for (i=0; i < xcs->cs_clock_count; i++) { 587 if (xcs->cs_clocks[i].clk <= 0) 588 continue; /* skip non-existant or bad clocks */ 589 if (xcs->cs_clocks[i].flags & ZSC_BRG) { 590 /* check out BRG at /16 */ 591 tc1 = BPS_TO_TCONST(xcs->cs_clocks[i].clk >> 4, bps); 592 if (tc1 >= 0) { 593 rate1 = TCONST_TO_BPS(xcs->cs_clocks[i].clk >> 4, tc1); 594 err = abs(((rate1 - bps)*1000)/bps); 595 if (err < tol) { 596 tol = err; 597 src = i; 598 sf = xcs->cs_clocks[i].flags & ~ZSC_DIV; 599 tc0 = tc1; 600 rate0 = rate1; 601 } 602 } 603 } 604 if (xcs->cs_clocks[i].flags & ZSC_DIV) { 605 /* 606 * Check out either /1, /16, /32, or /64 607 * Note: for /1, you'd better be using a synchronized 608 * clock! 609 */ 610 int b0 = xcs->cs_clocks[i].clk, e0 = abs(b0-bps); 611 int b1 = b0 >> 4, e1 = abs(b1-bps); 612 int b2 = b1 >> 1, e2 = abs(b2-bps); 613 int b3 = b2 >> 1, e3 = abs(b3-bps); 614 615 if (e0 < e1 && e0 < e2 && e0 < e3) { 616 err = e0; 617 rate1 = b0; 618 tc1 = ZSWR4_CLK_X1; 619 } else if (e0 > e1 && e1 < e2 && e1 < e3) { 620 err = e1; 621 rate1 = b1; 622 tc1 = ZSWR4_CLK_X16; 623 } else if (e0 > e2 && e1 > e2 && e2 < e3) { 624 err = e2; 625 rate1 = b2; 626 tc1 = ZSWR4_CLK_X32; 627 } else { 628 err = e3; 629 rate1 = b3; 630 tc1 = ZSWR4_CLK_X64; 631 } 632 633 err = (err * 1000)/bps; 634 if (err < tol) { 635 tol = err; 636 src = i; 637 sf = xcs->cs_clocks[i].flags & ~ZSC_BRG; 638 tc0 = tc1; 639 rate0 = rate1; 640 } 641 } 642 } 643 #ifdef ZSMACDEBUG 644 zsprintf("Checking for rate %d. Found source #%d.\n",bps, src); 645 #endif 646 if (src == -1) 647 return (EINVAL); /* no can do */ 648 649 /* 650 * The M.I. layer likes to keep cs_brg_clk current, even though 651 * we are the only ones who should be touching the BRG's rate. 652 * 653 * Note: we are assuming that any ZSC_EXTERN signal source comes in 654 * on the RTxC pin. Correct for the mac68k obio zsc. 655 */ 656 if (sf & ZSC_EXTERN) 657 cs->cs_brg_clk = xcs->cs_clocks[i].clk >> 4; 658 else 659 cs->cs_brg_clk = ZS_STD_BRG; 660 661 /* 662 * Now we have a source, so set it up. 663 */ 664 s = splzs(); 665 xcs->cs_psource = src; 666 xcs->cs_pclk_flag = sf; 667 bps = rate0; 668 if (sf & ZSC_BRG) { 669 cs->cs_preg[4] = ZSWR4_CLK_X16; 670 cs->cs_preg[11]= ZSWR11_RXCLK_BAUD | ZSWR11_TXCLK_BAUD; 671 if (sf & ZSC_PCLK) { 672 cs->cs_preg[14] = ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK; 673 } else { 674 cs->cs_preg[14] = ZSWR14_BAUD_ENA; 675 } 676 tc = tc0; 677 } else { 678 cs->cs_preg[4] = tc0; 679 if (sf & ZSC_RTXDIV) { 680 cs->cs_preg[11] = ZSWR11_RXCLK_RTXC | ZSWR11_TXCLK_RTXC; 681 } else { 682 cs->cs_preg[11] = ZSWR11_RXCLK_TRXC | ZSWR11_TXCLK_TRXC; 683 } 684 cs->cs_preg[14]= 0; 685 tc = 0xffff; 686 } 687 /* Set the BAUD rate divisor. */ 688 cs->cs_preg[12] = tc; 689 cs->cs_preg[13] = tc >> 8; 690 splx(s); 691 692 #ifdef ZSMACDEBUG 693 zsprintf("Rate is %7d, tc is %7d, source no. %2d, flags %4x\n", \ 694 bps, tc, src, sf); 695 zsprintf("Registers are: 4 %x, 11 %x, 14 %x\n\n", 696 cs->cs_preg[4], cs->cs_preg[11], cs->cs_preg[14]); 697 #endif 698 699 cs->cs_preg[5] |= ZSWR5_RTS; /* Make sure the drivers are on! */ 700 701 /* Caller will stuff the pending registers. */ 702 return (0); 703 } 704 705 int 706 zs_set_modes(cs, cflag) 707 struct zs_chanstate *cs; 708 int cflag; /* bits per second */ 709 { 710 struct xzs_chanstate *xcs = (void*)cs; 711 int s; 712 713 /* 714 * Make sure we don't enable hfc on a signal line we're ignoring. 715 * As we enable CTS interrupts only if we have CRTSCTS or CDTRCTS, 716 * this code also effectivly turns off ZSWR15_CTS_IE. 717 * 718 * Also, disable DCD interrupts if we've been told to ignore 719 * the DCD pin. Happens on mac68k because the input line for 720 * DCD can also be used as a clock input. (Just set CLOCAL.) 721 * 722 * If someone tries to turn an invalid flow mode on, Just Say No 723 * (Suggested by gwr) 724 */ 725 if ((cflag & CDTRCTS) && (cflag & (CRTSCTS | MDMBUF))) 726 return (EINVAL); 727 if (xcs->cs_hwflags & ZS_HWFLAG_NO_DCD) { 728 if (cflag & MDMBUF) 729 return (EINVAL); 730 cflag |= CLOCAL; 731 } 732 if ((xcs->cs_hwflags & ZS_HWFLAG_NO_CTS) && (cflag & (CRTSCTS | CDTRCTS))) 733 return (EINVAL); 734 735 /* 736 * Output hardware flow control on the chip is horrendous: 737 * if carrier detect drops, the receiver is disabled, and if 738 * CTS drops, the transmitter is stoped IN MID CHARACTER! 739 * Therefore, NEVER set the HFC bit, and instead use the 740 * status interrupt to detect CTS changes. 741 */ 742 s = splzs(); 743 if ((cflag & (CLOCAL | MDMBUF)) != 0) 744 cs->cs_rr0_dcd = 0; 745 else 746 cs->cs_rr0_dcd = ZSRR0_DCD; 747 /* 748 * The mac hardware only has one output, DTR (HSKo in Mac 749 * parlance). In HFC mode, we use it for the functions 750 * typically served by RTS and DTR on other ports, so we 751 * have to fake the upper layer out some. 752 * 753 * CRTSCTS we use CTS as an input which tells us when to shut up. 754 * We make no effort to shut up the other side of the connection. 755 * DTR is used to hang up the modem. 756 * 757 * In CDTRCTS, we use CTS to tell us to stop, but we use DTR to 758 * shut up the other side. 759 */ 760 if ((cflag & CRTSCTS) != 0) { 761 cs->cs_wr5_dtr = ZSWR5_DTR; 762 cs->cs_wr5_rts = 0; 763 cs->cs_rr0_cts = ZSRR0_CTS; 764 } else if ((cflag & CDTRCTS) != 0) { 765 cs->cs_wr5_dtr = 0; 766 cs->cs_wr5_rts = ZSWR5_DTR; 767 cs->cs_rr0_cts = ZSRR0_CTS; 768 } else if ((cflag & MDMBUF) != 0) { 769 cs->cs_wr5_dtr = 0; 770 cs->cs_wr5_rts = ZSWR5_DTR; 771 cs->cs_rr0_cts = ZSRR0_DCD; 772 } else { 773 cs->cs_wr5_dtr = ZSWR5_DTR; 774 cs->cs_wr5_rts = 0; 775 cs->cs_rr0_cts = 0; 776 } 777 splx(s); 778 779 /* Caller will stuff the pending registers. */ 780 return (0); 781 } 782 783 784 /* 785 * Read or write the chip with suitable delays. 786 * MacII hardware has the delay built in. 787 * No need for extra delay. :-) However, some clock-chirped 788 * macs, or zsc's on serial add-on boards might need it. 789 */ 790 #define ZS_DELAY() 791 792 u_char 793 zs_read_reg(cs, reg) 794 struct zs_chanstate *cs; 795 u_char reg; 796 { 797 u_char val; 798 799 *cs->cs_reg_csr = reg; 800 ZS_DELAY(); 801 val = *cs->cs_reg_csr; 802 ZS_DELAY(); 803 return val; 804 } 805 806 void 807 zs_write_reg(cs, reg, val) 808 struct zs_chanstate *cs; 809 u_char reg, val; 810 { 811 *cs->cs_reg_csr = reg; 812 ZS_DELAY(); 813 *cs->cs_reg_csr = val; 814 ZS_DELAY(); 815 } 816 817 u_char zs_read_csr(cs) 818 struct zs_chanstate *cs; 819 { 820 register u_char val; 821 822 val = *cs->cs_reg_csr; 823 ZS_DELAY(); 824 /* make up for the fact CTS is wired backwards */ 825 val ^= ZSRR0_CTS; 826 return val; 827 } 828 829 void zs_write_csr(cs, val) 830 struct zs_chanstate *cs; 831 u_char val; 832 { 833 /* Note, the csr does not write CTS... */ 834 *cs->cs_reg_csr = val; 835 ZS_DELAY(); 836 } 837 838 u_char zs_read_data(cs) 839 struct zs_chanstate *cs; 840 { 841 register u_char val; 842 843 val = *cs->cs_reg_data; 844 ZS_DELAY(); 845 return val; 846 } 847 848 void zs_write_data(cs, val) 849 struct zs_chanstate *cs; 850 u_char val; 851 { 852 *cs->cs_reg_data = val; 853 ZS_DELAY(); 854 } 855 856 /**************************************************************** 857 * Console support functions (mac68k specific!) 858 * Note: this code is allowed to know about the layout of 859 * the chip registers, and uses that to keep things simple. 860 * XXX - I think I like the mvme167 code better. -gwr 861 * XXX - Well :-P :-) -wrs 862 ****************************************************************/ 863 864 #define zscnpollc nullcnpollc 865 cons_decl(zs); 866 867 static void zs_putc __P((register volatile struct zschan *, int)); 868 static int zs_getc __P((register volatile struct zschan *)); 869 static void zscnsetup __P((void)); 870 extern int zsopen __P(( dev_t dev, int flags, int mode, struct proc *p)); 871 872 /* 873 * Console functions. 874 */ 875 876 /* 877 * This code modled after the zs_setparam routine in zskgdb 878 * It sets the console unit to a known state so we can output 879 * correctly. 880 */ 881 static void 882 zscnsetup() 883 { 884 struct xzs_chanstate xcs; 885 struct zs_chanstate *cs; 886 struct zschan *zc; 887 int tconst, s; 888 889 /* Setup temporary chanstate. */ 890 bzero((caddr_t)&xcs, sizeof(xcs)); 891 cs = &xcs.xzs_cs; 892 zc = zs_conschan; 893 cs->cs_reg_csr = &zc->zc_csr; 894 cs->cs_reg_data = &zc->zc_data; 895 cs->cs_channel = zs_consunit; 896 cs->cs_brg_clk = ZS_STD_BRG; 897 898 bcopy(zs_init_reg, cs->cs_preg, 16); 899 cs->cs_preg[5] |= ZSWR5_DTR | ZSWR5_RTS; 900 cs->cs_preg[15] = ZSWR15_BREAK_IE; 901 tconst = BPS_TO_TCONST(cs->cs_brg_clk, 902 zs_defspeed[0][zs_consunit]); 903 cs->cs_preg[12] = tconst; 904 cs->cs_preg[13] = tconst >> 8; 905 /* can't use zs_set_speed as we haven't set up the 906 * signal sources, and it's not worth it for now 907 */ 908 909 cs->cs_preg[9] &= ~ZSWR9_MASTER_IE; 910 /* no interrupts until later, after attach. */ 911 s = splhigh(); 912 zs_loadchannelregs(cs); 913 splx(s); 914 } 915 916 /* 917 * zscnprobe is the routine which gets called as the kernel is trying to 918 * figure out where the console should be. Each io driver which might 919 * be the console (as defined in mac68k/conf.c) gets probed. The probe 920 * fills in the consdev structure. Important parts are the device #, 921 * and the console priority. Values are CN_DEAD (don't touch me), 922 * CN_NORMAL (I'm here, but elsewhere might be better), CN_INTERNAL 923 * (the video, better than CN_NORMAL), and CN_REMOTE (pick me!) 924 * 925 * As the mac's a bit different, we do extra work here. We mainly check 926 * to see if we have serial echo going on. Also chould check for default 927 * speeds. 928 */ 929 void 930 zscnprobe(struct consdev * cp) 931 { 932 extern u_long IOBase; 933 int maj, unit, i; 934 935 for (maj = 0; maj < nchrdev; maj++) { 936 if (cdevsw[maj].d_open == zsopen) { 937 break; 938 } 939 } 940 if (maj != nchrdev) { 941 cp->cn_pri = CN_NORMAL; /* Lower than CN_INTERNAL */ 942 if (mac68k_machine.serial_console != 0) { 943 cp->cn_pri = CN_REMOTE; /* Higher than CN_INTERNAL */ 944 mac68k_machine.serial_boot_echo =0; 945 } 946 947 unit = (mac68k_machine.serial_console == 1) ? 0 : 1; 948 zs_consunit = unit; 949 zs_conschan = (struct zschan *) -1; /* dummy flag for zs_init() */ 950 951 mac68k_zsdev = cp->cn_dev = makedev(maj, unit); 952 } 953 if (mac68k_machine.serial_boot_echo) { 954 /* 955 * at this point, we know that we don't have a serial 956 * console, but are doing echo 957 */ 958 zs_conschan = (struct zschan *) -1; /* dummy flag for zs_init() */ 959 zs_consunit = 1; 960 zs_hwflags[0][zs_consunit] = ZS_HWFLAG_CONSOLE; 961 } 962 963 if ((i = mac68k_machine.modem_d_speed) > 0) { 964 if (zs_cn_check_speed(i)) 965 zs_defspeed[0][0] = i; 966 } 967 if ((i = mac68k_machine.print_d_speed) > 0) { 968 if (zs_cn_check_speed(i)) 969 zs_defspeed[0][1] = i; 970 } 971 mac68k_set_io_offsets(IOBase); 972 zs_init(); 973 /* 974 * zsinit will set up the addresses of the scc. It will also, if 975 * zs_conschan != 0, calculate the new address of the conschan for 976 * unit zs_consunit. So if we are (or think we are) going to use the 977 * chip for console I/O, we just set up the internal addresses for it. 978 * 979 * Now turn off interrupts for the chip. Note: this code piece is the 980 * only vestage of the NetBSD 1.0 ser driver. :-) 981 */ 982 sccA[2] = 9; sccA[2] = 0; /* write 0 to register 9, clearing MIE */ 983 984 if (mac68k_machine.serial_boot_echo) 985 zscnsetup(); 986 return; 987 } 988 989 void 990 zscninit(struct consdev * cp) 991 { 992 993 zs_hwflags[0][zs_consunit] = ZS_HWFLAG_CONSOLE; 994 /* 995 * zsinit will set up the addresses of the scc. It will also, if 996 * zs_conschan != 0, calculate the new address of the conschan for 997 * unit zs_consunit. So zs_init implicitly sets zs_conschan to the right 998 * number. :-) 999 */ 1000 zscnsetup(); 1001 printf("\nNetBSD/mac68k console\n"); 1002 } 1003 1004 1005 /* 1006 * Polled input char. 1007 */ 1008 static int 1009 zs_getc(zc) 1010 register volatile struct zschan *zc; 1011 { 1012 register int s, c, rr0; 1013 1014 s = splhigh(); 1015 /* Wait for a character to arrive. */ 1016 do { 1017 rr0 = zc->zc_csr; 1018 ZS_DELAY(); 1019 } while ((rr0 & ZSRR0_RX_READY) == 0); 1020 1021 c = zc->zc_data; 1022 ZS_DELAY(); 1023 splx(s); 1024 1025 /* 1026 * This is used by the kd driver to read scan codes, 1027 * so don't translate '\r' ==> '\n' here... 1028 */ 1029 return (c); 1030 } 1031 1032 /* 1033 * Polled output char. 1034 */ 1035 static void 1036 zs_putc(zc, c) 1037 register volatile struct zschan *zc; 1038 int c; 1039 { 1040 register int s, rr0; 1041 register long wait = 0; 1042 1043 s = splhigh(); 1044 /* Wait for transmitter to become ready. */ 1045 do { 1046 rr0 = zc->zc_csr; 1047 ZS_DELAY(); 1048 } while (((rr0 & ZSRR0_TX_READY) == 0) && (wait++ < 1000000)); 1049 1050 if ((rr0 & ZSRR0_TX_READY) != 0) { 1051 zc->zc_data = c; 1052 ZS_DELAY(); 1053 } 1054 splx(s); 1055 } 1056 1057 1058 /* 1059 * Polled console input putchar. 1060 */ 1061 int 1062 zscngetc(dev) 1063 dev_t dev; 1064 { 1065 register volatile struct zschan *zc = zs_conschan; 1066 register int c; 1067 1068 c = zs_getc(zc); 1069 return (c); 1070 } 1071 1072 /* 1073 * Polled console output putchar. 1074 */ 1075 void 1076 zscnputc(dev, c) 1077 dev_t dev; 1078 int c; 1079 { 1080 register volatile struct zschan *zc = zs_conschan; 1081 1082 zs_putc(zc, c); 1083 } 1084 1085 1086 1087 /* 1088 * Handle user request to enter kernel debugger. 1089 */ 1090 void 1091 zs_abort(cs) 1092 struct zs_chanstate *cs; 1093 { 1094 volatile struct zschan *zc = zs_conschan; 1095 int rr0; 1096 register long wait = 0; 1097 1098 if (zs_cons_canabort == 0) 1099 return; 1100 1101 /* Wait for end of break to avoid PROM abort. */ 1102 do { 1103 rr0 = zc->zc_csr; 1104 ZS_DELAY(); 1105 } while ((rr0 & ZSRR0_BREAK) && (wait++ < ZSABORT_DELAY)); 1106 1107 if (wait > ZSABORT_DELAY) { 1108 zs_cons_canabort = 0; 1109 /* If we time out, turn off the abort ability! */ 1110 } 1111 1112 #ifdef DDB 1113 Debugger(); 1114 #endif 1115 } 1116 1117