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