summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorYe.Li <B37916@freescale.com>2014-02-20 18:00:57 +0800
committerPantelis Antoniou <panto@antoniou-consulting.com>2014-05-22 18:52:45 +0300
commit716897760fe41c350f55564a73d2e58dafd1ee53 (patch)
treea6f32ab9837db4b7fef57f504dc36879a9563a33 /drivers/mmc
parentd7782d06534fe4fa47a49fa7c106de5ba85a9687 (diff)
esdhc/usdhc: Fix PIO mode bug in fsl_esdhc driver
When configure the fsl_esdhc 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. Acked-by: Pantelis Antoniou <panto@antoniou-consulting.com> Signed-off-by: Ye.Li <B37916@freescale.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/fsl_esdhc.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 50cba64d99..dca28f4495 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -174,7 +174,7 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
int timeout;
struct fsl_esdhc_cfg *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;
@@ -184,12 +184,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) {
@@ -199,19 +202,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);
@@ -388,9 +382,10 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
goto out;
}
} while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE);
-#endif
+
if (data->flags & MMC_DATA_READ)
check_and_invalidate_dcache_range(cmd, data);
+#endif
}
out: