[BACK]Return to pxa2x0_mmc.c CVS log [TXT][DIR] Up to [local] / sys / arch / arm / xscale

Annotation of sys/arch/arm/xscale/pxa2x0_mmc.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: pxa2x0_mmc.c,v 1.2 2007/03/18 22:14:52 deraadt Exp $  */
                      2:
                      3: /*
                      4:  * Copyright (c) 2007 Uwe Stuehler <uwe@openbsd.org>
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
                     19: /*
                     20:  * MMC/SD/SDIO controller driver for Intel PXA27x processors
                     21:  *
                     22:  * Power management is beyond control of the processor's SD/SDIO/MMC
                     23:  * block, so this driver depends on the attachment driver to provide
                     24:  * us with some callback functions via the "tag" member in our softc.
                     25:  * Bus power management calls are then dispatched to the attachment
                     26:  * driver.
                     27:  */
                     28:
                     29: #include <sys/param.h>
                     30: #include <sys/device.h>
                     31: #include <sys/kernel.h>
                     32: #include <sys/proc.h>
                     33: #include <sys/systm.h>
                     34:
                     35: #include <machine/bus.h>
                     36:
                     37: #include <arch/arm/xscale/pxa2x0_gpio.h>
                     38: #include <arch/arm/xscale/pxa2x0reg.h>
                     39: #include <arch/arm/xscale/pxa2x0var.h>
                     40: #include <arch/arm/xscale/pxammcvar.h>
                     41:
                     42: #include <dev/sdmmc/sdmmcchip.h>
                     43: #include <dev/sdmmc/sdmmcreg.h>
                     44: #include <dev/sdmmc/sdmmcvar.h>
                     45:
                     46: /* GPIO pins */
                     47: #define PXAMMC_CARD_DETECT     9 /* XXX zaurus-specific */
                     48: #define PXAMMC_MMCLK           32
                     49: #define PXAMMC_MMCMD           112
                     50: #define PXAMMC_MMDAT0          92
                     51: #define PXAMMC_MMDAT1          109
                     52: #define PXAMMC_MMDAT2          110
                     53: #define PXAMMC_MMDAT3          111
                     54:
                     55: int    pxammc_host_reset(sdmmc_chipset_handle_t);
                     56: u_int32_t pxammc_host_ocr(sdmmc_chipset_handle_t);
                     57: int    pxammc_host_maxblklen(sdmmc_chipset_handle_t);
                     58: int    pxammc_card_detect(sdmmc_chipset_handle_t);
                     59: int    pxammc_bus_power(sdmmc_chipset_handle_t, u_int32_t);
                     60: int    pxammc_bus_clock(sdmmc_chipset_handle_t, int);
                     61: void   pxammc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *);
                     62: void   pxammc_clock_stop(struct pxammc_softc *);
                     63: void   pxammc_clock_start(struct pxammc_softc *);
                     64: int    pxammc_card_intr(void *);
                     65: int    pxammc_intr(void *);
                     66: void   pxammc_intr_cmd(struct pxammc_softc *);
                     67: void   pxammc_intr_data(struct pxammc_softc *);
                     68: void   pxammc_intr_done(struct pxammc_softc *);
                     69:
                     70: #define CSR_READ_1(sc, reg) \
                     71:        bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (reg))
                     72: #define CSR_WRITE_1(sc, reg, val) \
                     73:        bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
                     74: #define CSR_READ_4(sc, reg) \
                     75:        bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))
                     76: #define CSR_WRITE_4(sc, reg, val) \
                     77:        bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
                     78: #define CSR_SET_4(sc, reg, bits) \
                     79:        CSR_WRITE_4((sc), (reg), CSR_READ_4((sc), (reg)) | (bits))
                     80: #define CSR_CLR_4(sc, reg, bits) \
                     81:        CSR_WRITE_4((sc), (reg), CSR_READ_4((sc), (reg)) & ~(bits))
                     82:
                     83: struct sdmmc_chip_functions pxammc_functions = {
                     84:        /* host controller reset */
                     85:        pxammc_host_reset,
                     86:        /* host controller capabilities */
                     87:        pxammc_host_ocr,
                     88:        pxammc_host_maxblklen,
                     89:        /* card detection */
                     90:        pxammc_card_detect,
                     91:        /* bus power and clock frequency */
                     92:        pxammc_bus_power,
                     93:        pxammc_bus_clock,
                     94:        /* command execution */
                     95:        pxammc_exec_command
                     96: };
                     97:
                     98: struct cfdriver pxammc_cd = {
                     99:        NULL, "pxammc", DV_DULL
                    100: };
                    101:
                    102: #define SDMMC_DEBUG
                    103: #ifdef SDMMC_DEBUG
                    104: int sdhcdebug = 0;     /* XXX must be named sdhcdebug for sdmmc.c */
                    105: #define DPRINTF(n,s)   do { if ((n) <= sdhcdebug) printf s; } while (0)
                    106: #else
                    107: #define DPRINTF(n,s)   do {} while (0)
                    108: #endif
                    109:
                    110: int
                    111: pxammc_match(void)
                    112: {
                    113:        return (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X;
                    114: }
                    115:
                    116: void
                    117: pxammc_attach(struct pxammc_softc *sc, void *aux)
                    118: {
                    119:        struct pxaip_attach_args *pxa = aux;
                    120:        struct sdmmcbus_attach_args saa;
                    121:        int s;
                    122:
                    123:        /* Enable the clocks to the MMC controller. */
                    124:        pxa2x0_clkman_config(CKEN_MMC, 1);
                    125:
                    126:        sc->sc_iot = pxa->pxa_sa.sa_iot;
                    127:        if (bus_space_map(sc->sc_iot, PXA2X0_MMC_BASE, PXA2X0_MMC_SIZE, 0,
                    128:            &sc->sc_ioh) != 0) {
                    129:                printf(": can't map regs\n");
                    130:                goto fail;
                    131:        }
                    132:
                    133:        /*
                    134:         * Establish the card detection and MMC interrupt handlers and
                    135:         * mask all interrupts until we are prepared to handle them.
                    136:         */
                    137:        s = splsdmmc();
                    138:
                    139:        pxa2x0_gpio_set_function(PXAMMC_CARD_DETECT, GPIO_IN);
                    140:        sc->sc_card_ih = pxa2x0_gpio_intr_establish(PXAMMC_CARD_DETECT,
                    141:            IST_EDGE_BOTH, IPL_SDMMC, pxammc_card_intr, sc, "mmccd");
                    142:        if (sc->sc_card_ih == NULL) {
                    143:                splx(s);
                    144:                printf(": can't establish card interrupt\n");
                    145:                goto fail;
                    146:        }
                    147:        pxa2x0_gpio_intr_mask(sc->sc_card_ih);
                    148:
                    149:        sc->sc_ih = pxa2x0_intr_establish(PXA2X0_INT_MMC, IPL_SDMMC,
                    150:            pxammc_intr, sc, sc->sc_dev.dv_xname);
                    151:        if (sc->sc_ih == NULL) {
                    152:                splx(s);
                    153:                printf(": can't establish MMC interrupt\n");
                    154:                goto fail;
                    155:        }
                    156:        CSR_WRITE_4(sc, MMC_I_MASK, 0xffffffff);
                    157:
                    158:        splx(s);
                    159:
                    160:        printf(": MMC/SD/SDIO controller\n");
                    161:
                    162:        /*
                    163:         * Configure the GPIO pins.  In SD/MMC mode, all pins except
                    164:         * MMCLK are bidirectional and the direction is controlled in
                    165:         * hardware without our assistence.
                    166:         */
                    167:        pxa2x0_gpio_set_function(PXAMMC_MMCLK, GPIO_ALT_FN_2_OUT);
                    168:        pxa2x0_gpio_set_function(PXAMMC_MMCMD, GPIO_ALT_FN_1_IN);
                    169:        pxa2x0_gpio_set_function(PXAMMC_MMDAT0, GPIO_ALT_FN_1_IN);
                    170:        pxa2x0_gpio_set_function(PXAMMC_MMDAT1, GPIO_ALT_FN_1_IN);
                    171:        pxa2x0_gpio_set_function(PXAMMC_MMDAT2, GPIO_ALT_FN_1_IN);
                    172:        pxa2x0_gpio_set_function(PXAMMC_MMDAT3, GPIO_ALT_FN_1_IN);
                    173:
                    174:        /*
                    175:         * Reset the host controller and unmask normal interrupts.
                    176:         */
                    177:        (void)pxammc_host_reset(sc);
                    178:
                    179:        /*
                    180:         * Attach the generic sdmmc bus driver.
                    181:         */
                    182:        bzero(&saa, sizeof saa);
                    183:        saa.saa_busname = "sdmmc";
                    184:        saa.sct = &pxammc_functions;
                    185:        saa.sch = sc;
                    186:
                    187:        sc->sc_sdmmc = config_found(&sc->sc_dev, &saa, NULL);
                    188:        if (sc->sc_sdmmc == NULL) {
                    189:                printf("%s: can't attach bus\n", sc->sc_dev.dv_xname);
                    190:                goto fail;
                    191:        }
                    192:
                    193:        /* Enable card detection interrupt. */
                    194:        pxa2x0_gpio_intr_unmask(sc->sc_card_ih);
                    195:        return;
                    196:
                    197: fail:
                    198:        if (sc->sc_ih != NULL) {
                    199:                pxa2x0_intr_disestablish(sc->sc_ih);
                    200:                sc->sc_ih = NULL;
                    201:        }
                    202:        if (sc->sc_card_ih != NULL) {
                    203:                pxa2x0_gpio_intr_disestablish(sc->sc_card_ih);
                    204:                sc->sc_card_ih = NULL;
                    205:        }
                    206:        if (sc->sc_ioh != NULL) {
                    207:                bus_space_unmap(sc->sc_iot, sc->sc_ioh, PXA2X0_MMC_SIZE);
                    208:                sc->sc_ioh = NULL;
                    209:        }
                    210:        pxa2x0_clkman_config(CKEN_MMC, 0);
                    211: }
                    212:
                    213: int
                    214: pxammc_host_reset(sdmmc_chipset_handle_t sch)
                    215: {
                    216:        struct pxammc_softc *sc = sch;
                    217:        int s = splsdmmc();
                    218:
                    219:        /* Make sure to initialize the card before the next command. */
                    220:        CLR(sc->sc_flags, PMF_CARD_INITED);
                    221:
                    222:        /* Disable SPI mode (we don't support SPI). */
                    223:        CSR_WRITE_4(sc, MMC_SPI, 0);
                    224:
                    225:        /* Set response timeout to maximum. */
                    226:        CSR_WRITE_4(sc, MMC_RESTO, 0x7f);
                    227:
                    228:        /* Enable all interrupts. */
                    229:        CSR_WRITE_4(sc, MMC_I_MASK, 0);
                    230:
                    231:        splx(s);
                    232:        return 0;
                    233: }
                    234:
                    235: int
                    236: pxammc_host_maxblklen(sdmmc_chipset_handle_t sch)
                    237: {
                    238:        return 2048;
                    239: }
                    240:
                    241: u_int32_t
                    242: pxammc_host_ocr(sdmmc_chipset_handle_t sch)
                    243: {
                    244:        struct pxammc_softc *sc = sch;
                    245:
                    246:        if (sc->tag.get_ocr != NULL)
                    247:                return sc->tag.get_ocr(sc->tag.cookie);
                    248:
                    249:        DPRINTF(0,("%s: driver lacks get_ocr() function\n",
                    250:            sc->sc_dev.dv_xname));
                    251:        return ENXIO;
                    252: }
                    253:
                    254: int
                    255: pxammc_card_detect(sdmmc_chipset_handle_t sch)
                    256: {
                    257:        return !pxa2x0_gpio_get_bit(PXAMMC_CARD_DETECT);
                    258: }
                    259:
                    260: int
                    261: pxammc_bus_power(sdmmc_chipset_handle_t sch, u_int32_t ocr)
                    262: {
                    263:        struct pxammc_softc *sc = sch;
                    264:
                    265:        /*
                    266:         * Bus power management is beyond control of the SD/SDIO/MMC
                    267:         * block of the PXA2xx processors, so we have to hand this
                    268:         * task off to the attachment driver.
                    269:         */
                    270:        if (sc->tag.set_power != NULL)
                    271:                return sc->tag.set_power(sc->tag.cookie, ocr);
                    272:
                    273:        DPRINTF(0,("%s: driver lacks set_power() function\n",
                    274:            sc->sc_dev.dv_xname));
                    275:        return ENXIO;
                    276: }
                    277:
                    278: int
                    279: pxammc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
                    280: {
                    281:        struct pxammc_softc *sc = sch;
                    282:        int actfreq = 19500; /* KHz */
                    283:        int div = 0;
                    284:        int s;
                    285:
                    286:        s = splsdmmc();
                    287:
                    288:        /* Stop the clock and wait for the interrupt. */
                    289:        pxammc_clock_stop(sc);
                    290:
                    291:        /* Just stop the clock. */
                    292:        if (freq == 0) {
                    293:                splx(s);
                    294:                return 0;
                    295:        }
                    296:
                    297:        /*
                    298:         * PXA27x Errata...
                    299:         *
                    300:         * <snip>
                    301:         * E40. SDIO: SDIO Devices Not Working at 19.5 Mbps
                    302:         *
                    303:         * SD/SDIO controller can only support up to 9.75 Mbps data
                    304:         * transfer rate for SDIO card.
                    305:         * </snip>
                    306:         *
                    307:         * If we don't limit the frequency, CRC errors will be
                    308:         * reported by the controller after we set the bus speed.
                    309:         * XXX slow down incrementally.
                    310:         */
                    311:        if (freq > 9750)
                    312:                freq = 9750;
                    313:
                    314:        /*
                    315:         * Pick the smallest divider that produces a frequency not
                    316:         * more than `freq' KHz.
                    317:         */
                    318:        while (div < 7) {
                    319:                if (actfreq <= freq)
                    320:                        break;
                    321:                actfreq /= 2;
                    322:                div++;
                    323:        }
                    324:        if (div == 7) {
                    325:                splx(s);
                    326:                printf("%s: unsupported bus frequency of %d KHz\n",
                    327:                    sc->sc_dev.dv_xname, freq);
                    328:                return -1;
                    329:        }
                    330:
                    331:        DPRINTF(1,("pxammc_bus_clock freq=%d actfreq=%d div=%d\n",
                    332:            freq, actfreq, div));
                    333:        sc->sc_clkdiv = div;
                    334:        pxammc_clock_start(sc);
                    335:        splx(s);
                    336:        return 0;
                    337: }
                    338:
                    339: void
                    340: pxammc_exec_command(sdmmc_chipset_handle_t sch,
                    341:     struct sdmmc_command *cmd)
                    342: {
                    343:        struct pxammc_softc *sc = sch;
                    344:        u_int32_t cmdat;
                    345:        int timo;
                    346:        int s;
                    347:
                    348:        DPRINTF(1,("%s: cmd %u arg=%#x data=%#x dlen=%d flags=%#x "
                    349:            "proc=\"%s\"\n", sc->sc_dev.dv_xname, cmd->c_opcode,
                    350:            cmd->c_arg, cmd->c_data, cmd->c_datalen, cmd->c_flags,
                    351:            curproc ? curproc->p_comm : ""));
                    352:
                    353:        s = splsdmmc();
                    354:
                    355:        /* Stop the bus clock (MMCLK). [15.8.3] */
                    356:        pxammc_clock_stop(sc);
                    357:
                    358:        /* Set the command and argument. */
                    359:        CSR_WRITE_4(sc, MMC_CMD, cmd->c_opcode);
                    360:        CSR_WRITE_4(sc, MMC_ARGH, (cmd->c_arg >> 16) & 0xffff);
                    361:        CSR_WRITE_4(sc, MMC_ARGL, cmd->c_arg & 0xffff);
                    362:
                    363:        /* Set response characteristics for this command. */
                    364:        if (!ISSET(cmd->c_flags, SCF_RSP_PRESENT))
                    365:                cmdat = CMDAT_RESPONSE_FORMAT_NO;
                    366:        else if (ISSET(cmd->c_flags, SCF_RSP_136))
                    367:                cmdat = CMDAT_RESPONSE_FORMAT_R2;
                    368:        else if (!ISSET(cmd->c_flags, SCF_RSP_CRC))
                    369:                cmdat = CMDAT_RESPONSE_FORMAT_R3;
                    370:        else
                    371:                cmdat = CMDAT_RESPONSE_FORMAT_R1;
                    372:
                    373:        if (ISSET(cmd->c_flags, SCF_RSP_BSY))
                    374:                cmdat |= CMDAT_BUSY;
                    375:
                    376:        if (!ISSET(cmd->c_flags, SCF_CMD_READ))
                    377:                cmdat |= CMDAT_WRITE;
                    378:
                    379:        /* Fragment the data into proper blocks. */
                    380:        if (cmd->c_datalen > 0) {
                    381:                int blklen = MIN(cmd->c_datalen, cmd->c_blklen);
                    382:                int numblk = cmd->c_datalen / blklen;
                    383:
                    384:                if (cmd->c_datalen % blklen > 0) {
                    385:                        /* XXX: Split this command. (1.7.4) */
                    386:                        printf("%s: data not a multiple of %d bytes\n",
                    387:                            sc->sc_dev.dv_xname, blklen);
                    388:                        cmd->c_error = EINVAL;
                    389:                        splx(s);
                    390:                        return;
                    391:                }
                    392:
                    393:                CSR_WRITE_4(sc, MMC_BLKLEN, blklen);
                    394:                CSR_WRITE_4(sc, MMC_NUMBLK, numblk);
                    395:
                    396:                /* Enable data interrupts. */
                    397:                CSR_CLR_4(sc, MMC_I_MASK, MMC_I_DATA_TRAN_DONE |
                    398:                    MMC_I_RXFIFO_RD_REQ | MMC_I_TXFIFO_WR_REQ |
                    399:                    MMC_I_DAT_ERR);
                    400:
                    401:                cmd->c_resid = cmd->c_datalen;
                    402:                cmd->c_buf = cmd->c_data;
                    403:
                    404:                cmdat |= CMDAT_DATA_EN;
                    405:        } else {
                    406:                cmd->c_resid = 0;
                    407:                cmd->c_buf = NULL;
                    408:        }
                    409:
                    410:        /*
                    411:         * "After reset, the MMC card must be initialized by sending
                    412:         * 80 clocks to it on the MMCLK signal." [15.4.3.2]
                    413:         */
                    414:        if (!ISSET(sc->sc_flags, PMF_CARD_INITED)) {
                    415:                DPRINTF(1,("%s: first command\n", sc->sc_dev.dv_xname));
                    416:                cmdat |= CMDAT_INIT;
                    417:                SET(sc->sc_flags, PMF_CARD_INITED);
                    418:        }
                    419:
                    420:        /* Begin the transfer and start the bus clock. */
                    421:        CSR_WRITE_4(sc, MMC_CMDAT, cmdat);
                    422:        pxammc_clock_start(sc);
                    423:
                    424:        /* Wait for it to complete (in no more than 2 seconds). */
                    425:        CSR_CLR_4(sc, MMC_I_MASK, MMC_I_END_CMD_RES | MMC_I_RES_ERR);
                    426:        timo = 2;
                    427:        sc->sc_cmd = cmd;
                    428:        do { tsleep(sc, PWAIT, "mmcmd", hz); }
                    429:        while (sc->sc_cmd == cmd && timo-- > 0);
                    430:
                    431:        /* If it completed in time, SCF_ITSDONE is already set. */
                    432:        if (sc->sc_cmd == cmd) {
                    433:                sc->sc_cmd = NULL;
                    434:                cmd->c_error = ETIMEDOUT;
                    435:                SET(cmd->c_flags, SCF_ITSDONE);
                    436:        }
                    437:        splx(s);
                    438: }
                    439:
                    440: void
                    441: pxammc_clock_stop(struct pxammc_softc *sc)
                    442: {
                    443:        if (ISSET(CSR_READ_4(sc, MMC_STAT), STAT_CLK_EN)) {
                    444:                CSR_CLR_4(sc, MMC_I_MASK, MMC_I_CLK_IS_OFF);
                    445:                CSR_WRITE_4(sc, MMC_STRPCL, STRPCL_STOP);
                    446:                while (ISSET(CSR_READ_4(sc, MMC_STAT), STAT_CLK_EN))
                    447:                        tsleep(sc, PWAIT, "mmclk", 0);
                    448:        }
                    449: }
                    450:
                    451: void
                    452: pxammc_clock_start(struct pxammc_softc *sc)
                    453: {
                    454:        CSR_WRITE_4(sc, MMC_CLKRT, sc->sc_clkdiv);
                    455:        CSR_WRITE_4(sc, MMC_STRPCL, STRPCL_START);
                    456: }
                    457:
                    458: int
                    459: pxammc_card_intr(void *arg)
                    460: {
                    461:        struct pxammc_softc *sc = arg;
                    462:
                    463:        DPRINTF(1,("%s: card intr\n", sc->sc_dev.dv_xname));
                    464:
                    465:        /* Scan for inserted or removed cards. */
                    466:        sdmmc_needs_discover(sc->sc_sdmmc);
                    467:
                    468:        return 1;
                    469: }
                    470:
                    471: int
                    472: pxammc_intr(void *arg)
                    473: {
                    474:        struct pxammc_softc *sc = arg;
                    475:        int status;
                    476:
                    477: #define MMC_I_REG_STR  "\20\001DATADONE\002PRGDONE\003ENDCMDRES"       \
                    478:                        "\004STOPCMD\005CLKISOFF\006RXFIFO\007TXFIFO"   \
                    479:                        "\011DATERR\012RESERR\014SDIO"
                    480:
                    481:        status = CSR_READ_4(sc, MMC_I_REG) & ~CSR_READ_4(sc, MMC_I_MASK);
                    482:        DPRINTF(1,("%s: intr %b\n", sc->sc_dev.dv_xname, status,
                    483:            MMC_I_REG_STR));
                    484:
                    485:        /*
                    486:         * Notify the process waiting in pxammc_clock_stop() when
                    487:         * the clock has really stopped.
                    488:         */
                    489:        if (ISSET(status, MMC_I_CLK_IS_OFF)) {
                    490:                DPRINTF(2,("%s: clock is now off\n", sc->sc_dev.dv_xname));
                    491:                wakeup(sc);
                    492:                CSR_SET_4(sc, MMC_I_MASK, MMC_I_CLK_IS_OFF);
                    493:                CLR(status, MMC_I_CLK_IS_OFF);
                    494:        }
                    495:
                    496:        if (sc->sc_cmd == NULL)
                    497:                goto end;
                    498:
                    499:        if (ISSET(status, MMC_I_RES_ERR)) {
                    500:                CSR_SET_4(sc, MMC_I_MASK, MMC_I_RES_ERR);
                    501:                CLR(status, MMC_I_RES_ERR | MMC_I_END_CMD_RES);
                    502:                sc->sc_cmd->c_error = ENOEXEC;
                    503:                pxammc_intr_done(sc);
                    504:                goto end;
                    505:        }
                    506:
                    507:        if (ISSET(status, MMC_I_END_CMD_RES)) {
                    508:                pxammc_intr_cmd(sc);
                    509:                CSR_SET_4(sc, MMC_I_MASK, MMC_I_END_CMD_RES);
                    510:                CLR(status, MMC_I_END_CMD_RES);
                    511:                if (sc->sc_cmd == NULL)
                    512:                        goto end;
                    513:        }
                    514:
                    515:        if (ISSET(status, MMC_I_TXFIFO_WR_REQ | MMC_I_RXFIFO_RD_REQ)) {
                    516:                pxammc_intr_data(sc);
                    517:                CLR(status, MMC_I_TXFIFO_WR_REQ | MMC_I_RXFIFO_RD_REQ);
                    518:        }
                    519:
                    520:        if (ISSET(status, MMC_I_DAT_ERR)) {
                    521:                sc->sc_cmd->c_error = EIO;
                    522:                pxammc_intr_done(sc);
                    523:                CSR_SET_4(sc, MMC_I_MASK, MMC_I_DAT_ERR);
                    524:                CLR(status, MMC_I_DAT_ERR);
                    525:                goto end;
                    526:        }
                    527:
                    528:        if (ISSET(status, MMC_I_DATA_TRAN_DONE)) {
                    529:                pxammc_intr_done(sc);
                    530:                CSR_SET_4(sc, MMC_I_MASK, MMC_I_DATA_TRAN_DONE);
                    531:                CLR(status, MMC_I_DATA_TRAN_DONE);
                    532:        }
                    533:
                    534: end:
                    535:        /* Avoid further unhandled interrupts. */
                    536:        if (status != 0) {
                    537: #ifdef DIAGNOSTIC
                    538:                printf("%s: unhandled interrupt %b\n", sc->sc_dev.dv_xname,
                    539:                    status, MMC_I_REG_STR);
                    540: #endif
                    541:                CSR_SET_4(sc, MMC_I_MASK, status);
                    542:        }
                    543:
                    544:        return 1;
                    545: }
                    546:
                    547: void
                    548: pxammc_intr_cmd(struct pxammc_softc *sc)
                    549: {
                    550:        struct sdmmc_command *cmd = sc->sc_cmd;
                    551:        u_int32_t status;
                    552:        int i;
                    553:
                    554: #define MMC_STAT_STR   "\20\001READ_TIME_OUT\002TIMEOUT_RESPONSE"      \
                    555:                        "\003CRC_WRITE_ERROR\004CRC_READ_ERROR"         \
                    556:                        "\005SPI_READ_ERROR_TOKEN\006RES_CRC_ERR"       \
                    557:                        "\007XMIT_FIFO_EMPTY\010RECV_FIFO_FULL"         \
                    558:                        "\011CLK_EN\012FLASH_ERR\013SPI_WR_ERR"         \
                    559:                        "\014DATA_TRAN_DONE\015PRG_DONE\016END_CMD_RES" \
                    560:                        "\017RD_STALLED\020SDIO_INT\021SDIO_SUSPEND_ACK"
                    561:
                    562: #define STAT_ERR       (STAT_READ_TIME_OUT | STAT_TIMEOUT_RESPONSE |   \
                    563:                         STAT_CRC_WRITE_ERROR | STAT_CRC_READ_ERROR |   \
                    564:                         STAT_SPI_READ_ERROR_TOKEN | STAT_RES_CRC_ERR)
                    565:
                    566:        if (ISSET(cmd->c_flags, SCF_RSP_136)) {
                    567:                for (i = 3; i >= 0; i--) {
                    568:                        u_int32_t h = CSR_READ_4(sc, MMC_RES) & 0xffff;
                    569:                        u_int32_t l = CSR_READ_4(sc, MMC_RES) & 0xffff;
                    570:                        cmd->c_resp[i] = (h << 16) | l;
                    571:                }
                    572:                cmd->c_error = 0;
                    573:        } else if (ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
                    574:                /*
                    575:                 * Grrr... The processor manual is not clear about
                    576:                 * the layout of the response FIFO.  It just states
                    577:                 * that the FIFO is 16 bits wide, has a depth of 8,
                    578:                 * and that the CRC is not copied into the FIFO.
                    579:                 *
                    580:                 * A 16-bit word in the FIFO is filled from highest
                    581:                 * to lowest bit as the response comes in.  The two
                    582:                 * start bits and the 6 command index bits are thus
                    583:                 * stored in the upper 8 bits of the first 16-bit
                    584:                 * word that we read back from the FIFO.
                    585:                 *
                    586:                 * Since the sdmmc(4) framework expects the host
                    587:                 * controller to discard the first 8 bits of the
                    588:                 * response, what we must do is discard the upper
                    589:                 * byte of the first 16-bit word.
                    590:                 */
                    591:                u_int32_t h = CSR_READ_4(sc, MMC_RES) & 0xffff;
                    592:                u_int32_t m = CSR_READ_4(sc, MMC_RES) & 0xffff;
                    593:                u_int32_t l = CSR_READ_4(sc, MMC_RES) & 0xffff;
                    594:                cmd->c_resp[0] = h << 24 | m << 8 | l >> 8;
                    595:                for (i = 1; i < 4; i++)
                    596:                        cmd->c_resp[i] = 0;
                    597:                cmd->c_error = 0;
                    598:        }
                    599:
                    600:        status = CSR_READ_4(sc, MMC_STAT);
                    601:
                    602:        if (!ISSET(cmd->c_flags, SCF_RSP_PRESENT))
                    603:                status &= ~STAT_TIMEOUT_RESPONSE;
                    604:
                    605:        /* XXX only for R6, not for R2 */
                    606:        if (!ISSET(cmd->c_flags, SCF_RSP_IDX))
                    607:                status &= ~STAT_RES_CRC_ERR;
                    608:
                    609:        if (ISSET(status, STAT_TIMEOUT_RESPONSE))
                    610:                cmd->c_error = ETIMEDOUT;
                    611:        else if (ISSET(status, STAT_ERR))
                    612:                cmd->c_error = EIO;
                    613:
                    614:        if (cmd->c_error || cmd->c_datalen < 1)
                    615:                pxammc_intr_done(sc);
                    616: }
                    617:
                    618: void
                    619: pxammc_intr_data(struct pxammc_softc *sc)
                    620: {
                    621:        struct sdmmc_command *cmd = sc->sc_cmd;
                    622:
                    623:        DPRINTF(2,("%s: cmd %p resid %d\n", sc->sc_dev.dv_xname,
                    624:            cmd, cmd->c_resid));
                    625:
                    626:        if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
                    627:                int n;
                    628:
                    629:                n = MIN(32, cmd->c_resid);
                    630:                cmd->c_resid -= n;
                    631:                while (n-- > 0)
                    632:                        *cmd->c_buf++ = CSR_READ_1(sc, MMC_RXFIFO);
                    633:
                    634:                if (cmd->c_resid > 0)
                    635:                        CSR_CLR_4(sc, MMC_I_MASK, MMC_I_RXFIFO_RD_REQ);
                    636:                else
                    637:                        CSR_SET_4(sc, MMC_I_MASK, MMC_I_RXFIFO_RD_REQ);
                    638:        } else {
                    639:                int n;
                    640:                int short_xfer = cmd->c_resid < 32;
                    641:
                    642:                n = MIN(32, cmd->c_resid);
                    643:                cmd->c_resid -= n;
                    644:                for (n = MIN(32, cmd->c_resid); n > 0; n--)
                    645:                        CSR_WRITE_1(sc, MMC_TXFIFO, *cmd->c_buf++);
                    646:                if (short_xfer)
                    647:                        CSR_WRITE_4(sc, MMC_PRTBUF, 1);
                    648:
                    649:                if (cmd->c_resid > 0)
                    650:                        CSR_CLR_4(sc, MMC_I_MASK, MMC_I_TXFIFO_WR_REQ);
                    651:                else
                    652:                        CSR_SET_4(sc, MMC_I_MASK, MMC_I_TXFIFO_WR_REQ);
                    653:        }
                    654: }
                    655:
                    656: /*
                    657:  * Wake up the process sleeping in pxammc_exec_command().
                    658:  */
                    659: void
                    660: pxammc_intr_done(struct pxammc_softc *sc)
                    661: {
                    662:        u_int32_t status;
                    663:
                    664:        status = CSR_READ_4(sc, MMC_STAT);
                    665:        DPRINTF(1,("%s: status %b\n", sc->sc_dev.dv_xname,
                    666:            status, MMC_STAT_STR));
                    667:
                    668:        CSR_SET_4(sc, MMC_I_MASK, MMC_I_TXFIFO_WR_REQ |
                    669:            MMC_I_RXFIFO_RD_REQ | MMC_I_DATA_TRAN_DONE |
                    670:            MMC_I_END_CMD_RES | MMC_I_RES_ERR | MMC_I_DAT_ERR);
                    671:
                    672:        SET(sc->sc_cmd->c_flags, SCF_ITSDONE);
                    673:        sc->sc_cmd = NULL;
                    674:        wakeup(sc);
                    675: }

CVSweb