* [PATCH v3] mmc: sdhci-esdhc-imx: wait for data transfer completion before reset
@ 2025-12-11 7:56 ziniu.wang_1
2025-12-12 11:58 ` Adrian Hunter
2025-12-15 15:43 ` Ulf Hansson
0 siblings, 2 replies; 3+ messages in thread
From: ziniu.wang_1 @ 2025-12-11 7:56 UTC (permalink / raw)
To: adrian.hunter, haibo.chen, ulf.hansson
Cc: shawnguo, s.hauer, kernel, festevam, linux-mmc, imx, s32,
linux-arm-kernel, linux-kernel
From: Luke Wang <ziniu.wang_1@nxp.com>
On IMX7ULP platforms, certain SD cards (e.g. Kingston Canvas Go! Plus)
cause system hangs and reboots during manual tuning. These cards exhibit
large gaps (~16us) between tuning command response and data transmission.
When cmd CRC errors occur during tuning, the code assumes data errors even
tuning data hasn't been fully received and then reset host data circuit.
Per IMX7ULP reference manual, reset operations (RESET_DATA/ALL) need to
make sure no active data transfers. Previously, resetting while data was
in-flight would clear data circuit, including ADMA/SDMA address, causing
data to be transmitted to incorrect memory address. This patch adds
polling for data transfer completion before executing resets.
Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
Reviewed-by: Bough Chen <haibo.chen@nxp.com>
---
v3: add define for timeout value
v2: amend commit message
---
drivers/mmc/host/sdhci-esdhc-imx.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index a7a5df673b0f..97461e20425d 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -216,6 +216,8 @@
#define ESDHC_FLAG_DUMMY_PAD BIT(19)
#define ESDHC_AUTO_TUNING_WINDOW 3
+/* 100ms timeout for data inhibit */
+#define ESDHC_DATA_INHIBIT_WAIT_US 100000
enum wp_types {
ESDHC_WP_NONE, /* no WP, neither controller nor gpio */
@@ -1453,6 +1455,22 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
static void esdhc_reset(struct sdhci_host *host, u8 mask)
{
+ u32 present_state;
+ int ret;
+
+ /*
+ * For data or full reset, ensure any active data transfer completes
+ * before resetting to avoid system hang.
+ */
+ if (mask & (SDHCI_RESET_DATA | SDHCI_RESET_ALL)) {
+ ret = readl_poll_timeout_atomic(host->ioaddr + ESDHC_PRSSTAT, present_state,
+ !(present_state & SDHCI_DATA_INHIBIT), 2,
+ ESDHC_DATA_INHIBIT_WAIT_US);
+ if (ret == -ETIMEDOUT)
+ dev_warn(mmc_dev(host->mmc),
+ "timeout waiting for data transfer completion\n");
+ }
+
sdhci_and_cqhci_reset(host, mask);
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v3] mmc: sdhci-esdhc-imx: wait for data transfer completion before reset
2025-12-11 7:56 [PATCH v3] mmc: sdhci-esdhc-imx: wait for data transfer completion before reset ziniu.wang_1
@ 2025-12-12 11:58 ` Adrian Hunter
2025-12-15 15:43 ` Ulf Hansson
1 sibling, 0 replies; 3+ messages in thread
From: Adrian Hunter @ 2025-12-12 11:58 UTC (permalink / raw)
To: ziniu.wang_1, haibo.chen, ulf.hansson
Cc: shawnguo, s.hauer, kernel, festevam, linux-mmc, imx, s32,
linux-arm-kernel, linux-kernel
On 11/12/2025 09:56, ziniu.wang_1@nxp.com wrote:
> From: Luke Wang <ziniu.wang_1@nxp.com>
>
> On IMX7ULP platforms, certain SD cards (e.g. Kingston Canvas Go! Plus)
> cause system hangs and reboots during manual tuning. These cards exhibit
> large gaps (~16us) between tuning command response and data transmission.
> When cmd CRC errors occur during tuning, the code assumes data errors even
> tuning data hasn't been fully received and then reset host data circuit.
>
> Per IMX7ULP reference manual, reset operations (RESET_DATA/ALL) need to
> make sure no active data transfers. Previously, resetting while data was
> in-flight would clear data circuit, including ADMA/SDMA address, causing
> data to be transmitted to incorrect memory address. This patch adds
> polling for data transfer completion before executing resets.
>
> Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
> Reviewed-by: Bough Chen <haibo.chen@nxp.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
> v3: add define for timeout value
> v2: amend commit message
> ---
> drivers/mmc/host/sdhci-esdhc-imx.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index a7a5df673b0f..97461e20425d 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -216,6 +216,8 @@
> #define ESDHC_FLAG_DUMMY_PAD BIT(19)
>
> #define ESDHC_AUTO_TUNING_WINDOW 3
> +/* 100ms timeout for data inhibit */
> +#define ESDHC_DATA_INHIBIT_WAIT_US 100000
>
> enum wp_types {
> ESDHC_WP_NONE, /* no WP, neither controller nor gpio */
> @@ -1453,6 +1455,22 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
>
> static void esdhc_reset(struct sdhci_host *host, u8 mask)
> {
> + u32 present_state;
> + int ret;
> +
> + /*
> + * For data or full reset, ensure any active data transfer completes
> + * before resetting to avoid system hang.
> + */
> + if (mask & (SDHCI_RESET_DATA | SDHCI_RESET_ALL)) {
> + ret = readl_poll_timeout_atomic(host->ioaddr + ESDHC_PRSSTAT, present_state,
> + !(present_state & SDHCI_DATA_INHIBIT), 2,
> + ESDHC_DATA_INHIBIT_WAIT_US);
> + if (ret == -ETIMEDOUT)
> + dev_warn(mmc_dev(host->mmc),
> + "timeout waiting for data transfer completion\n");
> + }
> +
> sdhci_and_cqhci_reset(host, mask);
>
> sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v3] mmc: sdhci-esdhc-imx: wait for data transfer completion before reset
2025-12-11 7:56 [PATCH v3] mmc: sdhci-esdhc-imx: wait for data transfer completion before reset ziniu.wang_1
2025-12-12 11:58 ` Adrian Hunter
@ 2025-12-15 15:43 ` Ulf Hansson
1 sibling, 0 replies; 3+ messages in thread
From: Ulf Hansson @ 2025-12-15 15:43 UTC (permalink / raw)
To: ziniu.wang_1
Cc: adrian.hunter, haibo.chen, shawnguo, s.hauer, kernel, festevam,
linux-mmc, imx, s32, linux-arm-kernel, linux-kernel
On Thu, 11 Dec 2025 at 08:54, <ziniu.wang_1@nxp.com> wrote:
>
> From: Luke Wang <ziniu.wang_1@nxp.com>
>
> On IMX7ULP platforms, certain SD cards (e.g. Kingston Canvas Go! Plus)
> cause system hangs and reboots during manual tuning. These cards exhibit
> large gaps (~16us) between tuning command response and data transmission.
> When cmd CRC errors occur during tuning, the code assumes data errors even
> tuning data hasn't been fully received and then reset host data circuit.
>
> Per IMX7ULP reference manual, reset operations (RESET_DATA/ALL) need to
> make sure no active data transfers. Previously, resetting while data was
> in-flight would clear data circuit, including ADMA/SDMA address, causing
> data to be transmitted to incorrect memory address. This patch adds
> polling for data transfer completion before executing resets.
>
> Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
> Reviewed-by: Bough Chen <haibo.chen@nxp.com>
Applied for next, thanks!
Kind regards
Uffe
> ---
> v3: add define for timeout value
> v2: amend commit message
> ---
> drivers/mmc/host/sdhci-esdhc-imx.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index a7a5df673b0f..97461e20425d 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -216,6 +216,8 @@
> #define ESDHC_FLAG_DUMMY_PAD BIT(19)
>
> #define ESDHC_AUTO_TUNING_WINDOW 3
> +/* 100ms timeout for data inhibit */
> +#define ESDHC_DATA_INHIBIT_WAIT_US 100000
>
> enum wp_types {
> ESDHC_WP_NONE, /* no WP, neither controller nor gpio */
> @@ -1453,6 +1455,22 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
>
> static void esdhc_reset(struct sdhci_host *host, u8 mask)
> {
> + u32 present_state;
> + int ret;
> +
> + /*
> + * For data or full reset, ensure any active data transfer completes
> + * before resetting to avoid system hang.
> + */
> + if (mask & (SDHCI_RESET_DATA | SDHCI_RESET_ALL)) {
> + ret = readl_poll_timeout_atomic(host->ioaddr + ESDHC_PRSSTAT, present_state,
> + !(present_state & SDHCI_DATA_INHIBIT), 2,
> + ESDHC_DATA_INHIBIT_WAIT_US);
> + if (ret == -ETIMEDOUT)
> + dev_warn(mmc_dev(host->mmc),
> + "timeout waiting for data transfer completion\n");
> + }
> +
> sdhci_and_cqhci_reset(host, mask);
>
> sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-12-15 15:44 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-11 7:56 [PATCH v3] mmc: sdhci-esdhc-imx: wait for data transfer completion before reset ziniu.wang_1
2025-12-12 11:58 ` Adrian Hunter
2025-12-15 15:43 ` Ulf Hansson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).