summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBenoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>2017-10-29 21:08:58 (GMT)
committerStefano Babic <sbabic@denx.de>2017-11-07 09:26:27 (GMT)
commitbcfb36537552441faeceb6b0089ab40a29b9dff3 (patch)
tree1270d542e8e13e1399be7a4e7cc42ebf2ef29c31 /drivers
parentcc65e354feb6f13fb4d7c910edaddf805fe08c71 (diff)
downloadu-boot-bcfb36537552441faeceb6b0089ab40a29b9dff3.tar.xz
mmc: fsl_esdhc: Fix PIO timeout
The following error has been observed on i.MX25 with a high-speed SDSC card: Data Write Failed in PIO Mode. It was caused by the timeout set on PRSSTAT.BWEN, which was triggered because this bit takes 15 ms to be set after writing the first block to DATPORT with this card. Without this timeout, all the blocks are properly written. This timeout was implemented by decrementing a variable, so it was depending on the CPU frequency. Fix this issue by setting this timeout to a long enough absolute duration (500 ms). Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com> Cc: Stefano Babic <sbabic@denx.de> Cc: Fabio Estevam <fabio.estevam@nxp.com> Cc: Jaehoon Chung <jh80.chung@samsung.com> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com> Reviewed-by: Jagan Teki <jagan@openedev.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/fsl_esdhc.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index cc188c4..499d622 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -171,20 +171,20 @@ static void esdhc_pio_read_write(struct fsl_esdhc_priv *priv,
uint databuf;
uint size;
uint irqstat;
- uint timeout;
+ ulong start;
if (data->flags & MMC_DATA_READ) {
blocks = data->blocks;
buffer = data->dest;
while (blocks) {
- timeout = PIO_TIMEOUT;
+ start = get_timer(0);
size = data->blocksize;
irqstat = esdhc_read32(&regs->irqstat);
- while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BREN)
- && --timeout);
- if (timeout <= 0) {
- printf("\nData Read Failed in PIO Mode.");
- return;
+ while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BREN)) {
+ if (get_timer(start) > PIO_TIMEOUT) {
+ printf("\nData Read Failed in PIO Mode.");
+ return;
+ }
}
while (size && (!(irqstat & IRQSTAT_TC))) {
udelay(100); /* Wait before last byte transfer complete */
@@ -200,14 +200,14 @@ static void esdhc_pio_read_write(struct fsl_esdhc_priv *priv,
blocks = data->blocks;
buffer = (char *)data->src;
while (blocks) {
- timeout = PIO_TIMEOUT;
+ start = get_timer(0);
size = data->blocksize;
irqstat = esdhc_read32(&regs->irqstat);
- while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BWEN)
- && --timeout);
- if (timeout <= 0) {
- printf("\nData Write Failed in PIO Mode.");
- return;
+ while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BWEN)) {
+ if (get_timer(start) > PIO_TIMEOUT) {
+ printf("\nData Write Failed in PIO Mode.");
+ return;
+ }
}
while (size && (!(irqstat & IRQSTAT_TC))) {
udelay(100); /* Wait before last byte transfer complete */