Skip to content

Commit

Permalink
esdhc/usdhc: Fix PIO mode bug in fsl_esdhc driver
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Ye.Li <[email protected]>
  • Loading branch information
Ye.Li authored and pantoniou committed May 22, 2014
1 parent d7782d0 commit 7168977
Showing 1 changed file with 9 additions and 14 deletions.
23 changes: 9 additions & 14 deletions drivers/mmc/fsl_esdhc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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);

Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 7168977

Please sign in to comment.