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