diff mbox series

mmc: tmio: Check INFO1 for completion during DMA transfer

Message ID 20240220083827.34473-1-marek.vasut+renesas@mailbox.org
State Accepted
Commit 60649a8d6cc975a36d06aad14ed55079e75bc4fa
Delegated to: Jaehoon Chung
Headers show
Series mmc: tmio: Check INFO1 for completion during DMA transfer | expand

Commit Message

Marek Vasut Feb. 20, 2024, 8:38 a.m. UTC
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>
---
Cc: Hai Pham <hai.pham.ud@renesas.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Cc: Paul Barker <paul.barker.ct@bp.renesas.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sean Anderson <seanga2@gmail.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 drivers/mmc/tmio-common.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

Comments

Paul Barker Feb. 20, 2024, 11:02 a.m. UTC | #1
On 20/02/2024 08:38, Marek Vasut wrote:
> 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>
> ---
> Cc: Hai Pham <hai.pham.ud@renesas.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
> Cc: Paul Barker <paul.barker.ct@bp.renesas.com>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sean Anderson <seanga2@gmail.com>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> ---
>  drivers/mmc/tmio-common.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c
> index 890c496b535..719c4830bc3 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;

Reviewed-by: Paul Barker <paul.barker.ct@bp.renesas.com>
Tested-by: Paul Barker <paul.barker.ct@bp.renesas.com>
  (tested on RZ/G2L with commit ad50a8151387 from
  https://source.denx.de/u-boot/custodians/u-boot-sh)
Jaehoon Chung April 3, 2024, 1:02 a.m. UTC | #2
On 2/20/24 17:38, Marek Vasut wrote:
> 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>

Sorry for late. Will apply to u-boot-mmc/master, Thanks!

Best Regards,
Jaehoon Chung

> ---
> Cc: Hai Pham <hai.pham.ud@renesas.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
> Cc: Paul Barker <paul.barker.ct@bp.renesas.com>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sean Anderson <seanga2@gmail.com>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> ---
>  drivers/mmc/tmio-common.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c
> index 890c496b535..719c4830bc3 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;
diff mbox series

Patch

diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c
index 890c496b535..719c4830bc3 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;