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
This commit is contained in:
parent
a7e8133750
commit
98770c509f
@ -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_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))
|
||||
|
@ -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, 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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user