diff --git a/sys/arch/arm/omap/omap3_sdhc.c b/sys/arch/arm/omap/omap3_sdhc.c index 1b66a70dea28..6f3f6e4fa188 100644 --- a/sys/arch/arm/omap/omap3_sdhc.c +++ b/sys/arch/arm/omap/omap3_sdhc.c @@ -1,4 +1,4 @@ -/* $NetBSD: omap3_sdhc.c,v 1.5 2012/12/12 15:19:53 matt Exp $ */ +/* $NetBSD: omap3_sdhc.c,v 1.6 2012/12/13 06:43:38 riastradh Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. @@ -29,7 +29,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: omap3_sdhc.c,v 1.5 2012/12/12 15:19:53 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: omap3_sdhc.c,v 1.6 2012/12/13 06:43:38 riastradh Exp $"); #include "opt_omap.h" @@ -150,6 +150,9 @@ obiosdhc_attach(device_t parent, device_t self, void *aux) sc->sc.sc_flags |= SDHC_FLAG_NO_LED_ON; sc->sc.sc_flags |= SDHC_FLAG_RSP136_CRC; sc->sc.sc_flags |= SDHC_FLAG_SINGLE_ONLY; +#ifdef TI_AM335X + sc->sc.sc_flags |= SDHC_FLAG_WAIT_RESET; +#endif sc->sc.sc_host = sc->sc_hosts; sc->sc.sc_clkbase = 96000; /* 96MHZ */ if (!prop_dictionary_get_uint32(prop, "clkmask", &sc->sc.sc_clkmsk)) diff --git a/sys/dev/sdmmc/sdhc.c b/sys/dev/sdmmc/sdhc.c index bb449ba3f9e4..931e16b556f1 100644 --- a/sys/dev/sdmmc/sdhc.c +++ b/sys/dev/sdmmc/sdhc.c @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.34 2012/12/12 15:15:31 matt Exp $ */ +/* $NetBSD: sdhc.c,v 1.35 2012/12/13 06:43:37 riastradh Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.34 2012/12/12 15:15:31 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.35 2012/12/13 06:43:37 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1518,17 +1518,37 @@ sdhc_soft_reset(struct sdhc_host *hp, int mask) DPRINTF(1,("%s: software reset reg=%08x\n", HDEVNAME(hp), mask)); + /* Request the reset. */ HWRITE1(hp, SDHC_SOFTWARE_RESET, mask); + + /* + * If necessary, wait for the controller to set the bits to + * acknowledge the reset. + */ + if (ISSET(hp->sc->sc_flags, SDHC_FLAG_WAIT_RESET) && + ISSET(mask, (SDHC_RESET_DAT | SDHC_RESET_CMD))) { + for (timo = 10000; timo > 0; timo--) { + if (ISSET(HREAD1(hp, SDHC_SOFTWARE_RESET), mask)) + break; + /* Short delay because I worry we may miss it... */ + sdmmc_delay(1); + } + if (timo == 0) + return ETIMEDOUT; + } + + /* + * Wait for the controller to clear the bits to indicate that + * the reset has completed. + */ for (timo = 10; timo > 0; timo--) { if (!ISSET(HREAD1(hp, SDHC_SOFTWARE_RESET), mask)) break; sdmmc_delay(10000); - HWRITE1(hp, SDHC_SOFTWARE_RESET, 0); } if (timo == 0) { DPRINTF(1,("%s: timeout reg=%08x\n", HDEVNAME(hp), HREAD1(hp, SDHC_SOFTWARE_RESET))); - HWRITE1(hp, SDHC_SOFTWARE_RESET, 0); return ETIMEDOUT; } diff --git a/sys/dev/sdmmc/sdhcvar.h b/sys/dev/sdmmc/sdhcvar.h index 4d945549819c..fd1441c349b1 100644 --- a/sys/dev/sdmmc/sdhcvar.h +++ b/sys/dev/sdmmc/sdhcvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: sdhcvar.h,v 1.10 2012/12/12 15:15:31 matt Exp $ */ +/* $NetBSD: sdhcvar.h,v 1.11 2012/12/13 06:43:37 riastradh Exp $ */ /* $OpenBSD: sdhcvar.h,v 1.3 2007/09/06 08:01:01 jsg Exp $ */ /* @@ -47,6 +47,7 @@ struct sdhc_softc { #define SDHC_FLAG_HOSTCAPS 0x0200 /* No device provided capabilities */ #define SDHC_FLAG_RSP136_CRC 0x0400 /* Resp 136 with CRC and end-bit */ #define SDHC_FLAG_SINGLE_ONLY 0x0800 /* Single transfer only */ +#define SDHC_FLAG_WAIT_RESET 0x1000 /* Wait for soft resets to start */ uint32_t sc_clkbase; int sc_clkmsk; /* Mask for SDCLK */