[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(®s->irqstat);
>> - while (!(esdhc_read32(®s->prsstat) & PRSSTAT_BREN)
>> - && --timeout);
>> - if (timeout <= 0) {
>> - printf("\nData Read Failed in PIO Mode.");
>> - return;
>> + while (!(esdhc_read32(®s->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