On Tue, 20 Oct 2020 at 10:20, Yangbo Lu <yangbo.lu@xxxxxxx> 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@xxxxxxx> 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@xxxxxxxxxxxxxx> > */ > > @@ -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@xxxxxxxxxxxxx> > * Anton Vorontsov <avorontsov@xxxxxxxxxxxxx> > @@ -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 >