[PATCH v1 2/2] mmc: rockchip_sdhci: Add support for RK3568

Jaehoon Chung jh80.chung at samsung.com
Tue Jun 8 00:21:45 CEST 2021


On 6/7/21 4:38 PM, Yifeng Zhao wrote:
> This patch adds support for the RK3568 platform to this driver.
> 
> Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
> ---
> 
>  drivers/mmc/rockchip_sdhci.c | 103 +++++++++++++++++++++++++++++++++++
>  1 file changed, 103 insertions(+)
> 
> diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
> index 05ed998eca..befe48e061 100644
> --- a/drivers/mmc/rockchip_sdhci.c
> +++ b/drivers/mmc/rockchip_sdhci.c
> @@ -36,6 +36,31 @@
>  #define PHYCTRL_FREQSEL_100M		0x2
>  #define PHYCTRL_FREQSEL_150M		0x3
>  
> +/* Rockchip specific Registers */
> +#define DWCMSHC_EMMC_DLL_CTRL		0x800
> +#define DWCMSHC_EMMC_DLL_RXCLK		0x804
> +#define DWCMSHC_EMMC_DLL_TXCLK		0x808
> +#define DWCMSHC_EMMC_DLL_STRBIN		0x80c
> +#define DWCMSHC_EMMC_DLL_STATUS0	0x840
> +#define DWCMSHC_EMMC_DLL_STATUS1	0x844
> +#define DWCMSHC_EMMC_DLL_START		BIT(0)
> +#define DWCMSHC_EMMC_DLL_RXCLK_SRCSEL	29
> +#define DWCMSHC_EMMC_DLL_START_POINT	16
> +#define DWCMSHC_EMMC_DLL_INC		8
> +#define DWCMSHC_EMMC_DLL_DLYENA		BIT(27)
> +#define DLL_TXCLK_TAPNUM_DEFAULT	0x10
> +#define DLL_STRBIN_TAPNUM_DEFAULT	0x3
> +#define DLL_TXCLK_TAPNUM_FROM_SW	BIT(24)
> +#define DWCMSHC_EMMC_DLL_LOCKED		BIT(8)
> +#define DWCMSHC_EMMC_DLL_TIMEOUT	BIT(9)
> +#define DLL_RXCLK_NO_INVERTER		1
> +#define DLL_RXCLK_INVERTER		0
> +#define DWCMSHC_ENHANCED_STROBE		BIT(8)
> +#define DLL_LOCK_WO_TMOUT(x) \
> +	((((x) & DWCMSHC_EMMC_DLL_LOCKED) == DWCMSHC_EMMC_DLL_LOCKED) && \
> +	(((x) & DWCMSHC_EMMC_DLL_TIMEOUT) == 0))
> +#define ROCKCHIP_MAX_CLKS		3
> +
>  struct rockchip_sdhc_plat {
>  	struct mmc_config cfg;
>  	struct mmc mmc;
> @@ -267,6 +292,74 @@ static int rk3399_sdhci_emmc_set_clock(struct sdhci_host *host, unsigned int clo
>  	return 0;
>  }
>  
> +static int rk3568_emmc_phy_init(struct udevice *dev)
> +{
> +	struct rockchip_sdhc *prv = dev_get_priv(dev);
> +	struct sdhci_host *host = &prv->host;
> +	u32 extra;
> +
> +	extra = DLL_RXCLK_NO_INVERTER << DWCMSHC_EMMC_DLL_RXCLK_SRCSEL;
> +	sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK);
> +	return 0;
> +}
> +
> +static int rk3568_sdhci_emmc_set_clock(struct sdhci_host *host, unsigned int clock)
> +{
> +	u32 extra;
> +	int timeout = 500, ret;
> +
> +	ret = rockchip_emmc_set_clock(host, clock);

If set_clock is failed, is below codes meaningful?

> +
> +	if (clock >= 50 * 1000000) {> +		sdhci_writel(host, BIT(1), DWCMSHC_EMMC_DLL_CTRL);
> +		udelay(1);

Add comment why put udelay(1).

> +		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL);
> +		/* Init DLL settings */
> +		extra = 0x5 << DWCMSHC_EMMC_DLL_START_POINT |
> +			0x2 << DWCMSHC_EMMC_DLL_INC |
> +			DWCMSHC_EMMC_DLL_START;

What means 0x5 and 0x2? 

> +		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_CTRL);
> +
> +		while (1) {
> +			if (timeout < 0)
> +				return -ETIMEDOUT;
> +			if (DLL_LOCK_WO_TMOUT((sdhci_readl(host, DWCMSHC_EMMC_DLL_STATUS0))))
> +				break;
> +			udelay(1);
> +			timeout--;
> +		}

use poll_timeout macro.

> +
> +		extra = DWCMSHC_EMMC_DLL_DLYENA |
> +			DLL_RXCLK_NO_INVERTER << DWCMSHC_EMMC_DLL_RXCLK_SRCSEL;
> +		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK);
> +
> +		extra = DWCMSHC_EMMC_DLL_DLYENA |
> +			DLL_TXCLK_TAPNUM_DEFAULT |
> +			DLL_TXCLK_TAPNUM_FROM_SW;
> +		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_TXCLK);
> +
> +		extra = DWCMSHC_EMMC_DLL_DLYENA |
> +			DLL_STRBIN_TAPNUM_DEFAULT;
> +		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN);
> +		udelay(1);

ditto.

> +	} else {
> +		/* reset the clock phase when the frequency is lower than 52MHz */
> +		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL);
> +		extra = DLL_RXCLK_NO_INVERTER << DWCMSHC_EMMC_DLL_RXCLK_SRCSEL;
> +		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK);
> +		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK);
> +		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_STRBIN);
> +		udelay(1);

ditto.

> +	}


It seems that can be put udelay(1) at here.


Best Regards,
Jaehoon Chung

> +
> +	return ret;
> +}
> +
> +static int rk3568_emmc_get_phy(struct udevice *dev)
> +{
> +	return 0;
> +}
> +
>  static int sdhci_set_ios_post(struct sdhci_host *host)
>  {
>  	struct mmc *mmc = host->mmc;
> @@ -370,11 +463,21 @@ static const struct sdhci_data rk3399_data = {
>  	.emmc_phy_init = rk3399_emmc_phy_init,
>  };
>  
> +static const struct sdhci_data rk3568_data = {
> +	.emmc_set_clock = rk3568_sdhci_emmc_set_clock,
> +	.get_phy = rk3568_emmc_get_phy,
> +	.emmc_phy_init = rk3568_emmc_phy_init,
> +};
> +
>  static const struct udevice_id sdhci_ids[] = {
>  	{
>  		.compatible = "arasan,sdhci-5.1",
>  		.data = (ulong)&rk3399_data,
>  	},
> +	{
> +		.compatible = "rockchip,rk3568-dwcmshc",
> +		.data = (ulong)&rk3568_data,
> +	},
>  	{ }
>  };
>  
> 



More information about the U-Boot mailing list