Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/sdmmc sdhc(4), sdmmc(4): Added MMC HS DDR52 support.



details:   https://anonhg.NetBSD.org/src/rev/04afe114d9a1
branches:  trunk
changeset: 821799:04afe114d9a1
user:      nonaka <nonaka%NetBSD.org@localhost>
date:      Fri Feb 17 10:50:43 2017 +0000

description:
sdhc(4), sdmmc(4): Added MMC HS DDR52 support.

diffstat:

 sys/dev/sdmmc/sdhc.c      |  15 ++++++++++--
 sys/dev/sdmmc/sdmmc_mem.c |  54 ++++++++++++++++++++++++++++++++++++++++++----
 sys/dev/sdmmc/sdmmcchip.h |   4 +-
 3 files changed, 63 insertions(+), 10 deletions(-)

diffs (161 lines):

diff -r 9c2ad85f5528 -r 04afe114d9a1 sys/dev/sdmmc/sdhc.c
--- a/sys/dev/sdmmc/sdhc.c      Fri Feb 17 10:49:47 2017 +0000
+++ b/sys/dev/sdmmc/sdhc.c      Fri Feb 17 10:50:43 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdhc.c,v 1.97 2017/01/07 15:05:08 kiyohara Exp $       */
+/*     $NetBSD: sdhc.c,v 1.98 2017/02/17 10:50:43 nonaka Exp $ */
 /*     $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $        */
 
 /*
@@ -23,7 +23,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.97 2017/01/07 15:05:08 kiyohara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.98 2017/02/17 10:50:43 nonaka Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sdmmc.h"
@@ -1107,7 +1107,13 @@
                if (freq > 100000) {
                        HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR104);
                } else if (freq > 50000) {
-                       HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR50);
+                       if (ddr) {
+                               HSET2(hp, SDHC_HOST_CTL2,
+                                   SDHC_UHS_MODE_SELECT_DDR50);
+                       } else {
+                               HSET2(hp, SDHC_HOST_CTL2,
+                                   SDHC_UHS_MODE_SELECT_SDR50);
+                       }
                } else if (freq > 25000) {
                        if (ddr) {
                                HSET2(hp, SDHC_HOST_CTL2,
@@ -1335,6 +1341,9 @@
 {
        struct sdhc_host *hp = (struct sdhc_host *)sch;
 
+       if (hp->specver < SDHC_SPEC_VERS_300)
+               return EINVAL;
+
        mutex_enter(&hp->intr_lock);
        switch (signal_voltage) {
        case SDMMC_SIGNAL_VOLTAGE_180:
diff -r 9c2ad85f5528 -r 04afe114d9a1 sys/dev/sdmmc/sdmmc_mem.c
--- a/sys/dev/sdmmc/sdmmc_mem.c Fri Feb 17 10:49:47 2017 +0000
+++ b/sys/dev/sdmmc/sdmmc_mem.c Fri Feb 17 10:50:43 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdmmc_mem.c,v 1.53 2017/02/17 10:48:19 nonaka Exp $    */
+/*     $NetBSD: sdmmc_mem.c,v 1.54 2017/02/17 10:50:43 nonaka Exp $    */
 /*     $OpenBSD: sdmmc_mem.c,v 1.10 2009/01/09 10:55:22 jsg Exp $      */
 
 /*
@@ -45,7 +45,7 @@
 /* Routines for SD/MMC memory cards. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.53 2017/02/17 10:48:19 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.54 2017/02/17 10:50:43 nonaka Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sdmmc.h"
@@ -907,6 +907,7 @@
        int width, value, hs_timing, bus_clock, error;
        uint8_t ext_csd[512];
        uint32_t sectors = 0;
+       bool ddr = false;
 
        sc->sc_transfer_mode = NULL;
 
@@ -934,11 +935,15 @@
                        return ENOTSUP;
                }
 
-               sc->sc_transfer_mode = NULL;
                if (ISSET(sc->sc_caps, SMC_CAPS_MMC_HS200) &&
                    ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_HS200_1_8V) {
                        sf->csd.tran_speed = 200000;    /* 200MHz SDR */
                        hs_timing = EXT_CSD_HS_TIMING_HS200;
+               } else if (ISSET(sc->sc_caps, SMC_CAPS_MMC_DDR52) &&
+                   ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_DDR52_1_8V) {
+                       sf->csd.tran_speed = 52000;     /* 52MHz */
+                       hs_timing = EXT_CSD_HS_TIMING_HIGHSPEED;
+                       ddr = true;
                } else if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_52M) {
                        sf->csd.tran_speed = 52000;     /* 52MHz */
                        hs_timing = EXT_CSD_HS_TIMING_HIGHSPEED;
@@ -1022,6 +1027,47 @@
                        }
                }
 
+               /*
+                * HS_TIMING must be set to â??0x1â?? before setting BUS_WIDTH
+                * for dual data rate operation
+                */
+               if (ddr &&
+                   hs_timing == EXT_CSD_HS_TIMING_HIGHSPEED &&
+                   width > 1) {
+                       error = sdmmc_mem_mmc_switch(sf,
+                           EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
+                           (width == 8) ? EXT_CSD_BUS_WIDTH_8_DDR :
+                             EXT_CSD_BUS_WIDTH_4_DDR);
+                       if (error) {
+                               DPRINTF(("%s: can't switch to DDR"
+                                   " (%d bit)\n", SDMMCDEVNAME(sc), width));
+                               return error;
+                       }
+
+                       delay(10000);
+
+                       error = sdmmc_mem_signal_voltage(sc,
+                           SDMMC_SIGNAL_VOLTAGE_180);
+                       if (error) {
+                               aprint_error_dev(sc->sc_dev,
+                                   "can't switch signaling voltage\n");
+                               return error;
+                       }
+
+                       error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch,
+                           sc->sc_busclk, ddr);
+                       if (error) {
+                               aprint_error_dev(sc->sc_dev,
+                                   "can't change bus clock\n");
+                               return error;
+                       }
+
+                       delay(10000);
+
+                       sc->sc_transfer_mode = "DDR52";
+                       sc->sc_busddr = ddr;
+               }
+
                sectors = ext_csd[EXT_CSD_SEC_COUNT + 0] << 0 |
                    ext_csd[EXT_CSD_SEC_COUNT + 1] << 8  |
                    ext_csd[EXT_CSD_SEC_COUNT + 2] << 16 |
@@ -1041,8 +1087,6 @@
                                    "can't execute MMC tuning\n");
                                return error;
                        }
-               } else {
-                       sc->sc_transfer_mode = NULL;
                }
        } else {
                if (sc->sc_busclk > sf->csd.tran_speed)
diff -r 9c2ad85f5528 -r 04afe114d9a1 sys/dev/sdmmc/sdmmcchip.h
--- a/sys/dev/sdmmc/sdmmcchip.h Fri Feb 17 10:49:47 2017 +0000
+++ b/sys/dev/sdmmc/sdmmcchip.h Fri Feb 17 10:50:43 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdmmcchip.h,v 1.7 2015/08/05 10:29:37 jmcneill Exp $   */
+/*     $NetBSD: sdmmcchip.h,v 1.8 2017/02/17 10:50:43 nonaka Exp $     */
 /*     $OpenBSD: sdmmcchip.h,v 1.3 2007/05/31 10:09:01 uwe Exp $       */
 
 /*
@@ -97,7 +97,7 @@
        ((tag)->card_intr_ack((handle)))
 /* UHS functions */
 #define sdmmc_chip_signal_voltage(tag, handle, voltage)                        \
-       ((tag)->signal_voltage((handle), (voltage)))
+       ((tag)->signal_voltage ? (tag)->signal_voltage((handle), (voltage)) : EINVAL)
 #define sdmmc_chip_execute_tuning(tag, handle, timing)                 \
        ((tag)->execute_tuning ? (tag)->execute_tuning((handle), (timing)) : EINVAL)
 



Home | Main Index | Thread Index | Old Index