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