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

Jagan Teki jagannadh.teki at gmail.com
Wed Nov 1 14:47:23 UTC 2017


On Wed, Nov 1, 2017 at 2:05 AM, Benoît Thébaudeau
<benoit.thebaudeau.dev at gmail.com> wrote:
> 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.

Reviewed-by: Jagan Teki <jagan at openedev.com>

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


More information about the U-Boot mailing list