[U-Boot] [U-Boot,2/2] mmc: fsl_esdhc: enable HS400 feature

Jaehoon Chung jh80.chung at samsung.com
Thu Apr 26 10:30:31 UTC 2018


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 <peng.fan at nxp.com>
> Cc: Jaehoon Chung <jh80.chung at samsung.com>
> Cc: Stefano Babic <sbabic at denx.de>
> ---
>  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:
> 



More information about the U-Boot mailing list