An experimental hack that makes head -r338518 boot from e.MMC via an microsd card adapter, in DDR52 mode at that

Mark Millard marklmi at yahoo.com
Sat Sep 15 02:26:32 UTC 2018


[I'm replacing the original hack with something that is less of
one. But this is just investigatory, based on my limited testing
context (just a Pine64+ 2GB) and lack of a general background
in the source code and its criteria. Hopefully the material is
of some use.]

The following adjustments track the lack of wanting to
support 1.8V because of other restrictions and so lead to the
use of the e.MMC DDR52 using the range around 3V for the
Pine64+ 2GB. (I expect A64 generality but have only one test
context.)

# svnlite diff /usr/src/sys//dev/mmc/ /usr/src/sys/arm/allwinner/                                                                                                                          Index: /usr/src/sys/dev/mmc/mmc.c
===================================================================
--- /usr/src/sys/dev/mmc/mmc.c  (revision 338675)
+++ /usr/src/sys/dev/mmc/mmc.c  (working copy)
@@ -1814,10 +1814,10 @@
                                setbit(&ivar->timings, bus_timing_mmc_ddr52);
                                setbit(&ivar->vccq_120, bus_timing_mmc_ddr52);
                        }
-                       if ((card_type & EXT_CSD_CARD_TYPE_DDR_52_1_8V) != 0 &&
-                           (host_caps & MMC_CAP_SIGNALING_180) != 0) {
+                       if ((card_type & EXT_CSD_CARD_TYPE_DDR_52_3V_OR_1_8V) != 0) {
                                setbit(&ivar->timings, bus_timing_mmc_ddr52);
-                               setbit(&ivar->vccq_180, bus_timing_mmc_ddr52);
+                               if ((host_caps & MMC_CAP_SIGNALING_180) != 0)
+                                       setbit(&ivar->vccq_180, bus_timing_mmc_ddr52);
                        }
                        if ((card_type & EXT_CSD_CARD_TYPE_HS200_1_2V) != 0 &&
                            (host_caps & MMC_CAP_SIGNALING_120) != 0) {
Index: /usr/src/sys/dev/mmc/mmcreg.h
===================================================================
--- /usr/src/sys/dev/mmc/mmcreg.h       (revision 338675)
+++ /usr/src/sys/dev/mmc/mmcreg.h       (working copy)
@@ -463,7 +463,7 @@
 
 #define        EXT_CSD_CARD_TYPE_HS_26         0x0001
 #define        EXT_CSD_CARD_TYPE_HS_52         0x0002
-#define        EXT_CSD_CARD_TYPE_DDR_52_1_8V   0x0004
+#define        EXT_CSD_CARD_TYPE_DDR_52_3V_OR_1_8V     0x0004
 #define        EXT_CSD_CARD_TYPE_DDR_52_1_2V   0x0008
 #define        EXT_CSD_CARD_TYPE_HS200_1_8V    0x0010
 #define        EXT_CSD_CARD_TYPE_HS200_1_2V    0x0020
Index: /usr/src/sys/arm/allwinner/aw_mmc.c
===================================================================
--- /usr/src/sys/arm/allwinner/aw_mmc.c (revision 338675)
+++ /usr/src/sys/arm/allwinner/aw_mmc.c (working copy)
@@ -509,7 +509,7 @@
                           MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 |
                           MMC_CAP_UHS_DDR50 | MMC_CAP_MMC_DDR52;
 
-       sc->aw_host.caps |= MMC_CAP_SIGNALING_330 | MMC_CAP_SIGNALING_180;
+       sc->aw_host.caps |= MMC_CAP_SIGNALING_330; // | MMC_CAP_SIGNALING_180; not used on Pine64+ 2GB
 
        if (bus_width >= 4)
                sc->aw_host.caps |= MMC_CAP_4_BIT_DATA;
@@ -1308,17 +1308,20 @@
 
        sc = device_get_softc(bus);
 
-       if (sc->aw_reg_vqmmc == NULL)
-               return EOPNOTSUPP;
-
        switch (sc->aw_host.ios.vccq) {
        case vccq_180:
+               if (sc->aw_reg_vqmmc == NULL)
+                       return EOPNOTSUPP;
                uvolt = 1800000;
                break;
        case vccq_330:
+               if (sc->aw_reg_vqmmc == NULL) // implicitly already stuck at vccq_330
+                       return 0; // avoid calling code treating the assignment attempt as an error
                uvolt = 3300000;
                break;
        default:
+               if (sc->aw_reg_vqmmc == NULL)
+                       return EOPNOTSUPP;
                return EINVAL;
        }
 



The above is sufficient for the Pine64+ 2GB to boot and operate from
the e.MMC on a microsd card adapter, using DDR52, without the prior
hack being present.

I can not claim to know enough to make sure the changes are fully
general.

MMC_CAP_SIGNALING_180 is/was used in the following places:

# grep -r MMC_CAP_SIGNALING_180 /usr/src/sys/
/usr/src/sys/arm/allwinner/aw_mmc.c:    sc->aw_host.caps |= MMC_CAP_SIGNALING_330; // | MMC_CAP_SIGNALING_180; not used on Pine64+ 2GB
/usr/src/sys/dev/sdhci/sdhci.c:         host_caps |= MMC_CAP_SIGNALING_120 | MMC_CAP_SIGNALING_180;
/usr/src/sys/dev/sdhci/sdhci.c:         host_caps &= ~(MMC_CAP_SIGNALING_120 | MMC_CAP_SIGNALING_180);
/usr/src/sys/dev/sdhci/sdhci.c:             (host_caps & MMC_CAP_SIGNALING_180) ? " 1.8V" : "",
/usr/src/sys/dev/sdhci/sdhci.c:         if (!(slot->host.caps & MMC_CAP_SIGNALING_180)) {
/usr/src/sys/dev/mmc/mmc.c:                             if ((host_caps & MMC_CAP_SIGNALING_180) != 0)
/usr/src/sys/dev/mmc/mmc.c:                         (host_caps & MMC_CAP_SIGNALING_180) != 0) {
/usr/src/sys/dev/mmc/mmc.c:                         (host_caps & MMC_CAP_SIGNALING_180) != 0 &&
/usr/src/sys/dev/mmc/mmc.c:                         (host_caps & MMC_CAP_SIGNALING_180) != 0 &&
/usr/src/sys/dev/mmc/bridge.h:#define   MMC_CAP_SIGNALING_180   (1 << 19) /* Can do signaling at 1.8 V */



I've not done anything relative to the following, as in my limited
test context I've not found a operational difference and I do not
have the general background to work without such as a cross check.

It seem that sdhci_init_slot is another area of source code
that forces MMC_CAP_SIGNALING_180, this time for MMC_CAP_MMC_DDR52
use (and MMC_CAP_MMC_DDR52_180 use):

        /* Determine supported VCCQ signaling levels. */
        host_caps |= MMC_CAP_SIGNALING_330;
        if (host_caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
            MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 | MMC_CAP_UHS_SDR104 |
            MMC_CAP_MMC_DDR52_180 | MMC_CAP_MMC_HS200_180 |
            MMC_CAP_MMC_HS400_180))
                host_caps |= MMC_CAP_SIGNALING_120 | MMC_CAP_SIGNALING_180;

where MMC_CAP_MMC_DDR52 and MMC_CAP_MMC_DDR52 _180 are based on:

/usr/src/sys/dev/mmc/bridge.h:#define   MMC_CAP_MMC_DDR52_120   (1 << 11) /* Can do eMMC DDR52 at 1.2 V */
/usr/src/sys/dev/mmc/bridge.h:#define   MMC_CAP_MMC_DDR52_180   (1 << 12) /* Can do eMMC DDR52 at 1.8 V */
/usr/src/sys/dev/mmc/bridge.h:#define   MMC_CAP_MMC_DDR52       (MMC_CAP_MMC_DDR52_120 | MMC_CAP_MMC_DDR52_180)

(so MMC_CAP_MMC_DDR52 includes MMC_CAP_MMC_DDR52_180).

Having e.MMC DDR52 only using the range around 3V does not seem to be covered
in sdhci_init_slot .


===
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)



More information about the freebsd-arm mailing list