Module Name: src
Committed By: riastradh
Date: Thu Dec 13 06:43:38 UTC 2012
Modified Files:
src/sys/arch/arm/omap: omap3_sdhc.c
src/sys/dev/sdmmc: sdhc.c sdhcvar.h
Log Message:
Implement TI AM335x's SDHC reset quirk. Beaglebone SDHC works now!
On the AM335x, we first must wait for the controller to acknowledge
the reset; then we can wait for the reset to complete.
I believe this quirk also applies to the OMAP4 ES, but I don't have
one of those to test and we don't seem to have an obvious conditional
for it anyway.
This quirk may work for controllers that don't require it too, but I
am nervous about doing it by default because if we miss the reset
acknowledgement, then we'll just time out even though everything is
really hunky-dory.
Also, for all sdhc, don't bother writing 0 in sdhc_soft_reset while
waiting for the reset to complete; there is no need.
ok matt
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/omap/omap3_sdhc.c
cvs rdiff -u -r1.34 -r1.35 src/sys/dev/sdmmc/sdhc.c
cvs rdiff -u -r1.10 -r1.11 src/sys/dev/sdmmc/sdhcvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/omap/omap3_sdhc.c
diff -u src/sys/arch/arm/omap/omap3_sdhc.c:1.5 src/sys/arch/arm/omap/omap3_sdhc.c:1.6
--- src/sys/arch/arm/omap/omap3_sdhc.c:1.5 Wed Dec 12 15:19:53 2012
+++ src/sys/arch/arm/omap/omap3_sdhc.c Thu Dec 13 06:43:38 2012
@@ -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 <sys/cdefs.h>
-__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_
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))
Index: src/sys/dev/sdmmc/sdhc.c
diff -u src/sys/dev/sdmmc/sdhc.c:1.34 src/sys/dev/sdmmc/sdhc.c:1.35
--- src/sys/dev/sdmmc/sdhc.c:1.34 Wed Dec 12 15:15:31 2012
+++ src/sys/dev/sdmmc/sdhc.c Thu Dec 13 06:43:37 2012
@@ -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 <sys/cdefs.h>
-__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, in
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;
}
Index: src/sys/dev/sdmmc/sdhcvar.h
diff -u src/sys/dev/sdmmc/sdhcvar.h:1.10 src/sys/dev/sdmmc/sdhcvar.h:1.11
--- src/sys/dev/sdmmc/sdhcvar.h:1.10 Wed Dec 12 15:15:31 2012
+++ src/sys/dev/sdmmc/sdhcvar.h Thu Dec 13 06:43:37 2012
@@ -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 */