diff mbox series

[v3] mmc: sdhci-of-esdhc: make sure delay chain locked for HS400

Message ID 20201020081116.20918-1-yangbo.lu@nxp.com (mailing list archive)
State New, archived
Headers show
Series [v3] mmc: sdhci-of-esdhc: make sure delay chain locked for HS400 | expand

Commit Message

Yangbo Lu Oct. 20, 2020, 8:11 a.m. UTC
For eMMC HS400 mode initialization, the DLL reset is a required step
if DLL is enabled to use previously, like in bootloader.
This step has not been documented in reference manual, but the RM will
be fixed sooner or later.

This patch is to add the step of DLL reset, and make sure delay chain
locked for HS400.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- Converted to use read_poll_timeout.
Changes for v3:
	- Included iopoll.h.
---
 drivers/mmc/host/sdhci-esdhc.h    |  2 ++
 drivers/mmc/host/sdhci-of-esdhc.c | 17 +++++++++++++++++
 2 files changed, 19 insertions(+)

Comments

Adrian Hunter Oct. 27, 2020, 12:34 p.m. UTC | #1
On 20/10/20 11:11 am, Yangbo Lu wrote:
> For eMMC HS400 mode initialization, the DLL reset is a required step
> if DLL is enabled to use previously, like in bootloader.
> This step has not been documented in reference manual, but the RM will
> be fixed sooner or later.
> 
> This patch is to add the step of DLL reset, and make sure delay chain
> locked for HS400.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

Acked-by: Adrian Hunter <adrian.hunter@intel.com>

> ---
> Changes for v2:
> 	- Converted to use read_poll_timeout.
> Changes for v3:
> 	- Included iopoll.h.
> ---
>  drivers/mmc/host/sdhci-esdhc.h    |  2 ++
>  drivers/mmc/host/sdhci-of-esdhc.c | 17 +++++++++++++++++
>  2 files changed, 19 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index a30796e..6de02f0 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -5,6 +5,7 @@
>   * Copyright (c) 2007 Freescale Semiconductor, Inc.
>   * Copyright (c) 2009 MontaVista Software, Inc.
>   * Copyright (c) 2010 Pengutronix e.K.
> + * Copyright 2020 NXP
>   *   Author: Wolfram Sang <kernel@pengutronix.de>
>   */
>  
> @@ -88,6 +89,7 @@
>  /* DLL Config 0 Register */
>  #define ESDHC_DLLCFG0			0x160
>  #define ESDHC_DLL_ENABLE		0x80000000
> +#define ESDHC_DLL_RESET			0x40000000
>  #define ESDHC_DLL_FREQ_SEL		0x08000000
>  
>  /* DLL Config 1 Register */
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index 0b45eff..90e6085 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -4,6 +4,7 @@
>   *
>   * Copyright (c) 2007, 2010, 2012 Freescale Semiconductor, Inc.
>   * Copyright (c) 2009 MontaVista Software, Inc.
> + * Copyright 2020 NXP
>   *
>   * Authors: Xiaobo Xie <X.Xie@freescale.com>
>   *	    Anton Vorontsov <avorontsov@ru.mvista.com>
> @@ -19,6 +20,7 @@
>  #include <linux/clk.h>
>  #include <linux/ktime.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/iopoll.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mmc/mmc.h>
>  #include "sdhci-pltfm.h"
> @@ -743,6 +745,21 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>  		if (host->mmc->actual_clock == MMC_HS200_MAX_DTR)
>  			temp |= ESDHC_DLL_FREQ_SEL;
>  		sdhci_writel(host, temp, ESDHC_DLLCFG0);
> +
> +		temp |= ESDHC_DLL_RESET;
> +		sdhci_writel(host, temp, ESDHC_DLLCFG0);
> +		udelay(1);
> +		temp &= ~ESDHC_DLL_RESET;
> +		sdhci_writel(host, temp, ESDHC_DLLCFG0);
> +
> +		/* Wait max 20 ms */
> +		if (read_poll_timeout(sdhci_readl, temp,
> +				      temp & ESDHC_DLL_STS_SLV_LOCK,
> +				      10, 20000, false,
> +				      host, ESDHC_DLLSTAT0))
> +			pr_err("%s: timeout for delay chain lock.\n",
> +			       mmc_hostname(host->mmc));
> +
>  		temp = sdhci_readl(host, ESDHC_TBCTL);
>  		sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL);
>  
>
Ulf Hansson Oct. 27, 2020, 1:41 p.m. UTC | #2
On Tue, 20 Oct 2020 at 10:20, Yangbo Lu <yangbo.lu@nxp.com> wrote:
>
> For eMMC HS400 mode initialization, the DLL reset is a required step
> if DLL is enabled to use previously, like in bootloader.
> This step has not been documented in reference manual, but the RM will
> be fixed sooner or later.
>
> This patch is to add the step of DLL reset, and make sure delay chain
> locked for HS400.
>
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

Applied for next (please tell if you think this deserves to be tagged
for stable), thanks!

Kind regards
Uffe



> ---
> Changes for v2:
>         - Converted to use read_poll_timeout.
> Changes for v3:
>         - Included iopoll.h.
> ---
>  drivers/mmc/host/sdhci-esdhc.h    |  2 ++
>  drivers/mmc/host/sdhci-of-esdhc.c | 17 +++++++++++++++++
>  2 files changed, 19 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index a30796e..6de02f0 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -5,6 +5,7 @@
>   * Copyright (c) 2007 Freescale Semiconductor, Inc.
>   * Copyright (c) 2009 MontaVista Software, Inc.
>   * Copyright (c) 2010 Pengutronix e.K.
> + * Copyright 2020 NXP
>   *   Author: Wolfram Sang <kernel@pengutronix.de>
>   */
>
> @@ -88,6 +89,7 @@
>  /* DLL Config 0 Register */
>  #define ESDHC_DLLCFG0                  0x160
>  #define ESDHC_DLL_ENABLE               0x80000000
> +#define ESDHC_DLL_RESET                        0x40000000
>  #define ESDHC_DLL_FREQ_SEL             0x08000000
>
>  /* DLL Config 1 Register */
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index 0b45eff..90e6085 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -4,6 +4,7 @@
>   *
>   * Copyright (c) 2007, 2010, 2012 Freescale Semiconductor, Inc.
>   * Copyright (c) 2009 MontaVista Software, Inc.
> + * Copyright 2020 NXP
>   *
>   * Authors: Xiaobo Xie <X.Xie@freescale.com>
>   *         Anton Vorontsov <avorontsov@ru.mvista.com>
> @@ -19,6 +20,7 @@
>  #include <linux/clk.h>
>  #include <linux/ktime.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/iopoll.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mmc/mmc.h>
>  #include "sdhci-pltfm.h"
> @@ -743,6 +745,21 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>                 if (host->mmc->actual_clock == MMC_HS200_MAX_DTR)
>                         temp |= ESDHC_DLL_FREQ_SEL;
>                 sdhci_writel(host, temp, ESDHC_DLLCFG0);
> +
> +               temp |= ESDHC_DLL_RESET;
> +               sdhci_writel(host, temp, ESDHC_DLLCFG0);
> +               udelay(1);
> +               temp &= ~ESDHC_DLL_RESET;
> +               sdhci_writel(host, temp, ESDHC_DLLCFG0);
> +
> +               /* Wait max 20 ms */
> +               if (read_poll_timeout(sdhci_readl, temp,
> +                                     temp & ESDHC_DLL_STS_SLV_LOCK,
> +                                     10, 20000, false,
> +                                     host, ESDHC_DLLSTAT0))
> +                       pr_err("%s: timeout for delay chain lock.\n",
> +                              mmc_hostname(host->mmc));
> +
>                 temp = sdhci_readl(host, ESDHC_TBCTL);
>                 sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL);
>
> --
> 2.7.4
>
Yangbo Lu Oct. 28, 2020, 8:56 a.m. UTC | #3
Hi Uffe,

> -----Original Message-----
> From: Ulf Hansson <ulf.hansson@linaro.org>
> Sent: Tuesday, October 27, 2020 9:42 PM
> To: Y.b. Lu <yangbo.lu@nxp.com>
> Cc: linux-mmc@vger.kernel.org; Adrian Hunter <adrian.hunter@intel.com>
> Subject: Re: [v3] mmc: sdhci-of-esdhc: make sure delay chain locked for HS400
> 
> On Tue, 20 Oct 2020 at 10:20, Yangbo Lu <yangbo.lu@nxp.com> wrote:
> >
> > For eMMC HS400 mode initialization, the DLL reset is a required step
> > if DLL is enabled to use previously, like in bootloader.
> > This step has not been documented in reference manual, but the RM will
> > be fixed sooner or later.
> >
> > This patch is to add the step of DLL reset, and make sure delay chain
> > locked for HS400.
> >
> > Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> 
> Applied for next (please tell if you think this deserves to be tagged
> for stable), thanks!

Thanks!
Please help to tag for stable. The latest u-boot just supporting eSDHC HS400, may cause kernel HS400 issue without this patch.

> 
> Kind regards
> Uffe
> 
> 
> 
> > ---
> > Changes for v2:
> >         - Converted to use read_poll_timeout.
> > Changes for v3:
> >         - Included iopoll.h.
> > ---
> >  drivers/mmc/host/sdhci-esdhc.h    |  2 ++
> >  drivers/mmc/host/sdhci-of-esdhc.c | 17 +++++++++++++++++
> >  2 files changed, 19 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc.h
> b/drivers/mmc/host/sdhci-esdhc.h
> > index a30796e..6de02f0 100644
> > --- a/drivers/mmc/host/sdhci-esdhc.h
> > +++ b/drivers/mmc/host/sdhci-esdhc.h
> > @@ -5,6 +5,7 @@
> >   * Copyright (c) 2007 Freescale Semiconductor, Inc.
> >   * Copyright (c) 2009 MontaVista Software, Inc.
> >   * Copyright (c) 2010 Pengutronix e.K.
> > + * Copyright 2020 NXP
> >   *   Author: Wolfram Sang <kernel@pengutronix.de>
> >   */
> >
> > @@ -88,6 +89,7 @@
> >  /* DLL Config 0 Register */
> >  #define ESDHC_DLLCFG0                  0x160
> >  #define ESDHC_DLL_ENABLE               0x80000000
> > +#define ESDHC_DLL_RESET                        0x40000000
> >  #define ESDHC_DLL_FREQ_SEL             0x08000000
> >
> >  /* DLL Config 1 Register */
> > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c
> b/drivers/mmc/host/sdhci-of-esdhc.c
> > index 0b45eff..90e6085 100644
> > --- a/drivers/mmc/host/sdhci-of-esdhc.c
> > +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> > @@ -4,6 +4,7 @@
> >   *
> >   * Copyright (c) 2007, 2010, 2012 Freescale Semiconductor, Inc.
> >   * Copyright (c) 2009 MontaVista Software, Inc.
> > + * Copyright 2020 NXP
> >   *
> >   * Authors: Xiaobo Xie <X.Xie@freescale.com>
> >   *         Anton Vorontsov <avorontsov@ru.mvista.com>
> > @@ -19,6 +20,7 @@
> >  #include <linux/clk.h>
> >  #include <linux/ktime.h>
> >  #include <linux/dma-mapping.h>
> > +#include <linux/iopoll.h>
> >  #include <linux/mmc/host.h>
> >  #include <linux/mmc/mmc.h>
> >  #include "sdhci-pltfm.h"
> > @@ -743,6 +745,21 @@ static void esdhc_of_set_clock(struct sdhci_host
> *host, unsigned int clock)
> >                 if (host->mmc->actual_clock == MMC_HS200_MAX_DTR)
> >                         temp |= ESDHC_DLL_FREQ_SEL;
> >                 sdhci_writel(host, temp, ESDHC_DLLCFG0);
> > +
> > +               temp |= ESDHC_DLL_RESET;
> > +               sdhci_writel(host, temp, ESDHC_DLLCFG0);
> > +               udelay(1);
> > +               temp &= ~ESDHC_DLL_RESET;
> > +               sdhci_writel(host, temp, ESDHC_DLLCFG0);
> > +
> > +               /* Wait max 20 ms */
> > +               if (read_poll_timeout(sdhci_readl, temp,
> > +                                     temp &
> ESDHC_DLL_STS_SLV_LOCK,
> > +                                     10, 20000, false,
> > +                                     host, ESDHC_DLLSTAT0))
> > +                       pr_err("%s: timeout for delay chain lock.\n",
> > +                              mmc_hostname(host->mmc));
> > +
> >                 temp = sdhci_readl(host, ESDHC_TBCTL);
> >                 sdhci_writel(host, temp |
> ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL);
> >
> > --
> > 2.7.4
> >
Ulf Hansson Oct. 28, 2020, 10:21 a.m. UTC | #4
On Wed, 28 Oct 2020 at 09:56, Y.b. Lu <yangbo.lu@nxp.com> wrote:
>
> Hi Uffe,
>
> > -----Original Message-----
> > From: Ulf Hansson <ulf.hansson@linaro.org>
> > Sent: Tuesday, October 27, 2020 9:42 PM
> > To: Y.b. Lu <yangbo.lu@nxp.com>
> > Cc: linux-mmc@vger.kernel.org; Adrian Hunter <adrian.hunter@intel.com>
> > Subject: Re: [v3] mmc: sdhci-of-esdhc: make sure delay chain locked for HS400
> >
> > On Tue, 20 Oct 2020 at 10:20, Yangbo Lu <yangbo.lu@nxp.com> wrote:
> > >
> > > For eMMC HS400 mode initialization, the DLL reset is a required step
> > > if DLL is enabled to use previously, like in bootloader.
> > > This step has not been documented in reference manual, but the RM will
> > > be fixed sooner or later.
> > >
> > > This patch is to add the step of DLL reset, and make sure delay chain
> > > locked for HS400.
> > >
> > > Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> >
> > Applied for next (please tell if you think this deserves to be tagged
> > for stable), thanks!
>
> Thanks!
> Please help to tag for stable. The latest u-boot just supporting eSDHC HS400, may cause kernel HS400 issue without this patch.

I have added a stable and a fixes tag. Additionally I have moved the
patch to my fixes branch.

Please have a look in my git to make sure it looks good to you.

[...]

Kind regards
Uffe
Yangbo Lu Oct. 28, 2020, 10:36 a.m. UTC | #5
> -----Original Message-----
> From: Ulf Hansson <ulf.hansson@linaro.org>
> Sent: Wednesday, October 28, 2020 6:21 PM
> To: Y.b. Lu <yangbo.lu@nxp.com>
> Cc: linux-mmc@vger.kernel.org; Adrian Hunter <adrian.hunter@intel.com>
> Subject: Re: [v3] mmc: sdhci-of-esdhc: make sure delay chain locked for HS400
> 
> On Wed, 28 Oct 2020 at 09:56, Y.b. Lu <yangbo.lu@nxp.com> wrote:
> >
> > Hi Uffe,
> >
> > > -----Original Message-----
> > > From: Ulf Hansson <ulf.hansson@linaro.org>
> > > Sent: Tuesday, October 27, 2020 9:42 PM
> > > To: Y.b. Lu <yangbo.lu@nxp.com>
> > > Cc: linux-mmc@vger.kernel.org; Adrian Hunter <adrian.hunter@intel.com>
> > > Subject: Re: [v3] mmc: sdhci-of-esdhc: make sure delay chain locked for
> HS400
> > >
> > > On Tue, 20 Oct 2020 at 10:20, Yangbo Lu <yangbo.lu@nxp.com> wrote:
> > > >
> > > > For eMMC HS400 mode initialization, the DLL reset is a required step
> > > > if DLL is enabled to use previously, like in bootloader.
> > > > This step has not been documented in reference manual, but the RM will
> > > > be fixed sooner or later.
> > > >
> > > > This patch is to add the step of DLL reset, and make sure delay chain
> > > > locked for HS400.
> > > >
> > > > Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> > >
> > > Applied for next (please tell if you think this deserves to be tagged
> > > for stable), thanks!
> >
> > Thanks!
> > Please help to tag for stable. The latest u-boot just supporting eSDHC HS400,
> may cause kernel HS400 issue without this patch.
> 
> I have added a stable and a fixes tag. Additionally I have moved the
> patch to my fixes branch.
> 
> Please have a look in my git to make sure it looks good to you.

Thank you Uffe. It looks fine.

> 
> [...]
> 
> Kind regards
> Uffe
diff mbox series

Patch

diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index a30796e..6de02f0 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -5,6 +5,7 @@ 
  * Copyright (c) 2007 Freescale Semiconductor, Inc.
  * Copyright (c) 2009 MontaVista Software, Inc.
  * Copyright (c) 2010 Pengutronix e.K.
+ * Copyright 2020 NXP
  *   Author: Wolfram Sang <kernel@pengutronix.de>
  */
 
@@ -88,6 +89,7 @@ 
 /* DLL Config 0 Register */
 #define ESDHC_DLLCFG0			0x160
 #define ESDHC_DLL_ENABLE		0x80000000
+#define ESDHC_DLL_RESET			0x40000000
 #define ESDHC_DLL_FREQ_SEL		0x08000000
 
 /* DLL Config 1 Register */
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 0b45eff..90e6085 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -4,6 +4,7 @@ 
  *
  * Copyright (c) 2007, 2010, 2012 Freescale Semiconductor, Inc.
  * Copyright (c) 2009 MontaVista Software, Inc.
+ * Copyright 2020 NXP
  *
  * Authors: Xiaobo Xie <X.Xie@freescale.com>
  *	    Anton Vorontsov <avorontsov@ru.mvista.com>
@@ -19,6 +20,7 @@ 
 #include <linux/clk.h>
 #include <linux/ktime.h>
 #include <linux/dma-mapping.h>
+#include <linux/iopoll.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
 #include "sdhci-pltfm.h"
@@ -743,6 +745,21 @@  static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 		if (host->mmc->actual_clock == MMC_HS200_MAX_DTR)
 			temp |= ESDHC_DLL_FREQ_SEL;
 		sdhci_writel(host, temp, ESDHC_DLLCFG0);
+
+		temp |= ESDHC_DLL_RESET;
+		sdhci_writel(host, temp, ESDHC_DLLCFG0);
+		udelay(1);
+		temp &= ~ESDHC_DLL_RESET;
+		sdhci_writel(host, temp, ESDHC_DLLCFG0);
+
+		/* Wait max 20 ms */
+		if (read_poll_timeout(sdhci_readl, temp,
+				      temp & ESDHC_DLL_STS_SLV_LOCK,
+				      10, 20000, false,
+				      host, ESDHC_DLLSTAT0))
+			pr_err("%s: timeout for delay chain lock.\n",
+			       mmc_hostname(host->mmc));
+
 		temp = sdhci_readl(host, ESDHC_TBCTL);
 		sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL);