[U-Boot] [PATCH] mmc: fsl_esdhc: Fix PIO timeout

Jagan Teki jagannadh.teki at gmail.com
Tue Oct 31 15:18:30 UTC 2017


On Mon, Oct 30, 2017 at 2:38 AM, Benoît Thébaudeau
<benoit.thebaudeau.dev at gmail.com> wrote:
> 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 at gmail.com>
> Cc: Stefano Babic <sbabic at denx.de>
> Cc: Fabio Estevam <fabio.estevam at nxp.com>
> Cc: Jaehoon Chung <jh80.chung at samsung.com>
> ---
>  drivers/mmc/fsl_esdhc.c | 26 +++++++++++++-------------
>  include/fsl_esdhc.h     |  2 +-
>  2 files changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
> index cc188c4260..499d622c6d 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;
> +                               }

How about using wait_for_bit here?

thanks!
-- 
Jagan Teki
Free Software Engineer | www.openedev.com
U-Boot, Linux | Upstream Maintainer
Hyderabad, India.


More information about the U-Boot mailing list