mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-29 08:01:08 +00:00
mmc: dw_mmc: Calculate timeout from transfer length
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@denx.de> Cc: Jaehoon Chung <jh80.chung@samsung.com> Cc: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
72c347ced8
commit
4e16f0a67d
1 changed files with 21 additions and 3 deletions
|
@ -114,22 +114,40 @@ static int dwmci_fifo_ready(struct dwmci_host *host, u32 bit, u32 *len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int dwmci_get_timeout(struct mmc *mmc, const unsigned int size)
|
||||
{
|
||||
unsigned int timeout;
|
||||
|
||||
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;
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
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 = dwmci_get_timeout(mmc, size);
|
||||
|
||||
size /= 4;
|
||||
|
||||
for (;;) {
|
||||
mask = dwmci_readl(host, DWMCI_RINTSTS);
|
||||
/* Error during data transfer. */
|
||||
|
|
Loading…
Reference in a new issue