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.