Message ID | 1332195126-24719-1-git-send-email-notasas@gmail.com |
---|---|
State | Accepted |
Commit | 25c719e2c3247ef0bab28ee562f978e2ce9211e3 |
Delegated to: | Andy Fleming |
Headers | show |
On Tue, Mar 20, 2012 at 12:12:06AM +0200, Grazvydas Ignotas wrote: > According to OMAP3 TRM, when the controller reports certain errors, > driver must perform a software reset. This is done by setting a bit > in SYSCTL and waiting it to clear: > - SRC on command timeout (CTO) > - SRD on data errors (DTO, DCRC and DEB) > > This fixes a problem seen on OMAP3 pandora board with some cards > that won't work with a message printed multiple times: > timedout waiting on cmd inhibit to clear > > Code loosely based on Linux omap_hsmmc driver. > > Signed-off-by: Grazvydas Ignotas <notasas@gmail.com> On a BeagleBoard xM (rev A), tested various class 2 and 4 uSD cards I have (none of which have ever failed, however). On a BeagleBoard rev C5 and am335x EVM and an omap4_panda (ES), tested with various class 2, 4 and 6 SD cards (or uSD in adapter). Tested-by: Tom Rini <trini@ti.com> And I've sent a private message to folks that have had failing cards that previous changes have fixed to make sure this doesn't break them.
On Monday 19 March 2012 15:14:39 Tom Rini wrote: > On 03/19/2012 03:12 PM, Grazvydas Ignotas wrote: > > According to OMAP3 TRM, when the controller reports certain > > errors, driver must perform a software reset. This is done by > > setting a bit in SYSCTL and waiting it to clear: > > - SRC on command timeout (CTO) > > - SRD on data errors (DTO, DCRC and DEB) > > > > This fixes a problem seen on OMAP3 pandora board with some cards > > > > that won't work with a message printed multiple times: > > timedout waiting on cmd inhibit to clear > > > > Code loosely based on Linux omap_hsmmc driver. > > > > Signed-off-by: Grazvydas Ignotas<notasas@gmail.com> > > Most excellent! Pali, can you try this on N900 and see if that > helps out the problem you were having as well? > > Andy, I'll give this a spin through the boards I've got here but > I'd like this to go, via your tree, into u-boot/master assuming > all goes well. Hi! I tried this patch and it really fixed problem on Nokia N900.
On Wednesday 21 March 2012 20:11:08 Pali Rohár wrote: > On Monday 19 March 2012 15:14:39 Tom Rini wrote: > > On 03/19/2012 03:12 PM, Grazvydas Ignotas wrote: > > > According to OMAP3 TRM, when the controller reports certain > > > errors, driver must perform a software reset. This is done by > > > setting a bit in SYSCTL and waiting it to clear: > > > - SRC on command timeout (CTO) > > > - SRD on data errors (DTO, DCRC and DEB) > > > > > > This fixes a problem seen on OMAP3 pandora board with some > > > cards > > > > > > that won't work with a message printed multiple times: > > > timedout waiting on cmd inhibit to clear > > > > > > Code loosely based on Linux omap_hsmmc driver. > > > > > > Signed-off-by: Grazvydas Ignotas<notasas@gmail.com> > > > > Most excellent! Pali, can you try this on N900 and see if that > > helps out the problem you were having as well? > > > > Andy, I'll give this a spin through the boards I've got here but > > I'd like this to go, via your tree, into u-boot/master assuming > > all goes well. > > Hi! > > I tried this patch and it > really fixed problem on Nokia N900. Tested-by: Pali Rohár <pali.rohar@gmail.com>
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 4b81d0d..06cbebf 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -33,6 +33,10 @@ #include <asm/arch/mmc_host_def.h> #include <asm/arch/sys_proto.h> +/* common definitions for all OMAPs */ +#define SYSCTL_SRC (1 << 25) +#define SYSCTL_SRD (1 << 26) + /* If we fail after 1 second wait, something is really bad */ #define MAX_RETRY_MS 1000 @@ -195,6 +199,27 @@ static int mmc_init_setup(struct mmc *mmc) return 0; } +/* + * MMC controller internal finite state machine reset + * + * Used to reset command or data internal state machines, using respectively + * SRC or SRD bit of SYSCTL register + */ +static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit) +{ + ulong start; + + mmc_reg_out(&mmc_base->sysctl, bit, bit); + + start = get_timer(0); + while ((readl(&mmc_base->sysctl) & bit) != 0) { + if (get_timer(0) - start > MAX_RETRY_MS) { + printf("%s: timedout waiting for sysctl %x to clear\n", + __func__, bit); + return; + } + } +} static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) @@ -284,9 +309,10 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, } } while (!mmc_stat); - if ((mmc_stat & IE_CTO) != 0) + if ((mmc_stat & IE_CTO) != 0) { + mmc_reset_controller_fsm(mmc_base, SYSCTL_SRC); return TIMEOUT; - else if ((mmc_stat & ERRI_MASK) != 0) + } else if ((mmc_stat & ERRI_MASK) != 0) return -1; if (mmc_stat & CC_MASK) { @@ -337,6 +363,9 @@ static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size) } } while (mmc_stat == 0); + if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0) + mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD); + if ((mmc_stat & ERRI_MASK) != 0) return 1; @@ -389,6 +418,9 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, } } while (mmc_stat == 0); + if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0) + mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD); + if ((mmc_stat & ERRI_MASK) != 0) return 1;
According to OMAP3 TRM, when the controller reports certain errors, driver must perform a software reset. This is done by setting a bit in SYSCTL and waiting it to clear: - SRC on command timeout (CTO) - SRD on data errors (DTO, DCRC and DEB) This fixes a problem seen on OMAP3 pandora board with some cards that won't work with a message printed multiple times: timedout waiting on cmd inhibit to clear Code loosely based on Linux omap_hsmmc driver. Signed-off-by: Grazvydas Ignotas <notasas@gmail.com> --- drivers/mmc/omap_hsmmc.c | 36 ++++++++++++++++++++++++++++++++++-- 1 files changed, 34 insertions(+), 2 deletions(-)