Message ID | 20181023092840.13726-1-yinbo.zhu@nxp.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] mmc: sdhci-of-esdhc: temporary fixup for eMMC HS400 issue | expand |
On 23/10/18 12:28 PM, Yinbo Zhu wrote: > From: Yangbo Lu <yangbo.lu@nxp.com> > > Currently only LX2160A eSDHC supports eMMC HS400. According to > a large number of tests, eMMC HS400 failed to work at 150MHz, > and for a few boards failed to work at 175MHz. But eMMC HS400 > worked fine on 200MHz. We hadn't found the root cause but > setting eSDHC_DLLCFG0[DLL_FREQ_SEL] = 0 using slow delay chain > seemed to resovle this issue. Let's use this as fixup for now. > > Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> > Signed-off-by: Yinbo Zhu <yinbo.zhu@nxp.com> If you still need this, please re-base > --- > Change in v2: > Limit the erratum was executed when the soc is lx2160a. > > drivers/mmc/host/sdhci-of-esdhc.c | 16 +++++++++++++++- > 1 files changed, 15 insertions(+), 1 deletions(-) > > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c > index 199abd5..8071fde 100644 > --- a/drivers/mmc/host/sdhci-of-esdhc.c > +++ b/drivers/mmc/host/sdhci-of-esdhc.c > @@ -81,6 +81,7 @@ struct sdhci_esdhc { > bool quirk_limited_clk_division; > bool quirk_unreliable_pulse_detection; > bool quirk_fixup_tuning; > + bool quirk_incorrect_delay_chain; > unsigned int peripheral_clock; > const struct esdhc_clk_fixup *clk_fixup; > u32 div_ratio; > @@ -540,6 +541,11 @@ static void esdhc_clock_enable(struct sdhci_host *host, bool enable) > } > } > > +static struct soc_device_attribute soc_incorrect_delay_chain[] = { > + { .family = "QorIQ LX2160A", .revision = "1.0", }, > + { }, > +}; > + > static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) > { > struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); > @@ -624,7 +630,10 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) > esdhc_clock_enable(host, true); > > temp = sdhci_readl(host, ESDHC_DLLCFG0); > - temp |= ESDHC_DLL_ENABLE | ESDHC_DLL_FREQ_SEL; > + temp |= ESDHC_DLL_ENABLE; > + if (host->mmc->actual_clock == MMC_HS200_MAX_DTR || > + esdhc->quirk_incorrect_delay_chain == false) > + temp |= ESDHC_DLL_FREQ_SEL; > sdhci_writel(host, temp, ESDHC_DLLCFG0); > temp = sdhci_readl(host, ESDHC_TBCTL); > sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL); > @@ -985,6 +994,11 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) > else > esdhc->quirk_unreliable_pulse_detection = false; > > + if (soc_device_match(soc_incorrect_delay_chain)) > + esdhc->quirk_incorrect_delay_chain = true; > + else > + esdhc->quirk_incorrect_delay_chain = false; > + > match = of_match_node(sdhci_esdhc_of_match, pdev->dev.of_node); > if (match) > esdhc->clk_fixup = match->data; >
Hi hunter and ulf I had rebased the patches as v5 version series of patches and sent to upstream, Please help apply this Thanks, Best Regards, Yinbo Zhu. -----Original Message----- From: Adrian Hunter [mailto:adrian.hunter@intel.com] Sent: 2018年11月21日 17:28 To: Yinbo Zhu <yinbo.zhu@nxp.com>; Y.B. LU <yangbo.lu@nxp.com>; linux-mmc@vger.kernel.org; ulf.hansson@linaro.org; Leo Li <leoyang.li@nxp.com> Cc: Xiaobo Xie <xiaobo.xie@nxp.com> Subject: Re: [PATCH v2] mmc: sdhci-of-esdhc: temporary fixup for eMMC HS400 issue On 23/10/18 12:28 PM, Yinbo Zhu wrote: > From: Yangbo Lu <yangbo.lu@nxp.com> > > Currently only LX2160A eSDHC supports eMMC HS400. According to a large > number of tests, eMMC HS400 failed to work at 150MHz, and for a few > boards failed to work at 175MHz. But eMMC HS400 worked fine on 200MHz. > We hadn't found the root cause but setting eSDHC_DLLCFG0[DLL_FREQ_SEL] > = 0 using slow delay chain seemed to resovle this issue. Let's use > this as fixup for now. > > Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> > Signed-off-by: Yinbo Zhu <yinbo.zhu@nxp.com> > If you still need this, please re-base > --- > Change in v2: > Limit the erratum was executed when the soc is lx2160a. > > drivers/mmc/host/sdhci-of-esdhc.c | 16 +++++++++++++++- > 1 files changed, 15 insertions(+), 1 deletions(-) > > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c > b/drivers/mmc/host/sdhci-of-esdhc.c > index 199abd5..8071fde 100644 > --- a/drivers/mmc/host/sdhci-of-esdhc.c > +++ b/drivers/mmc/host/sdhci-of-esdhc.c > @@ -81,6 +81,7 @@ struct sdhci_esdhc { > bool quirk_limited_clk_division; > bool quirk_unreliable_pulse_detection; > bool quirk_fixup_tuning; > + bool quirk_incorrect_delay_chain; > unsigned int peripheral_clock; > const struct esdhc_clk_fixup *clk_fixup; > u32 div_ratio; > @@ -540,6 +541,11 @@ static void esdhc_clock_enable(struct sdhci_host *host, bool enable) > } > } > > +static struct soc_device_attribute soc_incorrect_delay_chain[] = { > + { .family = "QorIQ LX2160A", .revision = "1.0", }, > + { }, > +}; > + > static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int > clock) { > struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -624,7 > +630,10 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) > esdhc_clock_enable(host, true); > > temp = sdhci_readl(host, ESDHC_DLLCFG0); > - temp |= ESDHC_DLL_ENABLE | ESDHC_DLL_FREQ_SEL; > + temp |= ESDHC_DLL_ENABLE; > + if (host->mmc->actual_clock == MMC_HS200_MAX_DTR || > + esdhc->quirk_incorrect_delay_chain == false) > + temp |= ESDHC_DLL_FREQ_SEL; > sdhci_writel(host, temp, ESDHC_DLLCFG0); > temp = sdhci_readl(host, ESDHC_TBCTL); > sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL); @@ > -985,6 +994,11 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) > else > esdhc->quirk_unreliable_pulse_detection = false; > > + if (soc_device_match(soc_incorrect_delay_chain)) > + esdhc->quirk_incorrect_delay_chain = true; > + else > + esdhc->quirk_incorrect_delay_chain = false; > + > match = of_match_node(sdhci_esdhc_of_match, pdev->dev.of_node); > if (match) > esdhc->clk_fixup = match->data; >
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 199abd5..8071fde 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -81,6 +81,7 @@ struct sdhci_esdhc { bool quirk_limited_clk_division; bool quirk_unreliable_pulse_detection; bool quirk_fixup_tuning; + bool quirk_incorrect_delay_chain; unsigned int peripheral_clock; const struct esdhc_clk_fixup *clk_fixup; u32 div_ratio; @@ -540,6 +541,11 @@ static void esdhc_clock_enable(struct sdhci_host *host, bool enable) } } +static struct soc_device_attribute soc_incorrect_delay_chain[] = { + { .family = "QorIQ LX2160A", .revision = "1.0", }, + { }, +}; + static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -624,7 +630,10 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) esdhc_clock_enable(host, true); temp = sdhci_readl(host, ESDHC_DLLCFG0); - temp |= ESDHC_DLL_ENABLE | ESDHC_DLL_FREQ_SEL; + temp |= ESDHC_DLL_ENABLE; + if (host->mmc->actual_clock == MMC_HS200_MAX_DTR || + esdhc->quirk_incorrect_delay_chain == false) + temp |= ESDHC_DLL_FREQ_SEL; sdhci_writel(host, temp, ESDHC_DLLCFG0); temp = sdhci_readl(host, ESDHC_TBCTL); sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL); @@ -985,6 +994,11 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) else esdhc->quirk_unreliable_pulse_detection = false; + if (soc_device_match(soc_incorrect_delay_chain)) + esdhc->quirk_incorrect_delay_chain = true; + else + esdhc->quirk_incorrect_delay_chain = false; + match = of_match_node(sdhci_esdhc_of_match, pdev->dev.of_node); if (match) esdhc->clk_fixup = match->data;