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