[BACK]Return to omap3_sdhc.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / arm / omap

Annotation of src/sys/arch/arm/omap/omap3_sdhc.c, Revision 1.28

1.28    ! christos    1: /*     $NetBSD: omap3_sdhc.c,v 1.27 2016/10/05 13:12:08 kiyohara Exp $ */
1.1       matt        2: /*-
                      3:  * Copyright (c) 2011 The NetBSD Foundation, Inc.
                      4:  * All rights reserved.
                      5:  *
                      6:  * This code is derived from software contributed to The NetBSD Foundation
                      7:  * by Matt Thomas of 3am Software Foundry.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  *
                     18:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     19:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     20:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     21:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     22:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     23:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     24:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     25:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     26:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     27:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     28:  * POSSIBILITY OF SUCH DAMAGE.
                     29:  */
                     30:
                     31: #include <sys/cdefs.h>
1.28    ! christos   32: __KERNEL_RCSID(0, "$NetBSD: omap3_sdhc.c,v 1.27 2016/10/05 13:12:08 kiyohara Exp $");
1.1       matt       33:
                     34: #include "opt_omap.h"
1.16      bouyer     35: #include "edma.h"
1.1       matt       36:
                     37: #include <sys/param.h>
                     38: #include <sys/systm.h>
                     39: #include <sys/device.h>
1.26      kiyohara   40: #include <sys/errno.h>
1.1       matt       41: #include <sys/kernel.h>
                     42: #include <sys/proc.h>
                     43: #include <sys/queue.h>
1.16      bouyer     44: #include <sys/mutex.h>
                     45: #include <sys/condvar.h>
1.1       matt       46: #include <sys/bus.h>
                     47:
                     48: #include <arm/omap/omap2_obiovar.h>
1.5       matt       49: #include <arm/omap/omap2_reg.h>
1.1       matt       50: #include <arm/omap/omap3_sdmmcreg.h>
                     51:
1.4       riastrad   52: #ifdef TI_AM335X
1.26      kiyohara   53: #  include <arm/mainbus/mainbus.h>
1.4       riastrad   54: #  include <arm/omap/am335x_prcm.h>
                     55: #  include <arm/omap/omap2_prcm.h>
1.26      kiyohara   56: #  include <arm/omap/omap_var.h>
1.19      jmcneill   57: #  include <arm/omap/sitara_cm.h>
                     58: #  include <arm/omap/sitara_cmreg.h>
1.4       riastrad   59: #endif
                     60:
1.16      bouyer     61: #if NEDMA > 0
                     62: #  include <arm/omap/omap_edma.h>
                     63: #endif
                     64:
1.1       matt       65: #include <dev/sdmmc/sdhcreg.h>
                     66: #include <dev/sdmmc/sdhcvar.h>
1.16      bouyer     67: #include <dev/sdmmc/sdmmcvar.h>
                     68:
                     69: #ifdef TI_AM335X
                     70: #define EDMA_MAX_PARAMS                32
                     71: #endif
                     72:
                     73: #ifdef OM3SDHC_DEBUG
                     74: int om3sdhcdebug = 1;
                     75: #define DPRINTF(n,s)    do { if ((n) <= om3sdhcdebug) device_printf s; } while (0)
                     76: #else
                     77: #define DPRINTF(n,s)    do {} while (0)
                     78: #endif
                     79:
1.1       matt       80:
1.2       kiyohara   81: #define CLKD(kz)       (sc->sc.sc_clkbase / (kz))
                     82:
                     83: #define SDHC_READ(sc, reg) \
                     84:        bus_space_read_4((sc)->sc_bst, (sc)->sc_sdhc_bsh, (reg))
                     85: #define SDHC_WRITE(sc, reg, val) \
                     86:        bus_space_write_4((sc)->sc_bst, (sc)->sc_sdhc_bsh, (reg), (val))
                     87:
1.26      kiyohara   88: struct mmchs_softc {
1.1       matt       89:        struct sdhc_softc       sc;
1.26      kiyohara   90:        bus_addr_t              sc_addr;
1.1       matt       91:        bus_space_tag_t         sc_bst;
                     92:        bus_space_handle_t      sc_bsh;
1.22      kiyohara   93:        bus_space_handle_t      sc_hl_bsh;
1.1       matt       94:        bus_space_handle_t      sc_sdhc_bsh;
                     95:        struct sdhc_host        *sc_hosts[1];
1.26      kiyohara   96:        int                     sc_irq;
1.1       matt       97:        void                    *sc_ih;         /* interrupt vectoring */
1.16      bouyer     98:
                     99: #if NEDMA > 0
1.26      kiyohara  100:        int                     sc_edmabase;
1.16      bouyer    101:        struct edma_channel     *sc_edma_tx;
                    102:        struct edma_channel     *sc_edma_rx;
                    103:        uint16_t                sc_edma_param_tx[EDMA_MAX_PARAMS];
                    104:        uint16_t                sc_edma_param_rx[EDMA_MAX_PARAMS];
                    105:        kcondvar_t              sc_edma_cv;
                    106:        bus_addr_t              sc_edma_fifo;
                    107:        bool                    sc_edma_pending;
1.18      jmcneill  108:        bus_dmamap_t            sc_edma_dmamap;
                    109:        bus_dma_segment_t       sc_edma_segs[1];
                    110:        void                    *sc_edma_bbuf;
1.16      bouyer    111: #endif
1.1       matt      112: };
                    113:
1.26      kiyohara  114: static int obiosdhc_match(device_t, cfdata_t, void *);
                    115: static void obiosdhc_attach(device_t, device_t, void *);
                    116: #ifdef TI_AM335X
                    117: static int mainbussdhc_match(device_t, cfdata_t, void *);
                    118: static void mainbussdhc_attach(device_t, device_t, void *);
                    119: #endif
                    120: static int mmchs_detach(device_t, int);
                    121:
                    122: static int mmchs_attach(struct mmchs_softc *);
                    123: static void mmchs_init(device_t);
                    124:
                    125: static int mmchs_bus_width(struct sdhc_softc *, int);
                    126: static int mmchs_rod(struct sdhc_softc *, int);
                    127: static int mmchs_write_protect(struct sdhc_softc *);
                    128: static int mmchs_card_detect(struct sdhc_softc *);
                    129:
1.16      bouyer    130: #if NEDMA > 0
1.26      kiyohara  131: static int mmchs_edma_init(struct mmchs_softc *, unsigned int);
                    132: static int mmchs_edma_xfer_data(struct sdhc_softc *, struct sdmmc_command *);
                    133: static void mmchs_edma_done(void *);
                    134: static int mmchs_edma_transfer(struct sdhc_softc *, struct sdmmc_command *);
1.16      bouyer    135: #endif
                    136:
1.4       riastrad  137: #ifdef TI_AM335X
1.26      kiyohara  138: struct am335x_mmchs {
1.4       riastrad  139:        const char *as_name;
1.26      kiyohara  140:        const char *as_parent_name;
1.4       riastrad  141:        bus_addr_t as_base_addr;
                    142:        int as_intr;
                    143:        struct omap_module as_module;
                    144: };
                    145:
1.26      kiyohara  146: static const struct am335x_mmchs am335x_mmchs[] = {
                    147:        { "MMCHS0", "obio",
                    148:            SDMMC1_BASE_TIAM335X, 64, { AM335X_PRCM_CM_PER, 0x3c } },
                    149:        { "MMC1",   "obio",
                    150:            SDMMC2_BASE_TIAM335X, 28, { AM335X_PRCM_CM_PER, 0xf4 } },
                    151:        { "MMCHS2", "mainbus",
                    152:            SDMMC3_BASE_TIAM335X, 29, { AM335X_PRCM_CM_PER, 0xf8 } },
1.4       riastrad  153: };
1.19      jmcneill  154:
                    155: struct am335x_padconf {
                    156:        const char *padname;
                    157:        const char *padmode;
                    158: };
                    159: const struct am335x_padconf am335x_padconf_mmc1[] = {
                    160:        { "GPMC_CSn1", "mmc1_clk" },
                    161:        { "GPMC_CSn2", "mmc1_cmd" },
                    162:        { "GPMC_AD0", "mmc1_dat0" },
                    163:        { "GPMC_AD1", "mmc1_dat1" },
                    164:        { "GPMC_AD2", "mmc1_dat2" },
                    165:        { "GPMC_AD3", "mmc1_dat3" },
                    166:        { "GPMC_AD4", "mmc1_dat4" },
                    167:        { "GPMC_AD5", "mmc1_dat5" },
                    168:        { "GPMC_AD6", "mmc1_dat6" },
                    169:        { "GPMC_AD7", "mmc1_dat7" },
                    170:        { NULL, NULL }
                    171: };
1.4       riastrad  172: #endif
                    173:
1.26      kiyohara  174: CFATTACH_DECL_NEW(obiosdhc, sizeof(struct mmchs_softc),
                    175:     obiosdhc_match, obiosdhc_attach, mmchs_detach, NULL);
1.1       matt      176:
                    177: static int
                    178: obiosdhc_match(device_t parent, cfdata_t cf, void *aux)
                    179: {
                    180:        struct obio_attach_args * const oa = aux;
1.28    ! christos  181:        __USE(oa);      // Simpler than complex ifdef.
1.1       matt      182:
1.3       khorben   183: #if defined(OMAP_3430)
                    184:        if (oa->obio_addr == SDMMC1_BASE_3430
                    185:            || oa->obio_addr == SDMMC2_BASE_3430
                    186:            || oa->obio_addr == SDMMC3_BASE_3430)
1.22      kiyohara  187:                return 1;
1.3       khorben   188: #elif defined(OMAP_3530)
1.1       matt      189:        if (oa->obio_addr == SDMMC1_BASE_3530
                    190:            || oa->obio_addr == SDMMC2_BASE_3530
                    191:            || oa->obio_addr == SDMMC3_BASE_3530)
1.22      kiyohara  192:                return 1;
1.14      matt      193: #elif defined(OMAP4) || defined(OMAP5)
1.11      matt      194:        if (oa->obio_addr == SDMMC1_BASE_4430
                    195:            || oa->obio_addr == SDMMC2_BASE_4430
                    196:            || oa->obio_addr == SDMMC3_BASE_4430
                    197:            || oa->obio_addr == SDMMC4_BASE_4430
                    198:            || oa->obio_addr == SDMMC5_BASE_4430)
1.22      kiyohara  199:                return 1;
1.1       matt      200: #endif
                    201:
1.4       riastrad  202: #ifdef TI_AM335X
1.28    ! christos  203:        for (size _t i = 0; i < __arraycount(am335x_mmchs); i++)
1.26      kiyohara  204:                if (device_is_a(parent, am335x_mmchs[i].as_parent_name) &&
                    205:                    (oa->obio_addr == am335x_mmchs[i].as_base_addr) &&
                    206:                    (oa->obio_intr == am335x_mmchs[i].as_intr))
1.4       riastrad  207:                        return 1;
                    208: #endif
                    209:
1.22      kiyohara  210:        return 0;
1.1       matt      211: }
                    212:
                    213: static void
                    214: obiosdhc_attach(device_t parent, device_t self, void *aux)
                    215: {
1.26      kiyohara  216:        struct mmchs_softc * const sc = device_private(self);
1.1       matt      217:        struct obio_attach_args * const oa = aux;
1.26      kiyohara  218:        int error;
                    219:
                    220:        sc->sc.sc_dmat = oa->obio_dmat;
                    221:        sc->sc.sc_dev = self;
                    222:        sc->sc_addr = oa->obio_addr;
                    223:        sc->sc_bst = oa->obio_iot;
                    224:        sc->sc_irq = oa->obio_intr;
                    225: #if defined(TI_AM335X)
                    226:        sc->sc_edmabase = oa->obio_edmabase;
                    227: #endif
                    228:
                    229: #if defined(TI_AM335X)
                    230:        error = bus_space_map(sc->sc_bst, oa->obio_addr + OMAP4_SDMMC_HL_SIZE,
                    231:            oa->obio_size - OMAP4_SDMMC_HL_SIZE, 0, &sc->sc_bsh);
                    232: #elif defined(OMAP4)
                    233:        error = bus_space_map(sc->sc_bst, oa->obio_addr, oa->obio_size, 0,
                    234:            &sc->sc_hl_bsh);
                    235:        if (error == 0)
                    236:                error = bus_space_subregion(sc->sc_bst, sc->sc_hl_bsh,
                    237:                    OMAP4_SDMMC_HL_SIZE, oa->obio_size - OMAP4_SDMMC_HL_SIZE,
                    238:                    &sc->sc_bsh);
                    239: #else
                    240:        error = bus_space_map(sc->sc_bst, oa->obio_addr, oa->obio_size, 0,
                    241:            &sc->sc_bsh);
1.22      kiyohara  242: #endif
1.26      kiyohara  243:        if (error != 0) {
                    244:                aprint_error("can't map registers: %d\n", error);
                    245:                return;
                    246:        }
                    247:
                    248:        if (mmchs_attach(sc) == 0)
                    249:                mmchs_init(self);
                    250: }
                    251:
1.4       riastrad  252: #ifdef TI_AM335X
1.26      kiyohara  253: CFATTACH_DECL_NEW(mainbussdhc, sizeof(struct mmchs_softc),
                    254:     mainbussdhc_match, mainbussdhc_attach, mmchs_detach, NULL);
                    255:
                    256: static int
                    257: mainbussdhc_match(device_t parent, cfdata_t cf, void *aux)
                    258: {
                    259:        struct mainbus_attach_args * const mb = aux;
                    260:        int i;
                    261:
                    262:        for (i = 0; i < __arraycount(am335x_mmchs); i++)
                    263:                if (device_is_a(parent, am335x_mmchs[i].as_parent_name) &&
                    264:                    (mb->mb_iobase == am335x_mmchs[i].as_base_addr) &&
                    265:                    (mb->mb_irq == am335x_mmchs[i].as_intr))
                    266:                        return 1;
                    267:        return 0;
                    268: }
                    269:
                    270: static void
                    271: mainbussdhc_attach(device_t parent, device_t self, void *aux)
                    272: {
                    273:        struct mmchs_softc * const sc = device_private(self);
                    274:        struct mainbus_attach_args * const mb = aux;
                    275:        int error;
                    276:
                    277:        sc->sc.sc_dmat = &omap_bus_dma_tag;
                    278:        sc->sc.sc_dev = self;
                    279:        sc->sc_addr = mb->mb_iobase;
                    280:        sc->sc_bst = &omap_bs_tag;
                    281:        sc->sc_irq = mb->mb_irq;
                    282:        sc->sc_edmabase = -1;
                    283:
                    284:        error = bus_space_map(sc->sc_bst, mb->mb_iobase + OMAP4_SDMMC_HL_SIZE,
                    285:            mb->mb_iosize - OMAP4_SDMMC_HL_SIZE, 0, &sc->sc_bsh);
                    286:        if (error != 0) {
                    287:                aprint_error("can't map registers: %d\n", error);
                    288:                return;
                    289:        }
                    290:
                    291:        if (mmchs_attach(sc) == 0)
                    292:                /* Ensure attach prcm, icu and edma. */
                    293:                config_defer(self, mmchs_init);
                    294: }
1.4       riastrad  295: #endif
1.1       matt      296:
1.26      kiyohara  297: static int
                    298: mmchs_attach(struct mmchs_softc *sc)
                    299: {
                    300:        device_t dev = sc->sc.sc_dev;
                    301:        prop_dictionary_t prop = device_properties(dev);
                    302:        int error;
                    303:        bool support8bit = false, dualvolt = false;
                    304:
1.10      jmcneill  305:        prop_dictionary_get_bool(prop, "8bit", &support8bit);
1.26      kiyohara  306:        prop_dictionary_get_bool(prop, "dual-volt", &dualvolt);
1.10      jmcneill  307:
1.1       matt      308:        sc->sc.sc_flags |= SDHC_FLAG_32BIT_ACCESS;
                    309:        sc->sc.sc_flags |= SDHC_FLAG_NO_LED_ON;
1.2       kiyohara  310:        sc->sc.sc_flags |= SDHC_FLAG_RSP136_CRC;
1.10      jmcneill  311:        if (support8bit)
                    312:                sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE;
1.26      kiyohara  313: #if defined(OMAP_3430)
1.22      kiyohara  314:        sc->sc.sc_flags |= SDHC_FLAG_SINGLE_ONLY;
                    315: #elif defined(OMAP_3530) || defined(TI_DM37XX)
                    316:        /*
                    317:         * Advisory 2.1.1.128: MMC: Multiple Block Read Operation Issue
                    318:         * from "OMAP3530/25/15/03 Applications Processor Silicon Revisions
                    319:         * 3.1.2, 3.1, 3.0, 2.1, and 2.0".
                    320:         */
                    321:        switch (omap_devid()) {
                    322:        case DEVID_OMAP35X_ES10:
                    323:        case DEVID_OMAP35X_ES20:
                    324:        case DEVID_OMAP35X_ES21:
                    325:        case DEVID_AMDM37X_ES10:        /* XXXX ? */
                    326:        case DEVID_AMDM37X_ES11:        /* XXXX ? */
                    327:        case DEVID_AMDM37X_ES12:        /* XXXX ? */
                    328:                sc->sc.sc_flags |= SDHC_FLAG_SINGLE_ONLY;
                    329:                break;
                    330:        default:
                    331:                break;
                    332:        }
                    333:        sc->sc.sc_flags |= SDHC_FLAG_NO_HS_BIT;
                    334: #elif defined(TI_AM335X)
1.6       riastrad  335:        sc->sc.sc_flags |= SDHC_FLAG_WAIT_RESET;
1.22      kiyohara  336: #elif defined(OMAP_4430)
                    337:        /*
                    338:         * MMCHS_HCTL.HSPE Is Not Functional
                    339:         * Errata ID: i626
                    340:         *
                    341:         * Due to design issue MMCHS_HCTL.HSPE bit does not work as intended.
                    342:         * This means that the configuration must always be the normal speed
                    343:         * mode configuration (MMCHS_HCTL.HSPE=0).
                    344:         */
                    345:        sc->sc.sc_flags |= SDHC_FLAG_NO_HS_BIT;
1.8       jmcneill  346: #endif
1.1       matt      347:        sc->sc.sc_host = sc->sc_hosts;
                    348:        sc->sc.sc_clkbase = 96000;      /* 96MHZ */
1.5       matt      349:        if (!prop_dictionary_get_uint32(prop, "clkmask", &sc->sc.sc_clkmsk))
                    350:                sc->sc.sc_clkmsk = 0x0000ffc0;
1.26      kiyohara  351:        if (sc->sc_addr == SDMMC1_BASE_3530 ||
                    352:            sc->sc_addr == SDMMC1_BASE_TIAM335X ||
                    353:            sc->sc_addr == SDMMC1_BASE_4430 ||
                    354:            dualvolt)
                    355:                sc->sc.sc_caps = SDHC_VOLTAGE_SUPP_3_0V;
                    356:        sc->sc.sc_vendor_rod = mmchs_rod;
                    357:        sc->sc.sc_vendor_write_protect = mmchs_write_protect;
                    358:        sc->sc.sc_vendor_card_detect = mmchs_card_detect;
                    359:        sc->sc.sc_vendor_bus_width = mmchs_bus_width;
                    360:
                    361:        error = bus_space_subregion(sc->sc_bst, sc->sc_bsh,
                    362:            OMAP3_SDMMC_SDHC_OFFSET, OMAP3_SDMMC_SDHC_SIZE, &sc->sc_sdhc_bsh);
                    363:        if (error != 0) {
                    364:                aprint_error("can't map subregion: %d\n", error);
                    365:                return -1;
                    366:        }
                    367:
                    368:        aprint_naive("\n");
                    369:        aprint_normal(": SDHC controller\n");
1.1       matt      370:
1.26      kiyohara  371:        return 0;
                    372: }
1.2       kiyohara  373:
1.26      kiyohara  374: static void
                    375: mmchs_init(device_t dev)
                    376: {
                    377:        struct mmchs_softc * const sc = device_private(dev);
                    378:        uint32_t clkd, stat;
                    379:        int error, timo, clksft, n;
                    380: #if defined(OMAP4)
                    381:        uint32_t rev, hwinfo;
                    382:        int x, y;
                    383: #elif defined(TI_AM335X)
                    384:        int i;
1.21      kiyohara  385: #endif
1.1       matt      386:
1.16      bouyer    387: #if NEDMA > 0
1.26      kiyohara  388:        if (sc->sc_edmabase != -1) {
                    389:                if (mmchs_edma_init(sc, sc->sc_edmabase) != 0)
1.18      jmcneill  390:                        goto no_dma;
                    391:
1.16      bouyer    392:                cv_init(&sc->sc_edma_cv, "sdhcedma");
1.26      kiyohara  393:                sc->sc_edma_fifo = sc->sc_addr +
1.22      kiyohara  394: #ifdef TI_AM335X
                    395:                    OMAP4_SDMMC_HL_SIZE +
                    396: #endif
                    397:                    OMAP3_SDMMC_SDHC_OFFSET + SDHC_DATA;
1.16      bouyer    398:                sc->sc.sc_flags |= SDHC_FLAG_USE_DMA;
                    399:                sc->sc.sc_flags |= SDHC_FLAG_EXTERNAL_DMA;
                    400:                sc->sc.sc_flags |= SDHC_FLAG_EXTDMA_DMAEN;
1.26      kiyohara  401:                sc->sc.sc_vendor_transfer_data_dma = mmchs_edma_xfer_data;
1.22      kiyohara  402:                aprint_normal_dev(sc->sc.sc_dev,
                    403:                    "EDMA tx channel %d, rx channel %d\n",
                    404:                    edma_channel_index(sc->sc_edma_tx),
                    405:                    edma_channel_index(sc->sc_edma_rx));
1.26      kiyohara  406:        }
                    407: no_dma:
1.22      kiyohara  408: #endif
                    409:
1.26      kiyohara  410:        /* XXXXXX: Turn-on regulator via I2C. */
                    411:        /* XXXXXX: And enable ICLOCK/FCLOCK. */
                    412:
1.4       riastrad  413: #ifdef TI_AM335X
                    414:        /* XXX Not really AM335X-specific.  */
1.26      kiyohara  415:        for (i = 0; i < __arraycount(am335x_mmchs); i++)
                    416:                if ((sc->sc_addr == am335x_mmchs[i].as_base_addr) &&
                    417:                    (sc->sc_irq == am335x_mmchs[i].as_intr)) {
                    418:                        prcm_module_enable(&am335x_mmchs[i].as_module);
1.4       riastrad  419:                        break;
                    420:                }
1.26      kiyohara  421:        KASSERT(i < __arraycount(am335x_mmchs));
1.19      jmcneill  422:
1.26      kiyohara  423:        if (sc->sc_addr == SDMMC2_BASE_TIAM335X) {
1.19      jmcneill  424:                const char *mode;
                    425:                u_int state;
1.22      kiyohara  426:
1.19      jmcneill  427:                const struct am335x_padconf *padconf = am335x_padconf_mmc1;
                    428:                for (i = 0; padconf[i].padname; i++) {
                    429:                        const char *padname = padconf[i].padname;
                    430:                        const char *padmode = padconf[i].padmode;
1.26      kiyohara  431:                        if (sitara_cm_padconf_get(padname, &mode, &state) == 0)
                    432:                                aprint_debug_dev(dev, "%s mode %s state %d\n",
1.19      jmcneill  433:                                    padname, mode, state);
                    434:                        if (sitara_cm_padconf_set(padname, padmode,
                    435:                            (1 << 4) | (1 << 5)) != 0) {
1.26      kiyohara  436:                                aprint_error_dev(dev,
                    437:                                    "can't switch %s pad from %s to %s\n",
1.19      jmcneill  438:                                    padname, mode, padmode);
                    439:                                return;
                    440:                        }
                    441:                }
                    442:        }
1.4       riastrad  443: #endif
                    444:
1.26      kiyohara  445: #if defined(OMAP4)
                    446:        rev = bus_space_read_4(sc->sc_bst, sc->sc_hl_bsh, MMCHS_HL_REV);
                    447:        hwinfo = bus_space_read_4(sc->sc_bst, sc->sc_hl_bsh, MMCHS_HL_HWINFO);
                    448:        x = 0;
                    449:        switch (hwinfo & HL_HWINFO_MEM_SIZE_MASK) {
                    450:        case HL_HWINFO_MEM_SIZE_512:  x =  512; y =  512; break;
                    451:        case HL_HWINFO_MEM_SIZE_1024: x = 1024; y = 1024; break;
                    452:        case HL_HWINFO_MEM_SIZE_2048: x = 2048; y = 2048; break;
                    453:        case HL_HWINFO_MEM_SIZE_4096: x = 4096; y = 2048; break;
                    454:        }
                    455:        if (hwinfo & HL_HWINFO_MADMA_EN) {
                    456:                sc->sc.sc_flags |= SDHC_FLAG_USE_DMA;
                    457:                sc->sc.sc_flags |= SDHC_FLAG_USE_ADMA2;
                    458:        }
                    459:        aprint_normal_dev(sc->sc.sc_dev, "IP Rev 0x%08x%s",
                    460:            rev, hwinfo & HL_HWINFO_RETMODE ? ", Retention Mode" : "");
                    461:        if (x != 0)
                    462:                aprint_normal(", %d byte FIFO, max block length %d bytes",
                    463:                    x, y);
                    464:        aprint_normal("\n");
                    465: #endif
                    466:
                    467:        SDHC_WRITE(sc, SDHC_CAPABILITIES,
                    468:            SDHC_READ(sc, SDHC_CAPABILITIES) | SDHC_VOLTAGE_SUPP_1_8V);
                    469:        if (sc->sc.sc_caps & SDHC_VOLTAGE_SUPP_3_0V)
                    470:                SDHC_WRITE(sc, SDHC_CAPABILITIES,
                    471:                    SDHC_READ(sc, SDHC_CAPABILITIES) | SDHC_VOLTAGE_SUPP_3_0V);
1.2       kiyohara  472:
                    473:        /* MMCHS Soft reset */
                    474:        bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG,
                    475:            SYSCONFIG_SOFTRESET);
                    476:        timo = 3000000; /* XXXX 3 sec. */
                    477:        while (timo--) {
                    478:                if (bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSSTATUS) &
                    479:                    SYSSTATUS_RESETDONE)
                    480:                        break;
                    481:                delay(1);
                    482:        }
                    483:        if (timo == 0)
1.27      kiyohara  484:                aprint_error_dev(dev, "Soft reset timeout\n");
1.2       kiyohara  485:        bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG,
1.27      kiyohara  486:            SYSCONFIG_ENAWAKEUP |
                    487:            SYSCONFIG_AUTOIDLE |
                    488:            SYSCONFIG_SIDLEMODE_AUTO |
                    489:            SYSCONFIG_CLOCKACTIVITY_FCLK |
                    490:            SYSCONFIG_CLOCKACTIVITY_ICLK);
1.2       kiyohara  491:
1.27      kiyohara  492:        sc->sc_ih = intr_establish(sc->sc_irq, IPL_VM, IST_LEVEL,
1.1       matt      493:            sdhc_intr, &sc->sc);
                    494:        if (sc->sc_ih == NULL) {
1.27      kiyohara  495:                aprint_error_dev(dev, "failed to establish interrupt %d\n",
                    496:                     sc->sc_irq);
                    497:                return;
1.1       matt      498:        }
                    499:
                    500:        error = sdhc_host_found(&sc->sc, sc->sc_bst, sc->sc_sdhc_bsh,
1.27      kiyohara  501:            OMAP3_SDMMC_SDHC_SIZE);
1.1       matt      502:        if (error != 0) {
1.27      kiyohara  503:                aprint_error_dev(dev, "couldn't initialize host, error=%d\n",
1.1       matt      504:                    error);
1.27      kiyohara  505:                intr_disestablish(sc->sc_ih);
                    506:                return;
1.1       matt      507:        }
1.2       kiyohara  508:
1.27      kiyohara  509:        clksft = ffs(sc->sc.sc_clkmsk) - 1;
                    510:
1.2       kiyohara  511:        /* Set SDVS 1.8v and DTW 1bit mode */
                    512:        SDHC_WRITE(sc, SDHC_HOST_CTL,
                    513:            SDHC_VOLTAGE_1_8V << (SDHC_VOLTAGE_SHIFT + 8));
                    514:        SDHC_WRITE(sc, SDHC_CLOCK_CTL,
                    515:            SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_INTCLK_ENABLE |
                    516:                                                        SDHC_SDCLK_ENABLE);
                    517:        SDHC_WRITE(sc, SDHC_HOST_CTL,
                    518:            SDHC_READ(sc, SDHC_HOST_CTL) | SDHC_BUS_POWER << 8);
                    519:        SDHC_WRITE(sc, SDHC_CLOCK_CTL,
                    520:            SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);
                    521:
                    522:        /*
                    523:         * 22.6.1.3.1.5 MMCHS Controller INIT Procedure Start
                    524:         * from 'OMAP35x Applications Processor  Technical Reference Manual'.
                    525:         *
                    526:         * During the INIT procedure, the MMCHS controller generates 80 clock
                    527:         * periods. In order to keep the 1ms gap, the MMCHS controller should
                    528:         * be configured to generate a clock whose frequency is smaller or
                    529:         * equal to 80 KHz.
                    530:         */
                    531:
                    532:        SDHC_WRITE(sc, SDHC_CLOCK_CTL,
                    533:            SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
                    534:        SDHC_WRITE(sc, SDHC_CLOCK_CTL,
                    535:            SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
                    536:        clkd = CLKD(80);
                    537:        n = 1;
                    538:        while (clkd & ~(sc->sc.sc_clkmsk >> clksft)) {
                    539:                clkd >>= 1;
                    540:                n <<= 1;
                    541:        }
                    542:        SDHC_WRITE(sc, SDHC_CLOCK_CTL,
                    543:            SDHC_READ(sc, SDHC_CLOCK_CTL) | (clkd << clksft));
                    544:        SDHC_WRITE(sc, SDHC_CLOCK_CTL,
                    545:            SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);
                    546:
                    547:        bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
                    548:            bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_INIT);
1.22      kiyohara  549:        SDHC_WRITE(sc, SDHC_TRANSFER_MODE, 0x00000000);
                    550:        delay(1000);
                    551:        stat = SDHC_READ(sc, SDHC_NINTR_STATUS);
                    552:        SDHC_WRITE(sc, SDHC_NINTR_STATUS, stat | SDHC_COMMAND_COMPLETE);
1.2       kiyohara  553:        bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
                    554:            bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) & ~CON_INIT);
1.22      kiyohara  555:        SDHC_WRITE(sc, SDHC_NINTR_STATUS, 0xffffffff);
                    556:
1.2       kiyohara  557:        SDHC_WRITE(sc, SDHC_CLOCK_CTL,
                    558:            SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
                    559:        SDHC_WRITE(sc, SDHC_CLOCK_CTL,
                    560:            SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
                    561:        SDHC_WRITE(sc, SDHC_CLOCK_CTL,
                    562:            SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);
1.22      kiyohara  563:        timo = 3000000; /* XXXX 3 sec. */
                    564:        while (--timo) {
                    565:                if (SDHC_READ(sc, SDHC_CLOCK_CTL) & SDHC_INTCLK_STABLE)
                    566:                        break;
                    567:                delay(1);
                    568:        }
                    569:        if (timo == 0)
1.26      kiyohara  570:                aprint_error_dev(dev, "ICS timeout\n");
1.2       kiyohara  571:        SDHC_WRITE(sc, SDHC_CLOCK_CTL,
                    572:            SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);
                    573:
1.25      kiyohara  574:        if (sc->sc.sc_flags & SDHC_FLAG_USE_ADMA2)
                    575:                bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
                    576:                    bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) |
                    577:                    CON_MNS);
1.1       matt      578: }
1.2       kiyohara  579:
                    580: static int
1.26      kiyohara  581: mmchs_detach(device_t self, int flags)
1.2       kiyohara  582: {
1.26      kiyohara  583: //     struct mmchs_softc *sc = device_private(self);
1.2       kiyohara  584:        int error;
                    585:
                    586:        error = config_detach_children(self, flags);
                    587:
                    588:        /* XXXXXX: Regurator turn-off via I2C. */
                    589:        /* XXXXXX: And disable ICLOCK/FCLOCK. */
                    590:
                    591:        return error;
                    592: }
                    593:
                    594: static int
1.26      kiyohara  595: mmchs_rod(struct sdhc_softc *sc, int on)
1.2       kiyohara  596: {
1.26      kiyohara  597:        struct mmchs_softc *hmsc = (struct mmchs_softc *)sc;
1.2       kiyohara  598:        uint32_t con;
                    599:
1.26      kiyohara  600:        con = bus_space_read_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON);
1.2       kiyohara  601:        if (on)
                    602:                con |= CON_OD;
                    603:        else
                    604:                con &= ~CON_OD;
1.26      kiyohara  605:        bus_space_write_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON, con);
1.2       kiyohara  606:
                    607:        return 0;
                    608: }
                    609:
                    610: static int
1.26      kiyohara  611: mmchs_write_protect(struct sdhc_softc *sc)
1.2       kiyohara  612: {
                    613:
                    614:        /* Maybe board dependent, using GPIO. Get GPIO-pin from prop? */
                    615:        return 0;       /* XXXXXXX */
                    616: }
                    617:
                    618: static int
1.26      kiyohara  619: mmchs_card_detect(struct sdhc_softc *sc)
1.2       kiyohara  620: {
                    621:
                    622:        /* Maybe board dependent, using GPIO. Get GPIO-pin from prop? */
                    623:        return 1;       /* XXXXXXXX */
                    624: }
1.5       matt      625:
                    626: static int
1.26      kiyohara  627: mmchs_bus_width(struct sdhc_softc *sc, int width)
1.19      jmcneill  628: {
1.26      kiyohara  629:        struct mmchs_softc *hmsc = (struct mmchs_softc *)sc;
1.19      jmcneill  630:        uint32_t con;
                    631:
1.26      kiyohara  632:        con = bus_space_read_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON);
1.19      jmcneill  633:        if (width == 8) {
                    634:                con |= CON_DW8;
                    635:        } else {
                    636:                con &= ~CON_DW8;
                    637:        }
1.26      kiyohara  638:        bus_space_write_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON, con);
1.19      jmcneill  639:
                    640:        return 0;
                    641: }
                    642:
1.16      bouyer    643: #if NEDMA > 0
1.18      jmcneill  644: static int
1.26      kiyohara  645: mmchs_edma_init(struct mmchs_softc *sc, unsigned int edmabase)
1.16      bouyer    646: {
1.18      jmcneill  647:        int i, error, rseg;
1.16      bouyer    648:
                    649:        /* Request tx and rx DMA channels */
                    650:        sc->sc_edma_tx = edma_channel_alloc(EDMA_TYPE_DMA, edmabase + 0,
1.26      kiyohara  651:            mmchs_edma_done, sc);
1.16      bouyer    652:        KASSERT(sc->sc_edma_tx != NULL);
                    653:        sc->sc_edma_rx = edma_channel_alloc(EDMA_TYPE_DMA, edmabase + 1,
1.26      kiyohara  654:            mmchs_edma_done, sc);
1.16      bouyer    655:        KASSERT(sc->sc_edma_rx != NULL);
                    656:
                    657:        /* Allocate some PaRAM pages */
                    658:        for (i = 0; i < __arraycount(sc->sc_edma_param_tx); i++) {
                    659:                sc->sc_edma_param_tx[i] = edma_param_alloc(sc->sc_edma_tx);
                    660:                KASSERT(sc->sc_edma_param_tx[i] != 0xffff);
                    661:        }
                    662:        for (i = 0; i < __arraycount(sc->sc_edma_param_rx); i++) {
                    663:                sc->sc_edma_param_rx[i] = edma_param_alloc(sc->sc_edma_rx);
                    664:                KASSERT(sc->sc_edma_param_rx[i] != 0xffff);
                    665:        }
                    666:
1.18      jmcneill  667:        /* Setup bounce buffer */
                    668:        error = bus_dmamem_alloc(sc->sc.sc_dmat, MAXPHYS, 32, MAXPHYS,
                    669:            sc->sc_edma_segs, 1, &rseg, BUS_DMA_WAITOK);
                    670:        if (error) {
                    671:                aprint_error_dev(sc->sc.sc_dev,
                    672:                    "couldn't allocate dmamem: %d\n", error);
                    673:                return error;
                    674:        }
                    675:        KASSERT(rseg == 1);
                    676:        error = bus_dmamem_map(sc->sc.sc_dmat, sc->sc_edma_segs, rseg, MAXPHYS,
                    677:            &sc->sc_edma_bbuf, BUS_DMA_WAITOK);
                    678:        if (error) {
                    679:                aprint_error_dev(sc->sc.sc_dev, "couldn't map dmamem: %d\n",
                    680:                    error);
                    681:                return error;
                    682:        }
                    683:        error = bus_dmamap_create(sc->sc.sc_dmat, MAXPHYS, 1, MAXPHYS, 0,
                    684:            BUS_DMA_WAITOK, &sc->sc_edma_dmamap);
                    685:        if (error) {
                    686:                aprint_error_dev(sc->sc.sc_dev, "couldn't create dmamap: %d\n",
                    687:                    error);
                    688:                return error;
                    689:        }
                    690:
                    691:        return error;
1.16      bouyer    692: }
                    693:
                    694: static int
1.26      kiyohara  695: mmchs_edma_xfer_data(struct sdhc_softc *sdhc_sc, struct sdmmc_command *cmd)
1.16      bouyer    696: {
1.26      kiyohara  697:        struct mmchs_softc *sc = device_private(sdhc_sc->sc_dev);
1.18      jmcneill  698:        const bus_dmamap_t map = cmd->c_dmamap;
                    699:        int seg, error;
                    700:        bool bounce;
                    701:
                    702:        for (bounce = false, seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) {
                    703:                if ((cmd->c_dmamap->dm_segs[seg].ds_addr & 0x1f) != 0) {
                    704:                        bounce = true;
                    705:                        break;
                    706:                }
                    707:        }
                    708:
                    709:        if (bounce) {
                    710:                error = bus_dmamap_load(sc->sc.sc_dmat, sc->sc_edma_dmamap,
                    711:                    sc->sc_edma_bbuf, MAXPHYS, NULL, BUS_DMA_WAITOK);
                    712:                if (error) {
                    713:                        device_printf(sc->sc.sc_dev,
                    714:                            "[bounce] bus_dmamap_load failed: %d\n", error);
                    715:                        return error;
                    716:                }
                    717:                if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
                    718:                        bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0,
                    719:                            MAXPHYS, BUS_DMASYNC_PREREAD);
                    720:                } else {
                    721:                        memcpy(sc->sc_edma_bbuf, cmd->c_data, cmd->c_datalen);
                    722:                        bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0,
                    723:                            MAXPHYS, BUS_DMASYNC_PREWRITE);
                    724:                }
                    725:
                    726:                cmd->c_dmamap = sc->sc_edma_dmamap;
                    727:        }
                    728:
1.26      kiyohara  729:        error = mmchs_edma_transfer(sdhc_sc, cmd);
1.18      jmcneill  730:
                    731:        if (bounce) {
                    732:                if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
                    733:                        bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0,
                    734:                            MAXPHYS, BUS_DMASYNC_POSTREAD);
                    735:                } else {
                    736:                        bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0,
                    737:                            MAXPHYS, BUS_DMASYNC_POSTWRITE);
                    738:                }
                    739:                bus_dmamap_unload(sc->sc.sc_dmat, sc->sc_edma_dmamap);
                    740:                if (ISSET(cmd->c_flags, SCF_CMD_READ) && error == 0) {
                    741:                        memcpy(cmd->c_data, sc->sc_edma_bbuf, cmd->c_datalen);
                    742:                }
                    743:
                    744:                cmd->c_dmamap = map;
                    745:        }
                    746:
                    747:        return error;
                    748: }
                    749:
                    750: static int
1.26      kiyohara  751: mmchs_edma_transfer(struct sdhc_softc *sdhc_sc, struct sdmmc_command *cmd)
1.18      jmcneill  752: {
1.26      kiyohara  753:        struct mmchs_softc *sc = device_private(sdhc_sc->sc_dev);
1.17      jmcneill  754:        kmutex_t *plock = sdhc_host_lock(sc->sc_hosts[0]);
1.16      bouyer    755:        struct edma_channel *edma;
                    756:        uint16_t *edma_param;
                    757:        struct edma_param ep;
                    758:        size_t seg;
1.18      jmcneill  759:        int error, resid = cmd->c_datalen;
1.16      bouyer    760:        int blksize = MIN(cmd->c_datalen, cmd->c_blklen);
                    761:
1.17      jmcneill  762:        KASSERT(mutex_owned(plock));
                    763:
1.16      bouyer    764:        edma = ISSET(cmd->c_flags, SCF_CMD_READ) ?
                    765:            sc->sc_edma_rx : sc->sc_edma_tx;
                    766:        edma_param = ISSET(cmd->c_flags, SCF_CMD_READ) ?
                    767:            sc->sc_edma_param_rx : sc->sc_edma_param_tx;
                    768:
                    769:        DPRINTF(1, (sc->sc.sc_dev, "edma xfer: nsegs=%d ch# %d\n",
                    770:            cmd->c_dmamap->dm_nsegs, edma_channel_index(edma)));
                    771:
                    772:        if (cmd->c_dmamap->dm_nsegs > EDMA_MAX_PARAMS) {
                    773:                return ENOMEM;
                    774:        }
                    775:
                    776:        for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) {
1.18      jmcneill  777:                KASSERT(resid > 0);
                    778:                const int xferlen = min(resid,
                    779:                    cmd->c_dmamap->dm_segs[seg].ds_len);
                    780:                KASSERT(xferlen == cmd->c_dmamap->dm_segs[seg].ds_len ||
                    781:                        seg == cmd->c_dmamap->dm_nsegs - 1);
                    782:                resid -= xferlen;
                    783:                KASSERT((xferlen & 0x3) == 0);
1.16      bouyer    784:                ep.ep_opt = __SHIFTIN(2, EDMA_PARAM_OPT_FWID) /* 32-bit */;
                    785:                ep.ep_opt |= __SHIFTIN(edma_channel_index(edma),
                    786:                                       EDMA_PARAM_OPT_TCC);
                    787:                if (seg == cmd->c_dmamap->dm_nsegs - 1) {
                    788:                        ep.ep_opt |= EDMA_PARAM_OPT_TCINTEN;
                    789:                        ep.ep_link = 0xffff;
                    790:                } else {
                    791:                        ep.ep_link = EDMA_PARAM_BASE(edma_param[seg+1]);
                    792:                }
                    793:                if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
                    794:                        ep.ep_opt |= EDMA_PARAM_OPT_SAM;
                    795:                        ep.ep_src = sc->sc_edma_fifo;
                    796:                        ep.ep_dst = cmd->c_dmamap->dm_segs[seg].ds_addr;
                    797:                } else {
                    798:                        ep.ep_opt |= EDMA_PARAM_OPT_DAM;
                    799:                        ep.ep_src = cmd->c_dmamap->dm_segs[seg].ds_addr;
                    800:                        ep.ep_dst = sc->sc_edma_fifo;
                    801:                }
                    802:
1.18      jmcneill  803:                KASSERT(xferlen <= 65536 * 4);
                    804:
                    805:                /*
                    806:                 * In constant addressing mode, the address must be aligned
                    807:                 * to 256-bits.
                    808:                 */
                    809:                KASSERT((cmd->c_dmamap->dm_segs[seg].ds_addr & 0x1f) == 0);
1.16      bouyer    810:
1.22      kiyohara  811:                /*
1.16      bouyer    812:                 * For unknown reason, the A-DMA transfers never completes for
                    813:                 * transfers larger than 64 butes. So use a AB transfer,
                    814:                 * with a 64 bytes A len
                    815:                 */
                    816:                ep.ep_bcntrld = 0;      /* not used for AB-synchronous mode */
                    817:                ep.ep_opt |= EDMA_PARAM_OPT_SYNCDIM;
1.18      jmcneill  818:                ep.ep_acnt = min(xferlen, 64);
                    819:                ep.ep_bcnt = min(xferlen, blksize) / ep.ep_acnt;
                    820:                ep.ep_ccnt = xferlen / (ep.ep_acnt * ep.ep_bcnt);
1.16      bouyer    821:                ep.ep_srcbidx = ep.ep_dstbidx = 0;
                    822:                ep.ep_srccidx = ep.ep_dstcidx = 0;
                    823:                if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
                    824:                        ep.ep_dstbidx = ep.ep_acnt;
                    825:                        ep.ep_dstcidx = ep.ep_acnt * ep.ep_bcnt;
                    826:                } else {
                    827:                        ep.ep_srcbidx = ep.ep_acnt;
                    828:                        ep.ep_srccidx = ep.ep_acnt * ep.ep_bcnt;
                    829:                }
                    830:
                    831:                edma_set_param(edma, edma_param[seg], &ep);
                    832: #ifdef OM3SDHC_DEBUG
                    833:                if (om3sdhcdebug >= 1) {
                    834:                        printf("target OPT: %08x\n", ep.ep_opt);
                    835:                        edma_dump_param(edma, edma_param[seg]);
                    836:                }
                    837: #endif
                    838:        }
                    839:
                    840:        error = 0;
                    841:        sc->sc_edma_pending = true;
                    842:        edma_transfer_enable(edma, edma_param[0]);
                    843:        while (sc->sc_edma_pending) {
1.17      jmcneill  844:                error = cv_timedwait(&sc->sc_edma_cv, plock, hz*10);
1.16      bouyer    845:                if (error == EWOULDBLOCK) {
                    846:                        device_printf(sc->sc.sc_dev, "transfer timeout!\n");
                    847:                        edma_dump(edma);
                    848:                        edma_dump_param(edma, edma_param[0]);
                    849:                        edma_halt(edma);
                    850:                        sc->sc_edma_pending = false;
                    851:                        error = ETIMEDOUT;
                    852:                        break;
                    853:                }
                    854:        }
                    855:        edma_halt(edma);
                    856:
                    857:        return error;
                    858: }
                    859:
                    860: static void
1.26      kiyohara  861: mmchs_edma_done(void *priv)
1.16      bouyer    862: {
1.26      kiyohara  863:        struct mmchs_softc *sc = priv;
1.17      jmcneill  864:        kmutex_t *plock = sdhc_host_lock(sc->sc_hosts[0]);
1.16      bouyer    865:
1.17      jmcneill  866:        mutex_enter(plock);
1.16      bouyer    867:        KASSERT(sc->sc_edma_pending == true);
                    868:        sc->sc_edma_pending = false;
                    869:        cv_broadcast(&sc->sc_edma_cv);
1.17      jmcneill  870:        mutex_exit(plock);
1.16      bouyer    871: }
                    872: #endif

CVSweb <webmaster@jp.NetBSD.org>