From: Marek Vasut Date: Tue, 20 Feb 2024 08:38:14 +0000 (+0100) Subject: mmc: tmio: Check INFO1 for completion during DMA transfer X-Git-Url: http://git.dujemihanovic.xyz/html/static/%7B%7B%20.RelPermalink%20%7D%7D?a=commitdiff_plain;h=60649a8d6cc975a36d06aad14ed55079e75bc4fa;p=u-boot.git mmc: tmio: Check INFO1 for completion during DMA transfer In case a CRC error occurs during DMA transfer, the transfer completion flag is not set in TMIO_SD_DMA_INFO1 and the transfer would eventually time out. The timeout could be very long in case the transfer consists of a large amount of blocks, the base timeout is 10 seconds and every block adds 100 us more. In case a CRC error does occur, a completion flag is set in a different register, TMIO_SD_INFO1. Use this other completion flag to detect DMA transfer ended and stop waiting for TMIO_SD_DMA_INFO1 completion flag. This reduces the lengthy timeout in case of an error. The unconditional check of TMIO_SD_DMA_INFO2 register for DMA related errors must not be skipped in any case to actually recognize the DMA error and report it. Signed-off-by: Marek Vasut Reviewed-by: Paul Barker Tested-by: Paul Barker Reviewed-by: Jaehoon Chung --- diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c index 890c496b53..719c4830bc 100644 --- a/drivers/mmc/tmio-common.c +++ b/drivers/mmc/tmio-common.c @@ -299,7 +299,13 @@ static int tmio_sd_dma_wait_for_irq(struct udevice *dev, u32 flag, struct tmio_sd_priv *priv = dev_get_priv(dev); long wait = 1000000 + 10 * blocks; - while (!(tmio_sd_readl(priv, TMIO_SD_DMA_INFO1) & flag)) { + for (;;) { + if (tmio_sd_readl(priv, TMIO_SD_DMA_INFO1) & flag) + break; + + if (tmio_sd_readl(priv, TMIO_SD_INFO1) & TMIO_SD_INFO1_CMP) + break; + if (wait-- < 0) { dev_err(dev, "timeout during DMA\n"); return -ETIMEDOUT;