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