diff mbox

[U-Boot] mmc:sdhci: Fix card ready status timeout.

Message ID 1378212631-25526-1-git-send-email-p.marczak@samsung.com
State Changes Requested
Delegated to: Minkyu Kang
Headers show

Commit Message

Przemyslaw Marczak Sept. 3, 2013, 12:50 p.m. UTC
According to JEDEC eMMC specification, after data transfer
(multiple or single block) host must wait for card ready
status. This is done by waiting for command and data lines
to be at idle state after transfer. JEDEC does not specify
maximum timeout.

Before this change max timeout was 10 ms but in case of UMS
- when system does multiple read/write operations on random
card blocks - timeout causes I/O errors.
The timeout has been increased to 200ms after data transfer.
For other transfers it stays unchanged.

Tested on Goni and Trats.

Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com>
Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
---
 drivers/mmc/sdhci.c |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

Comments

Pantelis Antoniou Sept. 6, 2013, 1:24 p.m. UTC | #1
Hi there,

On Sep 3, 2013, at 3:50 PM, Przemyslaw Marczak wrote:

> According to JEDEC eMMC specification, after data transfer
> (multiple or single block) host must wait for card ready
> status. This is done by waiting for command and data lines
> to be at idle state after transfer. JEDEC does not specify
> maximum timeout.
> 
> Before this change max timeout was 10 ms but in case of UMS
> - when system does multiple read/write operations on random
> card blocks - timeout causes I/O errors.
> The timeout has been increased to 200ms after data transfer.
> For other transfers it stays unchanged.
> 
> Tested on Goni and Trats.
> 
> Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com>
> Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
> ---
> drivers/mmc/sdhci.c |   14 ++++++++++++--
> 1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
> index 4261991..c495482 100644
> --- a/drivers/mmc/sdhci.c
> +++ b/drivers/mmc/sdhci.c
> @@ -121,8 +121,18 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
> 	unsigned int timeout, start_addr = 0;
> 	unsigned int retry = 10000;
> 
> -	/* Wait max 10 ms */
> -	timeout = 10;
> +	/*
> +	 * For some commands this function is called with NULL mmc_data
> +	 * pointer. One of those is CMD13 - send card status.
> +	 * After read/write data transfer or block erase commands - host sends
> +	 * CMD13 and is waiting for card ready status with some timeout.
> +	 * According to some internal cards operations after those commands
> +	 * this time must be increased.
> +	 */
> +	if (data)
> +		timeout = 10; /* ms */
> +	else
> +		timeout = 200;
> 
> 	sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
> 	mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT;
> -- 
> 1.7.9.5
> 

Can we have a config option for these two values instead of magic numbers?

With the defaults being set at 10 & 200 ms.

Regards

-- Pantelis


> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
Przemyslaw Marczak Sept. 6, 2013, 3:23 p.m. UTC | #2
Hello Pantelis,

 > On 09/06/2013 03:24 PM, Pantelis Antoniou wrote:
> Hi there,
>
> Can we have a config option for these two values instead of magic numbers?
>
> With the defaults being set at 10 & 200 ms.
>
> Regards
>
> -- Pantelis

I'm not sure that this option is needed. Some cards I/O errors can be 
avoided by increasing timeout and has no negative influence on other 
cards read/write operations performance.
Moreover there are a lot of timeout values defined in sdhci and mmc 
drivers, so why should I put at config just only one? Maybe the simplest 
solution is to leave at this code only 200 ms value.
What do you think?

Regards,
Pantelis Antoniou Sept. 6, 2013, 3:27 p.m. UTC | #3
Hi there,

On Sep 6, 2013, at 6:23 PM, Przemyslaw Marczak wrote:

> Hello Pantelis,
> 
> > On 09/06/2013 03:24 PM, Pantelis Antoniou wrote:
>> Hi there,
>> 
>> Can we have a config option for these two values instead of magic numbers?
>> 
>> With the defaults being set at 10 & 200 ms.
>> 
>> Regards
>> 
>> -- Pantelis
> 
> I'm not sure that this option is needed. Some cards I/O errors can be avoided by increasing timeout and has no negative influence on other cards read/write operations performance.
> Moreover there are a lot of timeout values defined in sdhci and mmc drivers, so why should I put at config just only one? Maybe the simplest solution is to leave at this code only 200 ms value.
> What do you think?
> 

Still, it's a magic constant in the code; you don't have to export it to boards, just put it in the same source file
just before it's use.

Protect it with an #ifndef statement in case someone else would like to override it.

Regards

-- Pantelis

> Regards,
> 
> -- 
> Przemyslaw Marczak
> Samsung R&D Institute Poland
> Samsung Electronics
> p.marczak@samsung.com
diff mbox

Patch

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 4261991..c495482 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -121,8 +121,18 @@  int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
 	unsigned int timeout, start_addr = 0;
 	unsigned int retry = 10000;
 
-	/* Wait max 10 ms */
-	timeout = 10;
+	/*
+	 * For some commands this function is called with NULL mmc_data
+	 * pointer. One of those is CMD13 - send card status.
+	 * After read/write data transfer or block erase commands - host sends
+	 * CMD13 and is waiting for card ready status with some timeout.
+	 * According to some internal cards operations after those commands
+	 * this time must be increased.
+	 */
+	if (data)
+		timeout = 10; /* ms */
+	else
+		timeout = 200;
 
 	sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
 	mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT;