LCOV - code coverage report
Current view: top level - dev/sdmmc - sdhc.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 538 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 26 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: sdhc.c,v 1.61 2018/09/06 10:15:17 patrick Exp $       */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2006 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             :  * SD Host Controller driver based on the SD Host Controller Standard
      21             :  * Simplified Specification Version 1.00 (www.sdcard.com).
      22             :  */
      23             : 
      24             : #include <sys/param.h>
      25             : #include <sys/device.h>
      26             : #include <sys/kernel.h>
      27             : #include <sys/malloc.h>
      28             : #include <sys/proc.h>
      29             : #include <sys/systm.h>
      30             : 
      31             : #include <dev/sdmmc/sdhcreg.h>
      32             : #include <dev/sdmmc/sdhcvar.h>
      33             : #include <dev/sdmmc/sdmmcchip.h>
      34             : #include <dev/sdmmc/sdmmcreg.h>
      35             : #include <dev/sdmmc/sdmmcvar.h>
      36             : #include <dev/sdmmc/sdmmc_ioreg.h>
      37             : 
      38             : #define SDHC_COMMAND_TIMEOUT    hz
      39             : #define SDHC_BUFFER_TIMEOUT     hz
      40             : #define SDHC_TRANSFER_TIMEOUT   hz
      41             : #define SDHC_DMA_TIMEOUT        (hz*3)
      42             : 
      43             : struct sdhc_host {
      44             :         struct sdhc_softc *sc;          /* host controller device */
      45             :         struct device *sdmmc;           /* generic SD/MMC device */
      46             :         bus_space_tag_t iot;            /* host register set tag */
      47             :         bus_space_handle_t ioh;         /* host register set handle */
      48             :         u_int16_t version;              /* specification version */
      49             :         u_int clkbase;                  /* base clock frequency in KHz */
      50             :         int maxblklen;                  /* maximum block length */
      51             :         int flags;                      /* flags for this host */
      52             :         u_int32_t ocr;                  /* OCR value from capabilities */
      53             :         u_int8_t regs[14];              /* host controller state */
      54             :         u_int16_t intr_status;          /* soft interrupt status */
      55             :         u_int16_t intr_error_status;    /* soft error status */
      56             : 
      57             :         bus_dmamap_t adma_map;
      58             :         bus_dma_segment_t adma_segs[1];
      59             :         caddr_t adma2;
      60             : };
      61             : 
      62             : /* flag values */
      63             : #define SHF_USE_DMA             0x0001
      64             : #define SHF_USE_DMA64           0x0002
      65             : 
      66             : #define HREAD1(hp, reg)                                                 \
      67             :         (bus_space_read_1((hp)->iot, (hp)->ioh, (reg)))
      68             : #define HREAD2(hp, reg)                                                 \
      69             :         (bus_space_read_2((hp)->iot, (hp)->ioh, (reg)))
      70             : #define HREAD4(hp, reg)                                                 \
      71             :         (bus_space_read_4((hp)->iot, (hp)->ioh, (reg)))
      72             : #define HWRITE1(hp, reg, val)                                           \
      73             :         bus_space_write_1((hp)->iot, (hp)->ioh, (reg), (val))
      74             : #define HWRITE2(hp, reg, val)                                           \
      75             :         bus_space_write_2((hp)->iot, (hp)->ioh, (reg), (val))
      76             : #define HWRITE4(hp, reg, val)                                           \
      77             :         bus_space_write_4((hp)->iot, (hp)->ioh, (reg), (val))
      78             : #define HCLR1(hp, reg, bits)                                            \
      79             :         HWRITE1((hp), (reg), HREAD1((hp), (reg)) & ~(bits))
      80             : #define HCLR2(hp, reg, bits)                                            \
      81             :         HWRITE2((hp), (reg), HREAD2((hp), (reg)) & ~(bits))
      82             : #define HSET1(hp, reg, bits)                                            \
      83             :         HWRITE1((hp), (reg), HREAD1((hp), (reg)) | (bits))
      84             : #define HSET2(hp, reg, bits)                                            \
      85             :         HWRITE2((hp), (reg), HREAD2((hp), (reg)) | (bits))
      86             : 
      87             : int     sdhc_host_reset(sdmmc_chipset_handle_t);
      88             : u_int32_t sdhc_host_ocr(sdmmc_chipset_handle_t);
      89             : int     sdhc_host_maxblklen(sdmmc_chipset_handle_t);
      90             : int     sdhc_card_detect(sdmmc_chipset_handle_t);
      91             : int     sdhc_bus_power(sdmmc_chipset_handle_t, u_int32_t);
      92             : int     sdhc_bus_clock(sdmmc_chipset_handle_t, int, int);
      93             : int     sdhc_bus_width(sdmmc_chipset_handle_t, int);
      94             : void    sdhc_card_intr_mask(sdmmc_chipset_handle_t, int);
      95             : void    sdhc_card_intr_ack(sdmmc_chipset_handle_t);
      96             : int     sdhc_signal_voltage(sdmmc_chipset_handle_t, int);
      97             : void    sdhc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *);
      98             : int     sdhc_start_command(struct sdhc_host *, struct sdmmc_command *);
      99             : int     sdhc_wait_state(struct sdhc_host *, u_int32_t, u_int32_t);
     100             : int     sdhc_soft_reset(struct sdhc_host *, int);
     101             : int     sdhc_wait_intr_cold(struct sdhc_host *, int, int);
     102             : int     sdhc_wait_intr(struct sdhc_host *, int, int);
     103             : void    sdhc_transfer_data(struct sdhc_host *, struct sdmmc_command *);
     104             : void    sdhc_read_data(struct sdhc_host *, u_char *, int);
     105             : void    sdhc_write_data(struct sdhc_host *, u_char *, int);
     106             : int     sdhc_hibernate_init(sdmmc_chipset_handle_t, void *);
     107             : 
     108             : #ifdef SDHC_DEBUG
     109             : int sdhcdebug = 0;
     110             : #define DPRINTF(n,s)    do { if ((n) <= sdhcdebug) printf s; } while (0)
     111             : void    sdhc_dump_regs(struct sdhc_host *);
     112             : #else
     113             : #define DPRINTF(n,s)    do {} while(0)
     114             : #endif
     115             : 
     116             : struct sdmmc_chip_functions sdhc_functions = {
     117             :         /* host controller reset */
     118             :         sdhc_host_reset,
     119             :         /* host controller capabilities */
     120             :         sdhc_host_ocr,
     121             :         sdhc_host_maxblklen,
     122             :         /* card detection */
     123             :         sdhc_card_detect,
     124             :         /* bus power and clock frequency */
     125             :         sdhc_bus_power,
     126             :         sdhc_bus_clock,
     127             :         sdhc_bus_width,
     128             :         /* command execution */
     129             :         sdhc_exec_command,
     130             :         /* card interrupt */
     131             :         sdhc_card_intr_mask,
     132             :         sdhc_card_intr_ack,
     133             :         /* UHS functions */
     134             :         sdhc_signal_voltage,
     135             :         /* hibernate */
     136             :         sdhc_hibernate_init,
     137             : };
     138             : 
     139             : struct cfdriver sdhc_cd = {
     140             :         NULL, "sdhc", DV_DULL
     141             : };
     142             : 
     143             : /*
     144             :  * Called by attachment driver.  For each SD card slot there is one SD
     145             :  * host controller standard register set. (1.3)
     146             :  */
     147             : int
     148           0 : sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot,
     149             :     bus_space_handle_t ioh, bus_size_t iosize, int usedma, u_int32_t caps)
     150             : {
     151           0 :         struct sdmmcbus_attach_args saa;
     152             :         struct sdhc_host *hp;
     153             :         int error = 1;
     154             :         int max_clock;
     155             : #ifdef SDHC_DEBUG
     156             :         u_int16_t version;
     157             : 
     158             :         version = bus_space_read_2(iot, ioh, SDHC_HOST_CTL_VERSION);
     159             :         printf("%s: SD Host Specification/Vendor Version ",
     160             :             sc->sc_dev.dv_xname);
     161             :         switch(SDHC_SPEC_VERSION(version)) {
     162             :         case 0x00:
     163             :                 printf("1.0/%u\n", SDHC_VENDOR_VERSION(version));
     164             :                 break;
     165             :         default:
     166             :                 printf(">1.0/%u\n", SDHC_VENDOR_VERSION(version));
     167             :                 break;
     168             :         }
     169             : #endif
     170             : 
     171             :         /* Allocate one more host structure. */
     172           0 :         sc->sc_nhosts++;
     173           0 :         hp = malloc(sizeof(*hp), M_DEVBUF, M_WAITOK | M_ZERO);
     174           0 :         sc->sc_host[sc->sc_nhosts - 1] = hp;
     175             : 
     176             :         /* Fill in the new host structure. */
     177           0 :         hp->sc = sc;
     178           0 :         hp->iot = iot;
     179           0 :         hp->ioh = ioh;
     180             : 
     181             :         /* Store specification version. */
     182           0 :         hp->version = bus_space_read_2(iot, ioh, SDHC_HOST_CTL_VERSION);
     183             : 
     184             :         /*
     185             :          * Reset the host controller and enable interrupts.
     186             :          */
     187           0 :         (void)sdhc_host_reset(hp);
     188             : 
     189             :         /* Determine host capabilities. */
     190           0 :         if (caps == 0)
     191           0 :                 caps = HREAD4(hp, SDHC_CAPABILITIES);
     192             : 
     193             :         /* Use DMA if the host system and the controller support it. */
     194           0 :         if (usedma && ISSET(caps, SDHC_ADMA2_SUPP)) {
     195           0 :                 SET(hp->flags, SHF_USE_DMA);
     196           0 :                 if (ISSET(caps, SDHC_64BIT_DMA_SUPP))
     197           0 :                         SET(hp->flags, SHF_USE_DMA64);
     198             :         }
     199             : 
     200             :         /*
     201             :          * Determine the base clock frequency. (2.2.24)
     202             :          */
     203           0 :         if (SDHC_SPEC_VERSION(hp->version) >= SDHC_SPEC_V3) {
     204             :                 /* SDHC 3.0 supports 10-255 MHz. */
     205             :                 max_clock = 255000;
     206           0 :                 if (SDHC_BASE_FREQ_KHZ_V3(caps) != 0)
     207           0 :                         hp->clkbase = SDHC_BASE_FREQ_KHZ_V3(caps);
     208             :         } else {
     209             :                 /* SDHC 1.0/2.0 supports only 10-63 MHz. */
     210             :                 max_clock = 63000;
     211           0 :                 if (SDHC_BASE_FREQ_KHZ(caps) != 0)
     212           0 :                         hp->clkbase = SDHC_BASE_FREQ_KHZ(caps);
     213             :         }
     214           0 :         if (hp->clkbase == 0) {
     215             :                 /* Make sure we can clock down to 400 kHz. */
     216             :                 max_clock = 400 * SDHC_SDCLK_DIV_MAX_V3;
     217           0 :                 hp->clkbase = sc->sc_clkbase;
     218           0 :         }
     219           0 :         if (hp->clkbase == 0) {
     220             :                 /* The attachment driver must tell us. */
     221           0 :                 printf("%s: base clock frequency unknown\n",
     222           0 :                     sc->sc_dev.dv_xname);
     223           0 :                 goto err;
     224           0 :         } else if (hp->clkbase < 10000 || hp->clkbase > max_clock) {
     225           0 :                 printf("%s: base clock frequency out of range: %u MHz\n",
     226           0 :                     sc->sc_dev.dv_xname, hp->clkbase / 1000);
     227           0 :                 goto err;
     228             :         }
     229             : 
     230           0 :         printf("%s: SDHC %d.0, %d MHz base clock\n", DEVNAME(sc),
     231           0 :             SDHC_SPEC_VERSION(hp->version) + 1, hp->clkbase / 1000);
     232             : 
     233             :         /*
     234             :          * XXX Set the data timeout counter value according to
     235             :          * capabilities. (2.2.15)
     236             :          */
     237             : 
     238             :         /*
     239             :          * Determine SD bus voltage levels supported by the controller.
     240             :          */
     241           0 :         if (ISSET(caps, SDHC_VOLTAGE_SUPP_1_8V))
     242           0 :                 SET(hp->ocr, MMC_OCR_1_65V_1_95V);
     243           0 :         if (ISSET(caps, SDHC_VOLTAGE_SUPP_3_0V))
     244           0 :                 SET(hp->ocr, MMC_OCR_2_9V_3_0V | MMC_OCR_3_0V_3_1V);
     245           0 :         if (ISSET(caps, SDHC_VOLTAGE_SUPP_3_3V))
     246           0 :                 SET(hp->ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V);
     247             : 
     248             :         /*
     249             :          * Determine the maximum block length supported by the host
     250             :          * controller. (2.2.24)
     251             :          */
     252           0 :         switch((caps >> SDHC_MAX_BLK_LEN_SHIFT) & SDHC_MAX_BLK_LEN_MASK) {
     253             :         case SDHC_MAX_BLK_LEN_512:
     254           0 :                 hp->maxblklen = 512;
     255           0 :                 break;
     256             :         case SDHC_MAX_BLK_LEN_1024:
     257           0 :                 hp->maxblklen = 1024;
     258           0 :                 break;
     259             :         case SDHC_MAX_BLK_LEN_2048:
     260           0 :                 hp->maxblklen = 2048;
     261           0 :                 break;
     262             :         default:
     263           0 :                 hp->maxblklen = 1;
     264           0 :                 break;
     265             :         }
     266             : 
     267           0 :         if (ISSET(hp->flags, SHF_USE_DMA)) {
     268           0 :                 int rseg;
     269             : 
     270             :                 /* Allocate ADMA2 descriptor memory */
     271           0 :                 error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE,
     272             :                     PAGE_SIZE, hp->adma_segs, 1, &rseg,
     273             :                     BUS_DMA_WAITOK | BUS_DMA_ZERO);
     274           0 :                 if (error)
     275             :                         goto adma_done;
     276           0 :                 error = bus_dmamem_map(sc->sc_dmat, hp->adma_segs, rseg,
     277             :                     PAGE_SIZE, &hp->adma2, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
     278           0 :                 if (error) {
     279           0 :                         bus_dmamem_free(sc->sc_dmat, hp->adma_segs, rseg);
     280           0 :                         goto adma_done;
     281             :                 }
     282           0 :                 error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE,
     283             :                     0, BUS_DMA_WAITOK, &hp->adma_map);
     284           0 :                 if (error) {
     285           0 :                         bus_dmamem_unmap(sc->sc_dmat, hp->adma2, PAGE_SIZE);
     286           0 :                         bus_dmamem_free(sc->sc_dmat, hp->adma_segs, rseg);
     287           0 :                         goto adma_done;
     288             :                 }
     289           0 :                 error = bus_dmamap_load(sc->sc_dmat, hp->adma_map,
     290             :                     hp->adma2, PAGE_SIZE, NULL,
     291             :                     BUS_DMA_WAITOK | BUS_DMA_WRITE);
     292           0 :                 if (error) {
     293           0 :                         bus_dmamap_destroy(sc->sc_dmat, hp->adma_map);
     294           0 :                         bus_dmamem_unmap(sc->sc_dmat, hp->adma2, PAGE_SIZE);
     295           0 :                         bus_dmamem_free(sc->sc_dmat, hp->adma_segs, rseg);
     296           0 :                         goto adma_done;
     297             :                 }
     298             : 
     299             :         adma_done:
     300           0 :                 if (error) {
     301           0 :                         printf("%s: can't allocate DMA descriptor table\n",
     302           0 :                             DEVNAME(hp->sc));
     303           0 :                         CLR(hp->flags, SHF_USE_DMA);
     304           0 :                 }
     305           0 :         }
     306             : 
     307             :         /*
     308             :          * Attach the generic SD/MMC bus driver.  (The bus driver must
     309             :          * not invoke any chipset functions before it is attached.)
     310             :          */
     311           0 :         bzero(&saa, sizeof(saa));
     312           0 :         saa.saa_busname = "sdmmc";
     313           0 :         saa.sct = &sdhc_functions;
     314           0 :         saa.sch = hp;
     315           0 :         saa.caps = SMC_CAPS_4BIT_MODE;
     316           0 :         saa.dmat = sc->sc_dmat;
     317           0 :         if (ISSET(hp->flags, SHF_USE_DMA))
     318           0 :                 saa.caps |= SMC_CAPS_DMA;
     319             : 
     320           0 :         if (ISSET(caps, SDHC_HIGH_SPEED_SUPP))
     321           0 :                 saa.caps |= SMC_CAPS_SD_HIGHSPEED;
     322           0 :         if (ISSET(caps, SDHC_HIGH_SPEED_SUPP))
     323           0 :                 saa.caps |= SMC_CAPS_MMC_HIGHSPEED;
     324             : 
     325           0 :         if (SDHC_SPEC_VERSION(hp->version) >= SDHC_SPEC_V3) {
     326           0 :                 uint32_t caps2 = HREAD4(hp, SDHC_CAPABILITIES2);
     327             : 
     328           0 :                 if (ISSET(caps, SDHC_8BIT_MODE_SUPP))
     329           0 :                         saa.caps |= SMC_CAPS_8BIT_MODE;
     330             : 
     331           0 :                 if (ISSET(caps2, SDHC_DDR50_SUPP))
     332           0 :                         saa.caps |= SMC_CAPS_MMC_DDR52;
     333           0 :         }
     334             : 
     335           0 :         if (ISSET(sc->sc_flags, SDHC_F_NODDR50))
     336           0 :                 saa.caps &= ~SMC_CAPS_MMC_DDR52;
     337             : 
     338           0 :         hp->sdmmc = config_found(&sc->sc_dev, &saa, NULL);
     339           0 :         if (hp->sdmmc == NULL) {
     340             :                 error = 0;
     341           0 :                 goto err;
     342             :         }
     343             :         
     344           0 :         return 0;
     345             : 
     346             : err:
     347           0 :         free(hp, M_DEVBUF, sizeof *hp);
     348           0 :         sc->sc_host[sc->sc_nhosts - 1] = NULL;
     349           0 :         sc->sc_nhosts--;
     350           0 :         return (error);
     351           0 : }
     352             : 
     353             : int
     354           0 : sdhc_activate(struct device *self, int act)
     355             : {
     356           0 :         struct sdhc_softc *sc = (struct sdhc_softc *)self;
     357             :         struct sdhc_host *hp;
     358             :         int n, i, rv = 0;
     359             : 
     360           0 :         switch (act) {
     361             :         case DVACT_SUSPEND:
     362           0 :                 rv = config_activate_children(self, act);
     363             : 
     364             :                 /* Save the host controller state. */
     365           0 :                 for (n = 0; n < sc->sc_nhosts; n++) {
     366           0 :                         hp = sc->sc_host[n];
     367           0 :                         for (i = 0; i < sizeof hp->regs; i++)
     368           0 :                                 hp->regs[i] = HREAD1(hp, i);
     369             :                 }
     370             :                 break;
     371             :         case DVACT_RESUME:
     372             :                 /* Restore the host controller state. */
     373           0 :                 for (n = 0; n < sc->sc_nhosts; n++) {
     374           0 :                         hp = sc->sc_host[n];
     375           0 :                         (void)sdhc_host_reset(hp);
     376           0 :                         for (i = 0; i < sizeof hp->regs; i++)
     377           0 :                                 HWRITE1(hp, i, hp->regs[i]);
     378             :                 }
     379           0 :                 rv = config_activate_children(self, act);
     380           0 :                 break;
     381             :         case DVACT_POWERDOWN:
     382           0 :                 rv = config_activate_children(self, act);
     383           0 :                 sdhc_shutdown(self);
     384           0 :                 break;
     385             :         default:
     386           0 :                 rv = config_activate_children(self, act);
     387           0 :                 break;
     388             :         }
     389           0 :         return (rv);
     390             : }
     391             : 
     392             : /*
     393             :  * Shutdown hook established by or called from attachment driver.
     394             :  */
     395             : void
     396           0 : sdhc_shutdown(void *arg)
     397             : {
     398           0 :         struct sdhc_softc *sc = arg;
     399             :         struct sdhc_host *hp;
     400             :         int i;
     401             : 
     402             :         /* XXX chip locks up if we don't disable it before reboot. */
     403           0 :         for (i = 0; i < sc->sc_nhosts; i++) {
     404           0 :                 hp = sc->sc_host[i];
     405           0 :                 (void)sdhc_host_reset(hp);
     406             :         }
     407           0 : }
     408             : 
     409             : /*
     410             :  * Reset the host controller.  Called during initialization, when
     411             :  * cards are removed, upon resume, and during error recovery.
     412             :  */
     413             : int
     414           0 : sdhc_host_reset(sdmmc_chipset_handle_t sch)
     415             : {
     416           0 :         struct sdhc_host *hp = sch;
     417             :         u_int16_t imask;
     418             :         int error;
     419             :         int s;
     420             : 
     421           0 :         s = splsdmmc();
     422             : 
     423             :         /* Disable all interrupts. */
     424           0 :         HWRITE2(hp, SDHC_NINTR_SIGNAL_EN, 0);
     425             : 
     426             :         /*
     427             :          * Reset the entire host controller and wait up to 100ms for
     428             :          * the controller to clear the reset bit.
     429             :          */
     430           0 :         if ((error = sdhc_soft_reset(hp, SDHC_RESET_ALL)) != 0) {
     431           0 :                 splx(s);
     432           0 :                 return (error);
     433             :         }       
     434             : 
     435             :         /* Set data timeout counter value to max for now. */
     436           0 :         HWRITE1(hp, SDHC_TIMEOUT_CTL, SDHC_TIMEOUT_MAX);
     437             : 
     438             :         /* Enable interrupts. */
     439             :         imask = SDHC_CARD_REMOVAL | SDHC_CARD_INSERTION |
     440             :             SDHC_BUFFER_READ_READY | SDHC_BUFFER_WRITE_READY |
     441             :             SDHC_DMA_INTERRUPT | SDHC_BLOCK_GAP_EVENT |
     442             :             SDHC_TRANSFER_COMPLETE | SDHC_COMMAND_COMPLETE;
     443             : 
     444           0 :         HWRITE2(hp, SDHC_NINTR_STATUS_EN, imask);
     445           0 :         HWRITE2(hp, SDHC_EINTR_STATUS_EN, SDHC_EINTR_STATUS_MASK);
     446           0 :         HWRITE2(hp, SDHC_NINTR_SIGNAL_EN, imask);
     447           0 :         HWRITE2(hp, SDHC_EINTR_SIGNAL_EN, SDHC_EINTR_SIGNAL_MASK);
     448             : 
     449           0 :         splx(s);
     450           0 :         return 0;
     451           0 : }
     452             : 
     453             : u_int32_t
     454           0 : sdhc_host_ocr(sdmmc_chipset_handle_t sch)
     455             : {
     456           0 :         struct sdhc_host *hp = sch;
     457           0 :         return hp->ocr;
     458             : }
     459             : 
     460             : int
     461           0 : sdhc_host_maxblklen(sdmmc_chipset_handle_t sch)
     462             : {
     463           0 :         struct sdhc_host *hp = sch;
     464           0 :         return hp->maxblklen;
     465             : }
     466             : 
     467             : /*
     468             :  * Return non-zero if the card is currently inserted.
     469             :  */
     470             : int
     471           0 : sdhc_card_detect(sdmmc_chipset_handle_t sch)
     472             : {
     473           0 :         struct sdhc_host *hp = sch;
     474             : 
     475           0 :         if (hp->sc->sc_card_detect)
     476           0 :                 return hp->sc->sc_card_detect(hp->sc);
     477             : 
     478           0 :         return ISSET(HREAD4(hp, SDHC_PRESENT_STATE), SDHC_CARD_INSERTED) ?
     479             :             1 : 0;
     480           0 : }
     481             : 
     482             : /*
     483             :  * Set or change SD bus voltage and enable or disable SD bus power.
     484             :  * Return zero on success.
     485             :  */
     486             : int
     487           0 : sdhc_bus_power(sdmmc_chipset_handle_t sch, u_int32_t ocr)
     488             : {
     489           0 :         struct sdhc_host *hp = sch;
     490             :         u_int8_t vdd;
     491             :         int s;
     492             : 
     493           0 :         s = splsdmmc();
     494             : 
     495             :         /*
     496             :          * Disable bus power before voltage change.
     497             :          */
     498           0 :         if (!(hp->sc->sc_flags & SDHC_F_NOPWR0))
     499           0 :                 HWRITE1(hp, SDHC_POWER_CTL, 0);
     500             : 
     501             :         /* If power is disabled, reset the host and return now. */
     502           0 :         if (ocr == 0) {
     503           0 :                 splx(s);
     504           0 :                 (void)sdhc_host_reset(hp);
     505           0 :                 return 0;
     506             :         }
     507             : 
     508             :         /*
     509             :          * Select the maximum voltage according to capabilities.
     510             :          */
     511           0 :         ocr &= hp->ocr;
     512           0 :         if (ISSET(ocr, MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V))
     513           0 :                 vdd = SDHC_VOLTAGE_3_3V;
     514           0 :         else if (ISSET(ocr, MMC_OCR_2_9V_3_0V|MMC_OCR_3_0V_3_1V))
     515           0 :                 vdd = SDHC_VOLTAGE_3_0V;
     516           0 :         else if (ISSET(ocr, MMC_OCR_1_65V_1_95V))
     517             :                 vdd = SDHC_VOLTAGE_1_8V;
     518             :         else {
     519             :                 /* Unsupported voltage level requested. */
     520           0 :                 splx(s);
     521           0 :                 return EINVAL;
     522             :         }
     523             : 
     524             :         /*
     525             :          * Enable bus power.  Wait at least 1 ms (or 74 clocks) plus
     526             :          * voltage ramp until power rises.
     527             :          */
     528           0 :         HWRITE1(hp, SDHC_POWER_CTL, (vdd << SDHC_VOLTAGE_SHIFT) |
     529             :             SDHC_BUS_POWER);
     530           0 :         sdmmc_delay(10000);
     531             : 
     532             :         /*
     533             :          * The host system may not power the bus due to battery low,
     534             :          * etc.  In that case, the host controller should clear the
     535             :          * bus power bit.
     536             :          */
     537           0 :         if (!ISSET(HREAD1(hp, SDHC_POWER_CTL), SDHC_BUS_POWER)) {
     538             :                 splx(s);
     539           0 :                 return ENXIO;
     540             :         }
     541             : 
     542             :         splx(s);
     543           0 :         return 0;
     544           0 : }
     545             : 
     546             : /*
     547             :  * Return the smallest possible base clock frequency divisor value
     548             :  * for the CLOCK_CTL register to produce `freq' (KHz).
     549             :  */
     550             : static int
     551           0 : sdhc_clock_divisor(struct sdhc_host *hp, u_int freq)
     552             : {
     553             :         int max_div = SDHC_SDCLK_DIV_MAX;;
     554             :         int div;
     555             : 
     556           0 :         if (SDHC_SPEC_VERSION(hp->version) >= SDHC_SPEC_V3)
     557           0 :                 max_div = SDHC_SDCLK_DIV_MAX_V3;;
     558             : 
     559           0 :         for (div = 1; div <= max_div; div *= 2)
     560           0 :                 if ((hp->clkbase / div) <= freq)
     561           0 :                         return (div / 2);
     562             :         /* No divisor found. */
     563           0 :         return -1;
     564           0 : }
     565             : 
     566             : /*
     567             :  * Set or change SDCLK frequency or disable the SD clock.
     568             :  * Return zero on success.
     569             :  */
     570             : int
     571           0 : sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq, int timing)
     572             : {
     573           0 :         struct sdhc_host *hp = sch;
     574             :         int s;
     575             :         int div;
     576             :         int sdclk;
     577             :         int timo;
     578             :         int error = 0;
     579             : 
     580           0 :         s = splsdmmc();
     581             : 
     582             : #ifdef DIAGNOSTIC
     583             :         /* Must not stop the clock if commands are in progress. */
     584           0 :         if (ISSET(HREAD4(hp, SDHC_PRESENT_STATE), SDHC_CMD_INHIBIT_MASK) &&
     585           0 :             sdhc_card_detect(hp))
     586           0 :                 printf("sdhc_sdclk_frequency_select: command in progress\n");
     587             : #endif
     588             : 
     589             :         /*
     590             :          * Stop SD clock before changing the frequency.
     591             :          */
     592           0 :         HWRITE2(hp, SDHC_CLOCK_CTL, 0);
     593           0 :         if (freq == SDMMC_SDCLK_OFF)
     594             :                 goto ret;
     595             : 
     596           0 :         if (timing == SDMMC_TIMING_LEGACY)
     597           0 :                 HCLR1(hp, SDHC_HOST_CTL, SDHC_HIGH_SPEED);
     598             :         else
     599           0 :                 HSET1(hp, SDHC_HOST_CTL, SDHC_HIGH_SPEED);
     600             : 
     601           0 :         if (SDHC_SPEC_VERSION(hp->version) >= SDHC_SPEC_V3) {
     602           0 :                 switch (timing) {
     603             :                 case SDMMC_TIMING_MMC_DDR52:
     604           0 :                         HCLR2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_MASK);
     605           0 :                         HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_DDR50);
     606           0 :                         break;
     607             :                 }
     608             :         }
     609             : 
     610             :         /*
     611             :          * Set the minimum base clock frequency divisor.
     612             :          */
     613           0 :         if ((div = sdhc_clock_divisor(hp, freq)) < 0) {
     614             :                 /* Invalid base clock frequency or `freq' value. */
     615             :                 error = EINVAL;
     616           0 :                 goto ret;
     617             :         }
     618           0 :         if (SDHC_SPEC_VERSION(hp->version) >= SDHC_SPEC_V3)
     619           0 :                 sdclk = SDHC_SDCLK_DIV_V3(div);
     620             :         else
     621             :                 sdclk = SDHC_SDCLK_DIV(div);
     622           0 :         HWRITE2(hp, SDHC_CLOCK_CTL, sdclk);
     623             : 
     624             :         /*
     625             :          * Start internal clock.  Wait 10ms for stabilization.
     626             :          */
     627           0 :         HSET2(hp, SDHC_CLOCK_CTL, SDHC_INTCLK_ENABLE);
     628           0 :         for (timo = 1000; timo > 0; timo--) {
     629           0 :                 if (ISSET(HREAD2(hp, SDHC_CLOCK_CTL), SDHC_INTCLK_STABLE))
     630             :                         break;
     631           0 :                 sdmmc_delay(10);
     632             :         }
     633           0 :         if (timo == 0) {
     634             :                 error = ETIMEDOUT;
     635           0 :                 goto ret;
     636             :         }
     637             : 
     638             :         /*
     639             :          * Enable SD clock.
     640             :          */
     641           0 :         HSET2(hp, SDHC_CLOCK_CTL, SDHC_SDCLK_ENABLE);
     642             : 
     643             : ret:
     644           0 :         splx(s);
     645           0 :         return error;
     646             : }
     647             : 
     648             : int
     649           0 : sdhc_bus_width(sdmmc_chipset_handle_t sch, int width)
     650             : {
     651           0 :         struct sdhc_host *hp = (struct sdhc_host *)sch;
     652             :         int reg;
     653             :         int s;
     654             : 
     655           0 :         if (width != 1 && width != 4 && width != 8)
     656           0 :                 return EINVAL;
     657             : 
     658           0 :         s = splsdmmc();
     659             : 
     660           0 :         reg = HREAD1(hp, SDHC_HOST_CTL);
     661           0 :         reg &= ~SDHC_4BIT_MODE;
     662           0 :         if (SDHC_SPEC_VERSION(hp->version) >= SDHC_SPEC_V3) {
     663           0 :                 reg &= ~SDHC_8BIT_MODE;
     664           0 :         }
     665           0 :         if (width == 4) {
     666           0 :                 reg |= SDHC_4BIT_MODE;
     667           0 :         } else if (width == 8) {
     668           0 :                 KASSERT(SDHC_SPEC_VERSION(hp->version) >= SDHC_SPEC_V3);
     669           0 :                 reg |= SDHC_8BIT_MODE;
     670           0 :         }
     671           0 :         HWRITE1(hp, SDHC_HOST_CTL, reg);
     672             : 
     673           0 :         splx(s);
     674             : 
     675           0 :         return 0;
     676           0 : }
     677             : 
     678             : void
     679           0 : sdhc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable)
     680             : {
     681           0 :         struct sdhc_host *hp = sch;
     682             : 
     683           0 :         if (enable) {
     684           0 :                 HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
     685           0 :                 HSET2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT);
     686           0 :         } else {
     687           0 :                 HCLR2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT);
     688           0 :                 HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
     689             :         }
     690           0 : }
     691             : 
     692             : void
     693           0 : sdhc_card_intr_ack(sdmmc_chipset_handle_t sch)
     694             : {
     695           0 :         struct sdhc_host *hp = sch;
     696             : 
     697           0 :         HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
     698           0 : }
     699             : 
     700             : int
     701           0 : sdhc_signal_voltage(sdmmc_chipset_handle_t sch, int signal_voltage)
     702             : {
     703           0 :         struct sdhc_host *hp = sch;
     704             : 
     705           0 :         if (hp->sc->sc_signal_voltage)
     706           0 :                 return hp->sc->sc_signal_voltage(hp->sc, signal_voltage);
     707             : 
     708           0 :         if (SDHC_SPEC_VERSION(hp->version) < SDHC_SPEC_V3)
     709           0 :                 return EINVAL;
     710             : 
     711           0 :         switch (signal_voltage) {
     712             :         case SDMMC_SIGNAL_VOLTAGE_180:
     713           0 :                 HSET2(hp, SDHC_HOST_CTL2, SDHC_1_8V_SIGNAL_EN);
     714           0 :                 break;
     715             :         case SDMMC_SIGNAL_VOLTAGE_330:
     716           0 :                 HCLR2(hp, SDHC_HOST_CTL2, SDHC_1_8V_SIGNAL_EN);
     717           0 :                 break;
     718             :         default:
     719           0 :                 return EINVAL;
     720             :         }
     721             : 
     722             :         /* Regulator output shall be stable within 5 ms. */
     723           0 :         sdmmc_delay(5000);
     724             : 
     725             :         /* Host controller clears this bit if 1.8V signalling fails. */
     726           0 :         if (signal_voltage == SDMMC_SIGNAL_VOLTAGE_180 &&
     727           0 :             !ISSET(HREAD4(hp, SDHC_HOST_CTL2), SDHC_1_8V_SIGNAL_EN))
     728           0 :                 return EIO;
     729             : 
     730           0 :         return 0;
     731           0 : }
     732             : 
     733             : int
     734           0 : sdhc_wait_state(struct sdhc_host *hp, u_int32_t mask, u_int32_t value)
     735             : {
     736             :         u_int32_t state;
     737             :         int timeout;
     738             : 
     739           0 :         for (timeout = 10; timeout > 0; timeout--) {
     740           0 :                 if (((state = HREAD4(hp, SDHC_PRESENT_STATE)) & mask)
     741           0 :                     == value)
     742           0 :                         return 0;
     743           0 :                 sdmmc_delay(10000);
     744             :         }
     745             :         DPRINTF(0,("%s: timeout waiting for %x (state=%b)\n", DEVNAME(hp->sc),
     746             :             value, state, SDHC_PRESENT_STATE_BITS));
     747           0 :         return ETIMEDOUT;
     748           0 : }
     749             : 
     750             : void
     751           0 : sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
     752             : {
     753           0 :         struct sdhc_host *hp = sch;
     754             :         int error;
     755             : 
     756             :         /*
     757             :          * Start the MMC command, or mark `cmd' as failed and return.
     758             :          */
     759           0 :         error = sdhc_start_command(hp, cmd);
     760           0 :         if (error != 0) {
     761           0 :                 cmd->c_error = error;
     762           0 :                 SET(cmd->c_flags, SCF_ITSDONE);
     763           0 :                 return;
     764             :         }
     765             : 
     766             :         /*
     767             :          * Wait until the command phase is done, or until the command
     768             :          * is marked done for any other reason.
     769             :          */
     770           0 :         if (!sdhc_wait_intr(hp, SDHC_COMMAND_COMPLETE,
     771           0 :             SDHC_COMMAND_TIMEOUT)) {
     772           0 :                 cmd->c_error = ETIMEDOUT;
     773           0 :                 SET(cmd->c_flags, SCF_ITSDONE);
     774           0 :                 return;
     775             :         }
     776             : 
     777             :         /*
     778             :          * The host controller removes bits [0:7] from the response
     779             :          * data (CRC) and we pass the data up unchanged to the bus
     780             :          * driver (without padding).
     781             :          */
     782           0 :         if (cmd->c_error == 0 && ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
     783           0 :                 if (ISSET(cmd->c_flags, SCF_RSP_136)) {
     784           0 :                         u_char *p = (u_char *)cmd->c_resp;
     785             :                         int i;
     786             : 
     787           0 :                         for (i = 0; i < 15; i++)
     788           0 :                                 *p++ = HREAD1(hp, SDHC_RESPONSE + i);
     789           0 :                 } else
     790           0 :                         cmd->c_resp[0] = HREAD4(hp, SDHC_RESPONSE);
     791             :         }
     792             : 
     793             :         /*
     794             :          * If the command has data to transfer in any direction,
     795             :          * execute the transfer now.
     796             :          */
     797           0 :         if (cmd->c_error == 0 && cmd->c_data != NULL)
     798           0 :                 sdhc_transfer_data(hp, cmd);
     799             : 
     800             :         /* Turn off the LED. */
     801           0 :         HCLR1(hp, SDHC_HOST_CTL, SDHC_LED_ON);
     802             : 
     803             :         DPRINTF(1,("%s: cmd %u done (flags=%#x error=%d)\n",
     804             :             DEVNAME(hp->sc), cmd->c_opcode, cmd->c_flags, cmd->c_error));
     805           0 :         SET(cmd->c_flags, SCF_ITSDONE);
     806           0 : }
     807             : 
     808             : int
     809           0 : sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd)
     810             : {
     811           0 :         struct sdhc_adma2_descriptor32 *desc32 = (void *)hp->adma2;
     812           0 :         struct sdhc_adma2_descriptor64 *desc64 = (void *)hp->adma2;
     813           0 :         struct sdhc_softc *sc = hp->sc;
     814             :         u_int16_t blksize = 0;
     815             :         u_int16_t blkcount = 0;
     816             :         u_int16_t mode;
     817             :         u_int16_t command;
     818             :         int error;
     819             :         int seg;
     820             :         int s;
     821             :         
     822             :         DPRINTF(1,("%s: start cmd %u arg=%#x data=%p dlen=%d flags=%#x "
     823             :             "proc=\"%s\"\n", DEVNAME(hp->sc), cmd->c_opcode, cmd->c_arg,
     824             :             cmd->c_data, cmd->c_datalen, cmd->c_flags, curproc ?
     825             :             curproc->p_p->ps_comm : ""));
     826             : 
     827             :         /*
     828             :          * The maximum block length for commands should be the minimum
     829             :          * of the host buffer size and the card buffer size. (1.7.2)
     830             :          */
     831             : 
     832             :         /* Fragment the data into proper blocks. */
     833           0 :         if (cmd->c_datalen > 0) {
     834           0 :                 blksize = MIN(cmd->c_datalen, cmd->c_blklen);
     835           0 :                 blkcount = cmd->c_datalen / blksize;
     836           0 :                 if (cmd->c_datalen % blksize > 0) {
     837             :                         /* XXX: Split this command. (1.7.4) */
     838           0 :                         printf("%s: data not a multiple of %d bytes\n",
     839           0 :                             DEVNAME(hp->sc), blksize);
     840           0 :                         return EINVAL;
     841             :                 }
     842             :         }
     843             : 
     844             :         /* Check limit imposed by 9-bit block count. (1.7.2) */
     845           0 :         if (blkcount > SDHC_BLOCK_COUNT_MAX) {
     846           0 :                 printf("%s: too much data\n", DEVNAME(hp->sc));
     847           0 :                 return EINVAL;
     848             :         }
     849             : 
     850             :         /* Prepare transfer mode register value. (2.2.5) */
     851             :         mode = 0;
     852           0 :         if (ISSET(cmd->c_flags, SCF_CMD_READ))
     853           0 :                 mode |= SDHC_READ_MODE;
     854           0 :         if (blkcount > 0) {
     855           0 :                 mode |= SDHC_BLOCK_COUNT_ENABLE;
     856           0 :                 if (blkcount > 1) {
     857           0 :                         mode |= SDHC_MULTI_BLOCK_MODE;
     858           0 :                         if (cmd->c_opcode != SD_IO_RW_EXTENDED)
     859           0 :                                 mode |= SDHC_AUTO_CMD12_ENABLE;
     860             :                 }
     861             :         }
     862           0 :         if (cmd->c_dmamap && cmd->c_datalen > 0 &&
     863           0 :             ISSET(hp->flags, SHF_USE_DMA))
     864           0 :                 mode |= SDHC_DMA_ENABLE;
     865             : 
     866             :         /*
     867             :          * Prepare command register value. (2.2.6)
     868             :          */
     869           0 :         command = (cmd->c_opcode & SDHC_COMMAND_INDEX_MASK) <<
     870             :             SDHC_COMMAND_INDEX_SHIFT;
     871             : 
     872           0 :         if (ISSET(cmd->c_flags, SCF_RSP_CRC))
     873           0 :                 command |= SDHC_CRC_CHECK_ENABLE;
     874           0 :         if (ISSET(cmd->c_flags, SCF_RSP_IDX))
     875           0 :                 command |= SDHC_INDEX_CHECK_ENABLE;
     876           0 :         if (cmd->c_data != NULL)
     877           0 :                 command |= SDHC_DATA_PRESENT_SELECT;
     878             : 
     879           0 :         if (!ISSET(cmd->c_flags, SCF_RSP_PRESENT))
     880           0 :                 command |= SDHC_NO_RESPONSE;
     881           0 :         else if (ISSET(cmd->c_flags, SCF_RSP_136))
     882           0 :                 command |= SDHC_RESP_LEN_136;
     883           0 :         else if (ISSET(cmd->c_flags, SCF_RSP_BSY))
     884           0 :                 command |= SDHC_RESP_LEN_48_CHK_BUSY;
     885             :         else
     886           0 :                 command |= SDHC_RESP_LEN_48;
     887             : 
     888             :         /* Wait until command and data inhibit bits are clear. (1.5) */
     889           0 :         if ((error = sdhc_wait_state(hp, SDHC_CMD_INHIBIT_MASK, 0)) != 0)
     890           0 :                 return error;
     891             : 
     892           0 :         s = splsdmmc();
     893             : 
     894             :         /* Alert the user not to remove the card. */
     895           0 :         HSET1(hp, SDHC_HOST_CTL, SDHC_LED_ON);
     896             : 
     897             :         /* Set DMA start address if SHF_USE_DMA is set. */
     898           0 :         if (cmd->c_dmamap && ISSET(hp->flags, SHF_USE_DMA)) {
     899           0 :                 for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) {
     900             :                         bus_addr_t paddr =
     901           0 :                             cmd->c_dmamap->dm_segs[seg].ds_addr;
     902             :                         uint16_t len =
     903           0 :                             cmd->c_dmamap->dm_segs[seg].ds_len == 65536 ?
     904             :                             0 : cmd->c_dmamap->dm_segs[seg].ds_len;
     905             :                         uint16_t attr;
     906             : 
     907             :                         attr = SDHC_ADMA2_VALID | SDHC_ADMA2_ACT_TRANS;
     908           0 :                         if (seg == cmd->c_dmamap->dm_nsegs - 1)
     909           0 :                                 attr |= SDHC_ADMA2_END;
     910             : 
     911           0 :                         if (ISSET(hp->flags, SHF_USE_DMA64)) {
     912           0 :                                 desc64[seg].attribute = htole16(attr);
     913           0 :                                 desc64[seg].length = htole16(len);
     914           0 :                                 desc64[seg].address_lo =
     915           0 :                                     htole32((uint64_t)paddr & 0xffffffff);
     916           0 :                                 desc64[seg].address_hi =
     917           0 :                                     htole32((uint64_t)paddr >> 32);
     918           0 :                         } else {
     919           0 :                                 desc32[seg].attribute = htole16(attr);
     920           0 :                                 desc32[seg].length = htole16(len);
     921           0 :                                 desc32[seg].address = htole32(paddr);
     922             :                         }
     923             :                 }
     924             : 
     925           0 :                 if (ISSET(hp->flags, SHF_USE_DMA64))
     926           0 :                         desc64[cmd->c_dmamap->dm_nsegs].attribute = htole16(0);
     927             :                 else
     928           0 :                         desc32[cmd->c_dmamap->dm_nsegs].attribute = htole16(0);
     929             : 
     930           0 :                 bus_dmamap_sync(sc->sc_dmat, hp->adma_map, 0, PAGE_SIZE,
     931             :                     BUS_DMASYNC_PREWRITE);
     932             : 
     933           0 :                 HCLR1(hp, SDHC_HOST_CTL, SDHC_DMA_SELECT);
     934           0 :                 if (ISSET(hp->flags, SHF_USE_DMA64))
     935           0 :                         HSET1(hp, SDHC_HOST_CTL, SDHC_DMA_SELECT_ADMA64);
     936             :                 else
     937           0 :                         HSET1(hp, SDHC_HOST_CTL, SDHC_DMA_SELECT_ADMA32);
     938             : 
     939           0 :                 HWRITE4(hp, SDHC_ADMA_SYSTEM_ADDR,
     940             :                     hp->adma_map->dm_segs[0].ds_addr);
     941           0 :         } else
     942           0 :                 HCLR1(hp, SDHC_HOST_CTL, SDHC_DMA_SELECT);
     943             : 
     944             :         DPRINTF(1,("%s: cmd=%#x mode=%#x blksize=%d blkcount=%d\n",
     945             :             DEVNAME(hp->sc), command, mode, blksize, blkcount));
     946             : 
     947             :         /*
     948             :          * Start a CPU data transfer.  Writing to the high order byte
     949             :          * of the SDHC_COMMAND register triggers the SD command. (1.5)
     950             :          */
     951           0 :         HWRITE2(hp, SDHC_TRANSFER_MODE, mode);
     952           0 :         HWRITE2(hp, SDHC_BLOCK_SIZE, blksize);
     953           0 :         HWRITE2(hp, SDHC_BLOCK_COUNT, blkcount);
     954           0 :         HWRITE4(hp, SDHC_ARGUMENT, cmd->c_arg);
     955           0 :         HWRITE2(hp, SDHC_COMMAND, command);
     956             : 
     957           0 :         splx(s);
     958           0 :         return 0;
     959           0 : }
     960             : 
     961             : void
     962           0 : sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
     963             : {
     964           0 :         struct sdhc_softc *sc = hp->sc;
     965           0 :         u_char *datap = cmd->c_data;
     966             :         int i, datalen;
     967             :         int mask;
     968             :         int error;
     969             : 
     970           0 :         if (cmd->c_dmamap) {
     971             :                 int status;
     972             : 
     973             :                 error = 0;
     974           0 :                 for (;;) {
     975           0 :                         status = sdhc_wait_intr(hp,
     976             :                             SDHC_DMA_INTERRUPT|SDHC_TRANSFER_COMPLETE,
     977           0 :                             SDHC_DMA_TIMEOUT);
     978           0 :                         if (status & SDHC_TRANSFER_COMPLETE)
     979             :                                 break;
     980           0 :                         if (!status) {
     981             :                                 error = ETIMEDOUT;
     982           0 :                                 break;
     983             :                         }
     984             :                 }
     985             : 
     986           0 :                 bus_dmamap_sync(sc->sc_dmat, hp->adma_map, 0, PAGE_SIZE,
     987             :                     BUS_DMASYNC_POSTWRITE);
     988             :                 goto done;
     989             :         }
     990             : 
     991           0 :         mask = ISSET(cmd->c_flags, SCF_CMD_READ) ?
     992             :             SDHC_BUFFER_READ_ENABLE : SDHC_BUFFER_WRITE_ENABLE;
     993             :         error = 0;
     994           0 :         datalen = cmd->c_datalen;
     995             : 
     996             :         DPRINTF(1,("%s: resp=%#x datalen=%d\n", DEVNAME(hp->sc),
     997             :             MMC_R1(cmd->c_resp), datalen));
     998             : 
     999             : #ifdef SDHC_DEBUG
    1000             :         /* XXX I forgot why I wanted to know when this happens :-( */
    1001             :         if ((cmd->c_opcode == 52 || cmd->c_opcode == 53) &&
    1002             :             ISSET(MMC_R1(cmd->c_resp), 0xcb00))
    1003             :                 printf("%s: CMD52/53 error response flags %#x\n",
    1004             :                     DEVNAME(hp->sc), MMC_R1(cmd->c_resp) & 0xff00);
    1005             : #endif
    1006             : 
    1007           0 :         while (datalen > 0) {
    1008           0 :                 if (!sdhc_wait_intr(hp, SDHC_BUFFER_READ_READY|
    1009           0 :                     SDHC_BUFFER_WRITE_READY, SDHC_BUFFER_TIMEOUT)) {
    1010             :                         error = ETIMEDOUT;
    1011           0 :                         break;
    1012             :                 }
    1013             : 
    1014           0 :                 if ((error = sdhc_wait_state(hp, mask, mask)) != 0)
    1015             :                         break;
    1016             : 
    1017           0 :                 i = MIN(datalen, cmd->c_blklen);
    1018           0 :                 if (ISSET(cmd->c_flags, SCF_CMD_READ))
    1019           0 :                         sdhc_read_data(hp, datap, i);
    1020             :                 else
    1021           0 :                         sdhc_write_data(hp, datap, i);
    1022             : 
    1023           0 :                 datap += i;
    1024           0 :                 datalen -= i;
    1025             :         }
    1026             : 
    1027           0 :         if (error == 0 && !sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE,
    1028           0 :             SDHC_TRANSFER_TIMEOUT))
    1029           0 :                 error = ETIMEDOUT;
    1030             : 
    1031             : done:
    1032           0 :         if (error != 0)
    1033           0 :                 cmd->c_error = error;
    1034           0 :         SET(cmd->c_flags, SCF_ITSDONE);
    1035             : 
    1036             :         DPRINTF(1,("%s: data transfer done (error=%d)\n",
    1037             :             DEVNAME(hp->sc), cmd->c_error));
    1038           0 : }
    1039             : 
    1040             : void
    1041           0 : sdhc_read_data(struct sdhc_host *hp, u_char *datap, int datalen)
    1042             : {
    1043           0 :         while (datalen > 3) {
    1044           0 :                 *(u_int32_t *)datap = HREAD4(hp, SDHC_DATA);
    1045           0 :                 datap += 4;
    1046           0 :                 datalen -= 4;
    1047             :         }
    1048           0 :         if (datalen > 0) {
    1049           0 :                 u_int32_t rv = HREAD4(hp, SDHC_DATA);
    1050           0 :                 do {
    1051           0 :                         *datap++ = rv & 0xff;
    1052           0 :                         rv = rv >> 8;
    1053           0 :                 } while (--datalen > 0);
    1054           0 :         }
    1055           0 : }
    1056             : 
    1057             : void
    1058           0 : sdhc_write_data(struct sdhc_host *hp, u_char *datap, int datalen)
    1059             : {
    1060           0 :         while (datalen > 3) {
    1061             :                 DPRINTF(3,("%08x\n", *(u_int32_t *)datap));
    1062           0 :                 HWRITE4(hp, SDHC_DATA, *((u_int32_t *)datap));
    1063           0 :                 datap += 4;
    1064           0 :                 datalen -= 4;
    1065             :         }
    1066           0 :         if (datalen > 0) {
    1067           0 :                 u_int32_t rv = *datap++;
    1068           0 :                 if (datalen > 1)
    1069           0 :                         rv |= *datap++ << 8;
    1070           0 :                 if (datalen > 2)
    1071           0 :                         rv |= *datap++ << 16;
    1072             :                 DPRINTF(3,("rv %08x\n", rv));
    1073           0 :                 HWRITE4(hp, SDHC_DATA, rv);
    1074           0 :         }
    1075           0 : }
    1076             : 
    1077             : /* Prepare for another command. */
    1078             : int
    1079           0 : sdhc_soft_reset(struct sdhc_host *hp, int mask)
    1080             : {
    1081             :         int timo;
    1082             : 
    1083             :         DPRINTF(1,("%s: software reset reg=%#x\n", DEVNAME(hp->sc), mask));
    1084             : 
    1085           0 :         HWRITE1(hp, SDHC_SOFTWARE_RESET, mask);
    1086           0 :         for (timo = 10; timo > 0; timo--) {
    1087           0 :                 if (!ISSET(HREAD1(hp, SDHC_SOFTWARE_RESET), mask))
    1088             :                         break;
    1089           0 :                 sdmmc_delay(10000);
    1090           0 :                 HWRITE1(hp, SDHC_SOFTWARE_RESET, 0);
    1091             :         }
    1092           0 :         if (timo == 0) {
    1093             :                 DPRINTF(1,("%s: timeout reg=%#x\n", DEVNAME(hp->sc),
    1094             :                     HREAD1(hp, SDHC_SOFTWARE_RESET)));
    1095           0 :                 HWRITE1(hp, SDHC_SOFTWARE_RESET, 0);
    1096           0 :                 return (ETIMEDOUT);
    1097             :         }
    1098             : 
    1099           0 :         return (0);
    1100           0 : }
    1101             : 
    1102             : int
    1103           0 : sdhc_wait_intr_cold(struct sdhc_host *hp, int mask, int timo)
    1104             : {
    1105             :         int status;
    1106             : 
    1107           0 :         mask |= SDHC_ERROR_INTERRUPT;
    1108           0 :         timo = timo * tick;
    1109           0 :         status = hp->intr_status;
    1110           0 :         while ((status & mask) == 0) {
    1111             : 
    1112           0 :                 status = HREAD2(hp, SDHC_NINTR_STATUS);
    1113           0 :                 if (ISSET(status, SDHC_NINTR_STATUS_MASK)) {
    1114           0 :                         HWRITE2(hp, SDHC_NINTR_STATUS, status);
    1115           0 :                         if (ISSET(status, SDHC_ERROR_INTERRUPT)) {
    1116             :                                 uint16_t error;
    1117           0 :                                 error = HREAD2(hp, SDHC_EINTR_STATUS);
    1118           0 :                                 HWRITE2(hp, SDHC_EINTR_STATUS, error);
    1119           0 :                                 hp->intr_status |= status;
    1120             : 
    1121           0 :                                 if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR|
    1122             :                                     SDHC_DATA_TIMEOUT_ERROR))
    1123           0 :                                         break;
    1124           0 :                         }
    1125             : 
    1126           0 :                         if (ISSET(status, SDHC_BUFFER_READ_READY |
    1127             :                             SDHC_BUFFER_WRITE_READY | SDHC_COMMAND_COMPLETE |
    1128             :                             SDHC_TRANSFER_COMPLETE)) {
    1129           0 :                                 hp->intr_status |= status;
    1130           0 :                                 break;
    1131             :                         }
    1132             : 
    1133           0 :                         if (ISSET(status, SDHC_CARD_INTERRUPT)) {
    1134           0 :                                 HSET2(hp, SDHC_NINTR_STATUS_EN,
    1135             :                                     SDHC_CARD_INTERRUPT);
    1136           0 :                         }
    1137             : 
    1138           0 :                         continue;
    1139             :                 }
    1140             : 
    1141           0 :                 delay(1);
    1142           0 :                 if (timo-- == 0) {
    1143           0 :                         status |= SDHC_ERROR_INTERRUPT;
    1144           0 :                         break;
    1145             :                 }
    1146             :         }
    1147             : 
    1148           0 :         hp->intr_status &= ~(status & mask);
    1149           0 :         return (status & mask);
    1150             : }
    1151             : 
    1152             : int
    1153           0 : sdhc_wait_intr(struct sdhc_host *hp, int mask, int timo)
    1154             : {
    1155             :         int status;
    1156             :         int s;
    1157             : 
    1158           0 :         if (cold)
    1159           0 :                 return (sdhc_wait_intr_cold(hp, mask, timo));
    1160             : 
    1161           0 :         mask |= SDHC_ERROR_INTERRUPT;
    1162             : 
    1163           0 :         s = splsdmmc();
    1164           0 :         status = hp->intr_status & mask;
    1165           0 :         while (status == 0) {
    1166           0 :                 if (tsleep(&hp->intr_status, PWAIT, "hcintr", timo)
    1167           0 :                     == EWOULDBLOCK) {
    1168           0 :                         status |= SDHC_ERROR_INTERRUPT;
    1169           0 :                         break;
    1170             :                 }
    1171           0 :                 status = hp->intr_status & mask;
    1172             :         }
    1173           0 :         hp->intr_status &= ~status;
    1174             : 
    1175             :         DPRINTF(2,("%s: intr status %#x error %#x\n", DEVNAME(hp->sc), status,
    1176             :             hp->intr_error_status));
    1177             :         
    1178             :         /* Command timeout has higher priority than command complete. */
    1179           0 :         if (ISSET(status, SDHC_ERROR_INTERRUPT)) {
    1180           0 :                 hp->intr_error_status = 0;
    1181           0 :                 (void)sdhc_soft_reset(hp, SDHC_RESET_DAT|SDHC_RESET_CMD);
    1182             :                 status = 0;
    1183           0 :         }
    1184             : 
    1185           0 :         splx(s);
    1186           0 :         return status;
    1187           0 : }
    1188             : 
    1189             : /*
    1190             :  * Established by attachment driver at interrupt priority IPL_SDMMC.
    1191             :  */
    1192             : int
    1193           0 : sdhc_intr(void *arg)
    1194             : {
    1195           0 :         struct sdhc_softc *sc = arg;
    1196             :         int host;
    1197             :         int done = 0;
    1198             : 
    1199             :         /* We got an interrupt, but we don't know from which slot. */
    1200           0 :         for (host = 0; host < sc->sc_nhosts; host++) {
    1201           0 :                 struct sdhc_host *hp = sc->sc_host[host];
    1202             :                 u_int16_t status;
    1203             : 
    1204           0 :                 if (hp == NULL)
    1205           0 :                         continue;
    1206             : 
    1207             :                 /* Find out which interrupts are pending. */
    1208           0 :                 status = HREAD2(hp, SDHC_NINTR_STATUS);
    1209           0 :                 if (!ISSET(status, SDHC_NINTR_STATUS_MASK))
    1210           0 :                         continue; /* no interrupt for us */
    1211             : 
    1212             :                 /* Acknowledge the interrupts we are about to handle. */
    1213           0 :                 HWRITE2(hp, SDHC_NINTR_STATUS, status);
    1214             :                 DPRINTF(2,("%s: interrupt status=%b\n", DEVNAME(hp->sc),
    1215             :                     status, SDHC_NINTR_STATUS_BITS));
    1216             : 
    1217             :                 /* Claim this interrupt. */
    1218             :                 done = 1;
    1219             : 
    1220             :                 /*
    1221             :                  * Service error interrupts.
    1222             :                  */
    1223           0 :                 if (ISSET(status, SDHC_ERROR_INTERRUPT)) {
    1224             :                         u_int16_t error;
    1225             : 
    1226             :                         /* Acknowledge error interrupts. */
    1227           0 :                         error = HREAD2(hp, SDHC_EINTR_STATUS);
    1228           0 :                         HWRITE2(hp, SDHC_EINTR_STATUS, error);
    1229             :                         DPRINTF(2,("%s: error interrupt, status=%b\n",
    1230             :                             DEVNAME(hp->sc), error, SDHC_EINTR_STATUS_BITS));
    1231             : 
    1232           0 :                         if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR|
    1233             :                             SDHC_DATA_TIMEOUT_ERROR)) {
    1234           0 :                                 hp->intr_error_status |= error;
    1235           0 :                                 hp->intr_status |= status;
    1236           0 :                                 wakeup(&hp->intr_status);
    1237           0 :                         }
    1238           0 :                 }
    1239             : 
    1240             :                 /*
    1241             :                  * Wake up the sdmmc event thread to scan for cards.
    1242             :                  */
    1243           0 :                 if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION))
    1244           0 :                         sdmmc_needs_discover(hp->sdmmc);
    1245             : 
    1246             :                 /*
    1247             :                  * Wake up the blocking process to service command
    1248             :                  * related interrupt(s).
    1249             :                  */
    1250           0 :                 if (ISSET(status, SDHC_BUFFER_READ_READY|
    1251             :                     SDHC_BUFFER_WRITE_READY|SDHC_COMMAND_COMPLETE|
    1252             :                     SDHC_TRANSFER_COMPLETE)) {
    1253           0 :                         hp->intr_status |= status;
    1254           0 :                         wakeup(&hp->intr_status);
    1255           0 :                 }
    1256             : 
    1257             :                 /*
    1258             :                  * Service SD card interrupts.
    1259             :                  */
    1260           0 :                 if (ISSET(status, SDHC_CARD_INTERRUPT)) {
    1261             :                         DPRINTF(0,("%s: card interrupt\n", DEVNAME(hp->sc)));
    1262           0 :                         HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
    1263           0 :                         sdmmc_card_intr(hp->sdmmc);
    1264           0 :                 }
    1265           0 :         }
    1266           0 :         return done;
    1267             : }
    1268             : 
    1269             : void
    1270           0 : sdhc_needs_discover(struct sdhc_softc *sc)
    1271             : {
    1272             :         int host;
    1273             : 
    1274           0 :         for (host = 0; host < sc->sc_nhosts; host++)
    1275           0 :                 sdmmc_needs_discover(sc->sc_host[host]->sdmmc);
    1276           0 : }
    1277             : 
    1278             : #ifdef SDHC_DEBUG
    1279             : void
    1280             : sdhc_dump_regs(struct sdhc_host *hp)
    1281             : {
    1282             :         printf("0x%02x PRESENT_STATE:    %b\n", SDHC_PRESENT_STATE,
    1283             :             HREAD4(hp, SDHC_PRESENT_STATE), SDHC_PRESENT_STATE_BITS);
    1284             :         printf("0x%02x POWER_CTL:        %x\n", SDHC_POWER_CTL,
    1285             :             HREAD1(hp, SDHC_POWER_CTL));
    1286             :         printf("0x%02x NINTR_STATUS:     %x\n", SDHC_NINTR_STATUS,
    1287             :             HREAD2(hp, SDHC_NINTR_STATUS));
    1288             :         printf("0x%02x EINTR_STATUS:     %x\n", SDHC_EINTR_STATUS,
    1289             :             HREAD2(hp, SDHC_EINTR_STATUS));
    1290             :         printf("0x%02x NINTR_STATUS_EN:  %x\n", SDHC_NINTR_STATUS_EN,
    1291             :             HREAD2(hp, SDHC_NINTR_STATUS_EN));
    1292             :         printf("0x%02x EINTR_STATUS_EN:  %x\n", SDHC_EINTR_STATUS_EN,
    1293             :             HREAD2(hp, SDHC_EINTR_STATUS_EN));
    1294             :         printf("0x%02x NINTR_SIGNAL_EN:  %x\n", SDHC_NINTR_SIGNAL_EN,
    1295             :             HREAD2(hp, SDHC_NINTR_SIGNAL_EN));
    1296             :         printf("0x%02x EINTR_SIGNAL_EN:  %x\n", SDHC_EINTR_SIGNAL_EN,
    1297             :             HREAD2(hp, SDHC_EINTR_SIGNAL_EN));
    1298             :         printf("0x%02x CAPABILITIES:     %x\n", SDHC_CAPABILITIES,
    1299             :             HREAD4(hp, SDHC_CAPABILITIES));
    1300             :         printf("0x%02x MAX_CAPABILITIES: %x\n", SDHC_MAX_CAPABILITIES,
    1301             :             HREAD4(hp, SDHC_MAX_CAPABILITIES));
    1302             : }
    1303             : #endif
    1304             : 
    1305             : int
    1306           0 : sdhc_hibernate_init(sdmmc_chipset_handle_t sch, void *fake_softc)
    1307             : {
    1308             :         struct sdhc_host *hp, *fhp;
    1309           0 :         fhp = fake_softc;
    1310           0 :         hp = sch;
    1311           0 :         *fhp = *hp;
    1312             : 
    1313           0 :         return (0);
    1314             : }

Generated by: LCOV version 1.13