Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/sdmmc Add support for sampling clock tuning, require...



details:   https://anonhg.NetBSD.org/src/rev/55a62ca67cbf
branches:  trunk
changeset: 809858:55a62ca67cbf
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Wed Aug 05 10:29:37 2015 +0000

description:
Add support for sampling clock tuning, required for some UHS modes and
MMC HS200.

diffstat:

 sys/dev/sdmmc/sdmmc_mem.c |  64 ++++++++++++++++++++++++++++++++++++++++------
 sys/dev/sdmmc/sdmmcchip.h |  12 +++++++-
 sys/dev/sdmmc/sdmmcreg.h  |   4 ++-
 3 files changed, 68 insertions(+), 12 deletions(-)

diffs (165 lines):

diff -r 2961bf061268 -r 55a62ca67cbf sys/dev/sdmmc/sdmmc_mem.c
--- a/sys/dev/sdmmc/sdmmc_mem.c Wed Aug 05 07:34:56 2015 +0000
+++ b/sys/dev/sdmmc/sdmmc_mem.c Wed Aug 05 10:29:37 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdmmc_mem.c,v 1.44 2015/08/04 01:21:55 jmcneill Exp $  */
+/*     $NetBSD: sdmmc_mem.c,v 1.45 2015/08/05 10:29:37 jmcneill 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.44 2015/08/04 01:21:55 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.45 2015/08/05 10:29:37 jmcneill Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sdmmc.h"
@@ -142,13 +142,6 @@
        /* Reset memory (*must* do that before CMD55 or CMD1). */
        sdmmc_go_idle_state(sc);
 
-       /* Set 3.3V signaling */
-       if (sc->sc_sct->signal_voltage) {
-               error = sdmmc_mem_signal_voltage(sc, SDMMC_SIGNAL_VOLTAGE_330);
-               if (error)
-                       goto out;
-       }
-
        if (ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {
                /* Check SD Ver.2 */
                error = sdmmc_mem_send_if_cond(sc, 0x1aa, &card_ocr);
@@ -741,6 +734,44 @@
 }
 
 static int
+sdmmc_mem_execute_tuning(struct sdmmc_softc *sc, struct sdmmc_function *sf)
+{
+       int timing = -1;
+
+       if (!ISSET(sc->sc_flags, SMF_UHS_MODE))
+               return 0;
+
+       if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
+               if (!ISSET(sc->sc_flags, SMF_UHS_MODE))
+                       return 0;
+
+               switch (sf->csd.tran_speed) {
+               case 100000:
+                       timing = SDMMC_TIMING_UHS_SDR50;
+                       break;
+               case 208000:
+                       timing = SDMMC_TIMING_UHS_SDR104;
+                       break; 
+               default:
+                       return 0;
+               }
+       } else {
+               switch (sf->csd.tran_speed) {
+               case 200000:
+                       timing = SDMMC_TIMING_MMC_HS200;
+                       break;
+               default:
+                       return 0;
+               }
+       }
+
+       DPRINTF(("%s: execute tuning for timing %d\n", SDMMCDEVNAME(sc),
+           timing));
+
+       return sdmmc_chip_execute_tuning(sc->sc_sct, sc->sc_sch, timing);
+}
+
+static int
 sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
 {
        int support_func, best_func, bus_clock, error, i;
@@ -854,6 +885,13 @@
        sc->sc_transfer_mode = switch_group0_functions[best_func].name;
        sc->sc_busddr = ddr;
 
+       /* execute tuning (UHS) */
+       error = sdmmc_mem_execute_tuning(sc, sf);
+       if (error) {
+               aprint_error_dev(sc->sc_dev, "can't execute SD tuning\n");
+               return error;
+       }
+
        return 0;
 }
 
@@ -994,6 +1032,14 @@
 
                if (hs_timing == 2) {
                        sc->sc_transfer_mode = "HS200";
+
+                       /* execute tuning (HS200) */
+                       error = sdmmc_mem_execute_tuning(sc, sf);
+                       if (error) {
+                               aprint_error_dev(sc->sc_dev,
+                                   "can't execute MMC tuning\n");
+                               return error;
+                       }
                } else {
                        sc->sc_transfer_mode = NULL;
                }
diff -r 2961bf061268 -r 55a62ca67cbf sys/dev/sdmmc/sdmmcchip.h
--- a/sys/dev/sdmmc/sdmmcchip.h Wed Aug 05 07:34:56 2015 +0000
+++ b/sys/dev/sdmmc/sdmmcchip.h Wed Aug 05 10:29:37 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdmmcchip.h,v 1.6 2015/08/03 10:08:51 jmcneill Exp $   */
+/*     $NetBSD: sdmmcchip.h,v 1.7 2015/08/05 10:29:37 jmcneill Exp $   */
 /*     $OpenBSD: sdmmcchip.h,v 1.3 2007/05/31 10:09:01 uwe Exp $       */
 
 /*
@@ -61,6 +61,7 @@
        /* UHS functions */
        int             (*signal_voltage)(sdmmc_chipset_handle_t, int);
        int             (*bus_clock_ddr)(sdmmc_chipset_handle_t, int, bool);
+       int             (*execute_tuning)(sdmmc_chipset_handle_t, int);
 };
 
 /* host controller reset */
@@ -95,8 +96,10 @@
 #define sdmmc_chip_card_intr_ack(tag, handle)                          \
        ((tag)->card_intr_ack((handle)))
 /* UHS functions */
-#define sdmmc_chip_signal_voltage(tag, handle, voltage)                \
+#define sdmmc_chip_signal_voltage(tag, handle, voltage)                        \
        ((tag)->signal_voltage((handle), (voltage)))
+#define sdmmc_chip_execute_tuning(tag, handle, timing)                 \
+       ((tag)->execute_tuning ? (tag)->execute_tuning((handle), (timing)) : EINVAL)
 
 /* clock frequencies for sdmmc_chip_bus_clock() */
 #define SDMMC_SDCLK_OFF                0
@@ -106,6 +109,11 @@
 #define SDMMC_SIGNAL_VOLTAGE_330       0
 #define SDMMC_SIGNAL_VOLTAGE_180       1
 
+/* timings for sdmmc_chip_execute_tuning() */
+#define SDMMC_TIMING_UHS_SDR50         0
+#define SDMMC_TIMING_UHS_SDR104                1
+#define SDMMC_TIMING_MMC_HS200         2
+
 /* SPI mode */
 struct sdmmc_spi_chip_functions {
        /* card initialize */
diff -r 2961bf061268 -r 55a62ca67cbf sys/dev/sdmmc/sdmmcreg.h
--- a/sys/dev/sdmmc/sdmmcreg.h  Wed Aug 05 07:34:56 2015 +0000
+++ b/sys/dev/sdmmc/sdmmcreg.h  Wed Aug 05 10:29:37 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdmmcreg.h,v 1.18 2015/08/03 10:08:51 jmcneill Exp $   */
+/*     $NetBSD: sdmmcreg.h,v 1.19 2015/08/05 10:29:37 jmcneill Exp $   */
 /*     $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $        */
 
 /*
@@ -36,6 +36,8 @@
 #define MMC_SET_BLOCKLEN               16      /* R1 */
 #define MMC_READ_BLOCK_SINGLE          17      /* R1 */
 #define MMC_READ_BLOCK_MULTIPLE                18      /* R1 */
+#define MMC_SEND_TUNING_BLOCK          19      /* R1 */
+#define MMC_SEND_TUNING_BLOCK_HS200    21      /* R1 */
 #define MMC_SET_BLOCK_COUNT            23      /* R1 */
 #define MMC_WRITE_BLOCK_SINGLE         24      /* R1 */
 #define MMC_WRITE_BLOCK_MULTIPLE       25      /* R1 */



Home | Main Index | Thread Index | Old Index