ppc.c revision 38061
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.3 1998/04/17 22:36:37 des 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", ppc->ppc_unit, 453 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 469 } else 470 if ((inb(cio) & SMC_CR1_MODE) == 0) { 471 /* already in extended parallel port mode, read CR4 */ 472 outb(csr, 0x4); 473 r = (inb(cio) & SMC_CR4_EMODE); 474 475 switch (r) { 476 case SMC_SPP: 477 ppc->ppc_avm |= PPB_SPP; 478 break; 479 480 case SMC_EPPSPP: 481 ppc->ppc_avm |= PPB_EPP | PPB_SPP; 482 break; 483 484 case SMC_ECP: 485 ppc->ppc_avm |= PPB_ECP | PPB_SPP; 486 break; 487 488 case SMC_ECPEPP: 489 ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; 490 break; 491 } 492 } else { 493 /* not an extended port mode */ 494 ppc->ppc_avm |= PPB_SPP; 495 } 496 497 } else { 498 /* mode forced */ 499 500 /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */ 501 if (type == SMC_37C666GT) 502 goto end_detect; 503 504 r = inb(cio); 505 if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) { 506 /* do not use ECP when the mode is not forced to */ 507 outb(cio, r | SMC_CR1_MODE); 508 } else { 509 /* an extended mode is selected */ 510 outb(cio, r & ~SMC_CR1_MODE); 511 512 /* read CR4 register and reset mode field */ 513 outb(csr, 0x4); 514 r = inb(cio) & ~SMC_CR4_EMODE; 515 516 if (chipset_mode & PPB_ECP) { 517 if (chipset_mode & PPB_EPP) { 518 outb(cio, r | SMC_ECPEPP); 519 } else { 520 outb(cio, r | SMC_ECP); 521 } 522 } else { 523 /* PPB_EPP is set */ 524 outb(cio, r | SMC_EPPSPP); 525 } 526 } 527 ppc->ppc_avm = chipset_mode; 528 } 529 530end_detect: 531 532 if (bootverbose) 533 printf ("\n"); 534 535 if (chipset_mode & PPB_EPP) { 536 /* select CR4 */ 537 outb(csr, 0x4); 538 r = inb(cio); 539 540 /* 541 * Set the EPP protocol... 542 * Low=EPP 1.9 (1284 standard) and High=EPP 1.7 543 */ 544 if (ppc->ppc_epp == EPP_1_9) 545 outb(cio, (r & ~SMC_CR4_EPPTYPE)); 546 else 547 outb(cio, (r | SMC_CR4_EPPTYPE)); 548 } 549 550 /* end config mode */ 551 outb(csr, 0xaa); 552 553 if (ppc->ppc_avm & PPB_ECP) 554 ppc_ecp_config(ppc, chipset_mode); 555 556 return (chipset_mode); 557} 558 559/* 560 * Winbond W83877F stuff 561 * 562 * EFER: extended function enable register 563 * EFIR: extended function index register 564 * EFDR: extended function data register 565 */ 566#define efir ((efer == 0x250) ? 0x251 : 0x3f0) 567#define efdr ((efer == 0x250) ? 0x252 : 0x3f1) 568 569static int w83877f_efers[] = { 0x250, 0x3f0, 0x3f0, 0x250 }; 570static int w83877f_keys[] = { 0x89, 0x86, 0x87, 0x88 }; 571static int w83877f_keyiter[] = { 1, 2, 2, 1 }; 572static int w83877f_hefs[] = { WINB_HEFERE, WINB_HEFRAS, WINB_HEFERE | WINB_HEFRAS, 0 }; 573 574static int 575ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode) 576{ 577 int i, j, efer, base; 578 unsigned char r, hefere, hefras; 579 580 for (i = 0; i < 4; i ++) { 581 /* first try to enable configuration registers */ 582 efer = w83877f_efers[i]; 583 584 /* write the key to the EFER */ 585 for (j = 0; j < w83877f_keyiter[i]; j ++) 586 outb (efer, w83877f_keys[i]); 587 588 /* then check HEFERE and HEFRAS bits */ 589 outb (efir, 0x0c); 590 hefere = inb(efdr) & WINB_HEFERE; 591 592 outb (efir, 0x16); 593 hefras = inb(efdr) & WINB_HEFRAS; 594 595 /* 596 * HEFRAS HEFERE 597 * 0 1 write 89h to 250h (power-on default) 598 * 1 0 write 86h twice to 3f0h 599 * 1 1 write 87h twice to 3f0h 600 * 0 0 write 88h to 250h 601 */ 602 if ((hefere | hefras) == w83877f_hefs[i]) 603 goto found; 604 } 605 606 return (-1); /* failed */ 607 608found: 609 /* check base port address - read from CR23 */ 610 outb(efir, 0x23); 611 if (ppc->ppc_base != inb(efdr) * 4) /* 4 bytes boundaries */ 612 return (-1); 613 614 /* read CHIP ID from CR9/bits0-3 */ 615 outb(efir, 0x9); 616 617 switch (inb(efdr) & WINB_CHIPID) { 618 case WINB_W83877F_ID: 619 ppc->ppc_type = WINB_W83877F; 620 break; 621 622 case WINB_W83877AF_ID: 623 ppc->ppc_type = WINB_W83877AF; 624 break; 625 626 default: 627 ppc->ppc_type = WINB_UNKNOWN; 628 } 629 630 if (bootverbose) { 631 /* dump of registers */ 632 printf("ppc%d: 0x%x - ", ppc->ppc_unit, w83877f_keys[i]); 633 for (i = 0; i <= 0xd; i ++) { 634 outb(efir, i); 635 printf("0x%x ", inb(efdr)); 636 } 637 for (i = 0x10; i <= 0x17; i ++) { 638 outb(efir, i); 639 printf("0x%x ", inb(efdr)); 640 } 641 outb(efir, 0x1e); 642 printf("0x%x ", inb(efdr)); 643 for (i = 0x20; i <= 0x29; i ++) { 644 outb(efir, i); 645 printf("0x%x ", inb(efdr)); 646 } 647 printf("\n"); 648 } 649 650 if (!chipset_mode) { 651 /* autodetect mode */ 652 653 /* select CR0 */ 654 outb(efir, 0x0); 655 r = inb(efdr) & (WINB_PRTMODS0 | WINB_PRTMODS1); 656 657 /* select CR9 */ 658 outb(efir, 0x9); 659 r |= (inb(efdr) & WINB_PRTMODS2); 660 661 switch (r) { 662 case WINB_W83757: 663 if (bootverbose) 664 printf("ppc%d: W83757 compatible mode\n", 665 ppc->ppc_unit); 666 return (-1); /* generic or SMC-like */ 667 668 case WINB_EXTFDC: 669 case WINB_EXTADP: 670 case WINB_EXT2FDD: 671 case WINB_JOYSTICK: 672 if (bootverbose) 673 printf("ppc%d: not in parallel port mode\n", 674 ppc->ppc_unit); 675 return (-1); 676 677 case (WINB_PARALLEL | WINB_EPP_SPP): 678 ppc->ppc_avm |= PPB_EPP | PPB_SPP; 679 break; 680 681 case (WINB_PARALLEL | WINB_ECP): 682 ppc->ppc_avm |= PPB_ECP | PPB_SPP; 683 break; 684 685 case (WINB_PARALLEL | WINB_ECP_EPP): 686 ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; 687 break; 688 default: 689 printf("%s: unknown case (0x%x)!\n", __FUNCTION__, r); 690 } 691 692 } else { 693 /* mode forced */ 694 695 /* select CR9 and set PRTMODS2 bit */ 696 outb(efir, 0x9); 697 outb(efdr, inb(efdr) & ~WINB_PRTMODS2); 698 699 /* select CR0 and reset PRTMODSx bits */ 700 outb(efir, 0x0); 701 outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1)); 702 703 if (chipset_mode & PPB_ECP) { 704 if (chipset_mode & PPB_EPP) 705 outb(efdr, inb(efdr) | WINB_ECP_EPP); 706 else 707 outb(efdr, inb(efdr) | WINB_ECP); 708 } else { 709 /* select EPP_SPP otherwise */ 710 outb(efdr, inb(efdr) | WINB_EPP_SPP); 711 } 712 ppc->ppc_avm = chipset_mode; 713 } 714 715 /* exit configuration mode */ 716 outb(efer, 0xaa); 717 718 if (ppc->ppc_avm & PPB_ECP) 719 ppc_ecp_config(ppc, chipset_mode); 720 721 return (chipset_mode); 722} 723 724/* 725 * ppc_generic_detect 726 */ 727static int 728ppc_generic_detect(struct ppc_data *ppc, int chipset_mode) 729{ 730 char save_control; 731 732 if (!chipset_mode) { 733 /* first, check for ECP */ 734 w_ecr(ppc, 0x20); 735 if ((r_ecr(ppc) & 0xe0) == 0x20) { 736 ppc->ppc_avm |= PPB_ECP | PPB_SPP; 737 738 /* search for SMC style ECP+EPP mode */ 739 w_ecr(ppc, 0x80); 740 } 741 742 /* try to reset EPP timeout bit */ 743 if (ppc_check_epp_timeout(ppc)) { 744 ppc->ppc_avm |= PPB_EPP; 745 746 if (ppc->ppc_avm & PPB_ECP) 747 /* SMC like chipset found */ 748 ppc->ppc_type = SMC_LIKE; 749 } 750 751 /* XXX try to detect NIBBLE mode */ 752 ppc->ppc_avm |= PPB_NIBBLE; 753 754 } else 755 ppc->ppc_avm = chipset_mode; 756 757 if (ppc->ppc_avm & PPB_ECP) 758 ppc_ecp_config(ppc, chipset_mode); 759 760 return (chipset_mode); 761} 762 763/* 764 * ppc_detect() 765 * 766 * mode is the mode suggested at boot 767 */ 768static int 769ppc_detect(struct ppc_data *ppc, int chipset_mode) { 770 771 int i, mode; 772 773 /* list of supported chipsets */ 774 int (*chipset_detect[])(struct ppc_data *, int) = { 775 ppc_pc873xx_detect, 776 ppc_smc37c66xgt_detect, 777 ppc_w83877f_detect, 778 ppc_generic_detect, 779 NULL 780 }; 781 782 /* if can't find the port and mode not forced return error */ 783 if (!ppc_detect_port(ppc) && chipset_mode == 0) 784 return (EIO); /* failed, port not present */ 785 786 /* assume centronics compatible mode is supported */ 787 ppc->ppc_avm = PPB_COMPATIBLE; 788 789 /* we have to differenciate available chipset modes, 790 * chipset running modes and IEEE-1284 operating modes 791 * 792 * after detection, the port must support running in compatible mode 793 */ 794 for (i=0; chipset_detect[i] != NULL; i++) { 795 if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) { 796 ppc->ppc_mode = mode; 797 break; 798 } 799 } 800 801 return (0); 802} 803 804/* 805 * ppc_exec_microseq() 806 * 807 * Execute a microsequence. 808 * Microsequence mechanism is supposed to handle fast I/O operations. 809 */ 810static int 811ppc_exec_microseq(int unit, struct ppb_microseq *msq, int *ppbpc) 812{ 813 struct ppc_data *ppc = ppcdata[unit]; 814 struct ppb_microseq *pc; 815 char cc, *p; 816 int i, iter, reg; 817 int error; 818 819 /* static to be reused after few ppc_exec_microseq()/return calls 820 * XXX should be in a context variable shared with ppb level */ 821 static int accum; 822 static char *ptr; 823 824 struct ppb_microseq *microseq_stack = 0; 825 struct ppb_microseq *pc_stack = 0; 826 827/* microsequence registers are equivalent to PC-like port registers */ 828#define r_reg(register,ppc) ((char)inb((ppc)->ppc_base + register)) 829#define w_reg(register,ppc,byte) outb((ppc)->ppc_base + register, byte) 830 831#define INCR_PC (pc ++) /* increment program counter */ 832#define mi pc /* microinstruction currently executed */ 833 834 /* get the state of pc from ppb level of execution */ 835 pc = &msq[*ppbpc]; 836 837 for (;;) { 838 839 switch (mi->opcode) { 840 case MS_OP_RSET: 841 cc = r_reg(mi->arg[0].i, ppc); 842 cc &= mi->arg[2].c; /* clear mask */ 843 cc |= mi->arg[1].c; /* assert mask */ 844 w_reg(mi->arg[0].i, ppc, cc); 845 INCR_PC; 846 break; 847 848 case MS_OP_RASSERT_P: 849 for (i=0; i<mi->arg[0].i; i++) 850 w_reg(mi->arg[1].i, ppc, *ptr++); 851 INCR_PC; 852 break; 853 854 case MS_OP_RFETCH_P: 855 for (i=0; i<mi->arg[0].i; i++) 856 *ptr++ = r_reg(mi->arg[1].i, ppc) & 857 mi->arg[2].c; 858 INCR_PC; 859 break; 860 861 case MS_OP_RFETCH: 862 *((char *) mi->arg[2].p) = r_reg(mi->arg[0].i, ppc) & 863 mi->arg[1].c; 864 INCR_PC; 865 break; 866 867 case MS_OP_RASSERT: 868 869 /* let's suppose the next instr. is the same */ 870 prefetch: 871 for (;mi->opcode == MS_OP_RASSERT; INCR_PC) 872 w_reg(mi->arg[0].i, ppc, mi->arg[1].c); 873 874 if (mi->opcode == MS_OP_DELAY) { 875 DELAY(mi->arg[0].i); 876 INCR_PC; 877 goto prefetch; 878 } 879 break; 880 881 case MS_OP_DELAY: 882 DELAY(mi->arg[0].i); 883 INCR_PC; 884 break; 885 886 case MS_OP_TRIG: 887 reg = mi->arg[0].i; 888 iter = mi->arg[1].i; 889 p = (char *)mi->arg[2].p; 890 891 for (i=0; i<iter; i++) { 892 w_reg(reg, ppc, *p++); 893 DELAY((unsigned char)*p++); 894 } 895 INCR_PC; 896 break; 897 898 case MS_OP_SET: 899 accum = mi->arg[0].i; 900 INCR_PC; 901 break; 902 903 case MS_OP_DBRA: 904 if (--accum > 0) 905 pc += mi->arg[0].i; 906 else 907 INCR_PC; 908 break; 909 910 case MS_OP_BRSET: 911 cc = r_str(ppc); 912 if ((cc & mi->arg[0].c) == mi->arg[0].c) 913 pc += mi->arg[1].i; 914 else 915 INCR_PC; 916 break; 917 918 case MS_OP_BRCLEAR: 919 cc = r_str(ppc); 920 if ((cc & mi->arg[0].c) == 0) 921 pc += mi->arg[1].i; 922 else 923 INCR_PC; 924 break; 925 926 case MS_OP_C_CALL: 927 /* 928 * If the C call returns !0 then end the microseq. 929 * The current state of ptr is passed to the C function 930 */ 931 if ((error = mi->arg[0].f(mi->arg[1].p, ptr))) 932 return (error); 933 934 INCR_PC; 935 break; 936 937 case MS_OP_PTR: 938 ptr = (char *)mi->arg[0].p; 939 INCR_PC; 940 break; 941 942 case MS_OP_CALL: 943 if (microseq_stack) 944 panic("%s: too much calls", __FUNCTION__); 945 946 if (mi->arg[0].p) { 947 /* store the state of the actual 948 * microsequence 949 */ 950 microseq_stack = msq; 951 pc_stack = pc; 952 953 /* jump to the new microsequence */ 954 msq = (struct ppb_microseq *)mi->arg[0].p; 955 pc = msq; 956 } else 957 INCR_PC; 958 959 break; 960 961 case MS_OP_SUBRET: 962 /* retrieve microseq and pc state before the call */ 963 msq = microseq_stack; 964 pc = pc_stack; 965 966 /* reset the stack */ 967 microseq_stack = 0; 968 969 /* XXX return code */ 970 971 INCR_PC; 972 break; 973 974 case MS_OP_PUT: 975 case MS_OP_GET: 976 case MS_OP_RET: 977 /* can't return to ppb level during the execution 978 * of a submicrosequence */ 979 if (microseq_stack) 980 panic("%s: can't return to ppb level", 981 __FUNCTION__); 982 983 /* update pc for ppb level of execution */ 984 *ppbpc = (int)(pc - msq); 985 986 /* return to ppb level of execution */ 987 return (0); 988 989 default: 990 panic("%s: unknown microsequence opcode 0x%x", 991 __FUNCTION__, mi->opcode); 992 } 993 } 994 995 /* unreached */ 996} 997 998/* 999 * Configure current operating mode 1000 */ 1001static int 1002ppc_generic_setmode(int unit, int mode) 1003{ 1004 struct ppc_data *ppc = ppcdata[unit]; 1005 1006 /* back to compatible mode, XXX don't know yet what to do here */ 1007 if (mode == 0) { 1008 ppc->ppc_mode = PPB_COMPATIBLE; 1009 return (0); 1010 } 1011 1012 /* check if mode is available */ 1013 if (!(ppc->ppc_avm & mode)) 1014 return (EOPNOTSUPP); 1015 1016 /* if ECP mode, configure ecr register */ 1017 if (ppc->ppc_avm & PPB_ECP) 1018 ppc_ecp_config(ppc, mode); 1019 1020 ppc->ppc_mode = mode; 1021 1022 return (0); 1023} 1024 1025/* 1026 * EPP timeout, according to the PC87332 manual 1027 * Semantics of clearing EPP timeout bit. 1028 * PC87332 - reading SPP_STR does it... 1029 * SMC - write 1 to EPP timeout bit XXX 1030 * Others - (???) write 0 to EPP timeout bit 1031 */ 1032static void 1033ppc_reset_epp_timeout(int unit) 1034{ 1035 struct ppc_data *ppc = ppcdata[unit]; 1036 register char r; 1037 1038 r = r_str(ppc); 1039 w_str(ppc, r | 0x1); 1040 w_str(ppc, r & 0xfe); 1041 1042 return; 1043} 1044 1045static int 1046ppcprobe(struct isa_device *dvp) 1047{ 1048 static short next_bios_ppc = 0; 1049 struct ppc_data *ppc; 1050 int error; 1051 1052 /* 1053 * If port not specified, use bios list. 1054 */ 1055 if(dvp->id_iobase < 0) { 1056 if((next_bios_ppc < BIOS_MAX_PPC) && 1057 (*(BIOS_PORTS+next_bios_ppc) != 0) ) { 1058 dvp->id_iobase = *(BIOS_PORTS+next_bios_ppc++); 1059 } else 1060 return (0); 1061 } 1062 1063 /* 1064 * Port was explicitly specified. 1065 * This allows probing of ports unknown to the BIOS. 1066 */ 1067 1068 /* 1069 * Allocate the ppc_data structure. 1070 */ 1071 ppc = malloc(sizeof(struct ppc_data), M_DEVBUF, M_NOWAIT); 1072 if (!ppc) { 1073 printf("ppc: cannot malloc!\n"); 1074 goto error; 1075 } 1076 bzero(ppc, sizeof(struct ppc_data)); 1077 1078 ppc->ppc_base = dvp->id_iobase; 1079 ppc->ppc_unit = dvp->id_unit; 1080 ppc->ppc_type = GENERIC; 1081 1082 ppc->ppc_mode = PPB_COMPATIBLE; 1083 ppc->ppc_epp = (dvp->id_flags & 0x10) >> 4; 1084 1085 /* 1086 * XXX 1087 * Try and detect if interrupts are working. 1088 */ 1089 if (!(dvp->id_flags & 0x20)) 1090 ppc->ppc_irq = (dvp->id_irq); 1091 1092 ppcdata[ppc->ppc_unit] = ppc; 1093 nppc ++; 1094 1095 /* 1096 * Try to detect the chipset and its mode. 1097 */ 1098 if (ppc_detect(ppc, dvp->id_flags & 0xf)) 1099 goto error; 1100 1101end_probe: 1102 1103 return (1); 1104 1105error: 1106 return (0); 1107} 1108 1109static int 1110ppcattach(struct isa_device *isdp) 1111{ 1112 struct ppc_data *ppc = ppcdata[isdp->id_unit]; 1113 struct ppb_data *ppbus; 1114 char * mode; 1115 1116 /* 1117 * Link the Parallel Port Chipset (adapter) to 1118 * the future ppbus. 1119 */ 1120 ppc->ppc_link.adapter_unit = ppc->ppc_unit; 1121 ppc->ppc_link.adapter = &ppc_adapter; 1122 1123 printf("ppc%d: %s chipset (%s) in %s mode%s\n", ppc->ppc_unit, 1124 ppc_types[ppc->ppc_type], ppc_avms[ppc->ppc_avm], 1125 ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ? 1126 ppc_epp_protocol[ppc->ppc_epp] : ""); 1127 1128 /* 1129 * Prepare ppbus data area for upper level code. 1130 */ 1131 ppbus = ppb_alloc_bus(); 1132 1133 if (!ppbus) 1134 return (0); 1135 1136 ppc->ppc_link.ppbus = ppbus; 1137 ppbus->ppb_link = &ppc->ppc_link; 1138 1139 /* 1140 * Probe the ppbus and attach devices found. 1141 */ 1142 ppb_attachdevs(ppbus); 1143 1144 return (1); 1145} 1146#endif 1147