* [PATCH] mmc: sdhci-of-esdhc: make sure delay chain locked for HS400
@ 2020-10-16 4:25 Yangbo Lu
2020-10-16 9:05 ` Adrian Hunter
0 siblings, 1 reply; 3+ messages in thread
From: Yangbo Lu @ 2020-10-16 4:25 UTC (permalink / raw)
To: linux-mmc; +Cc: Yangbo Lu, Adrian Hunter, Ulf Hansson
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>
---
drivers/mmc/host/sdhci-esdhc.h | 2 ++
drivers/mmc/host/sdhci-of-esdhc.c | 24 ++++++++++++++++++++++++
2 files changed, 26 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..a39ff86 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>
@@ -743,6 +744,29 @@ 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 */
+ timeout = ktime_add_ms(ktime_get(), 20);
+ while (1) {
+ bool timedout = ktime_after(ktime_get(), timeout);
+
+ if (sdhci_readl(host, ESDHC_DLLSTAT0) &
+ ESDHC_DLL_STS_SLV_LOCK)
+ break;
+ if (timedout) {
+ pr_err("%s: timeout for delay chain lock.\n",
+ mmc_hostname(host->mmc));
+ break;
+ }
+ usleep_range(10, 20);
+ }
+
temp = sdhci_readl(host, ESDHC_TBCTL);
sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL);
--
2.7.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] mmc: sdhci-of-esdhc: make sure delay chain locked for HS400
2020-10-16 4:25 [PATCH] mmc: sdhci-of-esdhc: make sure delay chain locked for HS400 Yangbo Lu
@ 2020-10-16 9:05 ` Adrian Hunter
2020-10-20 2:55 ` Y.b. Lu
0 siblings, 1 reply; 3+ messages in thread
From: Adrian Hunter @ 2020-10-16 9:05 UTC (permalink / raw)
To: Yangbo Lu, linux-mmc; +Cc: Ulf Hansson
On 16/10/20 7:25 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>
> ---
> drivers/mmc/host/sdhci-esdhc.h | 2 ++
> drivers/mmc/host/sdhci-of-esdhc.c | 24 ++++++++++++++++++++++++
> 2 files changed, 26 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..a39ff86 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>
> @@ -743,6 +744,29 @@ 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 */
> + timeout = ktime_add_ms(ktime_get(), 20);
> + while (1) {
> + bool timedout = ktime_after(ktime_get(), timeout);
> +
> + if (sdhci_readl(host, ESDHC_DLLSTAT0) &
> + ESDHC_DLL_STS_SLV_LOCK)
> + break;
> + if (timedout) {
> + pr_err("%s: timeout for delay chain lock.\n",
> + mmc_hostname(host->mmc));
> + break;
> + }
> + usleep_range(10, 20);
> + }
It is possible now to do these loops using read_poll_timeout
e.g. something like this:
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);
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* RE: [PATCH] mmc: sdhci-of-esdhc: make sure delay chain locked for HS400
2020-10-16 9:05 ` Adrian Hunter
@ 2020-10-20 2:55 ` Y.b. Lu
0 siblings, 0 replies; 3+ messages in thread
From: Y.b. Lu @ 2020-10-20 2:55 UTC (permalink / raw)
To: Adrian Hunter, linux-mmc@vger.kernel.org; +Cc: Ulf Hansson
Hi Adrian,
> -----Original Message-----
> From: Adrian Hunter <adrian.hunter@intel.com>
> Sent: Friday, October 16, 2020 5:06 PM
> To: Y.b. Lu <yangbo.lu@nxp.com>; linux-mmc@vger.kernel.org
> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> Subject: Re: [PATCH] mmc: sdhci-of-esdhc: make sure delay chain locked for
> HS400
>
> On 16/10/20 7:25 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>
> > ---
> > drivers/mmc/host/sdhci-esdhc.h | 2 ++
> > drivers/mmc/host/sdhci-of-esdhc.c | 24 ++++++++++++++++++++++++
> > 2 files changed, 26 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..a39ff86 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>
> > @@ -743,6 +744,29 @@ 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 */
> > + timeout = ktime_add_ms(ktime_get(), 20);
> > + while (1) {
> > + bool timedout = ktime_after(ktime_get(), timeout);
> > +
> > + if (sdhci_readl(host, ESDHC_DLLSTAT0) &
> > + ESDHC_DLL_STS_SLV_LOCK)
> > + break;
> > + if (timedout) {
> > + pr_err("%s: timeout for delay chain lock.\n",
> > + mmc_hostname(host->mmc));
> > + break;
> > + }
> > + usleep_range(10, 20);
> > + }
>
> It is possible now to do these loops using read_poll_timeout
> e.g. something like this:
>
> 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));
Thank you very much.
I sent out v2 converting to use it.
>
>
>
> > +
> > temp = sdhci_readl(host, ESDHC_TBCTL);
> > sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST,
> ESDHC_TBCTL);
> >
> >
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-10-20 2:55 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-10-16 4:25 [PATCH] mmc: sdhci-of-esdhc: make sure delay chain locked for HS400 Yangbo Lu
2020-10-16 9:05 ` Adrian Hunter
2020-10-20 2:55 ` Y.b. Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox