[U-Boot] [PATCH 1/2] mmc: dw_mmc: Increase timeout to 20 seconds

Przemyslaw Marczak p.marczak at samsung.com
Mon Sep 14 12:33:04 CEST 2015


Hi all,

On 09/09/2015 09:01 AM, Lukasz Majewski wrote:
> Hi,
>
>> The commit: d9dbb97be0e4a550457aec5f11afefb446169c90
>> "mmc: dw_mmc: Zap endless timeout" removed endless loop waiting for
>> end of dw mmc transfer.
>>
>> For some workloads - dfu test @ Odroid XU3 (sending 8MiB file) -
>> and SD cards (e.g. MicroSD Kingston 4GiB, Adata 4GiB)
>> the default timeout is to short.
>>
>> The new value - 20 seconds - takes into account the situation when SD
>> card triggers internal clean up. Such process may take more than 10
>> seconds on some cards.
>>
>> Signed-off-by: Lukasz Majewski <l.majewski at samsung.com>
>> Cc: Marek Vasut <marex at denx.de>
>> Cc: Pantelis Antoniou <panto at antoniou-consulting.com>
>> Cc: Tom Rini <trini at konsulko.com>
>
> Are there any more questions regarding this patch or is it ready for
> submission as fix for v2015.10?
>
>> ---
>>   drivers/mmc/dw_mmc.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
>> index 77b87e0..21a92d2 100644
>> --- a/drivers/mmc/dw_mmc.c
>> +++ b/drivers/mmc/dw_mmc.c
>> @@ -213,7 +213,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct
>> mmc_cmd *cmd,
>>   	if (data) {
>>   		start = get_timer(0);
>> -		timeout = 1000;
>> +		timeout = 20000;
>>   		for (;;) {
>>   			mask = dwmci_readl(host, DWMCI_RINTSTS);
>>   			/* Error during data transfer. */
>
>
>

I made some quick mmc command time test with the following code changes:

========================================================================
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index a84c1e1..78e5d5d 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -113,7 +113,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct 
mmc_cmd *cmd,
  	ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac,
  				 data ? DIV_ROUND_UP(data->blocks, 8) : 0);
  	int ret = 0, flags = 0, i;
-	unsigned int timeout = 100000;
+	unsigned int t = 0, timeout = 100000;
  	u32 retry = 10000;
  	u32 mask, ctrl;
  	ulong start = get_timer(0);
@@ -219,7 +219,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct 
mmc_cmd *cmd,
  			mask = dwmci_readl(host, DWMCI_RINTSTS);
  			/* Error during data transfer. */
  			if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
-				debug("%s: DATA ERROR!\n", __func__);
+				printf("%s: DATA ERROR!\n", __func__);
  				ret = -EINVAL;
  				break;
  			}
@@ -231,13 +231,15 @@ static int dwmci_send_cmd(struct mmc *mmc, struct 
mmc_cmd *cmd,
  			}

  			/* Check for timeout. */
-			if (get_timer(start) > timeout) {
-				debug("%s: Timeout waiting for data!\n",
+			t = get_timer(start);
+			if (t > timeout) {
+				printf("%s: Timeout waiting for data!\n",
  				       __func__);
  				ret = TIMEOUT;
  				break;
  			}
  		}
+		printf("[MMC CMD] Tms: %u\n", t);

  		dwmci_writel(host, DWMCI_RINTSTS, mask);
  ========================================================================


Test info:
----------
1. Tree: commit 850f788709cef8f7d53d571aec3bfb73b14c5531
    "Merge branch 'rmobile' of git://git.denx.de/u-boot-sh"
2. SD card: SanDisk 32GB HC 4
3. eMMC card: Toshiba 16GB,  8-bit DDR mode
4. Board: Odroid XU3


Example usecase:
----------------
ODROID-XU3 # mmc read 0x40000000 0x0 0x800

MMC read: dev # 0, block # 0, count 2048 ... [MMC CMD] Tms: 46
2048 blocks read: OK


Time results for SD read/write:
------------------------------------
1MB:   46ms / 220ms
5MB:  229ms / 931ms
10MB: 456ms / timeout

Time results for eMMC read/write:
------------------------------------
1MB:   13ms / 46ms
5MB:   62ms / 260ms
10MB: 123ms / 515ms
20MB: 245ms / timeout


Timeout error for SD, write of 10MB data:
-----------------------------------------
ODROID-XU3 # mmc write 0x40000000 0x0 0x5000

MMC write: dev # 0, block # 0, count 20480 ... dwmci_send_cmd: Timeout 
waiting for data!
[MMC CMD] Tms: 1001
mmc write failed
0 blocks written: ERROR



I made one more test, by removing the SD card when reading the data:
----------------------------------------------------------------
ODROID-XU3 # mmc read 0x40000000 0x0 0xa000

MMC read: dev # 0, block # 0, count 40960 ... dwmci_send_cmd: DATA ERROR!
[MMC CMD] Tus: 283
0 blocks read: ERROR


Summary
-------
So, as we can see, the 1 second of timeout should be enough for small 
data size transfer. I also note some use cases for which, update the 
kernel of size ~4MB was failed. So this depends on the present card 
condition, and it can change for each use case - you never know, how 
much time card needs to finish the same command.

So, the conslusion is, that the 20-30 seconds of timeout seem to be 
okay. This will not introduce "unbounded loops", because the transfer 
status is read in the loop, and it works well - as the card removing 
example shows.

Please test this code on your platform and share your results.

Best regards,
-- 
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com


More information about the U-Boot mailing list