summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYe.Li <B37916@freescale.com>2014-02-17 16:38:36 +0800
committerYe.Li <B37916@freescale.com>2014-02-19 17:14:36 +0800
commit43a58af0a8e2a3b5c75b130291379acbac0da3d0 (patch)
tree57f03c00d25571351bf87977c2dcb0314167f914
parent738fa47255b9d8becc09df38178da175c2fc0527 (diff)
downloadu-boot-imx-43a58af0a8e2a3b5c75b130291379acbac0da3d0.zip
u-boot-imx-43a58af0a8e2a3b5c75b130291379acbac0da3d0.tar.gz
u-boot-imx-43a58af0a8e2a3b5c75b130291379acbac0da3d0.tar.bz2
ENGR00299356 ARM:imx6 Fix USDHC driver bug in PIO mode
When configure the USDHC driver to PIO mode by defining "CONFIG_SYS_FSL_ESDHC_USE_PIO", the SD/MMC read and write will fail. Two bugs in the driver to cause the issue: 1. The read buffer was invalidated after reading from DATAPORT register, which should be only applied to DMA mode. The valid data in cache was overwritten by physical memory. 2. The watermarks are not set in PIO mode, will cause according state not be set. Signed-off-by: Ye.Li <B37916@freescale.com> (cherry picked from commit e2ced39867a3001390bd23069e56b513ed268bb0)
-rw-r--r--drivers/mmc/fsl_esdhc.c25
1 files changed, 10 insertions, 15 deletions
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index b5f6d62..eed09e1 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, 2010-2013 Freescale Semiconductor, Inc.
+ * Copyright 2007, 2010-2014 Freescale Semiconductor, Inc.
* Andy Fleming
*
* Based vaguely on the pxa mmc code:
@@ -190,7 +190,7 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
int timeout;
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
-#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
+
uint wml_value;
wml_value = data->blocksize/4;
@@ -200,12 +200,15 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
wml_value = WML_RD_WML_MAX_VAL;
esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
+#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
esdhc_write32(&regs->dsaddr, (u32)data->dest);
+#endif
} else {
+#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
flush_dcache_range((ulong)data->src,
(ulong)data->src+data->blocks
*data->blocksize);
-
+#endif
if (wml_value > WML_WR_WML_MAX)
wml_value = WML_WR_WML_MAX_VAL;
if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
@@ -215,19 +218,10 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
wml_value << 16);
+#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
esdhc_write32(&regs->dsaddr, (u32)data->src);
+#endif
}
-#else /* CONFIG_SYS_FSL_ESDHC_USE_PIO */
- if (!(data->flags & MMC_DATA_READ)) {
- if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
- printf("\nThe SD card is locked. "
- "Can not write to a locked card.\n\n");
- return TIMEOUT;
- }
- esdhc_write32(&regs->dsaddr, (u32)data->src);
- } else
- esdhc_write32(&regs->dsaddr, (u32)data->dest);
-#endif /* CONFIG_SYS_FSL_ESDHC_USE_PIO */
esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
@@ -410,9 +404,10 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
if (irqstat & DATA_ERR)
return COMM_ERR;
} while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE);
-#endif
+
if (data->flags & MMC_DATA_READ)
check_and_invalidate_dcache_range(cmd, data);
+#endif
}
esdhc_write32(&regs->irqstat, -1);