1 /*- 2 * Copyright (c) 1997, 1998 Nicolas Souchu 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $Id: ppc.c,v 1.12 1998/12/07 21:58:22 archie Exp $ 27 * 28 */ 29 #include "ppc.h" 30 31 #if NPPC > 0 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/conf.h> 36 #include <sys/malloc.h> 37 #include <sys/kernel.h> 38 39 #include <machine/clock.h> 40 41 #include <vm/vm.h> 42 #include <vm/vm_param.h> 43 #include <vm/pmap.h> 44 45 #include <i386/isa/isa_device.h> 46 47 #include <dev/ppbus/ppbconf.h> 48 #include <dev/ppbus/ppb_msq.h> 49 50 #include <i386/isa/ppcreg.h> 51 52 static int ppcprobe(struct isa_device *); 53 static int ppcattach(struct isa_device *); 54 55 struct isa_driver ppcdriver = { 56 ppcprobe, ppcattach, "ppc" 57 }; 58 59 static struct ppc_data *ppcdata[NPPC]; 60 static int nppc = 0; 61 62 static char *ppc_types[] = { 63 "SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306", 64 "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334", 0 65 }; 66 67 /* list of available modes */ 68 static char *ppc_avms[] = { 69 "COMPATIBLE", "NIBBLE-only", "PS2-only", "PS2/NIBBLE", "EPP-only", 70 "EPP/NIBBLE", "EPP/PS2", "EPP/PS2/NIBBLE", "ECP-only", 71 "ECP/NIBBLE", "ECP/PS2", "ECP/PS2/NIBBLE", "ECP/EPP", 72 "ECP/EPP/NIBBLE", "ECP/EPP/PS2", "ECP/EPP/PS2/NIBBLE", 0 73 }; 74 75 /* list of current executing modes 76 * Note that few modes do not actually exist. 77 */ 78 static char *ppc_modes[] = { 79 "COMPATIBLE", "NIBBLE", "PS/2", "PS/2", "EPP", 80 "EPP", "EPP", "EPP", "ECP", 81 "ECP", "ECP+PS2", "ECP+PS2", "ECP+EPP", 82 "ECP+EPP", "ECP+EPP", "ECP+EPP", 0 83 }; 84 85 static char *ppc_epp_protocol[] = { " (EPP 1.9)", " (EPP 1.7)", 0 }; 86 87 /* 88 * BIOS printer list - used by BIOS probe. 89 */ 90 #define BIOS_PPC_PORTS 0x408 91 #define BIOS_PORTS (short *)(KERNBASE+BIOS_PPC_PORTS) 92 #define BIOS_MAX_PPC 4 93 94 /* 95 * All these functions are default actions for IN/OUT operations. 96 * They may be redefined if needed. 97 */ 98 static void ppc_outsb_epp(int unit, char *addr, int cnt) { 99 outsb(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); } 100 static void ppc_outsw_epp(int unit, char *addr, int cnt) { 101 outsw(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); } 102 static void ppc_outsl_epp(int unit, char *addr, int cnt) { 103 outsl(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); } 104 static void ppc_insb_epp(int unit, char *addr, int cnt) { 105 insb(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); } 106 static void ppc_insw_epp(int unit, char *addr, int cnt) { 107 insw(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); } 108 static void ppc_insl_epp(int unit, char *addr, int cnt) { 109 insl(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); } 110 111 static char ppc_rdtr(int unit) { return r_dtr(ppcdata[unit]); } 112 static char ppc_rstr(int unit) { return r_str(ppcdata[unit]); } 113 static char ppc_rctr(int unit) { return r_ctr(ppcdata[unit]); } 114 static char ppc_repp(int unit) { return r_epp(ppcdata[unit]); } 115 static char ppc_recr(int unit) { return r_ecr(ppcdata[unit]); } 116 static char ppc_rfifo(int unit) { return r_fifo(ppcdata[unit]); } 117 118 static void ppc_wdtr(int unit, char byte) { w_dtr(ppcdata[unit], byte); } 119 static void ppc_wstr(int unit, char byte) { w_str(ppcdata[unit], byte); } 120 static void ppc_wctr(int unit, char byte) { w_ctr(ppcdata[unit], byte); } 121 static void ppc_wepp(int unit, char byte) { w_epp(ppcdata[unit], byte); } 122 static void ppc_wecr(int unit, char byte) { w_ecr(ppcdata[unit], byte); } 123 static void ppc_wfifo(int unit, char byte) { w_fifo(ppcdata[unit], byte); } 124 125 static void ppc_reset_epp_timeout(int); 126 static void ppc_ecp_sync(int); 127 static ointhand2_t ppcintr; 128 129 static int ppc_exec_microseq(int, struct ppb_microseq **); 130 static int ppc_generic_setmode(int, int); 131 static int ppc_smclike_setmode(int, int); 132 133 static struct ppb_adapter ppc_smclike_adapter = { 134 135 0, /* no intr handler, filled by chipset dependent code */ 136 137 ppc_reset_epp_timeout, ppc_ecp_sync, 138 139 ppc_exec_microseq, 140 141 ppc_smclike_setmode, 142 143 ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp, 144 ppc_insb_epp, ppc_insw_epp, ppc_insl_epp, 145 146 ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp, ppc_recr, ppc_rfifo, 147 ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp, ppc_wecr, ppc_wfifo 148 }; 149 150 static struct ppb_adapter ppc_generic_adapter = { 151 152 0, /* no intr handler, filled by chipset dependent code */ 153 154 ppc_reset_epp_timeout, ppc_ecp_sync, 155 156 ppc_exec_microseq, 157 158 ppc_generic_setmode, 159 160 ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp, 161 ppc_insb_epp, ppc_insw_epp, ppc_insl_epp, 162 163 ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp, ppc_recr, ppc_rfifo, 164 ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp, ppc_wecr, ppc_wfifo 165 }; 166 167 /* 168 * ppc_ecp_sync() XXX 169 */ 170 static void 171 ppc_ecp_sync(int unit) { 172 173 struct ppc_data *ppc = ppcdata[unit]; 174 int i, r; 175 176 r = r_ecr(ppc); 177 if ((r & 0xe0) != 0x80) 178 return; 179 180 for (i = 0; i < 100; i++) { 181 r = r_ecr(ppc); 182 if (r & 0x1) 183 return; 184 DELAY(100); 185 } 186 187 printf("ppc%d: ECP sync failed as data still " \ 188 "present in FIFO.\n", unit); 189 190 return; 191 } 192 193 static void 194 ppcintr(int unit) 195 { 196 /* call directly upper code */ 197 ppb_intr(&ppcdata[unit]->ppc_link); 198 199 return; 200 } 201 202 static int 203 ppc_detect_port(struct ppc_data *ppc) 204 { 205 206 w_ctr(ppc, 0x0c); /* To avoid missing PS2 ports */ 207 w_dtr(ppc, 0xaa); 208 if (r_dtr(ppc) != (char) 0xaa) 209 return (0); 210 211 return (1); 212 } 213 214 /* 215 * ppc_pc873xx_detect 216 * 217 * Probe for a Natsemi PC873xx-family part. 218 * 219 * References in this function are to the National Semiconductor 220 * PC87332 datasheet TL/C/11930, May 1995 revision. 221 */ 222 static int pc873xx_basetab[] = {0x0398, 0x026e, 0x015c, 0x002e, 0}; 223 static int pc873xx_porttab[] = {0x0378, 0x03bc, 0x0278, 0}; 224 static int pc873xx_irqtab[] = {5, 7, 5, 0}; 225 226 static int pc873xx_regstab[] = { 227 PC873_FER, PC873_FAR, PC873_PTR, 228 PC873_FCR, PC873_PCR, PC873_PMC, 229 PC873_TUP, PC873_SID, PC873_PNP0, 230 PC873_PNP1, PC873_LPTBA, -1 231 }; 232 233 static char *pc873xx_rnametab[] = { 234 "FER", "FAR", "PTR", "FCR", "PCR", 235 "PMC", "TUP", "SID", "PNP0", "PNP1", 236 "LPTBA", NULL 237 }; 238 239 static int 240 ppc_pc873xx_detect(struct ppc_data *ppc, int chipset_mode) /* XXX mode never forced */ 241 { 242 static int index = 0; 243 int idport, irq; 244 int ptr, pcr, val, i; 245 246 while ((idport = pc873xx_basetab[index++])) { 247 248 /* XXX should check first to see if this location is already claimed */ 249 250 /* 251 * Pull the 873xx through the power-on ID cycle (2.2,1.). 252 * We can't use this to locate the chip as it may already have 253 * been used by the BIOS. 254 */ 255 (void)inb(idport); (void)inb(idport); 256 (void)inb(idport); (void)inb(idport); 257 258 /* 259 * Read the SID byte. Possible values are : 260 * 261 * 01010xxx PC87334 262 * 0001xxxx PC87332 263 * 01110xxx PC87306 264 */ 265 outb(idport, PC873_SID); 266 val = inb(idport + 1); 267 if ((val & 0xf0) == 0x10) { 268 ppc->ppc_type = NS_PC87332; 269 } else if ((val & 0xf8) == 0x70) { 270 ppc->ppc_type = NS_PC87306; 271 } else if ((val & 0xf8) == 0x50) { 272 ppc->ppc_type = NS_PC87334; 273 } else { 274 if (bootverbose && (val != 0xff)) 275 printf("PC873xx probe at 0x%x got unknown ID 0x%x\n", idport, val); 276 continue ; /* not recognised */ 277 } 278 279 /* print registers */ 280 if (bootverbose) { 281 printf("PC873xx"); 282 for (i=0; pc873xx_regstab[i] != -1; i++) { 283 outb(idport, pc873xx_regstab[i]); 284 printf(" %s=0x%x", pc873xx_rnametab[i], 285 inb(idport + 1) & 0xff); 286 } 287 printf("\n"); 288 } 289 290 /* 291 * We think we have one. Is it enabled and where we want it to be? 292 */ 293 outb(idport, PC873_FER); 294 val = inb(idport + 1); 295 if (!(val & PC873_PPENABLE)) { 296 if (bootverbose) 297 printf("PC873xx parallel port disabled\n"); 298 continue; 299 } 300 outb(idport, PC873_FAR); 301 val = inb(idport + 1) & 0x3; 302 /* XXX we should create a driver instance for every port found */ 303 if (pc873xx_porttab[val] != ppc->ppc_base) { 304 if (bootverbose) 305 printf("PC873xx at 0x%x not for driver at port 0x%x\n", 306 pc873xx_porttab[val], ppc->ppc_base); 307 continue; 308 } 309 310 outb(idport, PC873_PTR); 311 ptr = inb(idport + 1); 312 313 /* get irq settings */ 314 if (ppc->ppc_base == 0x378) 315 irq = (ptr & PC873_LPTBIRQ7) ? 7 : 5; 316 else 317 irq = pc873xx_irqtab[val]; 318 319 if (bootverbose) 320 printf("PC873xx irq %d at 0x%x\n", irq, ppc->ppc_base); 321 322 /* 323 * Check if irq settings are correct 324 */ 325 if (irq != ppc->ppc_irq) { 326 /* 327 * If the chipset is not locked and base address is 0x378, 328 * we have another chance 329 */ 330 if (ppc->ppc_base == 0x378 && !(ptr & PC873_CFGLOCK)) { 331 if (ppc->ppc_irq == 7) { 332 outb(idport + 1, (ptr | PC873_LPTBIRQ7)); 333 outb(idport + 1, (ptr | PC873_LPTBIRQ7)); 334 } else { 335 outb(idport + 1, (ptr & ~PC873_LPTBIRQ7)); 336 outb(idport + 1, (ptr & ~PC873_LPTBIRQ7)); 337 } 338 if (bootverbose) 339 printf("PC873xx irq set to %d\n", ppc->ppc_irq); 340 } else { 341 if (bootverbose) 342 printf("PC873xx sorry, can't change irq setting\n"); 343 } 344 } else { 345 if (bootverbose) 346 printf("PC873xx irq settings are correct\n"); 347 } 348 349 outb(idport, PC873_PCR); 350 pcr = inb(idport + 1); 351 352 if ((ptr & PC873_CFGLOCK) || !chipset_mode) { 353 if (bootverbose) 354 printf("PC873xx %s", (ptr & PC873_CFGLOCK)?"locked":"unlocked"); 355 356 ppc->ppc_avm |= PPB_NIBBLE; 357 if (bootverbose) 358 printf(", NIBBLE"); 359 360 if (pcr & PC873_EPPEN) { 361 ppc->ppc_avm |= PPB_EPP; 362 363 if (bootverbose) 364 printf(", EPP"); 365 366 if (pcr & PC873_EPP19) 367 ppc->ppc_epp = EPP_1_9; 368 else 369 ppc->ppc_epp = EPP_1_7; 370 371 if ((ppc->ppc_type == NS_PC87332) && bootverbose) { 372 outb(idport, PC873_PTR); 373 ptr = inb(idport + 1); 374 if (ptr & PC873_EPPRDIR) 375 printf(", Regular mode"); 376 else 377 printf(", Automatic mode"); 378 } 379 } else if (pcr & PC873_ECPEN) { 380 ppc->ppc_avm |= PPB_ECP; 381 if (bootverbose) 382 printf(", ECP"); 383 384 if (pcr & PC873_ECPCLK) { /* XXX */ 385 ppc->ppc_avm |= PPB_PS2; 386 if (bootverbose) 387 printf(", PS/2"); 388 } 389 } else { 390 outb(idport, PC873_PTR); 391 ptr = inb(idport + 1); 392 if (ptr & PC873_EXTENDED) { 393 ppc->ppc_avm |= PPB_SPP; 394 if (bootverbose) 395 printf(", SPP"); 396 } 397 } 398 } else { 399 if (bootverbose) 400 printf("PC873xx unlocked"); 401 402 if (chipset_mode & PPB_ECP) { 403 if ((chipset_mode & PPB_EPP) && bootverbose) 404 printf(", ECP+EPP not supported"); 405 406 pcr &= ~PC873_EPPEN; 407 pcr |= (PC873_ECPEN | PC873_ECPCLK); /* XXX */ 408 outb(idport + 1, pcr); 409 outb(idport + 1, pcr); 410 411 if (bootverbose) 412 printf(", ECP"); 413 414 } else if (chipset_mode & PPB_EPP) { 415 pcr &= ~(PC873_ECPEN | PC873_ECPCLK); 416 pcr |= (PC873_EPPEN | PC873_EPP19); 417 outb(idport + 1, pcr); 418 outb(idport + 1, pcr); 419 420 ppc->ppc_epp = EPP_1_9; /* XXX */ 421 422 if (bootverbose) 423 printf(", EPP1.9"); 424 425 /* enable automatic direction turnover */ 426 if (ppc->ppc_type == NS_PC87332) { 427 outb(idport, PC873_PTR); 428 ptr = inb(idport + 1); 429 ptr &= ~PC873_EPPRDIR; 430 outb(idport + 1, ptr); 431 outb(idport + 1, ptr); 432 433 if (bootverbose) 434 printf(", Automatic mode"); 435 } 436 } else { 437 pcr &= ~(PC873_ECPEN | PC873_ECPCLK | PC873_EPPEN); 438 outb(idport + 1, pcr); 439 outb(idport + 1, pcr); 440 441 /* configure extended bit in PTR */ 442 outb(idport, PC873_PTR); 443 ptr = inb(idport + 1); 444 445 if (chipset_mode & PPB_PS2) { 446 ptr |= PC873_EXTENDED; 447 448 if (bootverbose) 449 printf(", PS/2"); 450 451 } else { 452 /* default to NIBBLE mode */ 453 ptr &= ~PC873_EXTENDED; 454 455 if (bootverbose) 456 printf(", NIBBLE"); 457 } 458 outb(idport + 1, ptr); 459 outb(idport + 1, ptr); 460 } 461 462 ppc->ppc_avm = chipset_mode; 463 } 464 465 if (bootverbose) 466 printf("\n"); 467 468 ppc->ppc_link.adapter = &ppc_generic_adapter; 469 ppc_generic_setmode(ppc->ppc_unit, chipset_mode); 470 471 return(chipset_mode); 472 } 473 return(-1); 474 } 475 476 static int 477 ppc_check_epp_timeout(struct ppc_data *ppc) 478 { 479 ppc_reset_epp_timeout(ppc->ppc_unit); 480 481 return (!(r_str(ppc) & TIMEOUT)); 482 } 483 484 /* 485 * ppc_smc37c66xgt_detect 486 * 487 * SMC FDC37C66xGT configuration. 488 */ 489 static int 490 ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) 491 { 492 int s, i; 493 char r; 494 int type = -1; 495 int csr = SMC66x_CSR; /* initial value is 0x3F0 */ 496 497 int port_address[] = { -1 /* disabled */ , 0x3bc, 0x378, 0x278 }; 498 499 500 #define cio csr+1 /* config IO port is either 0x3F1 or 0x371 */ 501 502 /* 503 * Detection: enter configuration mode and read CRD register. 504 */ 505 506 s = splhigh(); 507 outb(csr, SMC665_iCODE); 508 outb(csr, SMC665_iCODE); 509 splx(s); 510 511 outb(csr, 0xd); 512 if (inb(cio) == 0x65) { 513 type = SMC_37C665GT; 514 goto config; 515 } 516 517 for (i = 0; i < 2; i++) { 518 s = splhigh(); 519 outb(csr, SMC666_iCODE); 520 outb(csr, SMC666_iCODE); 521 splx(s); 522 523 outb(csr, 0xd); 524 if (inb(cio) == 0x66) { 525 type = SMC_37C666GT; 526 break; 527 } 528 529 /* Another chance, CSR may be hard-configured to be at 0x370 */ 530 csr = SMC666_CSR; 531 } 532 533 config: 534 /* 535 * If chipset not found, do not continue. 536 */ 537 if (type == -1) 538 return (-1); 539 540 /* select CR1 */ 541 outb(csr, 0x1); 542 543 /* read the port's address: bits 0 and 1 of CR1 */ 544 r = inb(cio) & SMC_CR1_ADDR; 545 if (port_address[r] != ppc->ppc_base) 546 return (-1); 547 548 ppc->ppc_type = type; 549 550 /* 551 * CR1 and CR4 registers bits 3 and 0/1 for mode configuration 552 * If SPP mode is detected, try to set ECP+EPP mode 553 */ 554 555 if (bootverbose) { 556 outb(csr, 0x1); 557 printf("ppc%d: SMC registers CR1=0x%x", ppc->ppc_unit, 558 inb(cio) & 0xff); 559 560 outb(csr, 0x4); 561 printf(" CR4=0x%x", inb(cio) & 0xff); 562 } 563 564 /* select CR1 */ 565 outb(csr, 0x1); 566 567 if (!chipset_mode) { 568 /* autodetect mode */ 569 570 /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */ 571 if (type == SMC_37C666GT) { 572 ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; 573 if (bootverbose) 574 printf(" configuration hardwired, supposing " \ 575 "ECP+EPP SPP"); 576 577 } else 578 if ((inb(cio) & SMC_CR1_MODE) == 0) { 579 /* already in extended parallel port mode, read CR4 */ 580 outb(csr, 0x4); 581 r = (inb(cio) & SMC_CR4_EMODE); 582 583 switch (r) { 584 case SMC_SPP: 585 ppc->ppc_avm |= PPB_SPP; 586 if (bootverbose) 587 printf(" SPP"); 588 break; 589 590 case SMC_EPPSPP: 591 ppc->ppc_avm |= PPB_EPP | PPB_SPP; 592 if (bootverbose) 593 printf(" EPP SPP"); 594 break; 595 596 case SMC_ECP: 597 ppc->ppc_avm |= PPB_ECP | PPB_SPP; 598 if (bootverbose) 599 printf(" ECP SPP"); 600 break; 601 602 case SMC_ECPEPP: 603 ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; 604 if (bootverbose) 605 printf(" ECP+EPP SPP"); 606 break; 607 } 608 } else { 609 /* not an extended port mode */ 610 ppc->ppc_avm |= PPB_SPP; 611 if (bootverbose) 612 printf(" SPP"); 613 } 614 615 } else { 616 /* mode forced */ 617 ppc->ppc_avm = chipset_mode; 618 619 /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */ 620 if (type == SMC_37C666GT) 621 goto end_detect; 622 623 r = inb(cio); 624 if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) { 625 /* do not use ECP when the mode is not forced to */ 626 outb(cio, r | SMC_CR1_MODE); 627 if (bootverbose) 628 printf(" SPP"); 629 } else { 630 /* an extended mode is selected */ 631 outb(cio, r & ~SMC_CR1_MODE); 632 633 /* read CR4 register and reset mode field */ 634 outb(csr, 0x4); 635 r = inb(cio) & ~SMC_CR4_EMODE; 636 637 if (chipset_mode & PPB_ECP) { 638 if (chipset_mode & PPB_EPP) { 639 outb(cio, r | SMC_ECPEPP); 640 if (bootverbose) 641 printf(" ECP+EPP"); 642 } else { 643 outb(cio, r | SMC_ECP); 644 if (bootverbose) 645 printf(" ECP"); 646 } 647 } else { 648 /* PPB_EPP is set */ 649 outb(cio, r | SMC_EPPSPP); 650 if (bootverbose) 651 printf(" EPP SPP"); 652 } 653 } 654 ppc->ppc_avm = chipset_mode; 655 } 656 657 end_detect: 658 659 if (bootverbose) 660 printf ("\n"); 661 662 if (ppc->ppc_avm & PPB_EPP) { 663 /* select CR4 */ 664 outb(csr, 0x4); 665 r = inb(cio); 666 667 /* 668 * Set the EPP protocol... 669 * Low=EPP 1.9 (1284 standard) and High=EPP 1.7 670 */ 671 if (ppc->ppc_epp == EPP_1_9) 672 outb(cio, (r & ~SMC_CR4_EPPTYPE)); 673 else 674 outb(cio, (r | SMC_CR4_EPPTYPE)); 675 } 676 677 /* end config mode */ 678 outb(csr, 0xaa); 679 680 ppc->ppc_link.adapter = &ppc_smclike_adapter; 681 ppc_smclike_setmode(ppc->ppc_unit, chipset_mode); 682 683 return (chipset_mode); 684 } 685 686 /* 687 * Winbond W83877F stuff 688 * 689 * EFER: extended function enable register 690 * EFIR: extended function index register 691 * EFDR: extended function data register 692 */ 693 #define efir ((efer == 0x250) ? 0x251 : 0x3f0) 694 #define efdr ((efer == 0x250) ? 0x252 : 0x3f1) 695 696 static int w83877f_efers[] = { 0x250, 0x3f0, 0x3f0, 0x250 }; 697 static int w83877f_keys[] = { 0x89, 0x86, 0x87, 0x88 }; 698 static int w83877f_keyiter[] = { 1, 2, 2, 1 }; 699 static int w83877f_hefs[] = { WINB_HEFERE, WINB_HEFRAS, WINB_HEFERE | WINB_HEFRAS, 0 }; 700 701 static int 702 ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode) 703 { 704 int i, j, efer; 705 unsigned char r, hefere, hefras; 706 707 for (i = 0; i < 4; i ++) { 708 /* first try to enable configuration registers */ 709 efer = w83877f_efers[i]; 710 711 /* write the key to the EFER */ 712 for (j = 0; j < w83877f_keyiter[i]; j ++) 713 outb (efer, w83877f_keys[i]); 714 715 /* then check HEFERE and HEFRAS bits */ 716 outb (efir, 0x0c); 717 hefere = inb(efdr) & WINB_HEFERE; 718 719 outb (efir, 0x16); 720 hefras = inb(efdr) & WINB_HEFRAS; 721 722 /* 723 * HEFRAS HEFERE 724 * 0 1 write 89h to 250h (power-on default) 725 * 1 0 write 86h twice to 3f0h 726 * 1 1 write 87h twice to 3f0h 727 * 0 0 write 88h to 250h 728 */ 729 if ((hefere | hefras) == w83877f_hefs[i]) 730 goto found; 731 } 732 733 return (-1); /* failed */ 734 735 found: 736 /* check base port address - read from CR23 */ 737 outb(efir, 0x23); 738 if (ppc->ppc_base != inb(efdr) * 4) /* 4 bytes boundaries */ 739 return (-1); 740 741 /* read CHIP ID from CR9/bits0-3 */ 742 outb(efir, 0x9); 743 744 switch (inb(efdr) & WINB_CHIPID) { 745 case WINB_W83877F_ID: 746 ppc->ppc_type = WINB_W83877F; 747 break; 748 749 case WINB_W83877AF_ID: 750 ppc->ppc_type = WINB_W83877AF; 751 break; 752 753 default: 754 ppc->ppc_type = WINB_UNKNOWN; 755 } 756 757 if (bootverbose) { 758 /* dump of registers */ 759 printf("ppc%d: 0x%x - ", ppc->ppc_unit, w83877f_keys[i]); 760 for (i = 0; i <= 0xd; i ++) { 761 outb(efir, i); 762 printf("0x%x ", inb(efdr)); 763 } 764 for (i = 0x10; i <= 0x17; i ++) { 765 outb(efir, i); 766 printf("0x%x ", inb(efdr)); 767 } 768 outb(efir, 0x1e); 769 printf("0x%x ", inb(efdr)); 770 for (i = 0x20; i <= 0x29; i ++) { 771 outb(efir, i); 772 printf("0x%x ", inb(efdr)); 773 } 774 printf("\n"); 775 printf("ppc%d:", ppc->ppc_unit); 776 } 777 778 ppc->ppc_link.adapter = &ppc_generic_adapter; 779 780 if (!chipset_mode) { 781 /* autodetect mode */ 782 783 /* select CR0 */ 784 outb(efir, 0x0); 785 r = inb(efdr) & (WINB_PRTMODS0 | WINB_PRTMODS1); 786 787 /* select CR9 */ 788 outb(efir, 0x9); 789 r |= (inb(efdr) & WINB_PRTMODS2); 790 791 switch (r) { 792 case WINB_W83757: 793 if (bootverbose) 794 printf("ppc%d: W83757 compatible mode\n", 795 ppc->ppc_unit); 796 return (-1); /* generic or SMC-like */ 797 798 case WINB_EXTFDC: 799 case WINB_EXTADP: 800 case WINB_EXT2FDD: 801 case WINB_JOYSTICK: 802 if (bootverbose) 803 printf(" not in parallel port mode\n"); 804 return (-1); 805 806 case (WINB_PARALLEL | WINB_EPP_SPP): 807 ppc->ppc_avm |= PPB_EPP | PPB_SPP; 808 if (bootverbose) 809 printf(" EPP SPP"); 810 break; 811 812 case (WINB_PARALLEL | WINB_ECP): 813 ppc->ppc_avm |= PPB_ECP | PPB_SPP; 814 if (bootverbose) 815 printf(" ECP SPP"); 816 break; 817 818 case (WINB_PARALLEL | WINB_ECP_EPP): 819 ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; 820 ppc->ppc_link.adapter = &ppc_smclike_adapter; 821 822 if (bootverbose) 823 printf(" ECP+EPP SPP"); 824 break; 825 default: 826 printf("%s: unknown case (0x%x)!\n", __FUNCTION__, r); 827 } 828 829 } else { 830 /* mode forced */ 831 832 /* select CR9 and set PRTMODS2 bit */ 833 outb(efir, 0x9); 834 outb(efdr, inb(efdr) & ~WINB_PRTMODS2); 835 836 /* select CR0 and reset PRTMODSx bits */ 837 outb(efir, 0x0); 838 outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1)); 839 840 if (chipset_mode & PPB_ECP) { 841 if (chipset_mode & PPB_EPP) { 842 outb(efdr, inb(efdr) | WINB_ECP_EPP); 843 if (bootverbose) 844 printf(" ECP+EPP"); 845 846 ppc->ppc_link.adapter = &ppc_smclike_adapter; 847 848 } else { 849 outb(efdr, inb(efdr) | WINB_ECP); 850 if (bootverbose) 851 printf(" ECP"); 852 } 853 } else { 854 /* select EPP_SPP otherwise */ 855 outb(efdr, inb(efdr) | WINB_EPP_SPP); 856 if (bootverbose) 857 printf(" EPP SPP"); 858 } 859 ppc->ppc_avm = chipset_mode; 860 } 861 862 if (bootverbose) 863 printf("\n"); 864 865 /* exit configuration mode */ 866 outb(efer, 0xaa); 867 868 ppc->ppc_link.adapter->setmode(ppc->ppc_unit, chipset_mode); 869 870 return (chipset_mode); 871 } 872 873 /* 874 * ppc_generic_detect 875 */ 876 static int 877 ppc_generic_detect(struct ppc_data *ppc, int chipset_mode) 878 { 879 /* default to generic */ 880 ppc->ppc_link.adapter = &ppc_generic_adapter; 881 882 if (bootverbose) 883 printf("ppc%d:", ppc->ppc_unit); 884 885 if (!chipset_mode) { 886 /* first, check for ECP */ 887 w_ecr(ppc, 0x20); 888 if ((r_ecr(ppc) & 0xe0) == 0x20) { 889 ppc->ppc_avm |= PPB_ECP | PPB_SPP; 890 if (bootverbose) 891 printf(" ECP SPP"); 892 893 /* search for SMC style ECP+EPP mode */ 894 w_ecr(ppc, 0x80); 895 } 896 897 /* try to reset EPP timeout bit */ 898 if (ppc_check_epp_timeout(ppc)) { 899 ppc->ppc_avm |= PPB_EPP; 900 901 if (ppc->ppc_avm & PPB_ECP) { 902 /* SMC like chipset found */ 903 ppc->ppc_type = SMC_LIKE; 904 ppc->ppc_link.adapter = &ppc_smclike_adapter; 905 906 if (bootverbose) 907 printf(" ECP+EPP"); 908 } else { 909 if (bootverbose) 910 printf(" EPP"); 911 } 912 } else { 913 /* restore to standard mode */ 914 w_ecr(ppc, 0x0); 915 } 916 917 /* XXX try to detect NIBBLE and PS2 modes */ 918 ppc->ppc_avm |= PPB_NIBBLE; 919 920 if (bootverbose) 921 printf(" SPP"); 922 923 } else { 924 ppc->ppc_avm = chipset_mode; 925 } 926 927 if (bootverbose) 928 printf("\n"); 929 930 ppc->ppc_link.adapter->setmode(ppc->ppc_unit, chipset_mode); 931 932 return (chipset_mode); 933 } 934 935 /* 936 * ppc_detect() 937 * 938 * mode is the mode suggested at boot 939 */ 940 static int 941 ppc_detect(struct ppc_data *ppc, int chipset_mode) { 942 943 int i, mode; 944 945 /* list of supported chipsets */ 946 int (*chipset_detect[])(struct ppc_data *, int) = { 947 ppc_pc873xx_detect, 948 ppc_smc37c66xgt_detect, 949 ppc_w83877f_detect, 950 ppc_generic_detect, 951 NULL 952 }; 953 954 /* if can't find the port and mode not forced return error */ 955 if (!ppc_detect_port(ppc) && chipset_mode == 0) 956 return (EIO); /* failed, port not present */ 957 958 /* assume centronics compatible mode is supported */ 959 ppc->ppc_avm = PPB_COMPATIBLE; 960 961 /* we have to differenciate available chipset modes, 962 * chipset running modes and IEEE-1284 operating modes 963 * 964 * after detection, the port must support running in compatible mode 965 */ 966 if (ppc->ppc_flags & 0x40) { 967 if (bootverbose) 968 printf("ppc: chipset forced to generic\n"); 969 970 ppc->ppc_mode = ppc_generic_detect(ppc, chipset_mode); 971 972 } else { 973 for (i=0; chipset_detect[i] != NULL; i++) { 974 if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) { 975 ppc->ppc_mode = mode; 976 break; 977 } 978 } 979 } 980 981 return (0); 982 } 983 984 /* 985 * ppc_exec_microseq() 986 * 987 * Execute a microsequence. 988 * Microsequence mechanism is supposed to handle fast I/O operations. 989 */ 990 static int 991 ppc_exec_microseq(int unit, struct ppb_microseq **p_msq) 992 { 993 struct ppc_data *ppc = ppcdata[unit]; 994 struct ppb_microseq *mi; 995 char cc, *p; 996 int i, iter, len; 997 int error; 998 999 register int reg; 1000 register char mask; 1001 register int accum = 0; 1002 register char *ptr = 0; 1003 1004 struct ppb_microseq *stack = 0; 1005 1006 /* microsequence registers are equivalent to PC-like port registers */ 1007 #define r_reg(register,ppc) ((char)inb((ppc)->ppc_base + register)) 1008 #define w_reg(register,ppc,byte) outb((ppc)->ppc_base + register, byte) 1009 1010 #define INCR_PC (mi ++) /* increment program counter */ 1011 1012 mi = *p_msq; 1013 for (;;) { 1014 switch (mi->opcode) { 1015 case MS_OP_RSET: 1016 cc = r_reg(mi->arg[0].i, ppc); 1017 cc &= (char)mi->arg[2].i; /* clear mask */ 1018 cc |= (char)mi->arg[1].i; /* assert mask */ 1019 w_reg(mi->arg[0].i, ppc, cc); 1020 INCR_PC; 1021 break; 1022 1023 case MS_OP_RASSERT_P: 1024 reg = mi->arg[1].i; 1025 ptr = ppc->ppc_ptr; 1026 1027 if ((len = mi->arg[0].i) == MS_ACCUM) { 1028 accum = ppc->ppc_accum; 1029 for (; accum; accum--) 1030 w_reg(reg, ppc, *ptr++); 1031 ppc->ppc_accum = accum; 1032 } else 1033 for (i=0; i<len; i++) 1034 w_reg(reg, ppc, *ptr++); 1035 ppc->ppc_ptr = ptr; 1036 1037 INCR_PC; 1038 break; 1039 1040 case MS_OP_RFETCH_P: 1041 reg = mi->arg[1].i; 1042 mask = (char)mi->arg[2].i; 1043 ptr = ppc->ppc_ptr; 1044 1045 if ((len = mi->arg[0].i) == MS_ACCUM) { 1046 accum = ppc->ppc_accum; 1047 for (; accum; accum--) 1048 *ptr++ = r_reg(reg, ppc) & mask; 1049 ppc->ppc_accum = accum; 1050 } else 1051 for (i=0; i<len; i++) 1052 *ptr++ = r_reg(reg, ppc) & mask; 1053 ppc->ppc_ptr = ptr; 1054 1055 INCR_PC; 1056 break; 1057 1058 case MS_OP_RFETCH: 1059 *((char *) mi->arg[2].p) = r_reg(mi->arg[0].i, ppc) & 1060 (char)mi->arg[1].i; 1061 INCR_PC; 1062 break; 1063 1064 case MS_OP_RASSERT: 1065 case MS_OP_DELAY: 1066 1067 /* let's suppose the next instr. is the same */ 1068 prefetch: 1069 for (;mi->opcode == MS_OP_RASSERT; INCR_PC) 1070 w_reg(mi->arg[0].i, ppc, (char)mi->arg[1].i); 1071 1072 if (mi->opcode == MS_OP_DELAY) { 1073 DELAY(mi->arg[0].i); 1074 INCR_PC; 1075 goto prefetch; 1076 } 1077 break; 1078 1079 case MS_OP_ADELAY: 1080 if (mi->arg[0].i) 1081 tsleep(NULL, PPBPRI, "ppbdelay", 1082 mi->arg[0].i * (hz/1000)); 1083 INCR_PC; 1084 break; 1085 1086 case MS_OP_TRIG: 1087 reg = mi->arg[0].i; 1088 iter = mi->arg[1].i; 1089 p = (char *)mi->arg[2].p; 1090 1091 /* XXX delay limited to 255 us */ 1092 for (i=0; i<iter; i++) { 1093 w_reg(reg, ppc, *p++); 1094 DELAY((unsigned char)*p++); 1095 } 1096 INCR_PC; 1097 break; 1098 1099 case MS_OP_SET: 1100 ppc->ppc_accum = mi->arg[0].i; 1101 INCR_PC; 1102 break; 1103 1104 case MS_OP_DBRA: 1105 if (--ppc->ppc_accum > 0) 1106 mi += mi->arg[0].i; 1107 else 1108 INCR_PC; 1109 break; 1110 1111 case MS_OP_BRSET: 1112 cc = r_str(ppc); 1113 if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i) 1114 mi += mi->arg[1].i; 1115 else 1116 INCR_PC; 1117 break; 1118 1119 case MS_OP_BRCLEAR: 1120 cc = r_str(ppc); 1121 if ((cc & (char)mi->arg[0].i) == 0) 1122 mi += mi->arg[1].i; 1123 else 1124 INCR_PC; 1125 break; 1126 1127 case MS_OP_BRSTAT: 1128 cc = r_str(ppc); 1129 if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) == 1130 (char)mi->arg[0].i) 1131 mi += mi->arg[2].i; 1132 else 1133 INCR_PC; 1134 break; 1135 1136 case MS_OP_C_CALL: 1137 /* 1138 * If the C call returns !0 then end the microseq. 1139 * The current state of ptr is passed to the C function 1140 */ 1141 if ((error = mi->arg[0].f(mi->arg[1].p, ppc->ppc_ptr))) 1142 return (error); 1143 1144 INCR_PC; 1145 break; 1146 1147 case MS_OP_PTR: 1148 ppc->ppc_ptr = (char *)mi->arg[0].p; 1149 INCR_PC; 1150 break; 1151 1152 case MS_OP_CALL: 1153 if (stack) 1154 panic("%s: too much calls", __FUNCTION__); 1155 1156 if (mi->arg[0].p) { 1157 /* store the state of the actual 1158 * microsequence 1159 */ 1160 stack = mi; 1161 1162 /* jump to the new microsequence */ 1163 mi = (struct ppb_microseq *)mi->arg[0].p; 1164 } else 1165 INCR_PC; 1166 1167 break; 1168 1169 case MS_OP_SUBRET: 1170 /* retrieve microseq and pc state before the call */ 1171 mi = stack; 1172 1173 /* reset the stack */ 1174 stack = 0; 1175 1176 /* XXX return code */ 1177 1178 INCR_PC; 1179 break; 1180 1181 case MS_OP_PUT: 1182 case MS_OP_GET: 1183 case MS_OP_RET: 1184 /* can't return to ppb level during the execution 1185 * of a submicrosequence */ 1186 if (stack) 1187 panic("%s: can't return to ppb level", 1188 __FUNCTION__); 1189 1190 /* update pc for ppb level of execution */ 1191 *p_msq = mi; 1192 1193 /* return to ppb level of execution */ 1194 return (0); 1195 1196 default: 1197 panic("%s: unknown microsequence opcode 0x%x", 1198 __FUNCTION__, mi->opcode); 1199 } 1200 } 1201 1202 /* unreached */ 1203 } 1204 1205 /* 1206 * Configure current operating mode 1207 */ 1208 static int 1209 ppc_generic_setmode(int unit, int mode) 1210 { 1211 struct ppc_data *ppc = ppcdata[unit]; 1212 1213 /* back to compatible mode, XXX don't know yet what to do here */ 1214 if (mode == 0) { 1215 ppc->ppc_mode = PPB_COMPATIBLE; 1216 return (0); 1217 } 1218 1219 /* check if mode is available */ 1220 if (!(ppc->ppc_avm & mode)) 1221 return (EOPNOTSUPP); 1222 1223 /* if ECP mode, configure ecr register */ 1224 if (ppc->ppc_avm & PPB_ECP) { 1225 1226 /* XXX disable DMA, enable interrupts */ 1227 if (mode & PPB_EPP) 1228 return (EOPNOTSUPP); 1229 else if (mode & PPB_PS2) 1230 /* select PS2 mode with ECP */ 1231 w_ecr(ppc, 0x20); 1232 else if (mode & PPB_ECP) 1233 /* select ECP mode */ 1234 w_ecr(ppc, 0x60); 1235 else 1236 /* select standard parallel port mode */ 1237 w_ecr(ppc, 0x00); 1238 } 1239 1240 ppc->ppc_mode = mode; 1241 1242 return (0); 1243 } 1244 1245 int 1246 ppc_smclike_setmode(int unit, int mode) 1247 { 1248 struct ppc_data *ppc = ppcdata[unit]; 1249 1250 /* back to compatible mode, XXX don't know yet what to do here */ 1251 if (mode == 0) { 1252 ppc->ppc_mode = PPB_COMPATIBLE; 1253 return (0); 1254 } 1255 1256 /* check if mode is available */ 1257 if (!(ppc->ppc_avm & mode)) 1258 return (EOPNOTSUPP); 1259 1260 /* if ECP mode, configure ecr register */ 1261 if (ppc->ppc_avm & PPB_ECP) { 1262 1263 /* XXX disable DMA, enable interrupts */ 1264 if (mode & PPB_EPP) 1265 /* select EPP mode */ 1266 w_ecr(ppc, 0x80); 1267 else if (mode & PPB_PS2) 1268 /* select PS2 mode with ECP */ 1269 w_ecr(ppc, 0x20); 1270 else if (mode & PPB_ECP) 1271 /* select ECP mode */ 1272 w_ecr(ppc, 0x60); 1273 else 1274 /* select standard parallel port mode */ 1275 w_ecr(ppc, 0x00); 1276 } 1277 1278 ppc->ppc_mode = mode; 1279 1280 1281 return (0); 1282 } 1283 1284 /* 1285 * EPP timeout, according to the PC87332 manual 1286 * Semantics of clearing EPP timeout bit. 1287 * PC87332 - reading SPP_STR does it... 1288 * SMC - write 1 to EPP timeout bit XXX 1289 * Others - (?) write 0 to EPP timeout bit 1290 */ 1291 static void 1292 ppc_reset_epp_timeout(int unit) 1293 { 1294 struct ppc_data *ppc = ppcdata[unit]; 1295 register char r; 1296 1297 r = r_str(ppc); 1298 w_str(ppc, r | 0x1); 1299 w_str(ppc, r & 0xfe); 1300 1301 return; 1302 } 1303 1304 static int 1305 ppcprobe(struct isa_device *dvp) 1306 { 1307 static short next_bios_ppc = 0; 1308 struct ppc_data *ppc; 1309 1310 /* 1311 * If port not specified, use bios list. 1312 */ 1313 if(dvp->id_iobase < 0) { 1314 if((next_bios_ppc < BIOS_MAX_PPC) && 1315 (*(BIOS_PORTS+next_bios_ppc) != 0) ) { 1316 dvp->id_iobase = *(BIOS_PORTS+next_bios_ppc++); 1317 printf("ppc: parallel port found at 0x%x\n", 1318 dvp->id_iobase); 1319 } else 1320 return (0); 1321 } 1322 1323 /* 1324 * Port was explicitly specified. 1325 * This allows probing of ports unknown to the BIOS. 1326 */ 1327 1328 /* 1329 * Allocate the ppc_data structure. 1330 */ 1331 ppc = malloc(sizeof(struct ppc_data), M_DEVBUF, M_NOWAIT); 1332 if (!ppc) { 1333 printf("ppc: cannot malloc!\n"); 1334 goto error; 1335 } 1336 bzero(ppc, sizeof(struct ppc_data)); 1337 1338 ppc->ppc_base = dvp->id_iobase; 1339 ppc->ppc_unit = dvp->id_unit; 1340 ppc->ppc_type = GENERIC; 1341 1342 /* store boot flags */ 1343 ppc->ppc_flags = dvp->id_flags; 1344 1345 ppc->ppc_mode = PPB_COMPATIBLE; 1346 ppc->ppc_epp = (dvp->id_flags & 0x10) >> 4; 1347 1348 /* 1349 * XXX Try and detect if interrupts are working 1350 */ 1351 if (!(dvp->id_flags & 0x20)) 1352 ppc->ppc_irq = ffs(dvp->id_irq) - 1; 1353 1354 ppcdata[ppc->ppc_unit] = ppc; 1355 nppc ++; 1356 1357 /* 1358 * Link the Parallel Port Chipset (adapter) to 1359 * the future ppbus. Default to a generic chipset 1360 */ 1361 ppc->ppc_link.adapter_unit = ppc->ppc_unit; 1362 ppc->ppc_link.adapter = &ppc_generic_adapter; 1363 1364 /* 1365 * Try to detect the chipset and its mode. 1366 */ 1367 if (ppc_detect(ppc, dvp->id_flags & 0xf)) 1368 goto error; 1369 1370 return (1); 1371 1372 error: 1373 return (0); 1374 } 1375 1376 static int 1377 ppcattach(struct isa_device *isdp) 1378 { 1379 struct ppc_data *ppc = ppcdata[isdp->id_unit]; 1380 struct ppb_data *ppbus; 1381 1382 printf("ppc%d: %s chipset (%s) in %s mode%s\n", ppc->ppc_unit, 1383 ppc_types[ppc->ppc_type], ppc_avms[ppc->ppc_avm], 1384 ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ? 1385 ppc_epp_protocol[ppc->ppc_epp] : ""); 1386 1387 isdp->id_ointr = ppcintr; 1388 1389 /* 1390 * Prepare ppbus data area for upper level code. 1391 */ 1392 ppbus = ppb_alloc_bus(); 1393 1394 if (!ppbus) 1395 return (0); 1396 1397 ppc->ppc_link.ppbus = ppbus; 1398 ppbus->ppb_link = &ppc->ppc_link; 1399 1400 /* 1401 * Probe the ppbus and attach devices found. 1402 */ 1403 ppb_attachdevs(ppbus); 1404 1405 return (1); 1406 } 1407 #endif 1408