Source-Changes-HG archive

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

[src/netbsd-6]: src/sys/dev/sdmmc sys/dev/sdmmc/sdhc.c patch



details:   https://anonhg.NetBSD.org/src/rev/5386cb0557fb
branches:  netbsd-6
changeset: 775599:5386cb0557fb
user:      riz <riz%NetBSD.org@localhost>
date:      Wed Jan 02 23:34:56 2013 +0000

description:
sys/dev/sdmmc/sdhc.c                            patch
sys/dev/sdmmc/sdhcreg.h                         patch

        Support SDHC version 3 clocks.
        [skrll, ticket #759]

diffstat:

 sys/dev/sdmmc/sdhc.c    |  79 ++++++++++++++++++++++++++++++++----------------
 sys/dev/sdmmc/sdhcreg.h |  10 +++++-
 2 files changed, 62 insertions(+), 27 deletions(-)

diffs (181 lines):

diff -r fbc6be6310b5 -r 5386cb0557fb sys/dev/sdmmc/sdhc.c
--- a/sys/dev/sdmmc/sdhc.c      Wed Jan 02 23:23:15 2013 +0000
+++ b/sys/dev/sdmmc/sdhc.c      Wed Jan 02 23:34:56 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdhc.c,v 1.10.2.3 2012/08/09 06:36:48 jdc Exp $        */
+/*     $NetBSD: sdhc.c,v 1.10.2.4 2013/01/02 23:34:56 riz 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.10.2.3 2012/08/09 06:36:48 jdc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.10.2.4 2013/01/02 23:34:56 riz Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sdmmc.h"
@@ -79,6 +79,8 @@
        struct kmutex intr_mtx;
        struct kcondvar intr_cv;
 
+       int specver;                    /* spec. version */
+
        uint32_t flags;                 /* flags for this host */
 #define SHF_USE_DMA            0x0001
 #define SHF_USE_4BIT_MODE      0x0002
@@ -223,26 +225,8 @@
        struct sdmmcbus_attach_args saa;
        struct sdhc_host *hp;
        uint32_t caps;
-#ifdef SDHC_DEBUG
        uint16_t sdhcver;
 
-       sdhcver = bus_space_read_2(iot, ioh, SDHC_HOST_CTL_VERSION);
-       aprint_normal_dev(sc->sc_dev, "SD Host Specification/Vendor Version ");
-       switch (SDHC_SPEC_VERSION(sdhcver)) {
-       case 0x00:
-               aprint_normal("1.0/%u\n", SDHC_VENDOR_VERSION(sdhcver));
-               break;
-
-       case 0x01:
-               aprint_normal("2.0/%u\n", SDHC_VENDOR_VERSION(sdhcver));
-               break;
-
-       default:
-               aprint_normal(">2.0/%u\n", SDHC_VENDOR_VERSION(sdhcver));
-               break;
-       }
-#endif
-
        /* Allocate one more host structure. */
        hp = malloc(sizeof(struct sdhc_host), M_DEVBUF, M_WAITOK|M_ZERO);
        if (hp == NULL) {
@@ -262,6 +246,29 @@
        mutex_init(&hp->intr_mtx, MUTEX_DEFAULT, IPL_SDMMC);
        cv_init(&hp->intr_cv, "sdhcintr");
 
+       sdhcver = HREAD2(hp, SDHC_HOST_CTL_VERSION);
+       aprint_normal_dev(sc->sc_dev, "SD Host Specification ");
+       hp->specver = SDHC_SPEC_VERSION(sdhcver);
+       switch (SDHC_SPEC_VERSION(sdhcver)) {
+       case SDHC_SPEC_VERS_100:
+               aprint_normal("1.0");
+               break;
+
+       case SDHC_SPEC_VERS_200:
+               aprint_normal("2.0");
+               break;
+
+       case SDHC_SPEC_VERS_300:
+               aprint_normal("3.0");
+               break;
+
+       default:
+               aprint_normal("unknown version(0x%x)",
+                   SDHC_SPEC_VERSION(sdhcver));
+               break;
+       }
+       aprint_normal(", rev.%u\n", SDHC_VENDOR_VERSION(sdhcver));
+
        /*
         * Reset the host controller and enable interrupts.
         */
@@ -289,8 +296,11 @@
        /*
         * Determine the base clock frequency. (2.2.24)
         */
-       if (SDHC_BASE_FREQ_KHZ(caps) != 0)
+       if (hp->specver == SDHC_SPEC_VERS_300) {
+               hp->clkbase = SDHC_BASE_V3_FREQ_KHZ(caps);
+       } else {
                hp->clkbase = SDHC_BASE_FREQ_KHZ(caps);
+       }
        if (hp->clkbase == 0) {
                if (sc->sc_clkbase == 0) {
                        /* The attachment driver must tell us. */
@@ -370,12 +380,16 @@
        saa.saa_sct = &sdhc_functions;
        saa.saa_sch = hp;
        saa.saa_dmat = hp->dmat;
-       saa.saa_clkmin = hp->clkbase / 256;
        saa.saa_clkmax = hp->clkbase;
        if (ISSET(sc->sc_flags, SDHC_FLAG_HAVE_CGM))
-               saa.saa_clkmin /= 2046;
+               saa.saa_clkmin = hp->clkbase / 256 / 2046;
        else if (ISSET(sc->sc_flags, SDHC_FLAG_HAVE_DVS))
-               saa.saa_clkmin /= 16;
+               saa.saa_clkmin = hp->clkbase / 256 / 16;
+       else if (hp->specver == SDHC_SPEC_VERS_300)
+               saa.saa_clkmin = hp->clkbase / 0x3ff;
+       else
+               saa.saa_clkmin = hp->clkbase / 256;
+
        saa.saa_caps = SMC_CAPS_4BIT_MODE|SMC_CAPS_AUTO_STOP;
        if (ISSET(sc->sc_flags, SDHC_FLAG_8BIT_MODE))
                saa.saa_caps |= SMC_CAPS_8BIT_MODE;
@@ -725,16 +739,29 @@
                         */
                        roundup |= dvs & 1;
                }
-               panic("%s: can't find divisor for freq %u", HDEVNAME(hp), freq);
+               /* No divisor found. */
+               return false;
+       }
+       if (hp->specver == SDHC_SPEC_VERS_300) {
+               div = howmany(hp->clkbase, freq);
+               if (div > 0x3ff)
+                       return false;
+               *divp = (((div >> 8) & SDHC_SDCLK_XDIV_MASK)
+                        << SDHC_SDCLK_XDIV_SHIFT) |
+                       (((div >> 0) & SDHC_SDCLK_DIV_MASK)
+                        << SDHC_SDCLK_DIV_SHIFT);
+               return true;
        } else {
                for (div = 1; div <= 256; div *= 2) {
                        if ((hp->clkbase / div) <= freq) {
                                *divp = (div / 2) << SDHC_SDCLK_DIV_SHIFT;
+                               //freq = hp->clkbase / div;
                                return true;
                        }
                }
+               /* No divisor found. */
+               return false;
        }
-
        /* No divisor found. */
        return false;
 }
diff -r fbc6be6310b5 -r 5386cb0557fb sys/dev/sdmmc/sdhcreg.h
--- a/sys/dev/sdmmc/sdhcreg.h   Wed Jan 02 23:23:15 2013 +0000
+++ b/sys/dev/sdmmc/sdhcreg.h   Wed Jan 02 23:34:56 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdhcreg.h,v 1.5.2.1 2012/08/08 06:18:59 jdc Exp $      */
+/*     $NetBSD: sdhcreg.h,v 1.5.2.2 2013/01/02 23:34:56 riz Exp $      */
 /*     $OpenBSD: sdhcreg.h,v 1.4 2006/07/30 17:20:40 fgsch Exp $       */
 
 /*
@@ -149,6 +149,7 @@
 #define  SDHC_MAX_BLK_LEN_MASK         0x3
 #define  SDHC_BASE_FREQ_SHIFT          8
 #define  SDHC_BASE_FREQ_MASK           0x3f
+#define  SDHC_BASE_V3_FREQ_MASK                0xff
 #define  SDHC_TIMEOUT_FREQ_UNIT                (1<<7)  /* 0=KHz, 1=MHz */
 #define  SDHC_TIMEOUT_FREQ_SHIFT       0
 #define  SDHC_TIMEOUT_FREQ_MASK                0x1f
@@ -172,7 +173,14 @@
 #define        SDHC_DMA_CTL                    0x40c   /* eSDHC */
 #define         SDHC_DMA_SNOOP                 0x40
 
+/* SDHC_SPEC_VERS */
+#define SDHC_SPEC_VERS_100             0x00
+#define SDHC_SPEC_VERS_200             0x01
+#define SDHC_SPEC_VERS_300             0x02
+
 /* SDHC_CAPABILITIES decoding */
+#define SDHC_BASE_V3_FREQ_KHZ(cap)                                     \
+       ((((cap) >> SDHC_BASE_FREQ_SHIFT) & SDHC_BASE_V3_FREQ_MASK) * 1000)
 #define SDHC_BASE_FREQ_KHZ(cap)                                                \
        ((((cap) >> SDHC_BASE_FREQ_SHIFT) & SDHC_BASE_FREQ_MASK) * 1000)
 #define SDHC_TIMEOUT_FREQ(cap)                                         \



Home | Main Index | Thread Index | Old Index