Only set the highspeed bit in bus_clock if highspeed is supported
by the controller.  Needed as the bus_clock callback is called with
SDMMC_TIMING_HIGHSPEED even if the capability is not set.
Required to raise the bus width on pandaboard which doesn't have
the highspeed capability.

As anything other than 1 bit mode results in the emmc on the bbb
timing out waiting for command completion, limit high bus
modes to the first hsmmc controller (by way of dual-volt property).
This at least lets 4 bit modes work with sd cards on bbb.

Index: ommmc.c
===================================================================
RCS file: /cvs/src/sys/arch/armv7/omap/ommmc.c,v
retrieving revision 1.29
diff -u -p -r1.29 ommmc.c
--- ommmc.c     12 Aug 2016 03:22:41 -0000      1.29
+++ ommmc.c     2 Oct 2016 15:15:00 -0000
@@ -193,6 +193,7 @@ struct ommmc_softc {
        bus_space_handle_t      sc_ioh;
        void                    *sc_ih; /* Interrupt handler */
        uint32_t                sc_flags;
+#define FL_HSS         (1 << 0)
 
        struct device *sdmmc;           /* generic SD/MMC device */
        int clockbit;                   /* clock control bit */
@@ -298,7 +299,7 @@ ommmc_attach(struct device *parent, stru
        struct ommmc_softc              *sc = (struct ommmc_softc *) self;
        struct fdt_attach_args          *faa = aux;
        struct sdmmcbus_attach_args      saa;
-       uint32_t                         caps;
+       uint32_t                         caps, width;
        uint32_t                         addr, size;
        int                              len, unit;
        char                             hwmods[128];
@@ -432,8 +433,19 @@ ommmc_attach(struct device *parent, stru
        saa.saa_busname = "sdmmc";
        saa.sct = &ommmc_functions;
        saa.sch = sc;
-       if (caps & MMCHS_CAPA_HSS)
-               saa.caps |= SMC_CAPS_MMC_HIGHSPEED;
+       if (OF_getproplen(faa->fa_node, "ti,needs-special-hs-handling") == 0 &&
+           (caps & MMCHS_CAPA_HSS)) {
+               sc->sc_flags |= FL_HSS;
+               saa.caps |= SMC_CAPS_MMC_HIGHSPEED | SMC_CAPS_SD_HIGHSPEED;
+       }
+       width = OF_getpropint(faa->fa_node, "bus-width", 1);
+       /* with emmc width > 1 ommmc_wait_intr MMCHS_STAT_CC times out */
+       if (OF_getproplen(faa->fa_node, "ti,dual-volt") != 0)
+               width = 1;
+       if (width >= 8)
+               saa.caps |= SMC_CAPS_8BIT_MODE;
+       if (width >= 4)
+               saa.caps |= SMC_CAPS_4BIT_MODE;
 
        sc->sdmmc = config_found(&sc->sc_dev, &saa, NULL);
        if (sc->sdmmc == NULL) {
@@ -717,10 +729,10 @@ ommmc_bus_clock(sdmmc_chipset_handle_t s
        reg |= div << MMCHS_SYSCTL_CLKD_SH;
        HWRITE4(sc, MMCHS_SYSCTL, reg);
 
-       if (timing == SDMMC_TIMING_LEGACY)
-               HCLR4(sc, MMCHS_HCTL, MMCHS_HCTL_HSPE);
-       else
+       if ((timing == SDMMC_TIMING_HIGHSPEED) && (sc->sc_flags & FL_HSS))
                HSET4(sc, MMCHS_HCTL, MMCHS_HCTL_HSPE);
+       else
+               HCLR4(sc, MMCHS_HCTL, MMCHS_HCTL_HSPE);
 
        /*
         * Start internal clock.  Wait 10ms for stabilization.

Reply via email to