[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