1 /* $NetBSD: i82365.c,v 1.8 1998/02/01 23:36:23 marc Exp $ */ 2 3 #define PCICDEBUG 4 5 /* 6 * Copyright (c) 1997 Marc Horowitz. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Marc Horowitz. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/types.h> 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/device.h> 38 #include <sys/extent.h> 39 #include <sys/malloc.h> 40 41 #include <vm/vm.h> 42 43 #include <machine/bus.h> 44 #include <machine/intr.h> 45 46 #include <dev/pcmcia/pcmciareg.h> 47 #include <dev/pcmcia/pcmciavar.h> 48 49 #include <dev/ic/i82365reg.h> 50 #include <dev/ic/i82365var.h> 51 52 #include "locators.h" 53 54 #ifdef PCICDEBUG 55 int pcic_debug = 0; 56 #define DPRINTF(arg) if (pcic_debug) printf arg; 57 #else 58 #define DPRINTF(arg) 59 #endif 60 61 #define PCIC_VENDOR_UNKNOWN 0 62 #define PCIC_VENDOR_I82365SLR0 1 63 #define PCIC_VENDOR_I82365SLR1 2 64 #define PCIC_VENDOR_CIRRUS_PD6710 3 65 #define PCIC_VENDOR_CIRRUS_PD672X 4 66 67 /* 68 * Individual drivers will allocate their own memory and io regions. Memory 69 * regions must be a multiple of 4k, aligned on a 4k boundary. 70 */ 71 72 #define PCIC_MEM_ALIGN PCIC_MEM_PAGESIZE 73 74 void pcic_attach_socket __P((struct pcic_handle *)); 75 void pcic_init_socket __P((struct pcic_handle *)); 76 77 #ifdef __BROKEN_INDIRECT_CONFIG 78 int pcic_submatch __P((struct device *, void *, void *)); 79 #else 80 int pcic_submatch __P((struct device *, struct cfdata *, void *)); 81 #endif 82 int pcic_print __P((void *arg, const char *pnp)); 83 int pcic_intr_socket __P((struct pcic_handle *)); 84 85 void pcic_attach_card __P((struct pcic_handle *)); 86 void pcic_detach_card __P((struct pcic_handle *)); 87 88 void pcic_chip_do_mem_map __P((struct pcic_handle *, int)); 89 void pcic_chip_do_io_map __P((struct pcic_handle *, int)); 90 91 static void pcic_wait_ready __P((struct pcic_handle *)); 92 93 int 94 pcic_ident_ok(ident) 95 int ident; 96 { 97 /* this is very empirical and heuristic */ 98 99 if ((ident == 0) || (ident == 0xff) || (ident & PCIC_IDENT_ZERO)) 100 return (0); 101 102 if ((ident & PCIC_IDENT_IFTYPE_MASK) != PCIC_IDENT_IFTYPE_MEM_AND_IO) { 103 #ifdef DIAGNOSTIC 104 printf("pcic: does not support memory and I/O cards, " 105 "ignored (ident=%0x)\n", ident); 106 #endif 107 return (0); 108 } 109 return (1); 110 } 111 112 int 113 pcic_vendor(h) 114 struct pcic_handle *h; 115 { 116 int reg; 117 118 /* 119 * the chip_id of the cirrus toggles between 11 and 00 after a write. 120 * weird. 121 */ 122 123 pcic_write(h, PCIC_CIRRUS_CHIP_INFO, 0); 124 reg = pcic_read(h, -1); 125 126 if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == 127 PCIC_CIRRUS_CHIP_INFO_CHIP_ID) { 128 reg = pcic_read(h, -1); 129 if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == 0) { 130 if (reg & PCIC_CIRRUS_CHIP_INFO_SLOTS) 131 return (PCIC_VENDOR_CIRRUS_PD672X); 132 else 133 return (PCIC_VENDOR_CIRRUS_PD6710); 134 } 135 } 136 /* XXX how do I identify the GD6729? */ 137 138 reg = pcic_read(h, PCIC_IDENT); 139 140 if ((reg & PCIC_IDENT_REV_MASK) == PCIC_IDENT_REV_I82365SLR0) 141 return (PCIC_VENDOR_I82365SLR0); 142 else 143 return (PCIC_VENDOR_I82365SLR1); 144 145 return (PCIC_VENDOR_UNKNOWN); 146 } 147 148 char * 149 pcic_vendor_to_string(vendor) 150 int vendor; 151 { 152 switch (vendor) { 153 case PCIC_VENDOR_I82365SLR0: 154 return ("Intel 82365SL Revision 0"); 155 case PCIC_VENDOR_I82365SLR1: 156 return ("Intel 82365SL Revision 1"); 157 case PCIC_VENDOR_CIRRUS_PD6710: 158 return ("Cirrus PD6710"); 159 case PCIC_VENDOR_CIRRUS_PD672X: 160 return ("Cirrus PD672X"); 161 } 162 163 return ("Unknown controller"); 164 } 165 166 void 167 pcic_attach(sc) 168 struct pcic_softc *sc; 169 { 170 int vendor, count, i, reg; 171 172 /* now check for each controller/socket */ 173 174 /* 175 * this could be done with a loop, but it would violate the 176 * abstraction 177 */ 178 179 count = 0; 180 181 DPRINTF(("pcic ident regs:")); 182 183 sc->handle[0].sc = sc; 184 sc->handle[0].sock = C0SA; 185 if (pcic_ident_ok(reg = pcic_read(&sc->handle[0], PCIC_IDENT))) { 186 sc->handle[0].flags = PCIC_FLAG_SOCKETP; 187 count++; 188 } else { 189 sc->handle[0].flags = 0; 190 } 191 192 DPRINTF((" 0x%02x", reg)); 193 194 sc->handle[1].sc = sc; 195 sc->handle[1].sock = C0SB; 196 if (pcic_ident_ok(reg = pcic_read(&sc->handle[1], PCIC_IDENT))) { 197 sc->handle[1].flags = PCIC_FLAG_SOCKETP; 198 count++; 199 } else { 200 sc->handle[1].flags = 0; 201 } 202 203 DPRINTF((" 0x%02x", reg)); 204 205 sc->handle[2].sc = sc; 206 sc->handle[2].sock = C1SA; 207 if (pcic_ident_ok(reg = pcic_read(&sc->handle[2], PCIC_IDENT))) { 208 sc->handle[2].flags = PCIC_FLAG_SOCKETP; 209 count++; 210 } else { 211 sc->handle[2].flags = 0; 212 } 213 214 DPRINTF((" 0x%02x", reg)); 215 216 sc->handle[3].sc = sc; 217 sc->handle[3].sock = C1SB; 218 if (pcic_ident_ok(reg = pcic_read(&sc->handle[3], PCIC_IDENT))) { 219 sc->handle[3].flags = PCIC_FLAG_SOCKETP; 220 count++; 221 } else { 222 sc->handle[3].flags = 0; 223 } 224 225 DPRINTF((" 0x%02x\n", reg)); 226 227 if (count == 0) 228 panic("pcic_attach: attach found no sockets"); 229 230 /* establish the interrupt */ 231 232 /* XXX block interrupts? */ 233 234 for (i = 0; i < PCIC_NSLOTS; i++) { 235 #if 0 236 /* 237 * this should work, but w/o it, setting tty flags hangs at 238 * boot time. 239 */ 240 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP) 241 #endif 242 { 243 pcic_write(&sc->handle[i], PCIC_CSC_INTR, 0); 244 pcic_read(&sc->handle[i], PCIC_CSC); 245 } 246 } 247 248 if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) || 249 (sc->handle[1].flags & PCIC_FLAG_SOCKETP)) { 250 vendor = pcic_vendor(&sc->handle[0]); 251 252 printf("%s: controller 0 (%s) has ", sc->dev.dv_xname, 253 pcic_vendor_to_string(vendor)); 254 255 if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) && 256 (sc->handle[1].flags & PCIC_FLAG_SOCKETP)) 257 printf("sockets A and B\n"); 258 else if (sc->handle[0].flags & PCIC_FLAG_SOCKETP) 259 printf("socket A only\n"); 260 else 261 printf("socket B only\n"); 262 263 if (sc->handle[0].flags & PCIC_FLAG_SOCKETP) 264 sc->handle[0].vendor = vendor; 265 if (sc->handle[1].flags & PCIC_FLAG_SOCKETP) 266 sc->handle[1].vendor = vendor; 267 } 268 if ((sc->handle[2].flags & PCIC_FLAG_SOCKETP) || 269 (sc->handle[3].flags & PCIC_FLAG_SOCKETP)) { 270 vendor = pcic_vendor(&sc->handle[2]); 271 272 printf("%s: controller 1 (%s) has ", sc->dev.dv_xname, 273 pcic_vendor_to_string(vendor)); 274 275 if ((sc->handle[2].flags & PCIC_FLAG_SOCKETP) && 276 (sc->handle[3].flags & PCIC_FLAG_SOCKETP)) 277 printf("sockets A and B\n"); 278 else if (sc->handle[2].flags & PCIC_FLAG_SOCKETP) 279 printf("socket A only\n"); 280 else 281 printf("socket B only\n"); 282 283 if (sc->handle[2].flags & PCIC_FLAG_SOCKETP) 284 sc->handle[2].vendor = vendor; 285 if (sc->handle[3].flags & PCIC_FLAG_SOCKETP) 286 sc->handle[3].vendor = vendor; 287 } 288 } 289 290 void 291 pcic_attach_sockets(sc) 292 struct pcic_softc *sc; 293 { 294 int i; 295 296 for (i = 0; i < PCIC_NSLOTS; i++) 297 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP) 298 pcic_attach_socket(&sc->handle[i]); 299 } 300 301 void 302 pcic_attach_socket(h) 303 struct pcic_handle *h; 304 { 305 struct pcmciabus_attach_args paa; 306 307 /* initialize the rest of the handle */ 308 309 h->memalloc = 0; 310 h->ioalloc = 0; 311 h->ih_irq = 0; 312 313 /* now, config one pcmcia device per socket */ 314 315 paa.pct = (pcmcia_chipset_tag_t) h->sc->pct; 316 paa.pch = (pcmcia_chipset_handle_t) h; 317 paa.iobase = h->sc->iobase; 318 paa.iosize = h->sc->iosize; 319 320 h->pcmcia = config_found_sm(&h->sc->dev, &paa, pcic_print, 321 pcic_submatch); 322 323 /* if there's actually a pcmcia device attached, initialize the slot */ 324 325 if (h->pcmcia) 326 pcic_init_socket(h); 327 } 328 329 void 330 pcic_init_socket(h) 331 struct pcic_handle *h; 332 { 333 int reg; 334 335 /* set up the card to interrupt on card detect */ 336 337 pcic_write(h, PCIC_CSC_INTR, (h->sc->irq << PCIC_CSC_INTR_IRQ_SHIFT) | 338 PCIC_CSC_INTR_CD_ENABLE); 339 pcic_write(h, PCIC_INTR, 0); 340 pcic_read(h, PCIC_CSC); 341 342 /* unsleep the cirrus controller */ 343 344 if ((h->vendor == PCIC_VENDOR_CIRRUS_PD6710) || 345 (h->vendor == PCIC_VENDOR_CIRRUS_PD672X)) { 346 reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2); 347 if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) { 348 DPRINTF(("%s: socket %02x was suspended\n", 349 h->sc->dev.dv_xname, h->sock)); 350 reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND; 351 pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg); 352 } 353 } 354 /* if there's a card there, then attach it. */ 355 356 reg = pcic_read(h, PCIC_IF_STATUS); 357 358 if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) == 359 PCIC_IF_STATUS_CARDDETECT_PRESENT) 360 pcic_attach_card(h); 361 } 362 363 int 364 #ifdef __BROKEN_INDIRECT_CONFIG 365 pcic_submatch(parent, match, aux) 366 #else 367 pcic_submatch(parent, cf, aux) 368 #endif 369 struct device *parent; 370 #ifdef __BROKEN_INDIRECT_CONFIG 371 void *match; 372 #else 373 struct cfdata *cf; 374 #endif 375 void *aux; 376 { 377 #ifdef __BROKEN_INDIRECT_CONFIG 378 struct cfdata *cf = match; 379 #endif 380 381 struct pcmciabus_attach_args *paa = aux; 382 struct pcic_handle *h = (struct pcic_handle *) paa->pch; 383 384 switch (h->sock) { 385 case C0SA: 386 if (cf->cf_loc[PCICCF_CONTROLLER] != 387 PCICCF_CONTROLLER_DEFAULT && 388 cf->cf_loc[PCICCF_CONTROLLER] != 0) 389 return 0; 390 if (cf->cf_loc[PCICCF_SOCKET] != PCICCF_SOCKET_DEFAULT && 391 cf->cf_loc[PCICCF_SOCKET] != 0) 392 return 0; 393 394 break; 395 case C0SB: 396 if (cf->cf_loc[PCICCF_CONTROLLER] != 397 PCICCF_CONTROLLER_DEFAULT && 398 cf->cf_loc[PCICCF_CONTROLLER] != 0) 399 return 0; 400 if (cf->cf_loc[PCICCF_SOCKET] != PCICCF_SOCKET_DEFAULT && 401 cf->cf_loc[PCICCF_SOCKET] != 1) 402 return 0; 403 404 break; 405 case C1SA: 406 if (cf->cf_loc[PCICCF_CONTROLLER] != 407 PCICCF_CONTROLLER_DEFAULT && 408 cf->cf_loc[PCICCF_CONTROLLER] != 1) 409 return 0; 410 if (cf->cf_loc[PCICCF_SOCKET] != PCICCF_SOCKET_DEFAULT && 411 cf->cf_loc[PCICCF_SOCKET] != 0) 412 return 0; 413 414 break; 415 case C1SB: 416 if (cf->cf_loc[PCICCF_CONTROLLER] != 417 PCICCF_CONTROLLER_DEFAULT && 418 cf->cf_loc[PCICCF_CONTROLLER] != 1) 419 return 0; 420 if (cf->cf_loc[PCICCF_SOCKET] != PCICCF_SOCKET_DEFAULT && 421 cf->cf_loc[PCICCF_SOCKET] != 1) 422 return 0; 423 424 break; 425 default: 426 panic("unknown pcic socket"); 427 } 428 429 return ((*cf->cf_attach->ca_match)(parent, cf, aux)); 430 } 431 432 int 433 pcic_print(arg, pnp) 434 void *arg; 435 const char *pnp; 436 { 437 struct pcmciabus_attach_args *paa = arg; 438 struct pcic_handle *h = (struct pcic_handle *) paa->pch; 439 440 /* Only "pcmcia"s can attach to "pcic"s... easy. */ 441 if (pnp) 442 printf("pcmcia at %s", pnp); 443 444 switch (h->sock) { 445 case C0SA: 446 printf(" controller 0 socket 0"); 447 break; 448 case C0SB: 449 printf(" controller 0 socket 1"); 450 break; 451 case C1SA: 452 printf(" controller 1 socket 0"); 453 break; 454 case C1SB: 455 printf(" controller 1 socket 1"); 456 break; 457 default: 458 panic("unknown pcic socket"); 459 } 460 461 return (UNCONF); 462 } 463 464 int 465 pcic_intr(arg) 466 void *arg; 467 { 468 struct pcic_softc *sc = arg; 469 int i, ret = 0; 470 471 DPRINTF(("%s: intr\n", sc->dev.dv_xname)); 472 473 for (i = 0; i < PCIC_NSLOTS; i++) 474 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP) 475 ret += pcic_intr_socket(&sc->handle[i]); 476 477 return (ret ? 1 : 0); 478 } 479 480 int 481 pcic_intr_socket(h) 482 struct pcic_handle *h; 483 { 484 int cscreg; 485 486 cscreg = pcic_read(h, PCIC_CSC); 487 488 cscreg &= (PCIC_CSC_GPI | 489 PCIC_CSC_CD | 490 PCIC_CSC_READY | 491 PCIC_CSC_BATTWARN | 492 PCIC_CSC_BATTDEAD); 493 494 if (cscreg & PCIC_CSC_GPI) { 495 DPRINTF(("%s: %02x GPI\n", h->sc->dev.dv_xname, h->sock)); 496 } 497 if (cscreg & PCIC_CSC_CD) { 498 int statreg; 499 500 statreg = pcic_read(h, PCIC_IF_STATUS); 501 502 DPRINTF(("%s: %02x CD %x\n", h->sc->dev.dv_xname, h->sock, 503 statreg)); 504 505 /* 506 * XXX This should probably schedule something to happen 507 * after the interrupt handler completes 508 */ 509 510 if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) == 511 PCIC_IF_STATUS_CARDDETECT_PRESENT) { 512 if (!(h->flags & PCIC_FLAG_CARDP)) 513 pcic_attach_card(h); 514 } else { 515 if (h->flags & PCIC_FLAG_CARDP) 516 pcic_detach_card(h); 517 } 518 } 519 if (cscreg & PCIC_CSC_READY) { 520 DPRINTF(("%s: %02x READY\n", h->sc->dev.dv_xname, h->sock)); 521 /* shouldn't happen */ 522 } 523 if (cscreg & PCIC_CSC_BATTWARN) { 524 DPRINTF(("%s: %02x BATTWARN\n", h->sc->dev.dv_xname, h->sock)); 525 } 526 if (cscreg & PCIC_CSC_BATTDEAD) { 527 DPRINTF(("%s: %02x BATTDEAD\n", h->sc->dev.dv_xname, h->sock)); 528 } 529 return (cscreg ? 1 : 0); 530 } 531 532 void 533 pcic_attach_card(h) 534 struct pcic_handle *h; 535 { 536 if (h->flags & PCIC_FLAG_CARDP) 537 panic("pcic_attach_card: already attached"); 538 539 /* call the MI attach function */ 540 541 pcmcia_card_attach(h->pcmcia); 542 543 h->flags |= PCIC_FLAG_CARDP; 544 } 545 546 void 547 pcic_detach_card(h) 548 struct pcic_handle *h; 549 { 550 if (!(h->flags & PCIC_FLAG_CARDP)) 551 panic("pcic_attach_card: already detached"); 552 553 h->flags &= ~PCIC_FLAG_CARDP; 554 555 /* call the MI attach function */ 556 557 pcmcia_card_detach(h->pcmcia); 558 559 /* disable card detect resume and configuration reset */ 560 561 /* power down the socket */ 562 563 pcic_write(h, PCIC_PWRCTL, 0); 564 565 /* reset the card */ 566 567 pcic_write(h, PCIC_INTR, 0); 568 } 569 570 int 571 pcic_chip_mem_alloc(pch, size, pcmhp) 572 pcmcia_chipset_handle_t pch; 573 bus_size_t size; 574 struct pcmcia_mem_handle *pcmhp; 575 { 576 struct pcic_handle *h = (struct pcic_handle *) pch; 577 bus_space_handle_t memh; 578 bus_addr_t addr; 579 bus_size_t sizepg; 580 int i, mask, mhandle; 581 582 /* out of sc->memh, allocate as many pages as necessary */ 583 584 /* convert size to PCIC pages */ 585 sizepg = (size + (PCIC_MEM_ALIGN - 1)) / PCIC_MEM_ALIGN; 586 587 mask = (1 << sizepg) - 1; 588 589 addr = 0; /* XXX gcc -Wuninitialized */ 590 mhandle = 0; /* XXX gcc -Wuninitialized */ 591 592 for (i = 0; i < (PCIC_MEM_PAGES + 1 - sizepg); i++) { 593 if ((h->sc->subregionmask & (mask << i)) == (mask << i)) { 594 if (bus_space_subregion(h->sc->memt, h->sc->memh, 595 i * PCIC_MEM_PAGESIZE, 596 sizepg * PCIC_MEM_PAGESIZE, &memh)) 597 return (1); 598 mhandle = mask << i; 599 addr = h->sc->membase + (i * PCIC_MEM_PAGESIZE); 600 h->sc->subregionmask &= ~(mhandle); 601 break; 602 } 603 } 604 605 if (i == (PCIC_MEM_PAGES + 1 - size)) 606 return (1); 607 608 DPRINTF(("pcic_chip_mem_alloc bus addr 0x%lx+0x%lx\n", (u_long) addr, 609 (u_long) size)); 610 611 pcmhp->memt = h->sc->memt; 612 pcmhp->memh = memh; 613 pcmhp->addr = addr; 614 pcmhp->size = size; 615 pcmhp->mhandle = mhandle; 616 pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE; 617 618 return (0); 619 } 620 621 void 622 pcic_chip_mem_free(pch, pcmhp) 623 pcmcia_chipset_handle_t pch; 624 struct pcmcia_mem_handle *pcmhp; 625 { 626 struct pcic_handle *h = (struct pcic_handle *) pch; 627 628 h->sc->subregionmask |= pcmhp->mhandle; 629 } 630 631 static struct mem_map_index_st { 632 int sysmem_start_lsb; 633 int sysmem_start_msb; 634 int sysmem_stop_lsb; 635 int sysmem_stop_msb; 636 int cardmem_lsb; 637 int cardmem_msb; 638 int memenable; 639 } mem_map_index[] = { 640 { 641 PCIC_SYSMEM_ADDR0_START_LSB, 642 PCIC_SYSMEM_ADDR0_START_MSB, 643 PCIC_SYSMEM_ADDR0_STOP_LSB, 644 PCIC_SYSMEM_ADDR0_STOP_MSB, 645 PCIC_CARDMEM_ADDR0_LSB, 646 PCIC_CARDMEM_ADDR0_MSB, 647 PCIC_ADDRWIN_ENABLE_MEM0, 648 }, 649 { 650 PCIC_SYSMEM_ADDR1_START_LSB, 651 PCIC_SYSMEM_ADDR1_START_MSB, 652 PCIC_SYSMEM_ADDR1_STOP_LSB, 653 PCIC_SYSMEM_ADDR1_STOP_MSB, 654 PCIC_CARDMEM_ADDR1_LSB, 655 PCIC_CARDMEM_ADDR1_MSB, 656 PCIC_ADDRWIN_ENABLE_MEM1, 657 }, 658 { 659 PCIC_SYSMEM_ADDR2_START_LSB, 660 PCIC_SYSMEM_ADDR2_START_MSB, 661 PCIC_SYSMEM_ADDR2_STOP_LSB, 662 PCIC_SYSMEM_ADDR2_STOP_MSB, 663 PCIC_CARDMEM_ADDR2_LSB, 664 PCIC_CARDMEM_ADDR2_MSB, 665 PCIC_ADDRWIN_ENABLE_MEM2, 666 }, 667 { 668 PCIC_SYSMEM_ADDR3_START_LSB, 669 PCIC_SYSMEM_ADDR3_START_MSB, 670 PCIC_SYSMEM_ADDR3_STOP_LSB, 671 PCIC_SYSMEM_ADDR3_STOP_MSB, 672 PCIC_CARDMEM_ADDR3_LSB, 673 PCIC_CARDMEM_ADDR3_MSB, 674 PCIC_ADDRWIN_ENABLE_MEM3, 675 }, 676 { 677 PCIC_SYSMEM_ADDR4_START_LSB, 678 PCIC_SYSMEM_ADDR4_START_MSB, 679 PCIC_SYSMEM_ADDR4_STOP_LSB, 680 PCIC_SYSMEM_ADDR4_STOP_MSB, 681 PCIC_CARDMEM_ADDR4_LSB, 682 PCIC_CARDMEM_ADDR4_MSB, 683 PCIC_ADDRWIN_ENABLE_MEM4, 684 }, 685 }; 686 687 void 688 pcic_chip_do_mem_map(h, win) 689 struct pcic_handle *h; 690 int win; 691 { 692 int reg; 693 694 pcic_write(h, mem_map_index[win].sysmem_start_lsb, 695 (h->mem[win].addr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff); 696 pcic_write(h, mem_map_index[win].sysmem_start_msb, 697 ((h->mem[win].addr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) & 698 PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK)); 699 700 #if 0 701 /* XXX do I want 16 bit all the time? */ 702 PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT; 703 #endif 704 705 pcic_write(h, mem_map_index[win].sysmem_stop_lsb, 706 ((h->mem[win].addr + h->mem[win].size) >> 707 PCIC_SYSMEM_ADDRX_SHIFT) & 0xff); 708 pcic_write(h, mem_map_index[win].sysmem_stop_msb, 709 (((h->mem[win].addr + h->mem[win].size) >> 710 (PCIC_SYSMEM_ADDRX_SHIFT + 8)) & 711 PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) | 712 PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2); 713 714 pcic_write(h, mem_map_index[win].cardmem_lsb, 715 (h->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff); 716 pcic_write(h, mem_map_index[win].cardmem_msb, 717 ((h->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8)) & 718 PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK) | 719 ((h->mem[win].kind == PCMCIA_MEM_ATTR) ? 720 PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0)); 721 722 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE); 723 reg |= (mem_map_index[win].memenable | PCIC_ADDRWIN_ENABLE_MEMCS16); 724 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg); 725 726 #ifdef PCICDEBUG 727 { 728 int r1, r2, r3, r4, r5, r6; 729 730 r1 = pcic_read(h, mem_map_index[win].sysmem_start_msb); 731 r2 = pcic_read(h, mem_map_index[win].sysmem_start_lsb); 732 r3 = pcic_read(h, mem_map_index[win].sysmem_stop_msb); 733 r4 = pcic_read(h, mem_map_index[win].sysmem_stop_lsb); 734 r5 = pcic_read(h, mem_map_index[win].cardmem_msb); 735 r6 = pcic_read(h, mem_map_index[win].cardmem_lsb); 736 737 DPRINTF(("pcic_chip_do_mem_map window %d: %02x%02x %02x%02x " 738 "%02x%02x\n", win, r1, r2, r3, r4, r5, r6)); 739 } 740 #endif 741 } 742 743 int 744 pcic_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp) 745 pcmcia_chipset_handle_t pch; 746 int kind; 747 bus_addr_t card_addr; 748 bus_size_t size; 749 struct pcmcia_mem_handle *pcmhp; 750 bus_addr_t *offsetp; 751 int *windowp; 752 { 753 struct pcic_handle *h = (struct pcic_handle *) pch; 754 bus_addr_t busaddr; 755 long card_offset; 756 int i, win; 757 758 win = -1; 759 for (i = 0; i < (sizeof(mem_map_index) / sizeof(mem_map_index[0])); 760 i++) { 761 if ((h->memalloc & (1 << i)) == 0) { 762 win = i; 763 h->memalloc |= (1 << i); 764 break; 765 } 766 } 767 768 if (win == -1) 769 return (1); 770 771 *windowp = win; 772 773 /* XXX this is pretty gross */ 774 775 if (h->sc->memt != pcmhp->memt) 776 panic("pcic_chip_mem_map memt is bogus"); 777 778 busaddr = pcmhp->addr; 779 780 /* 781 * compute the address offset to the pcmcia address space for the 782 * pcic. this is intentionally signed. The masks and shifts below 783 * will cause TRT to happen in the pcic registers. Deal with making 784 * sure the address is aligned, and return the alignment offset. 785 */ 786 787 *offsetp = card_addr % PCIC_MEM_ALIGN; 788 card_addr -= *offsetp; 789 790 DPRINTF(("pcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr " 791 "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size, 792 (u_long) card_addr)); 793 794 /* 795 * include the offset in the size, and decrement size by one, since 796 * the hw wants start/stop 797 */ 798 size += *offsetp - 1; 799 800 card_offset = (((long) card_addr) - ((long) busaddr)); 801 802 h->mem[win].addr = busaddr; 803 h->mem[win].size = size; 804 h->mem[win].offset = card_offset; 805 h->mem[win].kind = kind; 806 807 pcic_chip_do_mem_map(h, win); 808 809 return (0); 810 } 811 812 void 813 pcic_chip_mem_unmap(pch, window) 814 pcmcia_chipset_handle_t pch; 815 int window; 816 { 817 struct pcic_handle *h = (struct pcic_handle *) pch; 818 int reg; 819 820 if (window >= (sizeof(mem_map_index) / sizeof(mem_map_index[0]))) 821 panic("pcic_chip_mem_unmap: window out of range"); 822 823 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE); 824 reg &= ~mem_map_index[window].memenable; 825 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg); 826 827 h->memalloc &= ~(1 << window); 828 } 829 830 int 831 pcic_chip_io_alloc(pch, start, size, align, pcihp) 832 pcmcia_chipset_handle_t pch; 833 bus_addr_t start; 834 bus_size_t size; 835 bus_size_t align; 836 struct pcmcia_io_handle *pcihp; 837 { 838 struct pcic_handle *h = (struct pcic_handle *) pch; 839 bus_space_tag_t iot; 840 bus_space_handle_t ioh; 841 bus_addr_t ioaddr; 842 int flags = 0; 843 844 /* 845 * Allocate some arbitrary I/O space. 846 */ 847 848 iot = h->sc->iot; 849 850 if (start) { 851 ioaddr = start; 852 if (bus_space_map(iot, start, size, 0, &ioh)) 853 return (1); 854 DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n", 855 (u_long) ioaddr, (u_long) size)); 856 } else { 857 flags |= PCMCIA_IO_ALLOCATED; 858 if (bus_space_alloc(iot, h->sc->iobase, 859 h->sc->iobase + h->sc->iosize, size, align, 0, 0, 860 &ioaddr, &ioh)) 861 return (1); 862 DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n", 863 (u_long) ioaddr, (u_long) size)); 864 } 865 866 pcihp->iot = iot; 867 pcihp->ioh = ioh; 868 pcihp->addr = ioaddr; 869 pcihp->size = size; 870 pcihp->flags = flags; 871 872 return (0); 873 } 874 875 void 876 pcic_chip_io_free(pch, pcihp) 877 pcmcia_chipset_handle_t pch; 878 struct pcmcia_io_handle *pcihp; 879 { 880 bus_space_tag_t iot = pcihp->iot; 881 bus_space_handle_t ioh = pcihp->ioh; 882 bus_size_t size = pcihp->size; 883 884 if (pcihp->flags & PCMCIA_IO_ALLOCATED) 885 bus_space_free(iot, ioh, size); 886 else 887 bus_space_unmap(iot, ioh, size); 888 } 889 890 891 static struct io_map_index_st { 892 int start_lsb; 893 int start_msb; 894 int stop_lsb; 895 int stop_msb; 896 int ioenable; 897 int ioctlmask; 898 int ioctlbits[3]; /* indexed by PCMCIA_WIDTH_* */ 899 } io_map_index[] = { 900 { 901 PCIC_IOADDR0_START_LSB, 902 PCIC_IOADDR0_START_MSB, 903 PCIC_IOADDR0_STOP_LSB, 904 PCIC_IOADDR0_STOP_MSB, 905 PCIC_ADDRWIN_ENABLE_IO0, 906 PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT | 907 PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK, 908 { 909 PCIC_IOCTL_IO0_IOCS16SRC_CARD, 910 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | 911 PCIC_IOCTL_IO0_DATASIZE_8BIT, 912 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | 913 PCIC_IOCTL_IO0_DATASIZE_16BIT, 914 }, 915 }, 916 { 917 PCIC_IOADDR1_START_LSB, 918 PCIC_IOADDR1_START_MSB, 919 PCIC_IOADDR1_STOP_LSB, 920 PCIC_IOADDR1_STOP_MSB, 921 PCIC_ADDRWIN_ENABLE_IO1, 922 PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT | 923 PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK, 924 { 925 PCIC_IOCTL_IO1_IOCS16SRC_CARD, 926 PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE | 927 PCIC_IOCTL_IO1_DATASIZE_8BIT, 928 PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE | 929 PCIC_IOCTL_IO1_DATASIZE_16BIT, 930 }, 931 }, 932 }; 933 934 void 935 pcic_chip_do_io_map(h, win) 936 struct pcic_handle *h; 937 int win; 938 { 939 int reg; 940 941 DPRINTF(("pcic_chip_do_io_map win %d addr %lx size %lx width %d\n", 942 win, (long) h->io[win].addr, (long) h->io[win].size, 943 h->io[win].width * 8)); 944 945 pcic_write(h, io_map_index[win].start_lsb, h->io[win].addr & 0xff); 946 pcic_write(h, io_map_index[win].start_msb, 947 (h->io[win].addr >> 8) & 0xff); 948 949 pcic_write(h, io_map_index[win].stop_lsb, 950 (h->io[win].addr + h->io[win].size - 1) & 0xff); 951 pcic_write(h, io_map_index[win].stop_msb, 952 ((h->io[win].addr + h->io[win].size - 1) >> 8) & 0xff); 953 954 reg = pcic_read(h, PCIC_IOCTL); 955 reg &= ~io_map_index[win].ioctlmask; 956 reg |= io_map_index[win].ioctlbits[h->io[win].width]; 957 pcic_write(h, PCIC_IOCTL, reg); 958 959 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE); 960 reg |= io_map_index[win].ioenable; 961 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg); 962 } 963 964 int 965 pcic_chip_io_map(pch, width, offset, size, pcihp, windowp) 966 pcmcia_chipset_handle_t pch; 967 int width; 968 bus_addr_t offset; 969 bus_size_t size; 970 struct pcmcia_io_handle *pcihp; 971 int *windowp; 972 { 973 struct pcic_handle *h = (struct pcic_handle *) pch; 974 bus_addr_t ioaddr = pcihp->addr + offset; 975 int i, win; 976 #ifdef PCICDEBUG 977 static char *width_names[] = { "auto", "io8", "io16" }; 978 #endif 979 980 /* XXX Sanity check offset/size. */ 981 982 win = -1; 983 for (i = 0; i < (sizeof(io_map_index) / sizeof(io_map_index[0])); i++) { 984 if ((h->ioalloc & (1 << i)) == 0) { 985 win = i; 986 h->ioalloc |= (1 << i); 987 break; 988 } 989 } 990 991 if (win == -1) 992 return (1); 993 994 *windowp = win; 995 996 /* XXX this is pretty gross */ 997 998 if (h->sc->iot != pcihp->iot) 999 panic("pcic_chip_io_map iot is bogus"); 1000 1001 DPRINTF(("pcic_chip_io_map window %d %s port %lx+%lx\n", 1002 win, width_names[width], (u_long) ioaddr, (u_long) size)); 1003 1004 /* XXX wtf is this doing here? */ 1005 1006 printf(" port 0x%lx", (u_long) ioaddr); 1007 if (size > 1) 1008 printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1); 1009 1010 h->io[win].addr = ioaddr; 1011 h->io[win].size = size; 1012 h->io[win].width = width; 1013 1014 pcic_chip_do_io_map(h, win); 1015 1016 return (0); 1017 } 1018 1019 void 1020 pcic_chip_io_unmap(pch, window) 1021 pcmcia_chipset_handle_t pch; 1022 int window; 1023 { 1024 struct pcic_handle *h = (struct pcic_handle *) pch; 1025 int reg; 1026 1027 if (window >= (sizeof(io_map_index) / sizeof(io_map_index[0]))) 1028 panic("pcic_chip_io_unmap: window out of range"); 1029 1030 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE); 1031 reg &= ~io_map_index[window].ioenable; 1032 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg); 1033 1034 h->ioalloc &= ~(1 << window); 1035 } 1036 1037 static void 1038 pcic_wait_ready(h) 1039 struct pcic_handle *h; 1040 { 1041 int i; 1042 1043 for (i = 0; i < 10000; i++) { 1044 if (pcic_read(h, PCIC_IF_STATUS) & PCIC_IF_STATUS_READY) 1045 return; 1046 delay(500); 1047 #ifdef PCICDEBUG 1048 if (pcic_debug) { 1049 if ((i>5000) && (i%100 == 99)) 1050 printf("."); 1051 } 1052 #endif 1053 } 1054 1055 #ifdef DIAGNOSTIC 1056 printf("pcic_wait_ready ready never happened\n"); 1057 #endif 1058 } 1059 1060 void 1061 pcic_chip_socket_enable(pch) 1062 pcmcia_chipset_handle_t pch; 1063 { 1064 struct pcic_handle *h = (struct pcic_handle *) pch; 1065 int cardtype, reg, win; 1066 1067 /* this bit is mostly stolen from pcic_attach_card */ 1068 1069 /* power down the socket to reset it, clear the card reset pin */ 1070 1071 pcic_write(h, PCIC_PWRCTL, 0); 1072 1073 /* power up the socket */ 1074 1075 pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_PWR_ENABLE); 1076 delay(10000); 1077 pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_PWR_ENABLE | PCIC_PWRCTL_OE); 1078 1079 /* clear the reset flag */ 1080 1081 pcic_write(h, PCIC_INTR, PCIC_INTR_RESET); 1082 1083 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */ 1084 1085 delay(20000); 1086 1087 /* wait for the chip to finish initializing */ 1088 1089 pcic_wait_ready(h); 1090 1091 /* zero out the address windows */ 1092 1093 pcic_write(h, PCIC_ADDRWIN_ENABLE, 0); 1094 1095 /* set the card type */ 1096 1097 cardtype = pcmcia_card_gettype(h->pcmcia); 1098 1099 reg = pcic_read(h, PCIC_INTR); 1100 reg &= ~PCIC_INTR_CARDTYPE_MASK; 1101 reg |= ((cardtype == PCMCIA_IFTYPE_IO) ? 1102 PCIC_INTR_CARDTYPE_IO : 1103 PCIC_INTR_CARDTYPE_MEM); 1104 reg |= h->ih_irq; 1105 pcic_write(h, PCIC_INTR, reg); 1106 1107 DPRINTF(("%s: pcic_chip_socket_enable %02x cardtype %s %02x\n", 1108 h->sc->dev.dv_xname, h->sock, 1109 ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), reg)); 1110 1111 /* reinstall all the memory and io mappings */ 1112 1113 for (win = 0; win < PCIC_MEM_WINS; win++) 1114 if (h->memalloc & (1 << win)) 1115 pcic_chip_do_mem_map(h, win); 1116 1117 for (win = 0; win < PCIC_IO_WINS; win++) 1118 if (h->ioalloc & (1 << win)) 1119 pcic_chip_do_io_map(h, win); 1120 } 1121 1122 void 1123 pcic_chip_socket_disable(pch) 1124 pcmcia_chipset_handle_t pch; 1125 { 1126 struct pcic_handle *h = (struct pcic_handle *) pch; 1127 1128 DPRINTF(("pcic_chip_socket_disable\n")); 1129 1130 /* power down the socket */ 1131 1132 pcic_write(h, PCIC_PWRCTL, 0); 1133 } 1134