Message ID | 1581324597-31031-8-git-send-email-haibo.chen@nxp.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | few fix for sdhci-esdhc-imx | expand |
On 10/02/20 10:49 am, 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> Acked-by: Adrian Hunter <adrian.hunter@intel.com> > --- > drivers/mmc/host/sdhci-esdhc-imx.c | 18 ++++++++++++++++-- > 1 file changed, 16 insertions(+), 2 deletions(-) > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c > index dedc067cd0dd..44837e3014e8 100644 > --- a/drivers/mmc/host/sdhci-esdhc-imx.c > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c > @@ -639,10 +639,24 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) > * For DMA access restore the levels to default value. > */ > m = readl(host->ioaddr + ESDHC_WTMK_LVL); > - if (val & SDHCI_TRNS_DMA) > + if (val & SDHCI_TRNS_DMA) { > wml = ESDHC_WTMK_LVL_WML_VAL_DEF; > - else > + } else { > + u8 ctrl; > wml = ESDHC_WTMK_LVL_WML_VAL_MAX; > + > + /* > + * Since already disable DMA mode, so also need > + * to clear the DMASEL. Otherwise, for standard > + * tuning, 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. > + */ > + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); > + ctrl &= ~SDHCI_CTRL_DMA_MASK; > + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); > + } > m &= ~(ESDHC_WTMK_LVL_RD_WML_MASK | > ESDHC_WTMK_LVL_WR_WML_MASK); > m |= (wml << ESDHC_WTMK_LVL_RD_WML_SHIFT) | >
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index dedc067cd0dd..44837e3014e8 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -639,10 +639,24 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) * For DMA access restore the levels to default value. */ m = readl(host->ioaddr + ESDHC_WTMK_LVL); - if (val & SDHCI_TRNS_DMA) + if (val & SDHCI_TRNS_DMA) { wml = ESDHC_WTMK_LVL_WML_VAL_DEF; - else + } else { + u8 ctrl; wml = ESDHC_WTMK_LVL_WML_VAL_MAX; + + /* + * Since already disable DMA mode, so also need + * to clear the DMASEL. Otherwise, for standard + * tuning, 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. + */ + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); + ctrl &= ~SDHCI_CTRL_DMA_MASK; + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); + } m &= ~(ESDHC_WTMK_LVL_RD_WML_MASK | ESDHC_WTMK_LVL_WR_WML_MASK); m |= (wml << ESDHC_WTMK_LVL_RD_WML_SHIFT) |