On Mon, 7 Jan 2019 at 11:11, BOUGH CHEN <haibo.chen@xxxxxxx> wrote: > > For some eMMC, after switch to HS400ES mode, it need to config the strobe > dll target dealy even if the clock is 50MHZ or 25MHz, otherwise will meet > CMD index/crc error when send CMD13 to check the switch status. > > [ 2.473915] IRQ status 0x000a8001 > [ 2.473934] mmc2: mmc_select_hs400es failed, error -84 > [ 2.473938] mmc2: error -84 whilst initialising MMC card > > Signed-off-by: Haibo Chen <haibo.chen@xxxxxxx> Applied for next, thanks! Kind regards Uffe > --- > drivers/mmc/host/sdhci-esdhc-imx.c | 55 +++++++++++++----------------- > 1 file changed, 24 insertions(+), 31 deletions(-) > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c > index cf187f8dbc6c..0489b60b8eb4 100644 > --- a/drivers/mmc/host/sdhci-esdhc-imx.c > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c > @@ -141,9 +141,6 @@ > /* The IP supports HS400 mode */ > #define ESDHC_FLAG_HS400 BIT(9) > > -/* A clock frequency higher than this rate requires strobe dll control */ > -#define ESDHC_STROBE_DLL_CLK_FREQ 100000000 > - > struct esdhc_soc_data { > u32 flags; > }; > @@ -907,39 +904,35 @@ static int esdhc_change_pinstate(struct sdhci_host *host, > * edge of data_strobe line. Due to the time delay between CLK line and > * data_strobe line, if the delay time is larger than one clock cycle, > * then CLK and data_strobe line will be misaligned, read error shows up. > - * So when the CLK is higher than 100MHz, each clock cycle is short enough, > - * host should configure the delay target. > */ > static void esdhc_set_strobe_dll(struct sdhci_host *host) > { > u32 v; > > - if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ) { > - /* disable clock before enabling strobe dll */ > - writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) & > - ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON, > - host->ioaddr + ESDHC_VENDOR_SPEC); > - > - /* force a reset on strobe dll */ > - writel(ESDHC_STROBE_DLL_CTRL_RESET, > - host->ioaddr + ESDHC_STROBE_DLL_CTRL); > - /* > - * enable strobe dll ctrl and adjust the delay target > - * for the uSDHC loopback read clock > - */ > - v = ESDHC_STROBE_DLL_CTRL_ENABLE | > - (7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT); > - writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL); > - /* wait 1us to make sure strobe dll status register stable */ > - udelay(1); > - v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS); > - if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK)) > - dev_warn(mmc_dev(host->mmc), > - "warning! HS400 strobe DLL status REF not lock!\n"); > - if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK)) > - dev_warn(mmc_dev(host->mmc), > - "warning! HS400 strobe DLL status SLV not lock!\n"); > - } > + /* disable clock before enabling strobe dll */ > + writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) & > + ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON, > + host->ioaddr + ESDHC_VENDOR_SPEC); > + > + /* force a reset on strobe dll */ > + writel(ESDHC_STROBE_DLL_CTRL_RESET, > + host->ioaddr + ESDHC_STROBE_DLL_CTRL); > + /* > + * enable strobe dll ctrl and adjust the delay target > + * for the uSDHC loopback read clock > + */ > + v = ESDHC_STROBE_DLL_CTRL_ENABLE | > + (7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT); > + writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL); > + /* wait 1us to make sure strobe dll status register stable */ > + udelay(1); > + v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS); > + if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK)) > + dev_warn(mmc_dev(host->mmc), > + "warning! HS400 strobe DLL status REF not lock!\n"); > + if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK)) > + dev_warn(mmc_dev(host->mmc), > + "warning! HS400 strobe DLL status SLV not lock!\n"); > } > > static void esdhc_reset_tuning(struct sdhci_host *host) > -- > 2.17.1 >