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.