[BACK]Return to tcic2.c CVS log [TXT][DIR] Up to [local] / sys / dev / ic

Annotation of sys/dev/ic/tcic2.c, Revision 1.1.1.1

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

CVSweb