]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
mmc: tmio: Check INFO1 for completion during DMA transfer
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Tue, 20 Feb 2024 08:38:14 +0000 (09:38 +0100)
committerJaehoon Chung <jh80.chung@samsung.com>
Mon, 15 Apr 2024 06:19:12 +0000 (15:19 +0900)
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 <marek.vasut+renesas@mailbox.org>
Reviewed-by: Paul Barker <paul.barker.ct@bp.renesas.com>
Tested-by: Paul Barker <paul.barker.ct@bp.renesas.com>
Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
drivers/mmc/tmio-common.c

index 890c496b5357c3a2258ab1fe0091c51e52d6ba30..719c4830bc30bad9fc4fa1f762cfeb1f44404474 100644 (file)
@@ -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;