public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH] mmc: fsl_esdhc: Fix PIO timeout
@ 2017-10-29 21:08 Benoît Thébaudeau
  2017-10-31 14:31 ` Fabio Estevam
  2017-10-31 15:18 ` Jagan Teki
  0 siblings, 2 replies; 5+ messages in thread
From: Benoît Thébaudeau @ 2017-10-29 21:08 UTC (permalink / raw)
  To: u-boot

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@gmail.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Jaehoon Chung <jh80.chung@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;
+				}
 			}
 			while (size && (!(irqstat & IRQSTAT_TC))) {
 				udelay(100); /* Wait before last byte transfer complete */
@@ -200,14 +200,14 @@ static void esdhc_pio_read_write(struct fsl_esdhc_priv *priv,
 		blocks = data->blocks;
 		buffer = (char *)data->src;
 		while (blocks) {
-			timeout = PIO_TIMEOUT;
+			start = get_timer(0);
 			size = data->blocksize;
 			irqstat = esdhc_read32(&regs->irqstat);
-			while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BWEN)
-				&& --timeout);
-			if (timeout <= 0) {
-				printf("\nData Write Failed in PIO Mode.");
-				return;
+			while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BWEN)) {
+				if (get_timer(start) > PIO_TIMEOUT) {
+					printf("\nData Write Failed in PIO Mode.");
+					return;
+				}
 			}
 			while (size && (!(irqstat & IRQSTAT_TC))) {
 				udelay(100); /* Wait before last byte transfer complete */
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index 02b362d5e3..de1f5e7d9f 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -130,7 +130,7 @@
 #define XFERTYP_DMAEN		0x00000001
 
 #define CINS_TIMEOUT		1000
-#define PIO_TIMEOUT		100000
+#define PIO_TIMEOUT		500
 
 #define DSADDR		0x2e004
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH] mmc: fsl_esdhc: Fix PIO timeout
  2017-10-29 21:08 [U-Boot] [PATCH] mmc: fsl_esdhc: Fix PIO timeout Benoît Thébaudeau
@ 2017-10-31 14:31 ` Fabio Estevam
  2017-10-31 15:18 ` Jagan Teki
  1 sibling, 0 replies; 5+ messages in thread
From: Fabio Estevam @ 2017-10-31 14:31 UTC (permalink / raw)
  To: u-boot

On Sun, Oct 29, 2017 at 7:08 PM, Benoît Thébaudeau
<benoit.thebaudeau.dev@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@gmail.com>
> Cc: Stefano Babic <sbabic@denx.de>
> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>

Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH] mmc: fsl_esdhc: Fix PIO timeout
  2017-10-29 21:08 [U-Boot] [PATCH] mmc: fsl_esdhc: Fix PIO timeout Benoît Thébaudeau
  2017-10-31 14:31 ` Fabio Estevam
@ 2017-10-31 15:18 ` Jagan Teki
  2017-10-31 20:35   ` Benoît Thébaudeau
  1 sibling, 1 reply; 5+ messages in thread
From: Jagan Teki @ 2017-10-31 15:18 UTC (permalink / raw)
  To: u-boot

On Mon, Oct 30, 2017 at 2:38 AM, Benoît Thébaudeau
<benoit.thebaudeau.dev@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@gmail.com>
> Cc: Stefano Babic <sbabic@denx.de>
> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> Cc: Jaehoon Chung <jh80.chung@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.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH] mmc: fsl_esdhc: Fix PIO timeout
  2017-10-31 15:18 ` Jagan Teki
@ 2017-10-31 20:35   ` Benoît Thébaudeau
  2017-11-01 14:47     ` Jagan Teki
  0 siblings, 1 reply; 5+ messages in thread
From: Benoît Thébaudeau @ 2017-10-31 20:35 UTC (permalink / raw)
  To: u-boot

On Tue, Oct 31, 2017 at 4:18 PM, Jagan Teki <jagannadh.teki@gmail.com> wrote:
> On Mon, Oct 30, 2017 at 2:38 AM, Benoît Thébaudeau
> <benoit.thebaudeau.dev@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@gmail.com>
>> Cc: Stefano Babic <sbabic@denx.de>
>> Cc: Fabio Estevam <fabio.estevam@nxp.com>
>> Cc: Jaehoon Chung <jh80.chung@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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH] mmc: fsl_esdhc: Fix PIO timeout
  2017-10-31 20:35   ` Benoît Thébaudeau
@ 2017-11-01 14:47     ` Jagan Teki
  0 siblings, 0 replies; 5+ messages in thread
From: Jagan Teki @ 2017-11-01 14:47 UTC (permalink / raw)
  To: u-boot

On Wed, Nov 1, 2017 at 2:05 AM, Benoît Thébaudeau
<benoit.thebaudeau.dev@gmail.com> wrote:
> On Tue, Oct 31, 2017 at 4:18 PM, Jagan Teki <jagannadh.teki@gmail.com> wrote:
>> On Mon, Oct 30, 2017 at 2:38 AM, Benoît Thébaudeau
>> <benoit.thebaudeau.dev@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@gmail.com>
>>> Cc: Stefano Babic <sbabic@denx.de>
>>> Cc: Fabio Estevam <fabio.estevam@nxp.com>
>>> Cc: Jaehoon Chung <jh80.chung@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@openedev.com>

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-11-01 14:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-10-29 21:08 [U-Boot] [PATCH] mmc: fsl_esdhc: Fix PIO timeout Benoît Thébaudeau
2017-10-31 14:31 ` Fabio Estevam
2017-10-31 15:18 ` Jagan Teki
2017-10-31 20:35   ` Benoît Thébaudeau
2017-11-01 14:47     ` Jagan Teki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox