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

Benoît Thébaudeau benoit.thebaudeau.dev at gmail.com
Tue Oct 31 20:35:23 UTC 2017


On Tue, Oct 31, 2017 at 4:18 PM, Jagan Teki <jagannadh.teki at gmail.com> wrote:
> 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?

wait_for_bit() uses readl(), whereas here esdhc_read32() is used in
order to take the IP vs. CPU endianness compatibility issues into
account.

Best regards,
Benoît


More information about the U-Boot mailing list