1 /* $OpenBSD: tcic2.c,v 1.14 2021/03/07 06:21:38 jsg Exp $ */ 2 /* $NetBSD: tcic2.c,v 1.3 2000/01/13 09:38:17 joda Exp $ */ 3 4 #undef TCICDEBUG 5 6 /* 7 * Copyright (c) 1998, 1999 Christoph Badura. All rights reserved. 8 * Copyright (c) 1997 Marc Horowitz. All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by Marc Horowitz. 21 * 4. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/device.h> 39 #include <sys/extent.h> 40 #include <sys/malloc.h> 41 #include <sys/kthread.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/tcic2reg.h> 50 #include <dev/ic/tcic2var.h> 51 52 #ifdef TCICDEBUG 53 int tcic_debug = 1; 54 #define DPRINTF(arg) if (tcic_debug) printf arg; 55 #else 56 #define DPRINTF(arg) 57 #endif 58 59 /* 60 * Individual drivers will allocate their own memory and io regions. Memory 61 * regions must be a multiple of 4k, aligned on a 4k boundary. 62 */ 63 64 #define TCIC_MEM_ALIGN TCIC_MEM_PAGESIZE 65 66 void tcic_attach_socket(struct tcic_handle *); 67 void tcic_init_socket(struct tcic_handle *); 68 69 int tcic_submatch(struct device *, void *, void *); 70 int tcic_print(void *arg, const char *pnp); 71 int tcic_intr_socket(struct tcic_handle *); 72 73 void tcic_attach_card(struct tcic_handle *); 74 void tcic_detach_card(struct tcic_handle *, int); 75 void tcic_deactivate_card(struct tcic_handle *); 76 77 void tcic_chip_do_mem_map(struct tcic_handle *, int); 78 void tcic_chip_do_io_map(struct tcic_handle *, int); 79 80 void tcic_create_event_thread(void *); 81 void tcic_event_thread(void *); 82 83 void tcic_queue_event(struct tcic_handle *, int); 84 85 struct cfdriver tcic_cd = { 86 NULL, "tcic", DV_DULL 87 }; 88 89 /* Map between irq numbers and internal representation */ 90 #if 1 91 int tcic_irqmap[] = 92 { 0, 0, 0, 3, 4, 5, 6, 7, 0, 0, 10, 1, 0, 0, 14, 0 }; 93 int tcic_valid_irqs = 0x4cf8; 94 #else 95 int tcic_irqmap[] = /* irqs 9 and 6 switched, some ISA cards */ 96 { 0, 0, 0, 3, 4, 5, 0, 7, 0, 6, 10, 1, 0, 0, 14, 0 }; 97 int tcic_valid_irqs = 0x4eb8; 98 #endif 99 100 int tcic_mem_speed = 250; /* memory access time in nanoseconds */ 101 int tcic_io_speed = 165; /* io access time in nanoseconds */ 102 103 /* 104 * Check various reserved and otherwise in their value restricted bits. 105 */ 106 int 107 tcic_check_reserved_bits(bus_space_tag_t iot, bus_space_handle_t ioh) 108 { 109 int val, auxreg; 110 111 DPRINTF(("tcic: chkrsvd 1\n")); 112 /* R_ADDR bit 30:28 have a restricted range. */ 113 val = (bus_space_read_2(iot, ioh, TCIC_R_ADDR2) & TCIC_SS_MASK) 114 >> TCIC_SS_SHIFT; 115 if (val > 1) 116 return 0; 117 118 DPRINTF(("tcic: chkrsvd 2\n")); 119 /* R_SCTRL bits 6,2,1 are reserved. */ 120 val = bus_space_read_1(iot, ioh, TCIC_R_SCTRL); 121 if (val & TCIC_SCTRL_RSVD) 122 return 0; 123 124 DPRINTF(("tcic: chkrsvd 3\n")); 125 /* R_ICSR bit 2 must be same as bit 3. */ 126 val = bus_space_read_1(iot, ioh, TCIC_R_ICSR); 127 if (((val >> 1) & 1) != ((val >> 2) & 1)) 128 return 0; 129 130 DPRINTF(("tcic: chkrsvd 4\n")); 131 /* R_IENA bits 7,2 are reserved. */ 132 val = bus_space_read_1(iot, ioh, TCIC_R_IENA); 133 if (val & TCIC_IENA_RSVD) 134 return 0; 135 136 DPRINTF(("tcic: chkrsvd 5\n")); 137 /* Some aux registers have reserved bits. */ 138 /* Which are we looking at? */ 139 auxreg = bus_space_read_1(iot, ioh, TCIC_R_MODE) 140 & TCIC_AR_MASK; 141 val = bus_space_read_2(iot, ioh, TCIC_R_AUX); 142 DPRINTF(("tcic: auxreg 0x%02x val 0x%04x\n", auxreg, val)); 143 switch (auxreg) { 144 case TCIC_AR_SYSCFG: 145 if (INVALID_AR_SYSCFG(val)) 146 return 0; 147 break; 148 case TCIC_AR_ILOCK: 149 if (INVALID_AR_ILOCK(val)) 150 return 0; 151 break; 152 case TCIC_AR_TEST: 153 if (INVALID_AR_TEST(val)) 154 return 0; 155 break; 156 } 157 158 DPRINTF(("tcic: chkrsvd 6\n")); 159 /* XXX fails if pcmcia bios is enabled. */ 160 /* Various bits set or not depending if in RESET mode. */ 161 val = bus_space_read_1(iot, ioh, TCIC_R_SCTRL); 162 if (val & TCIC_SCTRL_RESET) { 163 DPRINTF(("tcic: chkrsvd 7\n")); 164 /* Address bits must be 0 */ 165 val = bus_space_read_2(iot, ioh, TCIC_R_ADDR); 166 if (val != 0) 167 return 0; 168 val = bus_space_read_2(iot, ioh, TCIC_R_ADDR2); 169 if (val != 0) 170 return 0; 171 DPRINTF(("tcic: chkrsvd 8\n")); 172 /* EDC bits must be 0 */ 173 val = bus_space_read_2(iot, ioh, TCIC_R_EDC); 174 if (val != 0) 175 return 0; 176 /* We're OK, so take it out of reset. XXX -chb */ 177 bus_space_write_1(iot, ioh, TCIC_R_SCTRL, 0); 178 } 179 else { /* not in RESET mode */ 180 int omode; 181 int val1, val2; 182 DPRINTF(("tcic: chkrsvd 9\n")); 183 /* Programming timers must have expired. */ 184 val = bus_space_read_1(iot, ioh, TCIC_R_SSTAT); 185 if ((val & (TCIC_SSTAT_6US|TCIC_SSTAT_10US|TCIC_SSTAT_PROGTIME)) 186 != (TCIC_SSTAT_6US|TCIC_SSTAT_10US|TCIC_SSTAT_PROGTIME)) 187 return 0; 188 DPRINTF(("tcic: chkrsvd 10\n")); 189 /* 190 * EDC bits should change on read from data space 191 * as long as either EDC or the data are nonzero. 192 */ 193 if ((bus_space_read_2(iot, ioh, TCIC_R_ADDR2) 194 & TCIC_ADDR2_INDREG) != 0) { 195 val1 = bus_space_read_2(iot, ioh, TCIC_R_EDC); 196 val2 = bus_space_read_2(iot, ioh, TCIC_R_DATA); 197 if (val1 | val2) { 198 val1 = bus_space_read_2(iot, ioh, TCIC_R_EDC); 199 if (val1 == val2) 200 return 0; 201 } 202 } 203 DPRINTF(("tcic: chkrsvd 11\n")); 204 /* XXX what does this check? -chb */ 205 omode = bus_space_read_1(iot, ioh, TCIC_R_MODE); 206 val1 = omode ^ TCIC_AR_MASK; 207 bus_space_write_1(iot, ioh, TCIC_R_MODE, val1); 208 val2 = bus_space_read_1(iot, ioh, TCIC_R_MODE); 209 bus_space_write_1(iot, ioh, TCIC_R_MODE, omode); 210 if ( val1 != val2) 211 return 0; 212 } 213 /* All tests passed */ 214 return 1; 215 } 216 217 /* 218 * Read chip ID from AR_ILOCK in test mode. 219 */ 220 int 221 tcic_chipid(bus_space_tag_t iot, bus_space_handle_t ioh) 222 { 223 unsigned id, otest; 224 225 otest = tcic_read_aux_2(iot, ioh, TCIC_AR_TEST); 226 tcic_write_aux_2(iot, ioh, TCIC_AR_TEST, TCIC_TEST_DIAG); 227 id = tcic_read_aux_2(iot, ioh, TCIC_AR_ILOCK); 228 tcic_write_aux_2(iot, ioh, TCIC_AR_TEST, otest); 229 id &= TCIC_ILOCKTEST_ID_MASK; 230 id >>= TCIC_ILOCKTEST_ID_SHFT; 231 232 /* clear up IRQs inside tcic. XXX -chb */ 233 while (bus_space_read_1(iot, ioh, TCIC_R_ICSR)) 234 bus_space_write_1(iot, ioh, TCIC_R_ICSR, TCIC_ICSR_JAM); 235 236 return id; 237 } 238 /* 239 * Indicate whether the driver can handle the chip. 240 */ 241 int 242 tcic_chipid_known(int id) 243 { 244 /* XXX only know how to handle DB86082 -chb */ 245 switch (id) { 246 case TCIC_CHIPID_DB86082_1: 247 case TCIC_CHIPID_DB86082A: 248 case TCIC_CHIPID_DB86082B_ES: 249 case TCIC_CHIPID_DB86082B: 250 case TCIC_CHIPID_DB86084_1: 251 case TCIC_CHIPID_DB86084A: 252 case TCIC_CHIPID_DB86184_1: 253 case TCIC_CHIPID_DB86072_1_ES: 254 case TCIC_CHIPID_DB86072_1: 255 return 1; 256 } 257 258 return 0; 259 } 260 261 char * 262 tcic_chipid_to_string(int id) 263 { 264 switch (id) { 265 case TCIC_CHIPID_DB86082_1: 266 return ("Databook DB86082"); 267 case TCIC_CHIPID_DB86082A: 268 return ("Databook DB86082A"); 269 case TCIC_CHIPID_DB86082B_ES: 270 return ("Databook DB86082B-es"); 271 case TCIC_CHIPID_DB86082B: 272 return ("Databook DB86082B"); 273 case TCIC_CHIPID_DB86084_1: 274 return ("Databook DB86084"); 275 case TCIC_CHIPID_DB86084A: 276 return ("Databook DB86084A"); 277 case TCIC_CHIPID_DB86184_1: 278 return ("Databook DB86184"); 279 case TCIC_CHIPID_DB86072_1_ES: 280 return ("Databook DB86072-es"); 281 case TCIC_CHIPID_DB86072_1: 282 return ("Databook DB86072"); 283 } 284 285 return ("Unknown controller"); 286 } 287 /* 288 * Return bitmask of IRQs that the chip can handle. 289 * XXX should be table driven. 290 */ 291 int 292 tcic_validirqs(int chipid) 293 { 294 switch (chipid) { 295 case TCIC_CHIPID_DB86082_1: 296 case TCIC_CHIPID_DB86082A: 297 case TCIC_CHIPID_DB86082B_ES: 298 case TCIC_CHIPID_DB86082B: 299 case TCIC_CHIPID_DB86084_1: 300 case TCIC_CHIPID_DB86084A: 301 case TCIC_CHIPID_DB86184_1: 302 case TCIC_CHIPID_DB86072_1_ES: 303 case TCIC_CHIPID_DB86072_1: 304 return tcic_valid_irqs; 305 } 306 return 0; 307 } 308 309 void 310 tcic_attach(struct tcic_softc *sc) 311 { 312 int i, reg; 313 314 /* set more chipset-dependent parameters in the softc. */ 315 switch (sc->chipid) { 316 case TCIC_CHIPID_DB86084_1: 317 case TCIC_CHIPID_DB86084A: 318 case TCIC_CHIPID_DB86184_1: 319 sc->pwrena = TCIC_PWR_ENA; 320 break; 321 default: 322 sc->pwrena = 0; 323 break; 324 } 325 326 /* set up global config registers */ 327 reg = TCIC_WAIT_SYNC | TCIC_WAIT_CCLK | TCIC_WAIT_RISING; 328 reg |= (tcic_ns2wscnt(250) & TCIC_WAIT_COUNT_MASK); 329 tcic_write_aux_1(sc->iot, sc->ioh, TCIC_AR_WCTL, TCIC_R_WCTL_WAIT, reg); 330 reg = TCIC_SYSCFG_MPSEL_RI | TCIC_SYSCFG_MCSFULL; 331 tcic_write_aux_2(sc->iot, sc->ioh, TCIC_AR_SYSCFG, reg); 332 reg = tcic_read_aux_2(sc->iot, sc->ioh, TCIC_AR_ILOCK); 333 reg |= TCIC_ILOCK_HOLD_CCLK; 334 tcic_write_aux_2(sc->iot, sc->ioh, TCIC_AR_ILOCK, reg); 335 336 /* the TCIC has two sockets */ 337 /* XXX should i check for actual presence of sockets? -chb */ 338 for (i = 0; i < TCIC_NSLOTS; i++) { 339 sc->handle[i].sc = sc; 340 sc->handle[i].sock = i; 341 sc->handle[i].flags = TCIC_FLAG_SOCKETP; 342 sc->handle[i].memwins 343 = sc->chipid == TCIC_CHIPID_DB86082_1 ? 4 : 5; 344 } 345 346 /* establish the interrupt */ 347 reg = tcic_read_1(&sc->handle[0], TCIC_R_IENA); 348 tcic_write_1(&sc->handle[0], TCIC_R_IENA, 349 (reg & ~TCIC_IENA_CFG_MASK) | TCIC_IENA_CFG_HIGH); 350 reg = tcic_read_aux_2(sc->iot, sc->ioh, TCIC_AR_SYSCFG); 351 tcic_write_aux_2(sc->iot, sc->ioh, TCIC_AR_SYSCFG, 352 (reg & ~TCIC_SYSCFG_IRQ_MASK) | tcic_irqmap[sc->irq]); 353 354 /* XXX block interrupts? */ 355 356 for (i = 0; i < TCIC_NSLOTS; i++) { 357 /* XXX make more clear what happens here -chb */ 358 tcic_sel_sock(&sc->handle[i]); 359 tcic_write_ind_2(&sc->handle[i], TCIC_IR_SCF1_N(i), 0); 360 tcic_write_ind_2(&sc->handle[i], TCIC_IR_SCF2_N(i), 361 (TCIC_SCF2_MCD|TCIC_SCF2_MWP|TCIC_SCF2_MRDY 362 #if 1 /* XXX explain byte routing issue */ 363 |TCIC_SCF2_MLBAT2|TCIC_SCF2_MLBAT1|TCIC_SCF2_IDBR)); 364 #else 365 |TCIC_SCF2_MLBAT2|TCIC_SCF2_MLBAT1)); 366 #endif 367 tcic_write_1(&sc->handle[i], TCIC_R_MODE, 0); 368 reg = tcic_read_aux_2(sc->iot, sc->ioh, TCIC_AR_SYSCFG); 369 reg &= ~TCIC_SYSCFG_AUTOBUSY; 370 tcic_write_aux_2(sc->iot, sc->ioh, TCIC_AR_SYSCFG, reg); 371 SIMPLEQ_INIT(&sc->handle[i].events); 372 } 373 374 if ((sc->handle[0].flags & TCIC_FLAG_SOCKETP) || 375 (sc->handle[1].flags & TCIC_FLAG_SOCKETP)) { 376 printf("%s: %s has ", sc->dev.dv_xname, 377 tcic_chipid_to_string(sc->chipid)); 378 379 if ((sc->handle[0].flags & TCIC_FLAG_SOCKETP) && 380 (sc->handle[1].flags & TCIC_FLAG_SOCKETP)) 381 printf("sockets A and B\n"); 382 else if (sc->handle[0].flags & TCIC_FLAG_SOCKETP) 383 printf("socket A only\n"); 384 else 385 printf("socket B only\n"); 386 387 } 388 } 389 390 void 391 tcic_attach_sockets(struct tcic_softc *sc) 392 { 393 int i; 394 395 for (i = 0; i < TCIC_NSLOTS; i++) 396 if (sc->handle[i].flags & TCIC_FLAG_SOCKETP) 397 tcic_attach_socket(&sc->handle[i]); 398 } 399 400 void 401 tcic_attach_socket(struct tcic_handle *h) 402 { 403 struct pcmciabus_attach_args paa; 404 405 /* initialize the rest of the handle */ 406 407 h->shutdown = 0; 408 h->memalloc = 0; 409 h->ioalloc = 0; 410 h->ih_irq = 0; 411 412 /* now, config one pcmcia device per socket */ 413 414 paa.paa_busname = "pcmcia"; 415 paa.pct = (pcmcia_chipset_tag_t) h->sc->pct; 416 paa.pch = (pcmcia_chipset_handle_t) h; 417 paa.iobase = h->sc->iobase; 418 paa.iosize = h->sc->iosize; 419 420 h->pcmcia = config_found_sm(&h->sc->dev, &paa, tcic_print, 421 tcic_submatch); 422 423 /* if there's actually a pcmcia device attached, initialize the slot */ 424 425 if (h->pcmcia) 426 tcic_init_socket(h); 427 else 428 h->flags &= ~TCIC_FLAG_SOCKETP; 429 } 430 431 void 432 tcic_create_event_thread(void *arg) 433 { 434 struct tcic_handle *h = arg; 435 char name[MAXCOMLEN+1]; 436 const char *cs; 437 438 switch (h->sock) { 439 case 0: 440 cs = "0"; 441 break; 442 case 1: 443 cs = "1"; 444 break; 445 default: 446 panic("tcic_create_event_thread: unknown tcic socket"); 447 } 448 449 snprintf(name, sizeof name, "%s,%s", h->sc->dev.dv_xname, cs); 450 if (kthread_create(tcic_event_thread, h, &h->event_thread, name)) { 451 printf("%s: unable to create event thread for sock 0x%02x\n", 452 h->sc->dev.dv_xname, h->sock); 453 panic("tcic_create_event_thread"); 454 } 455 } 456 457 void 458 tcic_event_thread(void *arg) 459 { 460 struct tcic_handle *h = arg; 461 struct tcic_event *pe; 462 int s; 463 464 while (h->shutdown == 0) { 465 s = splhigh(); 466 if ((pe = SIMPLEQ_FIRST(&h->events)) == NULL) { 467 splx(s); 468 tsleep_nsec(&h->events, PWAIT, "tcicev", INFSLP); 469 continue; 470 } 471 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); 472 splx(s); 473 474 switch (pe->pe_type) { 475 case TCIC_EVENT_INSERTION: 476 DPRINTF(("%s: insertion event\n", h->sc->dev.dv_xname)); 477 tcic_attach_card(h); 478 break; 479 480 case TCIC_EVENT_REMOVAL: 481 DPRINTF(("%s: removal event\n", h->sc->dev.dv_xname)); 482 tcic_detach_card(h, DETACH_FORCE); 483 break; 484 485 default: 486 panic("tcic_event_thread: unknown event %d", 487 pe->pe_type); 488 } 489 free(pe, M_TEMP, 0); 490 } 491 492 h->event_thread = NULL; 493 494 /* In case parent is waiting for us to exit. */ 495 wakeup(h->sc); 496 497 kthread_exit(0); 498 } 499 500 501 void 502 tcic_init_socket(struct tcic_handle *h) 503 { 504 int reg; 505 506 /* select this socket's config registers */ 507 tcic_sel_sock(h); 508 509 /* set up the socket to interrupt on card detect */ 510 reg = tcic_read_ind_2(h, TCIC_IR_SCF2_N(h->sock)); 511 tcic_write_ind_2(h, TCIC_IR_SCF2_N(h->sock), reg & ~TCIC_SCF2_MCD); 512 513 /* enable CD irq in R_IENA */ 514 reg = tcic_read_2(h, TCIC_R_IENA); 515 tcic_write_2(h, TCIC_R_IENA, reg |= TCIC_IENA_CDCHG); 516 517 /* if there's a card there, then attach it. also save sstat */ 518 h->sstat = reg = tcic_read_1(h, TCIC_R_SSTAT) & TCIC_SSTAT_STAT_MASK; 519 if (reg & TCIC_SSTAT_CD) 520 tcic_attach_card(h); 521 } 522 523 int 524 tcic_submatch(struct device *parent, void *match, void *aux) 525 { 526 struct cfdata *cf = match; 527 528 struct pcmciabus_attach_args *paa = aux; 529 struct tcic_handle *h = (struct tcic_handle *) paa->pch; 530 531 switch (h->sock) { 532 case 0: 533 if (cf->cf_loc[0 /* PCMCIABUSCF_CONTROLLER */] != 534 -1 /* PCMCIABUSCF_CONTROLLER_DEFAULT */ && 535 cf->cf_loc[0 /* PCMCIABUSCF_CONTROLLER */] != 0) 536 return 0; 537 if (cf->cf_loc[1 /* PCMCIABUSCF_SOCKET */] != 538 -1 /* PCMCIABUSCF_SOCKET_DEFAULT */ && 539 cf->cf_loc[1 /* PCMCIABUSCF_SOCKET */] != 0) 540 return 0; 541 542 break; 543 case 1: 544 if (cf->cf_loc[0 /* PCMCIABUSCF_CONTROLLER */] != 545 -1 /* PCMCIABUSCF_CONTROLLER_DEFAULT */ && 546 cf->cf_loc[0 /* PCMCIABUSCF_CONTROLLER */] != 0) 547 return 0; 548 if (cf->cf_loc[1 /* PCMCIABUSCF_SOCKET */] != 549 -1 /* PCMCIABUSCF_SOCKET_DEFAULT */ && 550 cf->cf_loc[1 /* PCMCIABUSCF_SOCKET */] != 1) 551 return 0; 552 553 break; 554 default: 555 panic("unknown tcic socket"); 556 } 557 558 return ((*cf->cf_attach->ca_match)(parent, cf, aux)); 559 } 560 561 int 562 tcic_print(void *arg, const char *pnp) 563 { 564 struct pcmciabus_attach_args *paa = arg; 565 struct tcic_handle *h = (struct tcic_handle *) paa->pch; 566 567 /* Only "pcmcia"s can attach to "tcic"s... easy. */ 568 if (pnp) 569 printf("pcmcia at %s", pnp); 570 571 switch (h->sock) { 572 case 0: 573 printf(" socket 0"); 574 break; 575 case 1: 576 printf(" socket 1"); 577 break; 578 default: 579 panic("unknown tcic socket"); 580 } 581 return (UNCONF); 582 } 583 584 int 585 tcic_intr(void *arg) 586 { 587 struct tcic_softc *sc = arg; 588 int i, ret = 0; 589 590 DPRINTF(("%s: intr\n", sc->dev.dv_xname)); 591 592 for (i = 0; i < TCIC_NSLOTS; i++) 593 if (sc->handle[i].flags & TCIC_FLAG_SOCKETP) 594 ret += tcic_intr_socket(&sc->handle[i]); 595 596 return (ret ? 1 : 0); 597 } 598 599 int 600 tcic_intr_socket(struct tcic_handle *h) 601 { 602 int icsr, rv; 603 604 rv = 0; 605 tcic_sel_sock(h); 606 icsr = tcic_read_1(h, TCIC_R_ICSR); 607 608 DPRINTF(("%s: %d icsr: 0x%02x \n", h->sc->dev.dv_xname, h->sock, icsr)); 609 610 /* XXX or should the next three be handled in tcic_intr? -chb */ 611 if (icsr & TCIC_ICSR_PROGTIME) { 612 DPRINTF(("%s: %02x PROGTIME\n", h->sc->dev.dv_xname, h->sock)); 613 rv = 1; 614 } 615 if (icsr & TCIC_ICSR_ILOCK) { 616 DPRINTF(("%s: %02x ILOCK\n", h->sc->dev.dv_xname, h->sock)); 617 rv = 1; 618 } 619 if (icsr & TCIC_ICSR_ERR) { 620 DPRINTF(("%s: %02x ERR\n", h->sc->dev.dv_xname, h->sock)); 621 rv = 1; 622 } 623 if (icsr & TCIC_ICSR_CDCHG) { 624 int sstat, delta; 625 626 /* compute what changed since last interrupt */ 627 sstat = tcic_read_aux_1(h->sc->iot, h->sc->ioh, 628 TCIC_AR_WCTL, TCIC_R_WCTL_XCSR) & TCIC_XCSR_STAT_MASK; 629 delta = h->sstat ^ sstat; 630 h->sstat = sstat; 631 632 if (delta) 633 rv = 1; 634 635 DPRINTF(("%s: %02x CDCHG %x\n", h->sc->dev.dv_xname, h->sock, 636 delta)); 637 638 /* 639 * XXX This should probably schedule something to happen 640 * after the interrupt handler completes 641 */ 642 643 if (delta & TCIC_SSTAT_CD) { 644 if (sstat & TCIC_SSTAT_CD) { 645 if (!(h->flags & TCIC_FLAG_CARDP)) { 646 DPRINTF(("%s: enqueuing INSERTION event\n", 647 h->sc->dev.dv_xname)); 648 tcic_queue_event(h, TCIC_EVENT_INSERTION); 649 } 650 } else { 651 if (h->flags & TCIC_FLAG_CARDP) { 652 /* Deactivate the card now. */ 653 DPRINTF(("%s: deactivating card\n", 654 h->sc->dev.dv_xname)); 655 tcic_deactivate_card(h); 656 657 DPRINTF(("%s: enqueuing REMOVAL event\n", 658 h->sc->dev.dv_xname)); 659 tcic_queue_event(h, TCIC_EVENT_REMOVAL); 660 } 661 } 662 } 663 if (delta & TCIC_SSTAT_RDY) { 664 DPRINTF(("%s: %02x READY\n", h->sc->dev.dv_xname, h->sock)); 665 /* shouldn't happen */ 666 } 667 if (delta & TCIC_SSTAT_LBAT1) { 668 DPRINTF(("%s: %02x LBAT1\n", h->sc->dev.dv_xname, h->sock)); 669 } 670 if (delta & TCIC_SSTAT_LBAT2) { 671 DPRINTF(("%s: %02x LBAT2\n", h->sc->dev.dv_xname, h->sock)); 672 } 673 if (delta & TCIC_SSTAT_WP) { 674 DPRINTF(("%s: %02x WP\n", h->sc->dev.dv_xname, h->sock)); 675 } 676 } 677 return rv; 678 } 679 680 void 681 tcic_queue_event(struct tcic_handle *h, int event) 682 { 683 struct tcic_event *pe; 684 int s; 685 686 pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT); 687 if (pe == NULL) 688 panic("tcic_queue_event: can't allocate event"); 689 690 pe->pe_type = event; 691 s = splhigh(); 692 SIMPLEQ_INSERT_TAIL(&h->events, pe, pe_q); 693 splx(s); 694 wakeup(&h->events); 695 } 696 697 void 698 tcic_attach_card(struct tcic_handle *h) 699 { 700 DPRINTF(("tcic_attach_card\n")); 701 702 if (h->flags & TCIC_FLAG_CARDP) 703 panic("tcic_attach_card: already attached"); 704 705 /* call the MI attach function */ 706 707 pcmcia_card_attach(h->pcmcia); 708 709 h->flags |= TCIC_FLAG_CARDP; 710 } 711 712 void 713 tcic_detach_card(struct tcic_handle *h, int flags) 714 { 715 DPRINTF(("tcic_detach_card\n")); 716 717 if (!(h->flags & TCIC_FLAG_CARDP)) 718 panic("tcic_detach_card: already detached"); 719 720 h->flags &= ~TCIC_FLAG_CARDP; 721 722 /* call the MI detach function */ 723 724 pcmcia_card_detach(h->pcmcia, flags); 725 726 } 727 728 void 729 tcic_deactivate_card(struct tcic_handle *h) 730 { 731 int val, reg; 732 733 if (!(h->flags & TCIC_FLAG_CARDP)) 734 panic("tcic_deactivate_card: already detached"); 735 736 /* call the MI deactivate function */ 737 pcmcia_card_deactivate(h->pcmcia); 738 739 tcic_sel_sock(h); 740 741 /* XXX disable card detect resume and configuration reset??? */ 742 743 /* power down the socket */ 744 tcic_write_1(h, TCIC_R_PWR, 0); 745 746 /* reset the card XXX ? -chb */ 747 748 /* turn off irq's for this socket */ 749 reg = TCIC_IR_SCF1_N(h->sock); 750 val = tcic_read_ind_2(h, reg); 751 tcic_write_ind_2(h, reg, (val & ~TCIC_SCF1_IRQ_MASK)|TCIC_SCF1_IRQOFF); 752 reg = TCIC_IR_SCF2_N(h->sock); 753 val = tcic_read_ind_2(h, reg); 754 tcic_write_ind_2(h, reg, 755 (val | (TCIC_SCF2_MLBAT1|TCIC_SCF2_MLBAT2|TCIC_SCF2_MRDY 756 |TCIC_SCF2_MWP|TCIC_SCF2_MCD))); 757 } 758 759 /* XXX the following routine may need to be rewritten. -chb */ 760 int 761 tcic_chip_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size, 762 struct pcmcia_mem_handle *pcmhp) 763 { 764 struct tcic_handle *h = (struct tcic_handle *) pch; 765 bus_space_handle_t memh; 766 bus_addr_t addr; 767 bus_size_t sizepg; 768 int i, mask, mhandle; 769 770 /* out of sc->memh, allocate as many pages as necessary */ 771 772 /* 773 * The TCIC can map memory only in sizes that are 774 * powers of two, aligned at the natural boundary for the size. 775 */ 776 i = tcic_log2((u_int)size); 777 if ((1<<i) < size) 778 i++; 779 sizepg = max(i, TCIC_MEM_SHIFT) - (TCIC_MEM_SHIFT-1); 780 781 DPRINTF(("tcic_chip_mem_alloc: size %ld sizepg %ld\n", size, sizepg)); 782 783 /* can't allocate that much anyway */ 784 if (sizepg > TCIC_MEM_PAGES) /* XXX -chb */ 785 return 1; 786 787 mask = (1 << sizepg) - 1; 788 789 addr = 0; /* XXX gcc -Wuninitialized */ 790 mhandle = 0; /* XXX gcc -Wuninitialized */ 791 792 /* XXX i should be initialised to always lay on boundary. -chb */ 793 for (i = 0; i < (TCIC_MEM_PAGES + 1 - sizepg); i += sizepg) { 794 if ((h->sc->subregionmask & (mask << i)) == (mask << i)) { 795 if (bus_space_subregion(h->sc->memt, h->sc->memh, 796 i * TCIC_MEM_PAGESIZE, 797 sizepg * TCIC_MEM_PAGESIZE, &memh)) 798 return (1); 799 mhandle = mask << i; 800 addr = h->sc->membase + (i * TCIC_MEM_PAGESIZE); 801 h->sc->subregionmask &= ~(mhandle); 802 break; 803 } 804 } 805 806 if (i == (TCIC_MEM_PAGES + 1 - sizepg)) 807 return (1); 808 809 DPRINTF(("tcic_chip_mem_alloc bus addr 0x%lx+0x%lx\n", (u_long) addr, 810 (u_long) size)); 811 812 pcmhp->memt = h->sc->memt; 813 pcmhp->memh = memh; 814 pcmhp->addr = addr; 815 pcmhp->size = size; 816 pcmhp->mhandle = mhandle; 817 pcmhp->realsize = sizepg * TCIC_MEM_PAGESIZE; 818 819 return (0); 820 } 821 822 /* XXX the following routine may need to be rewritten. -chb */ 823 void 824 tcic_chip_mem_free(pcmcia_chipset_handle_t pch, struct pcmcia_mem_handle *pcmhp) 825 { 826 struct tcic_handle *h = (struct tcic_handle *) pch; 827 828 h->sc->subregionmask |= pcmhp->mhandle; 829 } 830 831 void 832 tcic_chip_do_mem_map(struct tcic_handle *h, int win) 833 { 834 int reg, hwwin, wscnt; 835 836 int kind = h->mem[win].kind & ~PCMCIA_WIDTH_MEM_MASK; 837 int mem8 = (h->mem[win].kind & PCMCIA_WIDTH_MEM_MASK) == PCMCIA_WIDTH_MEM8; 838 DPRINTF(("tcic_chip_do_mem_map window %d: 0x%lx+0x%lx 0x%lx\n", 839 win, (u_long)h->mem[win].addr, (u_long)h->mem[win].size, 840 (u_long)h->mem[win].offset)); 841 /* 842 * the even windows are used for socket 0, 843 * the odd ones for socket 1. 844 */ 845 hwwin = (win << 1) + h->sock; 846 847 /* the WR_MEXT register is MBZ */ 848 tcic_write_ind_2(h, TCIC_WR_MEXT_N(hwwin), 0); 849 850 /* set the host base address and window size */ 851 if (h->mem[win].size2 <= 1) { 852 reg = ((h->mem[win].addr >> TCIC_MEM_SHIFT) & 853 TCIC_MBASE_ADDR_MASK) | TCIC_MBASE_4K; 854 } else { 855 reg = ((h->mem[win].addr >> TCIC_MEM_SHIFT) & 856 TCIC_MBASE_ADDR_MASK) | (h->mem[win].size2 >> 1); 857 } 858 tcic_write_ind_2(h, TCIC_WR_MBASE_N(hwwin), reg); 859 860 /* set the card address and address space */ 861 reg = 0; 862 reg = ((h->mem[win].offset >> TCIC_MEM_SHIFT) & TCIC_MMAP_ADDR_MASK); 863 reg |= (kind == PCMCIA_MEM_ATTR) ? TCIC_MMAP_ATTR : 0; 864 DPRINTF(("tcic_chip_do_map_mem window %d(%d) mmap 0x%04x\n", 865 win, hwwin, reg)); 866 tcic_write_ind_2(h, TCIC_WR_MMAP_N(hwwin), reg); 867 868 /* set the MCTL register */ 869 /* must save WSCNT field in case this is a DB86082 rev 0 */ 870 /* XXX why can't I do the following two in one statement? */ 871 reg = tcic_read_ind_2(h, TCIC_WR_MCTL_N(hwwin)) & TCIC_MCTL_WSCNT_MASK; 872 reg |= TCIC_MCTL_ENA|TCIC_MCTL_QUIET; 873 reg |= mem8 ? TCIC_MCTL_B8 : 0; 874 reg |= (h->sock << TCIC_MCTL_SS_SHIFT) & TCIC_MCTL_SS_MASK; 875 #ifdef notyet /* XXX must get speed from CIS somehow. -chb */ 876 wscnt = tcic_ns2wscnt(h->mem[win].speed); 877 #else 878 wscnt = tcic_ns2wscnt(tcic_mem_speed); /* 300 is "save" default for CIS memory */ 879 #endif 880 if (h->sc->chipid == TCIC_CHIPID_DB86082_1) { 881 /* 882 * this chip has the wait state count in window 883 * register 7 - hwwin. 884 */ 885 int reg2; 886 reg2 = tcic_read_ind_2(h, TCIC_WR_MCTL_N(7-hwwin)); 887 reg2 &= ~TCIC_MCTL_WSCNT_MASK; 888 reg2 |= wscnt & TCIC_MCTL_WSCNT_MASK; 889 tcic_write_ind_2(h, TCIC_WR_MCTL_N(7-hwwin), reg2); 890 } else { 891 reg |= wscnt & TCIC_MCTL_WSCNT_MASK; 892 } 893 tcic_write_ind_2(h, TCIC_WR_MCTL_N(hwwin), reg); 894 895 #ifdef TCICDEBUG 896 { 897 int r1, r2, r3; 898 899 r1 = tcic_read_ind_2(h, TCIC_WR_MBASE_N(hwwin)); 900 r2 = tcic_read_ind_2(h, TCIC_WR_MMAP_N(hwwin)); 901 r3 = tcic_read_ind_2(h, TCIC_WR_MCTL_N(hwwin)); 902 903 DPRINTF(("tcic_chip_do_mem_map window %d(%d): %04x %04x %04x\n", 904 win, hwwin, r1, r2, r3)); 905 } 906 #endif 907 } 908 909 /* XXX needs work */ 910 int 911 tcic_chip_mem_map(pcmcia_chipset_handle_t pch, int kind, bus_addr_t card_addr, 912 bus_size_t size, struct pcmcia_mem_handle *pcmhp, bus_size_t *offsetp, 913 int *windowp) 914 { 915 struct tcic_handle *h = (struct tcic_handle *) pch; 916 bus_addr_t busaddr; 917 long card_offset; 918 int i, win; 919 920 win = -1; 921 for (i = 0; i < h->memwins; i++) { 922 if ((h->memalloc & (1 << i)) == 0) { 923 win = i; 924 h->memalloc |= (1 << i); 925 break; 926 } 927 } 928 929 if (win == -1) 930 return (1); 931 932 *windowp = win; 933 934 /* XXX this is pretty gross */ 935 936 if (h->sc->memt != pcmhp->memt) 937 panic("tcic_chip_mem_map memt is bogus"); 938 939 busaddr = pcmhp->addr; 940 941 /* 942 * compute the address offset to the pcmcia address space for the 943 * tcic. this is intentionally signed. The masks and shifts below 944 * will cause TRT to happen in the tcic registers. Deal with making 945 * sure the address is aligned, and return the alignment offset. 946 */ 947 948 *offsetp = card_addr % TCIC_MEM_ALIGN; 949 card_addr -= *offsetp; 950 951 DPRINTF(("tcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr " 952 "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size, 953 (u_long) card_addr)); 954 955 /* XXX we can't use size. -chb */ 956 /* 957 * include the offset in the size, and decrement size by one, since 958 * the hw wants start/stop 959 */ 960 size += *offsetp - 1; 961 962 card_offset = (((long) card_addr) - ((long) busaddr)); 963 964 DPRINTF(("tcic_chip_mem_map window %d card_offset 0x%lx\n", 965 win, (u_long)card_offset)); 966 967 h->mem[win].addr = busaddr; 968 h->mem[win].size = size; 969 h->mem[win].size2 = tcic_log2((u_int)pcmhp->realsize) - TCIC_MEM_SHIFT; 970 h->mem[win].offset = card_offset; 971 h->mem[win].kind = kind; 972 973 tcic_chip_do_mem_map(h, win); 974 975 return (0); 976 } 977 978 void 979 tcic_chip_mem_unmap(pcmcia_chipset_handle_t pch, int window) 980 { 981 struct tcic_handle *h = (struct tcic_handle *) pch; 982 int reg, hwwin; 983 984 if (window >= h->memwins) 985 panic("tcic_chip_mem_unmap: window out of range"); 986 987 hwwin = (window << 1) + h->sock; 988 reg = tcic_read_ind_2(h, TCIC_WR_MCTL_N(hwwin)); 989 reg &= ~TCIC_MCTL_ENA; 990 tcic_write_ind_2(h, TCIC_WR_MCTL_N(hwwin), reg); 991 992 h->memalloc &= ~(1 << window); 993 } 994 995 int 996 tcic_chip_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start, 997 bus_size_t size, bus_size_t align, struct pcmcia_io_handle *pcihp) 998 { 999 struct tcic_handle *h = (struct tcic_handle *) pch; 1000 bus_space_tag_t iot; 1001 bus_space_handle_t ioh; 1002 bus_addr_t ioaddr; 1003 int size2, flags = 0; 1004 1005 /* 1006 * Allocate some arbitrary I/O space. 1007 */ 1008 1009 DPRINTF(("tcic_chip_io_alloc req 0x%lx %ld %ld\n", 1010 (u_long) start, (u_long) size, (u_long) align)); 1011 /* 1012 * The TCIC can map I/O space only in sizes that are 1013 * powers of two, aligned at the natural boundary for the size. 1014 */ 1015 size2 = tcic_log2((u_int)size); 1016 if ((1 << size2) < size) 1017 size2++; 1018 /* can't allocate that much anyway */ 1019 if (size2 > 16) /* XXX 64K -chb */ 1020 return 1; 1021 if (align) { 1022 if ((1 << size2) != align) 1023 return 1; /* not suitably aligned */ 1024 } else { 1025 align = 1 << size2; /* no alignment given, make it natural */ 1026 } 1027 if (start & (align - 1)) 1028 return 1; /* not suitably aligned */ 1029 1030 iot = h->sc->iot; 1031 1032 if (start) { 1033 ioaddr = start; 1034 if (bus_space_map(iot, start, size, 0, &ioh)) 1035 return (1); 1036 DPRINTF(("tcic_chip_io_alloc map port %lx+%lx\n", 1037 (u_long) ioaddr, (u_long) size)); 1038 } else { 1039 flags |= PCMCIA_IO_ALLOCATED; 1040 if (bus_space_alloc(iot, h->sc->iobase, 1041 h->sc->iobase + h->sc->iosize, size, align, 0, 0, 1042 &ioaddr, &ioh)) 1043 return (1); 1044 DPRINTF(("tcic_chip_io_alloc alloc port %lx+%lx\n", 1045 (u_long) ioaddr, (u_long) size)); 1046 } 1047 1048 pcihp->iot = iot; 1049 pcihp->ioh = ioh; 1050 pcihp->addr = ioaddr; 1051 pcihp->size = size; 1052 pcihp->flags = flags; 1053 1054 return (0); 1055 } 1056 1057 void 1058 tcic_chip_io_free(pcmcia_chipset_handle_t pch, struct pcmcia_io_handle *pcihp) 1059 { 1060 bus_space_tag_t iot = pcihp->iot; 1061 bus_space_handle_t ioh = pcihp->ioh; 1062 bus_size_t size = pcihp->size; 1063 1064 if (pcihp->flags & PCMCIA_IO_ALLOCATED) 1065 bus_space_free(iot, ioh, size); 1066 else 1067 bus_space_unmap(iot, ioh, size); 1068 } 1069 1070 static int tcic_iowidth_map[] = 1071 { TCIC_ICTL_AUTOSZ, TCIC_ICTL_B8, TCIC_ICTL_B16 }; 1072 1073 void 1074 tcic_chip_do_io_map(struct tcic_handle *h, int win) 1075 { 1076 int reg, size2, iotiny, wbase, hwwin, wscnt; 1077 1078 DPRINTF(("tcic_chip_do_io_map win %d addr %lx size %lx width %d\n", 1079 win, (long) h->io[win].addr, (long) h->io[win].size, 1080 h->io[win].width * 8)); 1081 1082 /* 1083 * the even windows are used for socket 0, 1084 * the odd ones for socket 1. 1085 */ 1086 hwwin = (win << 1) + h->sock; 1087 1088 /* set the WR_BASE register */ 1089 /* XXX what if size isn't power of 2? -chb */ 1090 size2 = tcic_log2((u_int)h->io[win].size); 1091 DPRINTF(("tcic_chip_do_io_map win %d size2 %d\n", win, size2)); 1092 if (size2 < 1) { 1093 iotiny = TCIC_ICTL_TINY; 1094 wbase = h->io[win].addr; 1095 } else { 1096 iotiny = 0; 1097 /* XXX we should do better -chb */ 1098 wbase = h->io[win].addr | (1 << (size2 - 1)); 1099 } 1100 tcic_write_ind_2(h, TCIC_WR_IBASE_N(hwwin), wbase); 1101 1102 /* set the WR_ICTL register */ 1103 reg = TCIC_ICTL_ENA | TCIC_ICTL_QUIET; 1104 reg |= (h->sock << TCIC_ICTL_SS_SHIFT) & TCIC_ICTL_SS_MASK; 1105 reg |= iotiny | tcic_iowidth_map[h->io[win].width]; 1106 if (h->sc->chipid != TCIC_CHIPID_DB86082_1) 1107 reg |= TCIC_ICTL_PASS16; 1108 #ifdef notyet /* XXX must get speed from CIS somehow. -chb */ 1109 wscnt = tcic_ns2wscnt(h->io[win].speed); 1110 #else 1111 wscnt = tcic_ns2wscnt(tcic_io_speed); /* linux uses 0 as default */ 1112 #endif 1113 reg |= wscnt & TCIC_ICTL_WSCNT_MASK; 1114 tcic_write_ind_2(h, TCIC_WR_ICTL_N(hwwin), reg); 1115 1116 #ifdef TCICDEBUG 1117 { 1118 int r1, r2; 1119 1120 r1 = tcic_read_ind_2(h, TCIC_WR_IBASE_N(hwwin)); 1121 r2 = tcic_read_ind_2(h, TCIC_WR_ICTL_N(hwwin)); 1122 1123 DPRINTF(("tcic_chip_do_io_map window %d(%d): %04x %04x\n", 1124 win, hwwin, r1, r2)); 1125 } 1126 #endif 1127 } 1128 1129 int 1130 tcic_chip_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset, 1131 bus_size_t size, struct pcmcia_io_handle *pcihp, int *windowp) 1132 { 1133 struct tcic_handle *h = (struct tcic_handle *) pch; 1134 bus_addr_t ioaddr = pcihp->addr + offset; 1135 int i, win; 1136 #ifdef TCICDEBUG 1137 static char *width_names[] = { "auto", "io8", "io16" }; 1138 #endif 1139 1140 /* XXX Sanity check offset/size. */ 1141 1142 win = -1; 1143 for (i = 0; i < TCIC_IO_WINS; i++) { 1144 if ((h->ioalloc & (1 << i)) == 0) { 1145 win = i; 1146 h->ioalloc |= (1 << i); 1147 break; 1148 } 1149 } 1150 1151 if (win == -1) 1152 return (1); 1153 1154 *windowp = win; 1155 1156 /* XXX this is pretty gross */ 1157 1158 if (h->sc->iot != pcihp->iot) 1159 panic("tcic_chip_io_map iot is bogus"); 1160 1161 DPRINTF(("tcic_chip_io_map window %d %s port %lx+%lx\n", 1162 win, width_names[width], (u_long) ioaddr, (u_long) size)); 1163 1164 /* XXX wtf is this doing here? */ 1165 1166 printf(" port 0x%lx", (u_long) ioaddr); 1167 if (size > 1) 1168 printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1); 1169 1170 h->io[win].addr = ioaddr; 1171 h->io[win].size = size; 1172 h->io[win].width = width; 1173 1174 tcic_chip_do_io_map(h, win); 1175 1176 return (0); 1177 } 1178 1179 void 1180 tcic_chip_io_unmap(pcmcia_chipset_handle_t pch, int window) 1181 { 1182 struct tcic_handle *h = (struct tcic_handle *) pch; 1183 int reg, hwwin; 1184 1185 if (window >= TCIC_IO_WINS) 1186 panic("tcic_chip_io_unmap: window out of range"); 1187 1188 hwwin = (window << 1) + h->sock; 1189 reg = tcic_read_ind_2(h, TCIC_WR_ICTL_N(hwwin)); 1190 reg &= ~TCIC_ICTL_ENA; 1191 tcic_write_ind_2(h, TCIC_WR_ICTL_N(hwwin), reg); 1192 1193 h->ioalloc &= ~(1 << window); 1194 } 1195 1196 void 1197 tcic_chip_socket_enable(pcmcia_chipset_handle_t pch) 1198 { 1199 struct tcic_handle *h = (struct tcic_handle *) pch; 1200 int cardtype, reg, win; 1201 1202 tcic_sel_sock(h); 1203 1204 /* 1205 * power down the socket to reset it. 1206 * put card reset into high-z, put chip outputs to card into high-z 1207 */ 1208 1209 tcic_write_1(h, TCIC_R_PWR, 0); 1210 reg = tcic_read_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK); 1211 reg |= TCIC_ILOCK_CWAIT; 1212 reg &= ~(TCIC_ILOCK_CRESET|TCIC_ILOCK_CRESENA); 1213 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg); 1214 tcic_write_1(h, TCIC_R_SCTRL, 0); /* clear TCIC_SCTRL_ENA */ 1215 1216 /* power up the socket */ 1217 1218 /* turn on VCC, turn of VPP */ 1219 reg = TCIC_PWR_VCC_N(h->sock) | TCIC_PWR_VPP_N(h->sock) | h->sc->pwrena; 1220 if (h->sc->pwrena) /* this is a '84 type chip */ 1221 reg |= TCIC_PWR_VCC5V; 1222 tcic_write_1(h, TCIC_R_PWR, reg); 1223 delay(10000); 1224 1225 /* enable reset and wiggle it to reset the card */ 1226 reg = tcic_read_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK); 1227 reg |= TCIC_ILOCK_CRESENA; 1228 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg); 1229 /* XXX need bus_space_barrier here */ 1230 reg |= TCIC_ILOCK_CRESET; 1231 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg); 1232 /* enable card signals */ 1233 tcic_write_1(h, TCIC_R_SCTRL, TCIC_SCTRL_ENA); 1234 delay(10); /* wait 10 us */ 1235 1236 /* clear the reset flag */ 1237 reg = tcic_read_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK); 1238 reg &= ~(TCIC_ILOCK_CRESET); 1239 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg); 1240 1241 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */ 1242 delay(20000); 1243 1244 /* wait for the chip to finish initializing */ 1245 tcic_wait_ready(h); 1246 1247 /* WWW */ 1248 /* zero out the address windows */ 1249 1250 /* writing to WR_MBASE_N disables the window */ 1251 for (win = 0; win < h->memwins; win++) { 1252 tcic_write_ind_2(h, TCIC_WR_MBASE_N((win<<1)+h->sock), 0); 1253 } 1254 /* writing to WR_IBASE_N disables the window */ 1255 for (win = 0; win < TCIC_IO_WINS; win++) { 1256 tcic_write_ind_2(h, TCIC_WR_IBASE_N((win<<1)+h->sock), 0); 1257 } 1258 1259 /* set the card type */ 1260 1261 cardtype = pcmcia_card_gettype(h->pcmcia); 1262 1263 #if 0 1264 reg = tcic_read_ind_2(h, TCIC_IR_SCF1_N(h->sock)); 1265 reg &= ~TCIC_SCF1_IRQ_MASK; 1266 #else 1267 reg = 0; 1268 #endif 1269 reg |= ((cardtype == PCMCIA_IFTYPE_IO) ? 1270 TCIC_SCF1_IOSTS : 0); 1271 reg |= tcic_irqmap[h->ih_irq]; /* enable interrupts */ 1272 reg &= ~TCIC_SCF1_IRQOD; 1273 tcic_write_ind_2(h, TCIC_IR_SCF1_N(h->sock), reg); 1274 1275 DPRINTF(("%s: tcic_chip_socket_enable %d cardtype %s 0x%02x\n", 1276 h->sc->dev.dv_xname, h->sock, 1277 ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), reg)); 1278 1279 /* reinstall all the memory and io mappings */ 1280 1281 for (win = 0; win < h->memwins; win++) 1282 if (h->memalloc & (1 << win)) 1283 tcic_chip_do_mem_map(h, win); 1284 1285 for (win = 0; win < TCIC_IO_WINS; win++) 1286 if (h->ioalloc & (1 << win)) 1287 tcic_chip_do_io_map(h, win); 1288 } 1289 1290 void 1291 tcic_chip_socket_disable(pcmcia_chipset_handle_t pch) 1292 { 1293 struct tcic_handle *h = (struct tcic_handle *) pch; 1294 int val; 1295 1296 DPRINTF(("tcic_chip_socket_disable\n")); 1297 1298 tcic_sel_sock(h); 1299 1300 /* disable interrupts */ 1301 val = tcic_read_ind_2(h, TCIC_IR_SCF1_N(h->sock)); 1302 val &= TCIC_SCF1_IRQ_MASK; 1303 tcic_write_ind_2(h, TCIC_IR_SCF1_N(h->sock), val); 1304 1305 /* disable the output signals */ 1306 tcic_write_1(h, TCIC_R_SCTRL, 0); 1307 val = tcic_read_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK); 1308 val &= ~TCIC_ILOCK_CRESENA; 1309 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, val); 1310 1311 /* power down the socket */ 1312 tcic_write_1(h, TCIC_R_PWR, 0); 1313 } 1314 1315 /* 1316 * XXX The following is Linux driver but doesn't match the table 1317 * in the manual. 1318 */ 1319 int 1320 tcic_ns2wscnt(int ns) 1321 { 1322 if (ns < 14) { 1323 return 0; 1324 } else { 1325 return (2*(ns-14))/70; /* XXX assumes 14.31818 MHz clock. */ 1326 } 1327 } 1328 1329 int 1330 tcic_log2(u_int val) 1331 { 1332 int i, l2; 1333 1334 l2 = i = 0; 1335 while (val) { 1336 if (val & 1) 1337 l2 = i; 1338 i++; 1339 val >>= 1; 1340 } 1341 return l2; 1342 } 1343