[U-Boot] [PATCH] mmc: dw_mmc: Calculate timeout from transfer length

Marek Vasut marex at denx.de
Tue Apr 2 03:39:56 UTC 2019


On 3/30/19 10:18 PM, Simon Glass wrote:
> Hi Marek,
> 
> On Sat, 23 Mar 2019 at 11:55, Marek Vasut <marex at denx.de> wrote:
>>
>> The current 4-minute data transfer timeout is misleading and broken.
>> Instead of such a long wait, calculate the timeout duration based on
>> the length of the data transfer. The current formula is the transfer
>> length in bits, divided by a multiplication of bus frequency in Hz,
>> bus width, DDR mode and converted the mSec. The value is bounded from
>> the bottom to 1000 mSec.
>>
>> Signed-off-by: Marek Vasut <marex at denx.de>
>> Cc: Jaehoon Chung <jh80.chung at samsung.com>
>> Cc: Simon Glass <sjg at chromium.org>
>> ---
>>  drivers/mmc/dw_mmc.c | 15 ++++++++++++---
>>  1 file changed, 12 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
>> index 93a836eac3..8278f1dacb 100644
>> --- a/drivers/mmc/dw_mmc.c
>> +++ b/drivers/mmc/dw_mmc.c
>> @@ -116,20 +116,29 @@ static int dwmci_fifo_ready(struct dwmci_host *host, u32 bit, u32 *len)
>>
>>  static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
>>  {
>> +       struct mmc *mmc = host->mmc;
>>         int ret = 0;
>> -       u32 timeout = 240000;
>> -       u32 mask, size, i, len = 0;
>> +       u32 timeout, mask, size, i, len = 0;
>>         u32 *buf = NULL;
>>         ulong start = get_timer(0);
>>         u32 fifo_depth = (((host->fifoth_val & RX_WMARK_MASK) >>
>>                             RX_WMARK_SHIFT) + 1) * 2;
>>
>> -       size = data->blocksize * data->blocks / 4;
>> +       size = data->blocksize * data->blocks;
>>         if (data->flags == MMC_DATA_READ)
>>                 buf = (unsigned int *)data->dest;
>>         else
>>                 buf = (unsigned int *)data->src;
>>
>> +       timeout = size * 8 * 1000;      /* counting in bits and msec */
>> +       timeout *= 2;                   /* wait twice as long */
>> +       timeout /= mmc->clock;
>> +       timeout /= mmc->bus_width;
>> +       timeout /= mmc->ddr_mode ? 2 : 1;
>> +       timeout = (timeout < 1000) ? 1000 : timeout;
> 
> Can you put all this in a function (like calc_timeout_ms(size, clock,
> bus_width, ddr_mode)) that returns the correct timeout given the
> parameters? That would provide a modicum of documentation.

Sure

-- 
Best regards,
Marek Vasut


More information about the U-Boot mailing list