Patchwork [U-Boot,u-boot,RFC,v1] omap_hsmmc: omap4+/am335x: modify MMC controller internal fsm reset func

login
register
mail settings
Submitter Oleksandr Tyshchenko
Date Aug. 6, 2013, 10:44 a.m.
Message ID <1375785856-7813-1-git-send-email-oleksandr.tyshchenko@ti.com>
Download mbox | patch
Permalink /patch/265000/
State Accepted
Delegated to: Pantelis Antoniou
Headers show

Comments

Oleksandr Tyshchenko - Aug. 6, 2013, 10:44 a.m.
"mmc_send_cmd: timeout: No status update" error sometimes happens in
omap_hsmmc driver func mmc_send_cmd() when the MMC controller card
identification and selection sequence is executed for eMMC on OMAP4
boards.

It happens due to incorrect execution of CMD line reset procedure
for OMAP4. Because CMD(DAT) lines reset procedures are slightly
different for OMAP3 and OMAP4(AM335x,OMAP5,DRA7xx).

According to OMAP3 TRM:
Set SRC(SRD) bit in MMCHS_SYSCTL register to 0x1 and wait until
it returns to 0x0.

According to OMAP4(AM335x,OMAP5,DRA7xx) TRMs, CMD(DATA) lines reset
procedure steps must be as follows:
1. Initiate CMD(DAT) line reset by writing 0x1 to SRC(SRD) bit in
   MMCHS_SYSCTL register (SD_SYSCTL for AM335x).
2. Poll the SRC(SRD) bit until it is set to 0x1.
3. Wait until the SRC(SRD) bit returns to 0x0
  (reset procedure is completed).

Unfortunately, at present omap_hsmmc driver has support only for
OMAP3. And as result step #2 is missing for OMAP4(AM335x,OMAP5,DRA7xx).
This sometimes leads to the fact that the waiting loop which is
required in step #3 does not executed, because SRC bit does not set
yet (at the moment of checking a condition of a loop execution).
And as a result this can cause to timeout error when sending a
next command.

In the particular case (working with eMMC witch do not respond to
some SD specific command) due to incorrect reset sequence after
command SD_CMD_SEND_IF_COND which finished with CTO flag within
64 clock cycles, the next command MMC_CMD_APP_CMD leads to a
timeout error within 1s.

So, extend CMD(DATA) lines reset procedure in func
mmc_reset_controller_fsm() by adding the missing step #2 for
OMAP4+/AM335x boards.

Signed-off-by: Oleksandr Tyshchenko <oleksandr.tyshchenko@ti.com>
---
 drivers/mmc/omap_hsmmc.c |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
Pantelis Antoniou - Sept. 6, 2013, 11:40 a.m.
Hi Oleksandr

On Aug 6, 2013, at 1:44 PM, Oleksandr Tyshchenko wrote:

> "mmc_send_cmd: timeout: No status update" error sometimes happens in
> omap_hsmmc driver func mmc_send_cmd() when the MMC controller card
> identification and selection sequence is executed for eMMC on OMAP4
> boards.
> 
> It happens due to incorrect execution of CMD line reset procedure
> for OMAP4. Because CMD(DAT) lines reset procedures are slightly
> different for OMAP3 and OMAP4(AM335x,OMAP5,DRA7xx).
> 
> According to OMAP3 TRM:
> Set SRC(SRD) bit in MMCHS_SYSCTL register to 0x1 and wait until
> it returns to 0x0.
> 
> According to OMAP4(AM335x,OMAP5,DRA7xx) TRMs, CMD(DATA) lines reset
> procedure steps must be as follows:
> 1. Initiate CMD(DAT) line reset by writing 0x1 to SRC(SRD) bit in
>   MMCHS_SYSCTL register (SD_SYSCTL for AM335x).
> 2. Poll the SRC(SRD) bit until it is set to 0x1.
> 3. Wait until the SRC(SRD) bit returns to 0x0
>  (reset procedure is completed).
> 
> Unfortunately, at present omap_hsmmc driver has support only for
> OMAP3. And as result step #2 is missing for OMAP4(AM335x,OMAP5,DRA7xx).
> This sometimes leads to the fact that the waiting loop which is
> required in step #3 does not executed, because SRC bit does not set
> yet (at the moment of checking a condition of a loop execution).
> And as a result this can cause to timeout error when sending a
> next command.
> 
> In the particular case (working with eMMC witch do not respond to
> some SD specific command) due to incorrect reset sequence after
> command SD_CMD_SEND_IF_COND which finished with CTO flag within
> 64 clock cycles, the next command MMC_CMD_APP_CMD leads to a
> timeout error within 1s.
> 
> So, extend CMD(DATA) lines reset procedure in func
> mmc_reset_controller_fsm() by adding the missing step #2 for
> OMAP4+/AM335x boards.
> 
> Signed-off-by: Oleksandr Tyshchenko <oleksandr.tyshchenko@ti.com>

Acked-by: Pantelis Antoniou <panto@antoniou-consulting.com>

Thanks

Patch

diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 975b2c5..0e36bf9 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -288,6 +288,30 @@  static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit)
 
 	mmc_reg_out(&mmc_base->sysctl, bit, bit);
 
+	/*
+	 * CMD(DAT) lines reset procedures are slightly different
+	 * for OMAP3 and OMAP4(AM335x,OMAP5,DRA7xx).
+	 * According to OMAP3 TRM:
+	 * Set SRC(SRD) bit in MMCHS_SYSCTL register to 0x1 and wait until it
+	 * returns to 0x0.
+	 * According to OMAP4(AM335x,OMAP5,DRA7xx) TRMs, CMD(DATA) lines reset
+	 * procedure steps must be as follows:
+	 * 1. Initiate CMD(DAT) line reset by writing 0x1 to SRC(SRD) bit in
+	 *    MMCHS_SYSCTL register (SD_SYSCTL for AM335x).
+	 * 2. Poll the SRC(SRD) bit until it is set to 0x1.
+	 * 3. Wait until the SRC (SRD) bit returns to 0x0
+	 *    (reset procedure is completed).
+	 */
+#if defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
+	defined(CONFIG_AM33XX)
+	if (!(readl(&mmc_base->sysctl) & bit)) {
+		start = get_timer(0);
+		while (!(readl(&mmc_base->sysctl) & bit)) {
+			if (get_timer(0) - start > MAX_RETRY_MS)
+				return;
+		}
+	}
+#endif
 	start = get_timer(0);
 	while ((readl(&mmc_base->sysctl) & bit) != 0) {
 		if (get_timer(0) - start > MAX_RETRY_MS) {