Message ID | 20190107101757.27647-1-haibo.chen@nxp.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/5] mmc: sdhci-esdhc-imx: remove the 100MHz limitation for Strobe DLL | expand |
On 7/01/19 12:11 PM, BOUGH CHEN 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@nxp.com> Acked-by: Adrian Hunter <adrian.hunter@intel.com> > --- > 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) >
On Mon, 7 Jan 2019 at 11:11, BOUGH CHEN <haibo.chen@nxp.com> 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@nxp.com> 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 >
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)
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@nxp.com> --- drivers/mmc/host/sdhci-esdhc-imx.c | 55 +++++++++++++----------------- 1 file changed, 24 insertions(+), 31 deletions(-)