diff mbox series

[02/14] mmc: sdhci: clear DMA_SEL before sending tuning command for Standard tuning

Message ID 1573816075-26390-2-git-send-email-haibo.chen@nxp.com (mailing list archive)
State New, archived
Headers show
Series [01/14] mmc: sdhci: do not enable card detect interrupt for gpio cd type | expand

Commit Message

Bough Chen Nov. 15, 2019, 11:07 a.m. UTC
From: Haibo Chen <haibo.chen@nxp.com>

Currently, when use standard tuning, driver default disable DMA just before
send tuning command. But on i.MX8 usdhc, this is not enough. Need also clear
DMA_SEL. If not, once the DMA_SEL select AMDA2 before, even dma already disabled,
when send tuning command, usdhc will still prefetch the ADMA script from wrong
DMA address, then we will see IOMMU report some error which show lack of TLB
mapping.

Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
---
 drivers/mmc/host/sdhci.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Adrian Hunter Nov. 26, 2019, 11:57 a.m. UTC | #1
On 15/11/19 1:07 PM, haibo.chen@nxp.com wrote:
> From: Haibo Chen <haibo.chen@nxp.com>
> 
> Currently, when use standard tuning, driver default disable DMA just before
> send tuning command. But on i.MX8 usdhc, this is not enough. Need also clear
> DMA_SEL. If not, once the DMA_SEL select AMDA2 before, even dma already disabled,
> when send tuning command, usdhc will still prefetch the ADMA script from wrong
> DMA address, then we will see IOMMU report some error which show lack of TLB
> mapping.
> 
> Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
> ---
>  drivers/mmc/host/sdhci.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 68db86c1b4c9..1436cc9c5f82 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -2361,6 +2361,7 @@ void sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
>  	struct mmc_request mrq = {};
>  	unsigned long flags;
>  	u32 b = host->sdma_boundary;
> +	u8 ctrl;
>  
>  	spin_lock_irqsave(&host->lock, flags);
>  
> @@ -2388,6 +2389,17 @@ void sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
>  	 */
>  	sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
>  
> +
> +	/* DMA already disabled, so clear the DMA Select here.
> +	 * Otherwise, if use ADMA2, even disable DMA, some
> +	 * controllers like i.MX usdhc will still prefetch the
> +	 * ADMA script when send tuning command, which will cause
> +	 * IOMMU report lack of TLB mapping error
> +	 */
> +	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
> +	ctrl &= ~SDHCI_CTRL_DMA_MASK;

Value zero is SDMA, so this does not look like a generic sdhci change.  What
about doing it in sdhci-esdhc-imx.c before executing tuning?

> +	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
> +
>  	sdhci_send_command(host, &cmd);
>  
>  	host->cmd = NULL;
>
Bough Chen Nov. 27, 2019, 3:33 a.m. UTC | #2
> -----Original Message-----
> From: Adrian Hunter <adrian.hunter@intel.com>
> Sent: 2019年11月26日 19:58
> To: BOUGH CHEN <haibo.chen@nxp.com>; ulf.hansson@linaro.org
> Cc: linux-mmc@vger.kernel.org; dl-linux-imx <linux-imx@nxp.com>
> Subject: Re: [PATCH 02/14] mmc: sdhci: clear DMA_SEL before sending tuning
> command for Standard tuning
> 
> On 15/11/19 1:07 PM, haibo.chen@nxp.com wrote:
> > From: Haibo Chen <haibo.chen@nxp.com>
> >
> > Currently, when use standard tuning, driver default disable DMA just
> > before send tuning command. But on i.MX8 usdhc, this is not enough.
> > Need also clear DMA_SEL. If not, once the DMA_SEL select AMDA2 before,
> > even dma already disabled, when send tuning command, usdhc will still
> > prefetch the ADMA script from wrong DMA address, then we will see
> > IOMMU report some error which show lack of TLB mapping.
> >
> > Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
> > ---
> >  drivers/mmc/host/sdhci.c | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index
> > 68db86c1b4c9..1436cc9c5f82 100644
> > --- a/drivers/mmc/host/sdhci.c
> > +++ b/drivers/mmc/host/sdhci.c
> > @@ -2361,6 +2361,7 @@ void sdhci_send_tuning(struct sdhci_host *host,
> u32 opcode)
> >  	struct mmc_request mrq = {};
> >  	unsigned long flags;
> >  	u32 b = host->sdma_boundary;
> > +	u8 ctrl;
> >
> >  	spin_lock_irqsave(&host->lock, flags);
> >
> > @@ -2388,6 +2389,17 @@ void sdhci_send_tuning(struct sdhci_host *host,
> u32 opcode)
> >  	 */
> >  	sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
> >
> > +
> > +	/* DMA already disabled, so clear the DMA Select here.
> > +	 * Otherwise, if use ADMA2, even disable DMA, some
> > +	 * controllers like i.MX usdhc will still prefetch the
> > +	 * ADMA script when send tuning command, which will cause
> > +	 * IOMMU report lack of TLB mapping error
> > +	 */
> > +	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
> > +	ctrl &= ~SDHCI_CTRL_DMA_MASK;
> 
> Value zero is SDMA, so this does not look like a generic sdhci change.  What
> about doing it in sdhci-esdhc-imx.c before executing tuning?
> 
Okay, the value zero for i.mx usdhc means "No DMA or Simple DMA is selected", a little bit different with generic sdhci definition.
I will add this change in sdhci-esdhc-imx.c in V2 patch. 
Thanks!

Haibo Chen


> > +	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
> > +
> >  	sdhci_send_command(host, &cmd);
> >
> >  	host->cmd = NULL;
> >
diff mbox series

Patch

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 68db86c1b4c9..1436cc9c5f82 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2361,6 +2361,7 @@  void sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
 	struct mmc_request mrq = {};
 	unsigned long flags;
 	u32 b = host->sdma_boundary;
+	u8 ctrl;
 
 	spin_lock_irqsave(&host->lock, flags);
 
@@ -2388,6 +2389,17 @@  void sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
 	 */
 	sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
 
+
+	/* DMA already disabled, so clear the DMA Select here.
+	 * Otherwise, if use ADMA2, even disable DMA, some
+	 * controllers like i.MX usdhc will still prefetch the
+	 * ADMA script when send tuning command, which will cause
+	 * IOMMU report lack of TLB mapping error
+	 */
+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+	ctrl &= ~SDHCI_CTRL_DMA_MASK;
+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+
 	sdhci_send_command(host, &cmd);
 
 	host->cmd = NULL;