Linux MultiMedia Card development
 help / color / mirror / Atom feed
* [PATCH 0/2] mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card
@ 2025-06-10  7:25 Yoshihiro Shimoda
  2025-06-10  7:25 ` [PATCH 1/2] mmc: host: tmio: Add .sdio_irq() Yoshihiro Shimoda
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Yoshihiro Shimoda @ 2025-06-10  7:25 UTC (permalink / raw)
  To: wsa+renesas, ulf.hansson; +Cc: linux-mmc, linux-renesas-soc, Yoshihiro Shimoda

This host controller is possible to change incorrect tap if an SDIO
card is used because DAT1 is used for interrupt signal on SDIO standard
but the contoller doesn't take care of it. So, in the worst case,
this behavior causes a CRC error.

To resolve the issue, add some new ops into the tmio core and
add fixed code into the renesas_sdhi driver.

This patch set tested on RZ/G2M (r8a774a1-hihope-rzg2m-ex.dtb) with
EmbeddedArtists 1ZM module.

Before I don't apply this patch set, the RVSCNTL value was changed
unexpectidly like below.

[  687.103589] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000701
...
[  768.490979] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000501
[  768.500307] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000401
[  768.509640] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000501
[  768.518947] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000501
[  768.528217] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000501
[  768.537494] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000601

Yoshihiro Shimoda (2):
  mmc: host: tmio: Add .sdio_irq()
  mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card

 drivers/mmc/host/renesas_sdhi.h      |  1 +
 drivers/mmc/host/renesas_sdhi_core.c | 48 ++++++++++++++++++++++++----
 drivers/mmc/host/tmio_mmc.h          |  1 +
 drivers/mmc/host/tmio_mmc_core.c     |  5 ++-
 4 files changed, 47 insertions(+), 8 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] mmc: host: tmio: Add .sdio_irq()
  2025-06-10  7:25 [PATCH 0/2] mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card Yoshihiro Shimoda
@ 2025-06-10  7:25 ` Yoshihiro Shimoda
  2025-06-10  8:23   ` Wolfram Sang
  2025-06-10  7:25 ` [PATCH 2/2] mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card Yoshihiro Shimoda
  2025-06-19 11:19 ` [PATCH 0/2] " Ulf Hansson
  2 siblings, 1 reply; 6+ messages in thread
From: Yoshihiro Shimoda @ 2025-06-10  7:25 UTC (permalink / raw)
  To: wsa+renesas, ulf.hansson; +Cc: linux-mmc, linux-renesas-soc, Yoshihiro Shimoda

Renesas SDHI controller requires vender specific handling when
an SDIO irq occurs. So, add .sdio_irq() to the tmio core.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 drivers/mmc/host/tmio_mmc.h      | 1 +
 drivers/mmc/host/tmio_mmc_core.c | 5 ++++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 41787ea77a134..717594a3dc698 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -193,6 +193,7 @@ struct tmio_mmc_host {
 	bool (*check_retune)(struct tmio_mmc_host *host, struct mmc_request *mrq);
 	void (*fixup_request)(struct tmio_mmc_host *host, struct mmc_request *mrq);
 	unsigned int (*get_timeout_cycles)(struct tmio_mmc_host *host);
+	void (*sdio_irq)(struct tmio_mmc_host *host);
 
 	const struct tmio_mmc_dma_ops *dma_ops;
 };
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index b71241f55df57..d16aa0017e8c5 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -696,8 +696,11 @@ static bool __tmio_mmc_sdio_irq(struct tmio_mmc_host *host)
 
 	sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status);
 
-	if (mmc->caps & MMC_CAP_SDIO_IRQ && ireg & TMIO_SDIO_STAT_IOIRQ)
+	if (mmc->caps & MMC_CAP_SDIO_IRQ && ireg & TMIO_SDIO_STAT_IOIRQ) {
+		if (host->sdio_irq)
+			host->sdio_irq(host);
 		mmc_signal_sdio_irq(mmc);
+	}
 
 	return ireg;
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card
  2025-06-10  7:25 [PATCH 0/2] mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card Yoshihiro Shimoda
  2025-06-10  7:25 ` [PATCH 1/2] mmc: host: tmio: Add .sdio_irq() Yoshihiro Shimoda
@ 2025-06-10  7:25 ` Yoshihiro Shimoda
  2025-06-10  8:24   ` Wolfram Sang
  2025-06-19 11:19 ` [PATCH 0/2] " Ulf Hansson
  2 siblings, 1 reply; 6+ messages in thread
From: Yoshihiro Shimoda @ 2025-06-10  7:25 UTC (permalink / raw)
  To: wsa+renesas, ulf.hansson; +Cc: linux-mmc, linux-renesas-soc, Yoshihiro Shimoda

This host controller is possible to change incorrect tap if an SDIO
card is used because DAT1 is used for interrupt signal on SDIO standard
but the controller doesn't take care of it. So, in the worst case,
this behavior causes a CRC error.

To resolve the issue, this driver uses manual correction mode instead
of auto correction if an SDIO card is used. Also, even if DAT1 is
mismatched on an SDIO card, this driver will not change the TAP.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 drivers/mmc/host/renesas_sdhi.h      |  1 +
 drivers/mmc/host/renesas_sdhi_core.c | 48 ++++++++++++++++++++++++----
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
index 291ddb4ad9bed..084964cecf9d8 100644
--- a/drivers/mmc/host/renesas_sdhi.h
+++ b/drivers/mmc/host/renesas_sdhi.h
@@ -85,6 +85,7 @@ struct renesas_sdhi {
 	u32 scc_tappos_hs400;
 	const u8 *adjust_hs400_calib_table;
 	bool needs_adjust_hs400;
+	bool card_is_sdio;
 
 	/* Tuning values: 1 for success, 0 for failure */
 	DECLARE_BITMAP(taps, BITS_PER_LONG);
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index e6fa3ed425606..c49e3faa0ef3b 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -686,9 +686,8 @@ static int renesas_sdhi_select_tuning(struct tmio_mmc_host *host)
 	/* Set SCC */
 	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TAPSET, priv->tap_set);
 
-	/* Enable auto re-tuning */
 	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL,
-		       SH_MOBILE_SDHI_SCC_RVSCNTL_RVSEN |
+		       (priv->card_is_sdio ? 0 : SH_MOBILE_SDHI_SCC_RVSCNTL_RVSEN) |
 		       sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL));
 
 	return 0;
@@ -778,6 +777,14 @@ static bool renesas_sdhi_manual_correction(struct tmio_mmc_host *host, bool use_
 		if (bad_taps & BIT(new_tap % priv->tap_num))
 			return test_bit(error_tap % priv->tap_num, priv->smpcmp);
 	} else {
+		if (!priv->card_is_sdio &&
+		    !(val & SH_MOBILE_SDHI_SCC_RVSREQ_RVSERR)) {
+			u32 smpcmp = sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_SMPCMP);
+
+			/* DAT1 is unmatched because of an SDIO irq */
+			if (smpcmp & (BIT(17) | BIT(1)))
+				return false;
+		}
 		if (val & SH_MOBILE_SDHI_SCC_RVSREQ_RVSERR)
 			return true;    /* need retune */
 		else if (val & SH_MOBILE_SDHI_SCC_RVSREQ_REQTAPUP)
@@ -828,11 +835,14 @@ static bool renesas_sdhi_check_scc_error(struct tmio_mmc_host *host,
 	if (mmc_doing_tune(host->mmc))
 		return false;
 
-	if (((mrq->cmd->error == -ETIMEDOUT) ||
-	     (mrq->data && mrq->data->error == -ETIMEDOUT)) &&
-	    ((host->mmc->caps & MMC_CAP_NONREMOVABLE) ||
-	     (host->ops.get_cd && host->ops.get_cd(host->mmc))))
-		ret |= true;
+	/* mrq can be NULL to check SCC error on SDIO irq without any request */
+	if (mrq) {
+		if (((mrq->cmd->error == -ETIMEDOUT) ||
+		     (mrq->data && mrq->data->error == -ETIMEDOUT)) &&
+		    ((host->mmc->caps & MMC_CAP_NONREMOVABLE) ||
+		     (host->ops.get_cd && host->ops.get_cd(host->mmc))))
+			ret |= true;
+	}
 
 	if (sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL) &
 	    SH_MOBILE_SDHI_SCC_RVSCNTL_RVSEN)
@@ -843,6 +853,28 @@ static bool renesas_sdhi_check_scc_error(struct tmio_mmc_host *host,
 	return ret;
 }
 
+static void renesas_sdhi_init_card(struct mmc_host *mmc, struct mmc_card *card)
+{
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+	struct renesas_sdhi *priv = host_to_priv(host);
+
+	/*
+	 * This controller cannot do auto-retune with SDIO irqs, so we
+	 * then need to enforce manual correction. However, when tuning,
+	 * mmc->card is not populated yet, so we don't know if the card
+	 * is SDIO. init_card provides this information earlier, so we
+	 * keep a copy of it.
+	 */
+	priv->card_is_sdio = mmc_card_sdio(card);
+}
+
+static void renesas_sdhi_sdio_irq(struct tmio_mmc_host *host)
+{
+	/* This controller requires retune when an SDIO irq occurs */
+	if (renesas_sdhi_check_scc_error(host, NULL))
+		mmc_retune_needed(host->mmc);
+}
+
 static int renesas_sdhi_wait_idle(struct tmio_mmc_host *host, u32 bit)
 {
 	int timeout = 1000;
@@ -1227,6 +1259,8 @@ int renesas_sdhi_probe(struct platform_device *pdev,
 			dev_warn(&host->pdev->dev, "Unknown clock rate for tuning\n");
 
 		host->check_retune = renesas_sdhi_check_scc_error;
+		host->sdio_irq = renesas_sdhi_sdio_irq;
+		host->ops.init_card = renesas_sdhi_init_card;
 		host->ops.execute_tuning = renesas_sdhi_execute_tuning;
 		host->ops.prepare_hs400_tuning = renesas_sdhi_prepare_hs400_tuning;
 		host->ops.hs400_downgrade = renesas_sdhi_disable_scc;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] mmc: host: tmio: Add .sdio_irq()
  2025-06-10  7:25 ` [PATCH 1/2] mmc: host: tmio: Add .sdio_irq() Yoshihiro Shimoda
@ 2025-06-10  8:23   ` Wolfram Sang
  0 siblings, 0 replies; 6+ messages in thread
From: Wolfram Sang @ 2025-06-10  8:23 UTC (permalink / raw)
  To: Yoshihiro Shimoda; +Cc: ulf.hansson, linux-mmc, linux-renesas-soc

[-- Attachment #1: Type: text/plain, Size: 398 bytes --]

On Tue, Jun 10, 2025 at 04:25:44PM +0900, Yoshihiro Shimoda wrote:
> Renesas SDHI controller requires vender specific handling when
> an SDIO irq occurs. So, add .sdio_irq() to the tmio core.
> 
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card
  2025-06-10  7:25 ` [PATCH 2/2] mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card Yoshihiro Shimoda
@ 2025-06-10  8:24   ` Wolfram Sang
  0 siblings, 0 replies; 6+ messages in thread
From: Wolfram Sang @ 2025-06-10  8:24 UTC (permalink / raw)
  To: Yoshihiro Shimoda; +Cc: ulf.hansson, linux-mmc, linux-renesas-soc

[-- Attachment #1: Type: text/plain, Size: 866 bytes --]

On Tue, Jun 10, 2025 at 04:25:45PM +0900, Yoshihiro Shimoda wrote:
> This host controller is possible to change incorrect tap if an SDIO
> card is used because DAT1 is used for interrupt signal on SDIO standard
> but the controller doesn't take care of it. So, in the worst case,
> this behavior causes a CRC error.
> 
> To resolve the issue, this driver uses manual correction mode instead
> of auto correction if an SDIO card is used. Also, even if DAT1 is
> mismatched on an SDIO card, this driver will not change the TAP.
> 
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

I tested this with my uBlox EMMY card (SDR104) on a Salvator-XS (R-Car
M3N) and some debug output added. Works as expected:

Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/2] mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card
  2025-06-10  7:25 [PATCH 0/2] mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card Yoshihiro Shimoda
  2025-06-10  7:25 ` [PATCH 1/2] mmc: host: tmio: Add .sdio_irq() Yoshihiro Shimoda
  2025-06-10  7:25 ` [PATCH 2/2] mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card Yoshihiro Shimoda
@ 2025-06-19 11:19 ` Ulf Hansson
  2 siblings, 0 replies; 6+ messages in thread
From: Ulf Hansson @ 2025-06-19 11:19 UTC (permalink / raw)
  To: Yoshihiro Shimoda; +Cc: wsa+renesas, linux-mmc, linux-renesas-soc

On Tue, 10 Jun 2025 at 09:25, Yoshihiro Shimoda
<yoshihiro.shimoda.uh@renesas.com> wrote:
>
> This host controller is possible to change incorrect tap if an SDIO
> card is used because DAT1 is used for interrupt signal on SDIO standard
> but the contoller doesn't take care of it. So, in the worst case,
> this behavior causes a CRC error.
>
> To resolve the issue, add some new ops into the tmio core and
> add fixed code into the renesas_sdhi driver.
>
> This patch set tested on RZ/G2M (r8a774a1-hihope-rzg2m-ex.dtb) with
> EmbeddedArtists 1ZM module.
>
> Before I don't apply this patch set, the RVSCNTL value was changed
> unexpectidly like below.
>
> [  687.103589] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000701
> ...
> [  768.490979] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000501
> [  768.500307] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000401
> [  768.509640] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000501
> [  768.518947] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000501
> [  768.528217] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000501
> [  768.537494] renesas_sdhi_internal_dmac ee100000.mmc: renesas_sdhi_auto_correction: rvscntl = 00000601
>
> Yoshihiro Shimoda (2):
>   mmc: host: tmio: Add .sdio_irq()
>   mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card
>
>  drivers/mmc/host/renesas_sdhi.h      |  1 +
>  drivers/mmc/host/renesas_sdhi_core.c | 48 ++++++++++++++++++++++++----
>  drivers/mmc/host/tmio_mmc.h          |  1 +
>  drivers/mmc/host/tmio_mmc_core.c     |  5 ++-
>  4 files changed, 47 insertions(+), 8 deletions(-)
>

The series applied for next, thanks!

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-06-19 11:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-10  7:25 [PATCH 0/2] mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card Yoshihiro Shimoda
2025-06-10  7:25 ` [PATCH 1/2] mmc: host: tmio: Add .sdio_irq() Yoshihiro Shimoda
2025-06-10  8:23   ` Wolfram Sang
2025-06-10  7:25 ` [PATCH 2/2] mmc: host: renesas_sdhi: Fix incorrect auto retuning for an SDIO card Yoshihiro Shimoda
2025-06-10  8:24   ` Wolfram Sang
2025-06-19 11:19 ` [PATCH 0/2] " Ulf Hansson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox