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