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, &regs->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, &regs->strobe_dllctrl);
> +             /* wait 1us to make sure strobe dll status register stable */
> +             mdelay(1);
> +             v = readl(&regs->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, &regs->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

Reply via email to