Hi, On 03/05/2018 06:11 PM, Peng Fan wrote: > The strobe dll code is ported from Linux Kernel: > drivers/mmc/host/sdhci-esdhc-imx.c > The comments are from the above file, > "For HS400 eMMC, there is a data_strobe line. This signal is generated > by the device and used for data output and CRC status response output > in HS400 mode. The frequency of this signal follows the frequency of > CLK generated by host. The host receives the data which is aligned to the > 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. "
Sorry for late. > > Signed-off-by: Peng Fan <[email protected]> > Cc: Jaehoon Chung <[email protected]> > Cc: Stefano Babic <[email protected]> > --- > drivers/mmc/fsl_esdhc.c | 35 ++++++++++++++++++++++++++++++++++- > 1 file changed, 34 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c > index 6018f84307..e42bdb6941 100644 > --- a/drivers/mmc/fsl_esdhc.c > +++ b/drivers/mmc/fsl_esdhc.c > @@ -663,6 +663,7 @@ static int esdhc_change_pinstate(struct udevice *dev) > break; > case UHS_SDR104: > case MMC_HS_200: > + case MMC_HS_400: > ret = pinctrl_select_state(dev, "state_200mhz"); > break; > default: > @@ -690,6 +691,33 @@ static void esdhc_reset_tuning(struct mmc *mmc) > } > } > > +static void esdhc_set_strobe_dll(struct mmc *mmc) > +{ > + struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev); > + struct fsl_esdhc *regs = priv->esdhc_regs; > + u32 v; v? I want to use the meaningful variable name. :) > + > + if (priv->clock > ESDHC_STROBE_DLL_CLK_FREQ) { > + writel(ESDHC_STROBE_DLL_CTRL_RESET, ®s->strobe_dllctrl); > + > + /* > + * enable strobe dll ctrl and adjust the delay target > + * for the uSDHC loopback read clock > + */ > + v = ESDHC_STROBE_DLL_CTRL_ENABLE | > + (priv->strobe_dll_delay_target << > + ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT); > + writel(v, ®s->strobe_dllctrl); > + /* wait 1us to make sure strobe dll status register stable */ > + mdelay(1); > + v = readl(®s->strobe_dllstat); > + if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK)) > + pr_warn("HS400 strobe DLL status REF not lock!\n"); > + if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK)) > + pr_warn("HS400 strobe DLL status SLV not lock!\n"); > + } > +} > + > static int esdhc_set_timing(struct mmc *mmc) > { > struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev); > @@ -704,6 +732,11 @@ static int esdhc_set_timing(struct mmc *mmc) > case SD_LEGACY: > esdhc_reset_tuning(mmc); > break; > + case MMC_HS_400: > + mixctrl |= MIX_CTRL_DDREN | MIX_CTRL_HS400_EN; > + writel(mixctrl, ®s->mixctrl); > + esdhc_set_strobe_dll(mmc); > + break; > case MMC_HS: > case MMC_HS_52: > case MMC_HS_200: > @@ -1439,7 +1472,7 @@ static int fsl_esdhc_probe(struct udevice *dev) > #endif > > if (fdt_get_property(fdt, node, "no-1-8-v", NULL)) > - priv->caps &= ~(UHS_CAPS | MMC_MODE_HS200); > + priv->caps &= ~(UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_HS400); > > /* > * TODO: > _______________________________________________ U-Boot mailing list [email protected] https://lists.denx.de/listinfo/u-boot

