diff mbox

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

Message ID 1377708592-16702-1-git-send-email-p.marczak@samsung.com
State Superseded
Delegated to: Pantelis Antoniou
Headers show

Commit Message

Przemyslaw Marczak Aug. 28, 2013, 4:49 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 do 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 |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Jaehoon Chung Aug. 29, 2013, 3:16 a.m. UTC | #1
Hi Przemyslaw,

Could you give me the test-case?
I want to test this problem.

On 08/29/2013 01:49 AM, 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 do 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 |    6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
> index 4261991..22c18d1 100644
> --- a/drivers/mmc/sdhci.c
> +++ b/drivers/mmc/sdhci.c
> @@ -121,8 +121,10 @@ 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;
> +	if (!data)
> +		timeout = 200;
> +	else
> +		timeout = 10;
And timeout = data ? 10 : 200; ?

Best Regards,
Jaehoon Chung
>  
>  	sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
>  	mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT;
>
Przemyslaw Marczak Sept. 2, 2013, 2:16 p.m. UTC | #2
On 08/29/2013 05:16 AM, Jaehoon Chung wrote:
> Hi Przemyslaw,
>
> Could you give me the test-case?
> I want to test this problem.
>
> On 08/29/2013 01:49 AM, 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 do 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>


Hello,

You can ease reproduce this problem by typing "ums" on prompt(Trats).
If you are using Goni (without ums config), the problem is hard to 
reproduce in this case. Sometimes read one block from mmc just after 
start causes error and then you can see information "Controller never
released inhibit bit(s)".
Patch will be completed with some code comment.

Thank you
diff mbox

Patch

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 4261991..22c18d1 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -121,8 +121,10 @@  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;
+	if (!data)
+		timeout = 200;
+	else
+		timeout = 10;
 
 	sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
 	mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT;