diff mbox

[U-Boot,v2,3/5] mmc: fsl_esdhc: add error recovery for data transfer with Auto CMD12

Message ID 1470129653-15854-3-git-send-email-yangbo.lu@nxp.com
State Changes Requested
Delegated to: York Sun
Headers show

Commit Message

Yangbo Lu Aug. 2, 2016, 9:20 a.m. UTC
For data transfer with Auto CMD12, the host will not send an Auto
CMD12 to stop when the transfer fails. So this patch adds a flag
to indicate the READ/WRITE command error, and makes the driver
continue to send a CMD12 manually.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None
---
 drivers/mmc/fsl_esdhc.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index b23845d..80bc177 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -106,6 +106,9 @@  struct fsl_esdhc_priv {
 	int wp_enable;
 	struct gpio_desc cd_gpio;
 	struct gpio_desc wp_gpio;
+#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
+	int rw_err;
+#endif
 };
 
 /* Return the XFERTYP flags for a given command and data packet */
@@ -362,8 +365,12 @@  esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 	struct fsl_esdhc *regs = priv->esdhc_regs;
 
 #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
-	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
-		return 0;
+	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) {
+		if (priv->rw_err)
+			priv->rw_err = 0;
+		else
+			return 0;
+	}
 #endif
 
 	esdhc_write32(&regs->irqstat, -1);
@@ -518,6 +525,13 @@  out:
 		/* If this was CMD11, then notify that power cycle is needed */
 		if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V)
 			printf("CMD11 to switch to 1.8V mode failed, card requires power cycle.\n");
+#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
+		if (cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK ||
+		    cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK ||
+		    cmd->cmdidx == MMC_CMD_WRITE_SINGLE_BLOCK ||
+		    cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)
+			priv->rw_err = 1;
+#endif
 	}
 
 	esdhc_write32(&regs->irqstat, -1);
@@ -828,6 +842,10 @@  static int fsl_esdhc_init(struct fsl_esdhc_priv *priv)
 
 	priv->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
+#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
+	priv->rw_err = 0;
+#endif
+
 	mmc = mmc_create(&priv->cfg, priv);
 	if (mmc == NULL)
 		return -1;