[U-Boot] [PATCH] mmc: omap: handle controller errors properly

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(-)
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;

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 Ignotasnotasas@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.

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 Ignotasnotasas@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 Ignotasnotasas@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

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.
participants (3)
-
Grazvydas Ignotas
-
Pali Rohár
-
Tom Rini