summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorMarek Vasut <marek.vasut+renesas@mailbox.org>2024-02-20 09:38:14 +0100
committerJaehoon Chung <jh80.chung@samsung.com>2024-04-15 15:19:12 +0900
commit60649a8d6cc975a36d06aad14ed55079e75bc4fa (patch)
tree7aadcd5e9163ecff0832564b5ff9c91442bdfbf7 /drivers/mmc
parenta3b2786651c7966ea9038f16c97f401406bdf7d3 (diff)
downloadu-boot-60649a8d6cc975a36d06aad14ed55079e75bc4fa.tar.gz
u-boot-60649a8d6cc975a36d06aad14ed55079e75bc4fa.tar.bz2
u-boot-60649a8d6cc975a36d06aad14ed55079e75bc4fa.zip
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 <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>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/tmio-common.c8
1 files changed, 7 insertions, 1 deletions
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;