[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(®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.
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