1 /* $NetBSD: zs.c,v 1.39 1996/08/27 21:57:45 cgd Exp $ */ 2 3 /* 4 * Copyright (c) 1995 Gordon W. Ross 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 4. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by Gordon Ross 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Zilog Z8530 Dual UART driver (machine-dependent part) 35 * 36 * Runs two serial lines per chip using slave drivers. 37 * Plain tty/async lines use the zs_async slave. 38 * Sun keyboard/mouse uses the zs_kbd/zs_ms slaves. 39 */ 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/proc.h> 44 #include <sys/device.h> 45 #include <sys/conf.h> 46 #include <sys/file.h> 47 #include <sys/ioctl.h> 48 #include <sys/tty.h> 49 #include <sys/time.h> 50 #include <sys/kernel.h> 51 #include <sys/syslog.h> 52 53 #include <dev/cons.h> 54 #include <dev/ic/z8530reg.h> 55 #include <machine/z8530var.h> 56 57 #include <machine/autoconf.h> 58 #include <machine/cpu.h> 59 #include <machine/isr.h> 60 #include <machine/obio.h> 61 #include <machine/mon.h> 62 63 /* 64 * XXX: Hard code this to make console init easier... 65 */ 66 #define NZS 2 /* XXX */ 67 68 69 /* The Sun3 provides a 4.9152 MHz clock to the ZS chips. */ 70 #define PCLK (9600 * 512) /* PCLK pin input clock rate */ 71 72 /* 73 * Define interrupt levels. 74 */ 75 #define ZSHARD_PRI 6 /* Wired on the CPU board... */ 76 #define ZSSOFT_PRI 3 /* Want tty pri (4) but this is OK. */ 77 78 #define ZS_DELAY() delay(2) 79 80 /* The layout of this is hardware-dependent (padding, order). */ 81 struct zschan { 82 volatile u_char zc_csr; /* ctrl,status, and indirect access */ 83 u_char zc_xxx0; 84 volatile u_char zc_data; /* data */ 85 u_char zc_xxx1; 86 }; 87 struct zsdevice { 88 /* Yes, they are backwards. */ 89 struct zschan zs_chan_b; 90 struct zschan zs_chan_a; 91 }; 92 93 94 /* Default OBIO addresses. */ 95 static int zs_physaddr[NZS] = { OBIO_KEYBD_MS, OBIO_ZS }; 96 /* Saved PROM mappings */ 97 static struct zsdevice *zsaddr[NZS]; /* See zs_init() */ 98 /* Flags from cninit() */ 99 static int zs_hwflags[NZS][2]; 100 /* Default speed for each channel */ 101 static int zs_defspeed[NZS][2] = { 102 { 1200, /* keyboard */ 103 1200 }, /* mouse */ 104 { 9600, /* ttya */ 105 9600 }, /* ttyb */ 106 }; 107 108 109 /* Find PROM mappings (for console support). */ 110 void zs_init() 111 { 112 int i; 113 114 for (i = 0; i < NZS; i++) { 115 zsaddr[i] = (struct zsdevice *) 116 obio_find_mapping(zs_physaddr[i], OBIO_ZS_SIZE); 117 } 118 } 119 120 121 struct zschan * 122 zs_get_chan_addr(zsc_unit, channel) 123 int zsc_unit, channel; 124 { 125 struct zsdevice *addr; 126 struct zschan *zc; 127 128 if (zsc_unit >= NZS) 129 return NULL; 130 addr = zsaddr[zsc_unit]; 131 if (addr == NULL) 132 return NULL; 133 if (channel == 0) { 134 zc = &addr->zs_chan_a; 135 } else { 136 zc = &addr->zs_chan_b; 137 } 138 return (zc); 139 } 140 141 142 static u_char zs_init_reg[16] = { 143 0, /* 0: CMD (reset, etc.) */ 144 ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE, 145 0x18 + ZSHARD_PRI, /* IVECT */ 146 ZSWR3_RX_8 | ZSWR3_RX_ENABLE, 147 ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP, 148 ZSWR5_TX_8 | ZSWR5_TX_ENABLE, 149 0, /* 6: TXSYNC/SYNCLO */ 150 0, /* 7: RXSYNC/SYNCHI */ 151 0, /* 8: alias for data port */ 152 ZSWR9_MASTER_IE, 153 0, /*10: Misc. TX/RX control bits */ 154 ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD, 155 14, /*12: BAUDLO (default=9600) */ 156 0, /*13: BAUDHI (default=9600) */ 157 ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA, 158 ZSWR15_BREAK_IE | ZSWR15_DCD_IE, 159 }; 160 161 162 /**************************************************************** 163 * Autoconfig 164 ****************************************************************/ 165 166 /* Definition of the driver for autoconfig. */ 167 static int zsc_match __P((struct device *, void *, void *)); 168 static void zsc_attach __P((struct device *, struct device *, void *)); 169 static int zsc_print __P((void *, const char *name)); 170 171 struct cfattach zsc_ca = { 172 sizeof(struct zsc_softc), zsc_match, zsc_attach 173 }; 174 175 struct cfdriver zsc_cd = { 176 NULL, "zsc", DV_DULL 177 }; 178 179 static int zshard(void *); 180 static int zssoft(void *); 181 182 183 /* 184 * Is the zs chip present? 185 */ 186 static int 187 zsc_match(parent, vcf, aux) 188 struct device *parent; 189 void *vcf, *aux; 190 { 191 struct cfdata *cf = vcf; 192 struct confargs *ca = aux; 193 int pa, unit, x; 194 void *va; 195 196 unit = cf->cf_unit; 197 if (unit < 0 || unit >= NZS) 198 return (0); 199 200 /* 201 * OBIO match functions may be called for every possible 202 * physical address, so match only our physical address. 203 * This driver only supports its default mappings, so 204 * non-default locators must match our defaults. 205 */ 206 if ((pa = cf->cf_paddr) == -1) { 207 /* Use our default PA. */ 208 pa = zs_physaddr[unit]; 209 } else { 210 /* Validate the given PA. */ 211 if (pa != zs_physaddr[unit]) 212 return (0); 213 } 214 if (pa != ca->ca_paddr) 215 return (0); 216 217 /* Make sure zs_init() found mappings. */ 218 va = zsaddr[unit]; 219 if (va == NULL) 220 return (0); 221 222 /* This returns -1 on a fault (bus error). */ 223 x = peek_byte(va); 224 return (x != -1); 225 } 226 227 /* 228 * Attach a found zs. 229 * 230 * Match slave number to zs unit number, so that misconfiguration will 231 * not set up the keyboard as ttya, etc. 232 */ 233 static void 234 zsc_attach(parent, self, aux) 235 struct device *parent; 236 struct device *self; 237 void *aux; 238 { 239 struct zsc_softc *zsc = (void *) self; 240 struct cfdata *cf = self->dv_cfdata; 241 struct confargs *ca = aux; 242 struct zsc_attach_args zsc_args; 243 volatile struct zschan *zc; 244 struct zs_chanstate *cs; 245 int zsc_unit, intpri, channel; 246 int reset, s; 247 static int didintr; 248 249 zsc_unit = zsc->zsc_dev.dv_unit; 250 251 if ((intpri = cf->cf_intpri) == -1) 252 intpri = ZSHARD_PRI; 253 254 printf(" level %d (softpri %d)\n", intpri, ZSSOFT_PRI); 255 256 /* Use the mapping setup by the Sun PROM. */ 257 if (zsaddr[zsc_unit] == NULL) 258 panic("zs_attach: zs%d not mapped\n", zsc_unit); 259 260 /* 261 * Initialize software state for each channel. 262 */ 263 for (channel = 0; channel < 2; channel++) { 264 cs = &zsc->zsc_cs[channel]; 265 266 zc = zs_get_chan_addr(zsc_unit, channel); 267 cs->cs_reg_csr = &zc->zc_csr; 268 cs->cs_reg_data = &zc->zc_data; 269 270 cs->cs_channel = channel; 271 cs->cs_private = NULL; 272 cs->cs_ops = &zsops_null; 273 274 /* Define BAUD rate clock for the MI code. */ 275 cs->cs_brg_clk = PCLK / 16; 276 277 /* XXX: get defspeed from EEPROM instead? */ 278 cs->cs_defspeed = zs_defspeed[zsc_unit][channel]; 279 280 bcopy(zs_init_reg, cs->cs_creg, 16); 281 bcopy(zs_init_reg, cs->cs_preg, 16); 282 283 /* 284 * Clear the master interrupt enable. 285 * The INTENA is common to both channels, 286 * so just do it on the A channel. 287 */ 288 if (channel == 0) { 289 zs_write_reg(cs, 9, 0); 290 } 291 292 /* 293 * Look for a child driver for this channel. 294 * The child attach will setup the hardware. 295 */ 296 zsc_args.channel = channel; 297 zsc_args.hwflags = zs_hwflags[zsc_unit][channel]; 298 if (config_found(self, (void *)&zsc_args, zsc_print) == NULL) { 299 /* No sub-driver. Just reset it. */ 300 reset = (channel == 0) ? 301 ZSWR9_A_RESET : ZSWR9_B_RESET; 302 s = splzs(); 303 zs_write_reg(cs, 9, reset); 304 splx(s); 305 } 306 } 307 308 /* Now safe to install interrupt handlers */ 309 if (!didintr) { 310 didintr = 1; 311 isr_add_autovect(zssoft, NULL, ZSSOFT_PRI); 312 isr_add_autovect(zshard, NULL, ZSHARD_PRI); 313 } 314 315 /* 316 * Set the master interrupt enable and interrupt vector. 317 * (common to both channels, do it on A) 318 */ 319 cs = &zsc->zsc_cs[0]; 320 s = splzs(); 321 /* interrupt vector */ 322 zs_write_reg(cs, 2, zs_init_reg[2]); 323 /* master interrupt control (enable) */ 324 zs_write_reg(cs, 9, zs_init_reg[9]); 325 splx(s); 326 } 327 328 static int 329 zsc_print(aux, name) 330 void *aux; 331 const char *name; 332 { 333 struct zsc_attach_args *args = aux; 334 335 if (name != NULL) 336 printf("%s: ", name); 337 338 if (args->channel != -1) 339 printf(" channel %d", args->channel); 340 341 return UNCONF; 342 } 343 344 static int 345 zshard(arg) 346 void *arg; 347 { 348 struct zsc_softc *zsc; 349 int unit, rval; 350 351 /* Do ttya/ttyb first, because they go faster. */ 352 rval = 0; 353 unit = zsc_cd.cd_ndevs; 354 while (--unit >= 0) { 355 zsc = zsc_cd.cd_devs[unit]; 356 if (zsc != NULL) { 357 rval |= zsc_intr_hard(zsc); 358 } 359 } 360 return (rval); 361 } 362 363 int zssoftpending; 364 365 void 366 zsc_req_softint(zsc) 367 struct zsc_softc *zsc; 368 { 369 if (zssoftpending == 0) { 370 /* We are at splzs here, so no need to lock. */ 371 zssoftpending = ZSSOFT_PRI; 372 isr_soft_request(ZSSOFT_PRI); 373 } 374 } 375 376 static int 377 zssoft(arg) 378 void *arg; 379 { 380 struct zsc_softc *zsc; 381 int unit; 382 383 /* This is not the only ISR on this IPL. */ 384 if (zssoftpending == 0) 385 return (0); 386 387 /* 388 * The soft intr. bit will be set by zshard only if 389 * the variable zssoftpending is zero. The order of 390 * these next two statements prevents our clearing 391 * the soft intr bit just after zshard has set it. 392 */ 393 isr_soft_clear(ZSSOFT_PRI); 394 zssoftpending = 0; 395 396 /* Do ttya/ttyb first, because they go faster. */ 397 unit = zsc_cd.cd_ndevs; 398 while (--unit >= 0) { 399 zsc = zsc_cd.cd_devs[unit]; 400 if (zsc != NULL) { 401 (void) zsc_intr_soft(zsc); 402 } 403 } 404 return (1); 405 } 406 407 408 /* 409 * Read or write the chip with suitable delays. 410 */ 411 412 u_char 413 zs_read_reg(cs, reg) 414 struct zs_chanstate *cs; 415 u_char reg; 416 { 417 u_char val; 418 419 *cs->cs_reg_csr = reg; 420 ZS_DELAY(); 421 val = *cs->cs_reg_csr; 422 ZS_DELAY(); 423 return val; 424 } 425 426 void 427 zs_write_reg(cs, reg, val) 428 struct zs_chanstate *cs; 429 u_char reg, val; 430 { 431 *cs->cs_reg_csr = reg; 432 ZS_DELAY(); 433 *cs->cs_reg_csr = val; 434 ZS_DELAY(); 435 } 436 437 u_char zs_read_csr(cs) 438 struct zs_chanstate *cs; 439 { 440 register u_char v; 441 442 v = *cs->cs_reg_csr; 443 ZS_DELAY(); 444 return v; 445 } 446 447 u_char zs_read_data(cs) 448 struct zs_chanstate *cs; 449 { 450 register u_char v; 451 452 v = *cs->cs_reg_data; 453 ZS_DELAY(); 454 return v; 455 } 456 457 void zs_write_csr(cs, val) 458 struct zs_chanstate *cs; 459 u_char val; 460 { 461 *cs->cs_reg_csr = val; 462 ZS_DELAY(); 463 } 464 465 void zs_write_data(cs, val) 466 struct zs_chanstate *cs; 467 u_char val; 468 { 469 *cs->cs_reg_data = val; 470 ZS_DELAY(); 471 } 472 473 /**************************************************************** 474 * Console support functions (Sun3 specific!) 475 ****************************************************************/ 476 477 /* 478 * Polled input char. 479 */ 480 int 481 zs_getc(arg) 482 void *arg; 483 { 484 register volatile struct zschan *zc = arg; 485 register int s, c, rr0; 486 487 s = splhigh(); 488 /* Wait for a character to arrive. */ 489 do { 490 rr0 = zc->zc_csr; 491 ZS_DELAY(); 492 } while ((rr0 & ZSRR0_RX_READY) == 0); 493 494 c = zc->zc_data; 495 ZS_DELAY(); 496 splx(s); 497 498 /* 499 * This is used by the kd driver to read scan codes, 500 * so don't translate '\r' ==> '\n' here... 501 */ 502 return (c); 503 } 504 505 /* 506 * Polled output char. 507 */ 508 void 509 zs_putc(arg, c) 510 void *arg; 511 int c; 512 { 513 register volatile struct zschan *zc = arg; 514 register int s, rr0; 515 516 s = splhigh(); 517 /* Wait for transmitter to become ready. */ 518 do { 519 rr0 = zc->zc_csr; 520 ZS_DELAY(); 521 } while ((rr0 & ZSRR0_TX_READY) == 0); 522 523 zc->zc_data = c; 524 ZS_DELAY(); 525 splx(s); 526 } 527 528 extern struct consdev consdev_kd; /* keyboard/display */ 529 extern struct consdev consdev_tty; 530 extern struct consdev *cn_tab; /* physical console device info */ 531 extern void nullcnpollc(); 532 533 void *zs_conschan; 534 535 /* 536 * This function replaces sys/dev/cninit.c 537 * Determine which device is the console using 538 * the PROM "input source" and "output sink". 539 */ 540 void 541 cninit() 542 { 543 MachMonRomVector *v; 544 struct zschan *zc; 545 struct consdev *cn; 546 int zsc_unit, channel; 547 char inSource; 548 549 v = romVectorPtr; 550 inSource = *(v->inSource); 551 552 if (inSource != *(v->outSink)) { 553 mon_printf("cninit: mismatched PROM output selector\n"); 554 } 555 556 switch (inSource) { 557 558 case 1: /* ttya */ 559 case 2: /* ttyb */ 560 zsc_unit = 1; 561 channel = inSource - 1; 562 cn = &consdev_tty; 563 cn->cn_dev = makedev(ZSTTY_MAJOR, channel); 564 cn->cn_pri = CN_REMOTE; 565 break; 566 567 case 3: /* ttyc (rewired keyboard connector) */ 568 case 4: /* ttyd (rewired mouse connector) */ 569 zsc_unit = 0; 570 channel = inSource - 3; 571 cn = &consdev_tty; 572 cn->cn_dev = makedev(ZSTTY_MAJOR, (channel+2)); 573 cn->cn_pri = CN_REMOTE; 574 break; 575 576 default: 577 mon_printf("cninit: invalid PROM console selector\n"); 578 /* assume keyboard/display */ 579 /* fallthrough */ 580 case 0: /* keyboard/display */ 581 zsc_unit = 0; 582 channel = 0; 583 cn = &consdev_kd; 584 /* Set cn_dev, cn_pri in kd.c */ 585 break; 586 } 587 588 zc = zs_get_chan_addr(zsc_unit, channel); 589 if (zc == NULL) { 590 mon_printf("cninit: zs not mapped.\n"); 591 return; 592 } 593 zs_conschan = zc; 594 zs_hwflags[zsc_unit][channel] = ZS_HWFLAG_CONSOLE; 595 cn_tab = cn; 596 (*cn->cn_init)(cn); 597 } 598 599 600 /* We never call this. */ 601 void 602 nullcnprobe(cn) 603 struct consdev *cn; 604 { 605 } 606 607 void 608 zscninit(cn) 609 struct consdev *cn; 610 { 611 int unit = minor(cn->cn_dev) & 1; 612 613 mon_printf("console is zstty%d (tty%c)\n", 614 unit, unit + 'a'); 615 } 616 617 /* 618 * Polled console input putchar. 619 */ 620 int 621 zscngetc(dev) 622 dev_t dev; 623 { 624 register volatile struct zschan *zc = zs_conschan; 625 register int c; 626 627 c = zs_getc(zc); 628 return (c); 629 } 630 631 /* 632 * Polled console output putchar. 633 */ 634 void 635 zscnputc(dev, c) 636 dev_t dev; 637 int c; 638 { 639 register volatile struct zschan *zc = zs_conschan; 640 641 zs_putc(zc, c); 642 } 643 644 645 struct consdev consdev_tty = { 646 nullcnprobe, 647 zscninit, 648 zscngetc, 649 zscnputc, 650 nullcnpollc, 651 }; 652 653 654 /* 655 * Handle user request to enter kernel debugger. 656 */ 657 void 658 zs_abort() 659 { 660 register volatile struct zschan *zc = zs_conschan; 661 int rr0; 662 663 /* Wait for end of break to avoid PROM abort. */ 664 /* XXX - Limit the wait? */ 665 do { 666 rr0 = zc->zc_csr; 667 ZS_DELAY(); 668 } while (rr0 & ZSRR0_BREAK); 669 670 /* XXX - Always available, but may be the PROM monitor. */ 671 Debugger(); 672 } 673