1/* $NetBSD: i82365.c,v 1.119 2024/02/13 21:39:02 andvar Exp $ */ 2 3/* 4 * Copyright (c) 2004 Charles M. Hannum. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Charles M. Hannum. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 */ 20 21/* 22 * Copyright (c) 2000 Christian E. Hopps. All rights reserved. 23 * Copyright (c) 1997 Marc Horowitz. All rights reserved. 24 * 25 * Redistribution and use in source and binary forms, with or without 26 * modification, are permitted provided that the following conditions 27 * are met: 28 * 1. Redistributions of source code must retain the above copyright 29 * notice, this list of conditions and the following disclaimer. 30 * 2. Redistributions in binary form must reproduce the above copyright 31 * notice, this list of conditions and the following disclaimer in the 32 * documentation and/or other materials provided with the distribution. 33 * 3. All advertising materials mentioning features or use of this software 34 * must display the following acknowledgement: 35 * This product includes software developed by Marc Horowitz. 36 * 4. The name of the author may not be used to endorse or promote products 37 * derived from this software without specific prior written permission. 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 40 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 41 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 43 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 45 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 46 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 47 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 48 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 49 */ 50 51#include <sys/cdefs.h> 52__KERNEL_RCSID(0, "$NetBSD: i82365.c,v 1.119 2024/02/13 21:39:02 andvar Exp $"); 53 54#define PCICDEBUG 55 56#include <sys/param.h> 57#include <sys/systm.h> 58#include <sys/device.h> 59#include <sys/extent.h> 60#include <sys/kernel.h> 61#include <sys/malloc.h> 62#include <sys/kthread.h> 63 64#include <sys/bus.h> 65#include <sys/intr.h> 66 67#include <dev/pcmcia/pcmciareg.h> 68#include <dev/pcmcia/pcmciavar.h> 69 70#include <dev/ic/i82365reg.h> 71#include <dev/ic/i82365var.h> 72 73#include "locators.h" 74 75#ifdef PCICDEBUG 76int pcic_debug = 0; 77#define DPRINTF(arg) if (pcic_debug) printf arg; 78#else 79#define DPRINTF(arg) 80#endif 81 82/* 83 * Individual drivers will allocate their own memory and io regions. Memory 84 * regions must be a multiple of 4k, aligned on a 4k boundary. 85 */ 86 87#define PCIC_MEM_ALIGN PCIC_MEM_PAGESIZE 88 89void pcic_attach_socket(struct pcic_handle *); 90void pcic_attach_socket_finish(struct pcic_handle *); 91 92int pcic_print (void *arg, const char *pnp); 93int pcic_intr_socket(struct pcic_handle *); 94void pcic_poll_intr(void *); 95 96void pcic_attach_card(struct pcic_handle *); 97void pcic_detach_card(struct pcic_handle *, int); 98void pcic_deactivate_card(struct pcic_handle *); 99 100void pcic_chip_do_mem_map(struct pcic_handle *, int); 101void pcic_chip_do_io_map(struct pcic_handle *, int); 102 103void pcic_event_thread(void *); 104 105void pcic_queue_event(struct pcic_handle *, int); 106void pcic_power(int, void *); 107 108static int pcic_wait_ready(struct pcic_handle *); 109static void pcic_delay(struct pcic_handle *, int, const char *); 110 111static uint8_t st_pcic_read(struct pcic_handle *, int); 112static void st_pcic_write(struct pcic_handle *, int, uint8_t); 113 114int 115pcic_ident_ok(int ident) 116{ 117 118 /* this is very empirical and heuristic */ 119 120 if ((ident == 0) || (ident == 0xff) || (ident & PCIC_IDENT_ZERO)) 121 return 0; 122 123 if ((ident & PCIC_IDENT_REV_MASK) == 0) 124 return 0; 125 126 if ((ident & PCIC_IDENT_IFTYPE_MASK) != PCIC_IDENT_IFTYPE_MEM_AND_IO) { 127#ifdef DIAGNOSTIC 128 printf("pcic: does not support memory and I/O cards, " 129 "ignored (ident=%0x)\n", ident); 130#endif 131 return 0; 132 } 133 134 return 1; 135} 136 137int 138pcic_vendor(struct pcic_handle *h) 139{ 140 int reg; 141 int vendor; 142 143 reg = pcic_read(h, PCIC_IDENT); 144 145 if ((reg & PCIC_IDENT_REV_MASK) == 0) 146 return PCIC_VENDOR_NONE; 147 148 switch (reg) { 149 case 0x00: 150 case 0xff: 151 return PCIC_VENDOR_NONE; 152 case PCIC_IDENT_ID_INTEL0: 153 vendor = PCIC_VENDOR_I82365SLR0; 154 break; 155 case PCIC_IDENT_ID_INTEL1: 156 vendor = PCIC_VENDOR_I82365SLR1; 157 break; 158 case PCIC_IDENT_ID_INTEL2: 159 vendor = PCIC_VENDOR_I82365SL_DF; 160 break; 161 case PCIC_IDENT_ID_IBM1: 162 case PCIC_IDENT_ID_IBM2: 163 vendor = PCIC_VENDOR_IBM; 164 break; 165 case PCIC_IDENT_ID_IBM3: 166 vendor = PCIC_VENDOR_IBM_KING; 167 break; 168 default: 169 vendor = PCIC_VENDOR_UNKNOWN; 170 break; 171 } 172 173 if (vendor == PCIC_VENDOR_I82365SLR0 || 174 vendor == PCIC_VENDOR_I82365SLR1) { 175 /* 176 * Check for Cirrus PD67xx. 177 * the chip_id of the cirrus toggles between 11 and 00 after a 178 * write. weird. 179 */ 180 pcic_write(h, PCIC_CIRRUS_CHIP_INFO, 0); 181 reg = pcic_read(h, -1); 182 if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == 183 PCIC_CIRRUS_CHIP_INFO_CHIP_ID) { 184 reg = pcic_read(h, -1); 185 if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == 0) 186 return PCIC_VENDOR_CIRRUS_PD67XX; 187 } 188 189 /* 190 * check for Ricoh RF5C[23]96 191 */ 192 reg = pcic_read(h, PCIC_RICOH_REG_CHIP_ID); 193 switch (reg) { 194 case PCIC_RICOH_CHIP_ID_5C296: 195 return PCIC_VENDOR_RICOH_5C296; 196 case PCIC_RICOH_CHIP_ID_5C396: 197 return PCIC_VENDOR_RICOH_5C396; 198 } 199 } 200 201 return vendor; 202} 203 204const char * 205pcic_vendor_to_string(int vendor) 206{ 207 208 switch (vendor) { 209 case PCIC_VENDOR_I82365SLR0: 210 return "Intel 82365SL Revision 0"; 211 case PCIC_VENDOR_I82365SLR1: 212 return "Intel 82365SL Revision 1"; 213 case PCIC_VENDOR_CIRRUS_PD67XX: 214 return "Cirrus PD6710/2X"; 215 case PCIC_VENDOR_I82365SL_DF: 216 return "Intel 82365SL-DF"; 217 case PCIC_VENDOR_RICOH_5C296: 218 return "Ricoh RF5C296"; 219 case PCIC_VENDOR_RICOH_5C396: 220 return "Ricoh RF5C396"; 221 case PCIC_VENDOR_IBM: 222 return "IBM PCIC"; 223 case PCIC_VENDOR_IBM_KING: 224 return "IBM KING"; 225 } 226 227 return "Unknown controller"; 228} 229 230void 231pcic_attach(struct pcic_softc *sc) 232{ 233 int i, reg, chip, socket; 234 struct pcic_handle *h; 235 device_t self; 236 237 DPRINTF(("pcic ident regs:")); 238 239 self = sc->dev; 240 mutex_init(&sc->sc_pcic_lock, MUTEX_DEFAULT, IPL_NONE); 241 242 /* find and configure for the available sockets */ 243 for (i = 0; i < __arraycount(sc->handle); i++) { 244 h = &sc->handle[i]; 245 chip = i / 2; 246 socket = i % 2; 247 248 h->ph_parent = self; 249 h->chip = chip; 250 h->socket = socket; 251 h->sock = chip * PCIC_CHIP_OFFSET + socket * PCIC_SOCKET_OFFSET; 252 h->laststate = PCIC_LASTSTATE_EMPTY; 253 /* initialize pcic_read and pcic_write functions */ 254 h->ph_read = st_pcic_read; 255 h->ph_write = st_pcic_write; 256 h->ph_bus_t = sc->iot; 257 h->ph_bus_h = sc->ioh; 258 h->flags = 0; 259 260 /* need to read vendor -- for cirrus to report no xtra chip */ 261 if (socket == 0) { 262 h->vendor = pcic_vendor(h); 263 if (i < __arraycount(sc->handle) - 1) 264 (h + 1)->vendor = h->vendor; 265 } 266 267 switch (h->vendor) { 268 case PCIC_VENDOR_NONE: 269 /* no chip */ 270 continue; 271 case PCIC_VENDOR_CIRRUS_PD67XX: 272 reg = pcic_read(h, PCIC_CIRRUS_CHIP_INFO); 273 if (socket == 0 || 274 (reg & PCIC_CIRRUS_CHIP_INFO_SLOTS)) 275 h->flags = PCIC_FLAG_SOCKETP; 276 break; 277 default: 278 /* 279 * During the socket probe, read the ident register 280 * twice. I don't understand why, but sometimes the 281 * clone chips in hpcmips boxes read all-0s the first 282 * time. -- mycroft 283 */ 284 reg = pcic_read(h, PCIC_IDENT); 285 DPRINTF(("socket %d ident reg 0x%02x\n", i, reg)); 286 reg = pcic_read(h, PCIC_IDENT); 287 DPRINTF(("socket %d ident reg 0x%02x\n", i, reg)); 288 if (pcic_ident_ok(reg)) 289 h->flags = PCIC_FLAG_SOCKETP; 290 break; 291 } 292 } 293 294 for (i = 0; i < __arraycount(sc->handle); i++) { 295 h = &sc->handle[i]; 296 297 if (h->flags & PCIC_FLAG_SOCKETP) { 298 SIMPLEQ_INIT(&h->events); 299 300 /* disable interrupts and leave socket in reset */ 301 pcic_write(h, PCIC_INTR, 0); 302 303 /* zero out the address windows */ 304 pcic_write(h, PCIC_ADDRWIN_ENABLE, 0); 305 306 /* power down the socket */ 307 pcic_write(h, PCIC_PWRCTL, 0); 308 309 pcic_write(h, PCIC_CSC_INTR, 0); 310 (void) pcic_read(h, PCIC_CSC); 311 } 312 } 313 314 /* print detected info */ 315 for (i = 0; i < __arraycount(sc->handle) - 1; i += 2) { 316 h = &sc->handle[i]; 317 chip = i / 2; 318 319 if (h->vendor == PCIC_VENDOR_NONE) 320 continue; 321 322 aprint_normal_dev(self, "controller %d (%s) has ", 323 chip, pcic_vendor_to_string(sc->handle[i].vendor)); 324 325 if ((h->flags & PCIC_FLAG_SOCKETP) && 326 ((h + 1)->flags & PCIC_FLAG_SOCKETP)) 327 aprint_normal("sockets A and B\n"); 328 else if (h->flags & PCIC_FLAG_SOCKETP) 329 aprint_normal("socket A only\n"); 330 else if ((h + 1)->flags & PCIC_FLAG_SOCKETP) 331 aprint_normal("socket B only\n"); 332 else 333 aprint_normal("no sockets\n"); 334 } 335} 336 337/* 338 * attach the sockets before we know what interrupts we have 339 */ 340void 341pcic_attach_sockets(struct pcic_softc *sc) 342{ 343 int i; 344 345 for (i = 0; i < __arraycount(sc->handle); i++) 346 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP) 347 pcic_attach_socket(&sc->handle[i]); 348} 349 350void 351pcic_power(int why, void *arg) 352{ 353 struct pcic_handle *h = arg; 354 struct pcic_softc *sc = device_private(h->ph_parent); 355 int reg; 356 357 DPRINTF(("%s: power: why %d\n", device_xname(h->ph_parent), why)); 358 359 if (h->flags & PCIC_FLAG_SOCKETP) { 360 if ((why == PWR_RESUME) && 361 (pcic_read(h, PCIC_CSC_INTR) == 0)) { 362#ifdef PCICDEBUG 363 char bitbuf[64]; 364#endif 365 reg = PCIC_CSC_INTR_CD_ENABLE; 366 if (sc->irq != -1) 367 reg |= sc->irq << PCIC_CSC_INTR_IRQ_SHIFT; 368 pcic_write(h, PCIC_CSC_INTR, reg); 369#ifdef PCICDEBUG 370 snprintb(bitbuf, sizeof(bitbuf), PCIC_CSC_INTR_FORMAT, 371 pcic_read(h, PCIC_CSC_INTR)); 372#endif 373 DPRINTF(("%s: CSC_INTR was zero; reset to %s\n", 374 device_xname(sc->dev), bitbuf)); 375 } 376 377 /* 378 * check for card insertion or removal during suspend period. 379 * XXX: the code can't cope with card swap (remove then insert). 380 * how can we detect such situation? 381 */ 382 if (why == PWR_RESUME) 383 (void)pcic_intr_socket(h); 384 } 385} 386 387 388/* 389 * attach a socket -- we don't know about irqs yet 390 */ 391void 392pcic_attach_socket(struct pcic_handle *h) 393{ 394 struct pcmciabus_attach_args paa; 395 struct pcic_softc *sc = device_private(h->ph_parent); 396 int locs[PCMCIABUSCF_NLOCS]; 397 398 /* initialize the rest of the handle */ 399 400 h->shutdown = 0; 401 h->memalloc = 0; 402 h->ioalloc = 0; 403 h->ih_irq = 0; 404 405 /* now, config one pcmcia device per socket */ 406 407 paa.paa_busname = "pcmcia"; 408 paa.pct = (pcmcia_chipset_tag_t) sc->pct; 409 paa.pch = (pcmcia_chipset_handle_t) h; 410 411 locs[PCMCIABUSCF_CONTROLLER] = h->chip; 412 locs[PCMCIABUSCF_SOCKET] = h->socket; 413 414 h->pcmcia = config_found(sc->dev, &paa, pcic_print, 415 CFARGS(.submatch = config_stdsubmatch, 416 .locators = locs)); 417 if (h->pcmcia == NULL) { 418 h->flags &= ~PCIC_FLAG_SOCKETP; 419 return; 420 } 421 422} 423 424/* 425 * now finish attaching the sockets, we are ready to allocate 426 * interrupts 427 */ 428void 429pcic_attach_sockets_finish(struct pcic_softc *sc) 430{ 431 int i; 432 433 for (i = 0; i < __arraycount(sc->handle); i++) 434 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP) 435 pcic_attach_socket_finish(&sc->handle[i]); 436} 437 438/* 439 * finishing attaching the socket. Interrupts may now be on 440 * if so expects the pcic interrupt to be blocked 441 */ 442void 443pcic_attach_socket_finish(struct pcic_handle *h) 444{ 445 struct pcic_softc *sc = device_private(h->ph_parent); 446 int reg; 447 char cs[4]; 448 449 DPRINTF(("%s: attach finish socket %ld\n", device_xname(h->ph_parent), 450 (long) (h - &sc->handle[0]))); 451 452 /* 453 * Set up a powerhook to ensure it continues to interrupt on 454 * card detect even after suspend. 455 * (this works around a bug seen in suspend-to-disk on the 456 * Sony VAIO Z505; on resume, the CSC_INTR state is not preserved). 457 */ 458 powerhook_establish(device_xname(h->ph_parent), pcic_power, h); 459 460 /* enable interrupts on card detect, poll for them if no irq avail */ 461 reg = PCIC_CSC_INTR_CD_ENABLE; 462 if (sc->irq == -1) { 463 if (sc->poll_established == 0) { 464 callout_init(&sc->poll_ch, 0); 465 callout_reset(&sc->poll_ch, hz / 2, pcic_poll_intr, sc); 466 sc->poll_established = 1; 467 } 468 } else 469 reg |= sc->irq << PCIC_CSC_INTR_IRQ_SHIFT; 470 pcic_write(h, PCIC_CSC_INTR, reg); 471 472 /* steer above mgmt interrupt to configured place */ 473 if (sc->irq == 0) 474 pcic_write(h, PCIC_INTR, PCIC_INTR_ENABLE); 475 476 /* clear possible card detect interrupt */ 477 (void) pcic_read(h, PCIC_CSC); 478 479 DPRINTF(("%s: attach finish vendor 0x%02x\n", 480 device_xname(h->ph_parent), h->vendor)); 481 482 /* unsleep the cirrus controller */ 483 if (h->vendor == PCIC_VENDOR_CIRRUS_PD67XX) { 484 reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2); 485 if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) { 486 DPRINTF(("%s: socket %02x was suspended\n", 487 device_xname(h->ph_parent), h->sock)); 488 reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND; 489 pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg); 490 } 491 } 492 493 /* if there's a card there, then attach it. */ 494 reg = pcic_read(h, PCIC_IF_STATUS); 495 if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) == 496 PCIC_IF_STATUS_CARDDETECT_PRESENT) { 497 pcic_queue_event(h, PCIC_EVENT_INSERTION); 498 h->laststate = PCIC_LASTSTATE_PRESENT; 499 } else { 500 h->laststate = PCIC_LASTSTATE_EMPTY; 501 } 502 503 /* 504 * queue creation of a kernel thread to handle insert/removal events. 505 */ 506#ifdef DIAGNOSTIC 507 if (h->event_thread != NULL) 508 panic("pcic_attach_socket: event thread"); 509#endif 510 config_pending_incr(sc->dev); 511 snprintf(cs, sizeof(cs), "%d,%d", h->chip, h->socket); 512 513 if (kthread_create(PRI_NONE, 0, NULL, pcic_event_thread, h, 514 &h->event_thread, "%s,%s", device_xname(h->ph_parent), cs)) { 515 aprint_error_dev(h->ph_parent, 516 "unable to create event thread for sock 0x%02x\n", h->sock); 517 panic("pcic_attach_socket"); 518 } 519} 520 521void 522pcic_event_thread(void *arg) 523{ 524 struct pcic_handle *h = arg; 525 struct pcic_event *pe; 526 int s, first = 1; 527 struct pcic_softc *sc = device_private(h->ph_parent); 528 529 while (h->shutdown == 0) { 530 /* 531 * Serialize event processing on the PCIC. We may 532 * sleep while we hold this lock. 533 */ 534 mutex_enter(&sc->sc_pcic_lock); 535 536 s = splhigh(); 537 if ((pe = SIMPLEQ_FIRST(&h->events)) == NULL) { 538 splx(s); 539 if (first) { 540 first = 0; 541 config_pending_decr(sc->dev); 542 } 543 /* 544 * No events to process; release the PCIC lock. 545 */ 546 (void) mutex_exit(&sc->sc_pcic_lock); 547 (void) tsleep(&h->events, PWAIT, "pcicev", 0); 548 continue; 549 } else { 550 splx(s); 551 /* sleep .25s to be enqueued chatterling interrupts */ 552 (void) tsleep((void *)pcic_event_thread, PWAIT, 553 "pcicss", hz / 4); 554 } 555 s = splhigh(); 556 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); 557 splx(s); 558 559 switch (pe->pe_type) { 560 case PCIC_EVENT_INSERTION: 561 s = splhigh(); 562 for (;;) { 563 struct pcic_event *pe1, *pe2; 564 565 if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL) 566 break; 567 if (pe1->pe_type != PCIC_EVENT_REMOVAL) 568 break; 569 if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL) 570 break; 571 if (pe2->pe_type == PCIC_EVENT_INSERTION) { 572 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); 573 free(pe1, M_TEMP); 574 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); 575 free(pe2, M_TEMP); 576 } 577 } 578 splx(s); 579 580 DPRINTF(("%s: insertion event\n", 581 device_xname(h->ph_parent))); 582 pcic_attach_card(h); 583 break; 584 585 case PCIC_EVENT_REMOVAL: 586 s = splhigh(); 587 for (;;) { 588 struct pcic_event *pe1, *pe2; 589 590 if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL) 591 break; 592 if (pe1->pe_type != PCIC_EVENT_INSERTION) 593 break; 594 if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL) 595 break; 596 if (pe2->pe_type == PCIC_EVENT_REMOVAL) { 597 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); 598 free(pe1, M_TEMP); 599 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); 600 free(pe2, M_TEMP); 601 } 602 } 603 splx(s); 604 605 DPRINTF(("%s: removal event\n", 606 device_xname(h->ph_parent))); 607 pcic_detach_card(h, DETACH_FORCE); 608 break; 609 610 default: 611 panic("pcic_event_thread: unknown event %d", 612 pe->pe_type); 613 } 614 free(pe, M_TEMP); 615 616 mutex_exit(&sc->sc_pcic_lock); 617 } 618 619 h->event_thread = NULL; 620 621 /* In case parent is waiting for us to exit. */ 622 wakeup(sc); 623 624 kthread_exit(0); 625} 626 627int 628pcic_print(void *arg, const char *pnp) 629{ 630 struct pcmciabus_attach_args *paa = arg; 631 struct pcic_handle *h = (struct pcic_handle *) paa->pch; 632 633 /* Only "pcmcia"s can attach to "pcic"s... easy. */ 634 if (pnp) 635 aprint_normal("pcmcia at %s", pnp); 636 637 aprint_normal(" controller %d socket %d", h->chip, h->socket); 638 639 return UNCONF; 640} 641 642void 643pcic_poll_intr(void *arg) 644{ 645 struct pcic_softc *sc; 646 int i, s; 647 648 s = spltty(); 649 sc = arg; 650 for (i = 0; i < __arraycount(sc->handle); i++) 651 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP) 652 (void)pcic_intr_socket(&sc->handle[i]); 653 callout_reset(&sc->poll_ch, hz / 2, pcic_poll_intr, sc); 654 splx(s); 655} 656 657int 658pcic_intr(void *arg) 659{ 660 struct pcic_softc *sc = arg; 661 int i, ret = 0; 662 663 DPRINTF(("%s: intr\n", device_xname(sc->dev))); 664 665 for (i = 0; i < __arraycount(sc->handle); i++) 666 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP) 667 ret += pcic_intr_socket(&sc->handle[i]); 668 669 return ret ? 1 : 0; 670} 671 672int 673pcic_intr_socket(struct pcic_handle *h) 674{ 675 int cscreg; 676 677 cscreg = pcic_read(h, PCIC_CSC); 678 679 cscreg &= (PCIC_CSC_GPI | 680 PCIC_CSC_CD | 681 PCIC_CSC_READY | 682 PCIC_CSC_BATTWARN | 683 PCIC_CSC_BATTDEAD); 684 685 if (cscreg & PCIC_CSC_GPI) { 686 DPRINTF(("%s: %02x GPI\n", 687 device_xname(h->ph_parent), h->sock)); 688 } 689 if (cscreg & PCIC_CSC_CD) { 690 int statreg; 691 692 statreg = pcic_read(h, PCIC_IF_STATUS); 693 694 DPRINTF(("%s: %02x CD %x\n", device_xname(h->ph_parent), 695 h->sock, statreg)); 696 697 if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) == 698 PCIC_IF_STATUS_CARDDETECT_PRESENT) { 699 if (h->laststate != PCIC_LASTSTATE_PRESENT) { 700 DPRINTF(("%s: enqueuing INSERTION event\n", 701 device_xname(h->ph_parent))); 702 pcic_queue_event(h, PCIC_EVENT_INSERTION); 703 } 704 h->laststate = PCIC_LASTSTATE_PRESENT; 705 } else { 706 if (h->laststate == PCIC_LASTSTATE_PRESENT) { 707 /* Deactivate the card now. */ 708 DPRINTF(("%s: deactivating card\n", 709 device_xname(h->ph_parent))); 710 pcic_deactivate_card(h); 711 712 DPRINTF(("%s: enqueuing REMOVAL event\n", 713 device_xname(h->ph_parent))); 714 pcic_queue_event(h, PCIC_EVENT_REMOVAL); 715 } 716 h->laststate = PCIC_LASTSTATE_EMPTY; 717 } 718 } 719 if (cscreg & PCIC_CSC_READY) { 720 DPRINTF(("%s: %02x READY\n", device_xname(h->ph_parent), 721 h->sock)); 722 /* shouldn't happen */ 723 } 724 if (cscreg & PCIC_CSC_BATTWARN) { 725 DPRINTF(("%s: %02x BATTWARN\n", device_xname(h->ph_parent), 726 h->sock)); 727 } 728 if (cscreg & PCIC_CSC_BATTDEAD) { 729 DPRINTF(("%s: %02x BATTDEAD\n", device_xname(h->ph_parent), 730 h->sock)); 731 } 732 return cscreg ? 1 : 0; 733} 734 735void 736pcic_queue_event(struct pcic_handle *h, int event) 737{ 738 struct pcic_event *pe; 739 int s; 740 741 pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT); 742 if (pe == NULL) 743 panic("pcic_queue_event: can't allocate event"); 744 745 pe->pe_type = event; 746 s = splhigh(); 747 SIMPLEQ_INSERT_TAIL(&h->events, pe, pe_q); 748 splx(s); 749 wakeup(&h->events); 750} 751 752void 753pcic_attach_card(struct pcic_handle *h) 754{ 755 756 if ((h->flags & PCIC_FLAG_CARDP) == 0) { 757 /* call the MI attach function */ 758 pcmcia_card_attach(h->pcmcia); 759 760 h->flags |= PCIC_FLAG_CARDP; 761 } else { 762 DPRINTF(("pcic_attach_card: already attached")); 763 } 764} 765 766void 767pcic_detach_card(struct pcic_handle *h, int flags) 768 /* flags: DETACH_* */ 769{ 770 771 if (h->flags & PCIC_FLAG_CARDP) { 772 h->flags &= ~PCIC_FLAG_CARDP; 773 774 /* call the MI detach function */ 775 pcmcia_card_detach(h->pcmcia, flags); 776 } else { 777 DPRINTF(("pcic_detach_card: already detached")); 778 } 779} 780 781void 782pcic_deactivate_card(struct pcic_handle *h) 783{ 784 int intr; 785 786 /* call the MI deactivate function */ 787 pcmcia_card_deactivate(h->pcmcia); 788 789 /* reset the socket */ 790 intr = pcic_read(h, PCIC_INTR); 791 intr &= PCIC_INTR_ENABLE; 792 pcic_write(h, PCIC_INTR, intr); 793 794 /* power down the socket */ 795 pcic_write(h, PCIC_PWRCTL, 0); 796} 797 798int 799pcic_chip_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size, 800 struct pcmcia_mem_handle *pcmhp) 801{ 802 struct pcic_handle *h = (struct pcic_handle *) pch; 803 bus_space_handle_t memh; 804 bus_addr_t addr; 805 bus_size_t sizepg; 806 int i, mask, mhandle; 807 struct pcic_softc *sc = device_private(h->ph_parent); 808 809 /* out of sc->memh, allocate as many pages as necessary */ 810 811 /* convert size to PCIC pages */ 812 sizepg = (size + (PCIC_MEM_ALIGN - 1)) / PCIC_MEM_ALIGN; 813 if (sizepg > PCIC_MAX_MEM_PAGES) 814 return 1; 815 816 mask = (1 << sizepg) - 1; 817 818 addr = 0; /* XXX gcc -Wuninitialized */ 819 mhandle = 0; /* XXX gcc -Wuninitialized */ 820 821 for (i = 0; i <= PCIC_MAX_MEM_PAGES - sizepg; i++) { 822 if ((sc->subregionmask & (mask << i)) == (mask << i)) { 823 if (bus_space_subregion(sc->memt, sc->memh, 824 i * PCIC_MEM_PAGESIZE, 825 sizepg * PCIC_MEM_PAGESIZE, &memh)) 826 return 1; 827 mhandle = mask << i; 828 addr = sc->membase + (i * PCIC_MEM_PAGESIZE); 829 sc->subregionmask &= ~(mhandle); 830 pcmhp->memt = sc->memt; 831 pcmhp->memh = memh; 832 pcmhp->addr = addr; 833 pcmhp->size = size; 834 pcmhp->mhandle = mhandle; 835 pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE; 836 return 0; 837 } 838 } 839 840 return 1; 841} 842 843void 844pcic_chip_mem_free(pcmcia_chipset_handle_t pch, struct pcmcia_mem_handle *pcmhp) 845{ 846 struct pcic_handle *h = (struct pcic_handle *) pch; 847 struct pcic_softc *sc = device_private(h->ph_parent); 848 849 sc->subregionmask |= pcmhp->mhandle; 850} 851 852static const struct mem_map_index_st { 853 int sysmem_start_lsb; 854 int sysmem_start_msb; 855 int sysmem_stop_lsb; 856 int sysmem_stop_msb; 857 int cardmem_lsb; 858 int cardmem_msb; 859 int memenable; 860} mem_map_index[] = { 861 { 862 PCIC_SYSMEM_ADDR0_START_LSB, 863 PCIC_SYSMEM_ADDR0_START_MSB, 864 PCIC_SYSMEM_ADDR0_STOP_LSB, 865 PCIC_SYSMEM_ADDR0_STOP_MSB, 866 PCIC_CARDMEM_ADDR0_LSB, 867 PCIC_CARDMEM_ADDR0_MSB, 868 PCIC_ADDRWIN_ENABLE_MEM0, 869 }, 870 { 871 PCIC_SYSMEM_ADDR1_START_LSB, 872 PCIC_SYSMEM_ADDR1_START_MSB, 873 PCIC_SYSMEM_ADDR1_STOP_LSB, 874 PCIC_SYSMEM_ADDR1_STOP_MSB, 875 PCIC_CARDMEM_ADDR1_LSB, 876 PCIC_CARDMEM_ADDR1_MSB, 877 PCIC_ADDRWIN_ENABLE_MEM1, 878 }, 879 { 880 PCIC_SYSMEM_ADDR2_START_LSB, 881 PCIC_SYSMEM_ADDR2_START_MSB, 882 PCIC_SYSMEM_ADDR2_STOP_LSB, 883 PCIC_SYSMEM_ADDR2_STOP_MSB, 884 PCIC_CARDMEM_ADDR2_LSB, 885 PCIC_CARDMEM_ADDR2_MSB, 886 PCIC_ADDRWIN_ENABLE_MEM2, 887 }, 888 { 889 PCIC_SYSMEM_ADDR3_START_LSB, 890 PCIC_SYSMEM_ADDR3_START_MSB, 891 PCIC_SYSMEM_ADDR3_STOP_LSB, 892 PCIC_SYSMEM_ADDR3_STOP_MSB, 893 PCIC_CARDMEM_ADDR3_LSB, 894 PCIC_CARDMEM_ADDR3_MSB, 895 PCIC_ADDRWIN_ENABLE_MEM3, 896 }, 897 { 898 PCIC_SYSMEM_ADDR4_START_LSB, 899 PCIC_SYSMEM_ADDR4_START_MSB, 900 PCIC_SYSMEM_ADDR4_STOP_LSB, 901 PCIC_SYSMEM_ADDR4_STOP_MSB, 902 PCIC_CARDMEM_ADDR4_LSB, 903 PCIC_CARDMEM_ADDR4_MSB, 904 PCIC_ADDRWIN_ENABLE_MEM4, 905 }, 906}; 907 908void 909pcic_chip_do_mem_map(struct pcic_handle *h, int win) 910{ 911 int reg; 912 int kind = h->mem[win].kind & ~PCMCIA_WIDTH_MEM_MASK; 913 int mem8 = 914 (h->mem[win].kind & PCMCIA_WIDTH_MEM_MASK) == PCMCIA_WIDTH_MEM8 915 || (kind == PCMCIA_MEM_ATTR); 916 917 DPRINTF(("mem8 %d\n", mem8)); 918 /* mem8 = 1; */ 919 920 pcic_write(h, mem_map_index[win].sysmem_start_lsb, 921 (h->mem[win].addr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff); 922 pcic_write(h, mem_map_index[win].sysmem_start_msb, 923 ((h->mem[win].addr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) & 924 PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK) | 925 (mem8 ? 0 : PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT)); 926 927 pcic_write(h, mem_map_index[win].sysmem_stop_lsb, 928 ((h->mem[win].addr + h->mem[win].size) >> 929 PCIC_SYSMEM_ADDRX_SHIFT) & 0xff); 930 pcic_write(h, mem_map_index[win].sysmem_stop_msb, 931 (((h->mem[win].addr + h->mem[win].size) >> 932 (PCIC_SYSMEM_ADDRX_SHIFT + 8)) & 933 PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) | 934 PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2); 935 936 pcic_write(h, mem_map_index[win].cardmem_lsb, 937 (h->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff); 938 pcic_write(h, mem_map_index[win].cardmem_msb, 939 ((h->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8)) & 940 PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK) | 941 ((kind == PCMCIA_MEM_ATTR) ? 942 PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0)); 943 944 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE); 945 reg |= (mem_map_index[win].memenable | PCIC_ADDRWIN_ENABLE_MEMCS16); 946 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg); 947 948 delay(100); 949 950#ifdef PCICDEBUG 951 { 952 int r1, r2, r3, r4, r5, r6; 953 954 r1 = pcic_read(h, mem_map_index[win].sysmem_start_msb); 955 r2 = pcic_read(h, mem_map_index[win].sysmem_start_lsb); 956 r3 = pcic_read(h, mem_map_index[win].sysmem_stop_msb); 957 r4 = pcic_read(h, mem_map_index[win].sysmem_stop_lsb); 958 r5 = pcic_read(h, mem_map_index[win].cardmem_msb); 959 r6 = pcic_read(h, mem_map_index[win].cardmem_lsb); 960 961 DPRINTF(("pcic_chip_do_mem_map window %d: %02x%02x %02x%02x " 962 "%02x%02x\n", win, r1, r2, r3, r4, r5, r6)); 963 } 964#endif 965} 966 967int 968pcic_chip_mem_map(pcmcia_chipset_handle_t pch, int kind, bus_addr_t card_addr, 969 bus_size_t size, struct pcmcia_mem_handle *pcmhp, bus_size_t *offsetp, 970 int *windowp) 971{ 972 struct pcic_handle *h = (struct pcic_handle *) pch; 973 bus_addr_t busaddr; 974 long card_offset; 975 int i, win; 976 977 win = -1; 978 for (i = 0; i < (sizeof(mem_map_index) / sizeof(mem_map_index[0])); 979 i++) { 980 if ((h->memalloc & (1 << i)) == 0) { 981 win = i; 982 h->memalloc |= (1 << i); 983 break; 984 } 985 } 986 987 if (win == -1) 988 return 1; 989 990 *windowp = win; 991 992 /* XXX this is pretty gross */ 993 994{ 995 struct pcic_softc *sc = device_private(h->ph_parent); 996 if (!bus_space_is_equal(sc->memt, pcmhp->memt)) 997 panic("pcic_chip_mem_map memt is bogus"); 998} 999 1000 busaddr = pcmhp->addr; 1001 1002 /* 1003 * compute the address offset to the pcmcia address space for the 1004 * pcic. this is intentionally signed. The masks and shifts below 1005 * will cause TRT to happen in the pcic registers. Deal with making 1006 * sure the address is aligned, and return the alignment offset. 1007 */ 1008 1009 *offsetp = card_addr % PCIC_MEM_ALIGN; 1010 card_addr -= *offsetp; 1011 1012 DPRINTF(("pcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr " 1013 "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size, 1014 (u_long) card_addr)); 1015 1016 /* 1017 * include the offset in the size, and decrement size by one, since 1018 * the hw wants start/stop 1019 */ 1020 size += *offsetp - 1; 1021 1022 card_offset = (((long) card_addr) - ((long) busaddr)); 1023 1024 h->mem[win].addr = busaddr; 1025 h->mem[win].size = size; 1026 h->mem[win].offset = card_offset; 1027 h->mem[win].kind = kind; 1028 1029 pcic_chip_do_mem_map(h, win); 1030 1031 return 0; 1032} 1033 1034void 1035pcic_chip_mem_unmap(pcmcia_chipset_handle_t pch, int window) 1036{ 1037 struct pcic_handle *h = (struct pcic_handle *) pch; 1038 int reg; 1039 1040 if (window >= (sizeof(mem_map_index) / sizeof(mem_map_index[0]))) 1041 panic("pcic_chip_mem_unmap: window out of range"); 1042 1043 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE); 1044 reg &= ~mem_map_index[window].memenable; 1045 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg); 1046 1047 h->memalloc &= ~(1 << window); 1048} 1049 1050int 1051pcic_chip_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start, 1052 bus_size_t size, bus_size_t align, struct pcmcia_io_handle *pcihp) 1053{ 1054 struct pcic_handle *h = (struct pcic_handle *) pch; 1055 bus_space_tag_t iot; 1056 bus_space_handle_t ioh; 1057 bus_addr_t ioaddr; 1058 int flags = 0; 1059 struct pcic_softc *sc = device_private(h->ph_parent); 1060 1061 /* 1062 * Allocate some arbitrary I/O space. 1063 */ 1064 1065 iot = sc->iot; 1066 1067 if (start) { 1068 ioaddr = start; 1069 if (bus_space_map(iot, start, size, 0, &ioh)) 1070 return 1; 1071 DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n", 1072 (u_long) ioaddr, (u_long) size)); 1073 } else { 1074 flags |= PCMCIA_IO_ALLOCATED; 1075 if (bus_space_alloc(iot, sc->iobase, 1076 sc->iobase + sc->iosize, size, align, 0, 0, 1077 &ioaddr, &ioh)) 1078 return 1; 1079 DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n", 1080 (u_long) ioaddr, (u_long) size)); 1081 } 1082 1083 pcihp->iot = iot; 1084 pcihp->ioh = ioh; 1085 pcihp->addr = ioaddr; 1086 pcihp->size = size; 1087 pcihp->flags = flags; 1088 1089 return 0; 1090} 1091 1092void 1093pcic_chip_io_free(pcmcia_chipset_handle_t pch, struct pcmcia_io_handle *pcihp) 1094{ 1095 bus_space_tag_t iot = pcihp->iot; 1096 bus_space_handle_t ioh = pcihp->ioh; 1097 bus_size_t size = pcihp->size; 1098 1099 if (pcihp->flags & PCMCIA_IO_ALLOCATED) 1100 bus_space_free(iot, ioh, size); 1101 else 1102 bus_space_unmap(iot, ioh, size); 1103} 1104 1105 1106static const struct io_map_index_st { 1107 int start_lsb; 1108 int start_msb; 1109 int stop_lsb; 1110 int stop_msb; 1111 int ioenable; 1112 int ioctlmask; 1113 int ioctlbits[3]; /* indexed by PCMCIA_WIDTH_* */ 1114} io_map_index[] = { 1115 { 1116 PCIC_IOADDR0_START_LSB, 1117 PCIC_IOADDR0_START_MSB, 1118 PCIC_IOADDR0_STOP_LSB, 1119 PCIC_IOADDR0_STOP_MSB, 1120 PCIC_ADDRWIN_ENABLE_IO0, 1121 PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT | 1122 PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK, 1123 { 1124 PCIC_IOCTL_IO0_IOCS16SRC_CARD, 1125 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | 1126 PCIC_IOCTL_IO0_DATASIZE_8BIT, 1127 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | 1128 PCIC_IOCTL_IO0_DATASIZE_16BIT, 1129 }, 1130 }, 1131 { 1132 PCIC_IOADDR1_START_LSB, 1133 PCIC_IOADDR1_START_MSB, 1134 PCIC_IOADDR1_STOP_LSB, 1135 PCIC_IOADDR1_STOP_MSB, 1136 PCIC_ADDRWIN_ENABLE_IO1, 1137 PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT | 1138 PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK, 1139 { 1140 PCIC_IOCTL_IO1_IOCS16SRC_CARD, 1141 PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE | 1142 PCIC_IOCTL_IO1_DATASIZE_8BIT, 1143 PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE | 1144 PCIC_IOCTL_IO1_DATASIZE_16BIT, 1145 }, 1146 }, 1147}; 1148 1149void 1150pcic_chip_do_io_map(struct pcic_handle *h, int win) 1151{ 1152 int reg; 1153 1154 DPRINTF(("pcic_chip_do_io_map win %d addr %lx size %lx width %d\n", 1155 win, (long) h->io[win].addr, (long) h->io[win].size, 1156 h->io[win].width * 8)); 1157 1158 pcic_write(h, io_map_index[win].start_lsb, h->io[win].addr & 0xff); 1159 pcic_write(h, io_map_index[win].start_msb, 1160 (h->io[win].addr >> 8) & 0xff); 1161 1162 pcic_write(h, io_map_index[win].stop_lsb, 1163 (h->io[win].addr + h->io[win].size - 1) & 0xff); 1164 pcic_write(h, io_map_index[win].stop_msb, 1165 ((h->io[win].addr + h->io[win].size - 1) >> 8) & 0xff); 1166 1167 reg = pcic_read(h, PCIC_IOCTL); 1168 reg &= ~io_map_index[win].ioctlmask; 1169 reg |= io_map_index[win].ioctlbits[h->io[win].width]; 1170 pcic_write(h, PCIC_IOCTL, reg); 1171 1172 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE); 1173 reg |= io_map_index[win].ioenable; 1174 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg); 1175} 1176 1177int 1178pcic_chip_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset, 1179 bus_size_t size, struct pcmcia_io_handle *pcihp, int *windowp) 1180{ 1181 struct pcic_handle *h = (struct pcic_handle *) pch; 1182 bus_addr_t ioaddr = pcihp->addr + offset; 1183 int i, win; 1184#ifdef PCICDEBUG 1185 static const char *width_names[] = { "auto", "io8", "io16" }; 1186#endif 1187 struct pcic_softc *sc = device_private(h->ph_parent); 1188 1189 /* XXX Sanity check offset/size. */ 1190 1191 win = -1; 1192 for (i = 0; i < (sizeof(io_map_index) / sizeof(io_map_index[0])); i++) { 1193 if ((h->ioalloc & (1 << i)) == 0) { 1194 win = i; 1195 h->ioalloc |= (1 << i); 1196 break; 1197 } 1198 } 1199 1200 if (win == -1) 1201 return 1; 1202 1203 *windowp = win; 1204 1205 /* XXX this is pretty gross */ 1206 1207 if (!bus_space_is_equal(sc->iot, pcihp->iot)) 1208 panic("pcic_chip_io_map iot is bogus"); 1209 1210 DPRINTF(("pcic_chip_io_map window %d %s port %lx+%lx\n", 1211 win, width_names[width], (u_long) ioaddr, (u_long) size)); 1212 1213 /* XXX wtf is this doing here? */ 1214 1215 printf("%s: port 0x%lx", device_xname(sc->dev), (u_long) ioaddr); 1216 if (size > 1) 1217 printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1); 1218 printf("\n"); 1219 1220 h->io[win].addr = ioaddr; 1221 h->io[win].size = size; 1222 h->io[win].width = width; 1223 1224 pcic_chip_do_io_map(h, win); 1225 1226 return 0; 1227} 1228 1229void 1230pcic_chip_io_unmap(pcmcia_chipset_handle_t pch, int window) 1231{ 1232 struct pcic_handle *h = (struct pcic_handle *) pch; 1233 int reg; 1234 1235 if (window >= (sizeof(io_map_index) / sizeof(io_map_index[0]))) 1236 panic("pcic_chip_io_unmap: window out of range"); 1237 1238 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE); 1239 reg &= ~io_map_index[window].ioenable; 1240 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg); 1241 1242 h->ioalloc &= ~(1 << window); 1243} 1244 1245static int 1246pcic_wait_ready(struct pcic_handle *h) 1247{ 1248 uint8_t stat; 1249 int i; 1250 1251 /* wait an initial 10ms for quick cards */ 1252 stat = pcic_read(h, PCIC_IF_STATUS); 1253 if (stat & PCIC_IF_STATUS_READY) 1254 return 0; 1255 pcic_delay(h, 10, "pccwr0"); 1256 for (i = 0; i < 50; i++) { 1257 stat = pcic_read(h, PCIC_IF_STATUS); 1258 if (stat & PCIC_IF_STATUS_READY) 1259 return 0; 1260 if ((stat & PCIC_IF_STATUS_CARDDETECT_MASK) != 1261 PCIC_IF_STATUS_CARDDETECT_PRESENT) 1262 return ENXIO; 1263 /* wait .1s (100ms) each iteration now */ 1264 pcic_delay(h, 100, "pccwr1"); 1265 } 1266 1267 printf("pcic_wait_ready: ready never happened, status=%02x\n", stat); 1268 return EWOULDBLOCK; 1269} 1270 1271/* 1272 * Perform long (msec order) delay. 1273 */ 1274static void 1275pcic_delay(struct pcic_handle *h, int timo, const char *wmesg) 1276 /* timo: in ms. must not be zero */ 1277{ 1278 1279#ifdef DIAGNOSTIC 1280 if (timo <= 0) 1281 panic("pcic_delay: called with timeout %d", timo); 1282 if (!curlwp) 1283 panic("pcic_delay: called in interrupt context"); 1284 if (!h->event_thread) 1285 panic("pcic_delay: no event thread"); 1286#endif 1287 DPRINTF(("pcic_delay: \"%s\" %p, sleep %d ms\n", 1288 wmesg, h->event_thread, timo)); 1289 if (doing_shutdown) 1290 delay(timo * 1000); 1291 else 1292 tsleep(pcic_delay, PWAIT, wmesg, 1293 roundup(timo * hz, 1000) / 1000); 1294} 1295 1296void 1297pcic_chip_socket_enable(pcmcia_chipset_handle_t pch) 1298{ 1299 struct pcic_handle *h = (struct pcic_handle *) pch; 1300 int win; 1301 uint8_t power, intr; 1302#ifdef DIAGNOSTIC 1303 int reg; 1304#endif 1305 1306#ifdef DIAGNOSTIC 1307 if (h->flags & PCIC_FLAG_ENABLED) 1308 printf("pcic_chip_socket_enable: enabling twice\n"); 1309#endif 1310 1311 /* disable interrupts; assert RESET */ 1312 intr = pcic_read(h, PCIC_INTR); 1313 intr &= PCIC_INTR_ENABLE; 1314 pcic_write(h, PCIC_INTR, intr); 1315 1316 /* zero out the address windows */ 1317 pcic_write(h, PCIC_ADDRWIN_ENABLE, 0); 1318 1319 /* power off; assert output enable bit */ 1320 power = PCIC_PWRCTL_OE; 1321 pcic_write(h, PCIC_PWRCTL, power); 1322 1323 /* 1324 * power hack for RICOH RF5C[23]96 1325 */ 1326 switch (h->vendor) { 1327 case PCIC_VENDOR_RICOH_5C296: 1328 case PCIC_VENDOR_RICOH_5C396: 1329 { 1330 int regtmp; 1331 regtmp = pcic_read(h, PCIC_RICOH_REG_MCR2); 1332#ifdef RICOH_POWER_HACK 1333 regtmp |= PCIC_RICOH_MCR2_VCC_DIRECT; 1334#else 1335 regtmp &= 1336 ~(PCIC_RICOH_MCR2_VCC_DIRECT|PCIC_RICOH_MCR2_VCC_SEL_3V); 1337#endif 1338 pcic_write(h, PCIC_RICOH_REG_MCR2, regtmp); 1339 } 1340 break; 1341 default: 1342 break; 1343 } 1344 1345#ifdef VADEM_POWER_HACK 1346 bus_space_write_1(sc->iot, sc->ioh, PCIC_REG_INDEX, 0x0e); 1347 bus_space_write_1(sc->iot, sc->ioh, PCIC_REG_INDEX, 0x37); 1348 printf("prcr = %02x\n", pcic_read(h, 0x02)); 1349 printf("cvsr = %02x\n", pcic_read(h, 0x2f)); 1350 printf("DANGER WILL ROBINSON! Changing voltage select!\n"); 1351 pcic_write(h, 0x2f, pcic_read(h, 0x2f) & ~0x03); 1352 printf("cvsr = %02x\n", pcic_read(h, 0x2f)); 1353#endif 1354 1355 /* power up the socket */ 1356 power |= PCIC_PWRCTL_PWR_ENABLE | PCIC_PWRCTL_VPP1_VCC; 1357 pcic_write(h, PCIC_PWRCTL, power); 1358 1359 /* 1360 * Table 4-18 and figure 4-6 of the PC Card specifiction say: 1361 * Vcc Rising Time (Tpr) = 100ms 1362 * RESET Width (Th (Hi-z RESET)) = 1ms 1363 * RESET Width (Tw (RESET)) = 10us 1364 * 1365 * some machines require some more time to be settled 1366 * (100ms is added here). 1367 */ 1368 pcic_delay(h, 200 + 1, "pccen1"); 1369 1370 /* negate RESET */ 1371 intr |= PCIC_INTR_RESET; 1372 pcic_write(h, PCIC_INTR, intr); 1373 1374 /* 1375 * RESET Setup Time (Tsu (RESET)) = 20ms 1376 */ 1377 pcic_delay(h, 20, "pccen2"); 1378 1379#ifdef DIAGNOSTIC 1380 reg = pcic_read(h, PCIC_IF_STATUS); 1381 if ((reg & PCIC_IF_STATUS_POWERACTIVE) == 0) 1382 printf("pcic_chip_socket_enable: no power, status=%x\n", reg); 1383#endif 1384 1385 /* wait for the chip to finish initializing */ 1386 if (pcic_wait_ready(h)) { 1387 /* XXX return a failure status?? */ 1388 pcic_write(h, PCIC_PWRCTL, 0); 1389 return; 1390 } 1391 1392 /* reinstall all the memory and io mappings */ 1393 for (win = 0; win < PCIC_MEM_WINS; win++) 1394 if (h->memalloc & (1 << win)) 1395 pcic_chip_do_mem_map(h, win); 1396 for (win = 0; win < PCIC_IO_WINS; win++) 1397 if (h->ioalloc & (1 << win)) 1398 pcic_chip_do_io_map(h, win); 1399 1400 h->flags |= PCIC_FLAG_ENABLED; 1401} 1402 1403void 1404pcic_chip_socket_disable(pcmcia_chipset_handle_t pch) 1405{ 1406 struct pcic_handle *h = (struct pcic_handle *) pch; 1407 uint8_t intr; 1408 1409 DPRINTF(("pcic_chip_socket_disable\n")); 1410 1411 /* disable interrupts; assert RESET */ 1412 intr = pcic_read(h, PCIC_INTR); 1413 intr &= PCIC_INTR_ENABLE; 1414 pcic_write(h, PCIC_INTR, intr); 1415 1416 /* zero out the address windows */ 1417 pcic_write(h, PCIC_ADDRWIN_ENABLE, 0); 1418 1419 /* disable socket: negate output enable bit and power off */ 1420 pcic_write(h, PCIC_PWRCTL, 0); 1421 1422 /* 1423 * Vcc Falling Time (Tpf) = 300ms 1424 */ 1425 pcic_delay(h, 300, "pccwr1"); 1426 1427 h->flags &= ~PCIC_FLAG_ENABLED; 1428} 1429 1430void 1431pcic_chip_socket_settype(pcmcia_chipset_handle_t pch, int type) 1432{ 1433 struct pcic_handle *h = (struct pcic_handle *) pch; 1434 int intr; 1435 1436 intr = pcic_read(h, PCIC_INTR); 1437 intr &= ~(PCIC_INTR_IRQ_MASK | PCIC_INTR_CARDTYPE_MASK); 1438 if (type == PCMCIA_IFTYPE_IO) { 1439 intr |= PCIC_INTR_CARDTYPE_IO; 1440 intr |= h->ih_irq << PCIC_INTR_IRQ_SHIFT; 1441 } else 1442 intr |= PCIC_INTR_CARDTYPE_MEM; 1443 pcic_write(h, PCIC_INTR, intr); 1444 1445 DPRINTF(("%s: pcic_chip_socket_settype %02x type %s %02x\n", 1446 device_xname(h->ph_parent), h->sock, 1447 ((type == PCMCIA_IFTYPE_IO) ? "io" : "mem"), intr)); 1448} 1449 1450static uint8_t 1451st_pcic_read(struct pcic_handle *h, int idx) 1452{ 1453 1454 if (idx != -1) 1455 bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_INDEX, 1456 h->sock + idx); 1457 return bus_space_read_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_DATA); 1458} 1459 1460static void 1461st_pcic_write(struct pcic_handle *h, int idx, uint8_t data) 1462{ 1463 1464 if (idx != -1) 1465 bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_INDEX, 1466 h->sock + idx); 1467 bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_DATA, data); 1468} 1469