[PATCH v2 13/17] mmc: rockchip_sdhci: Add support for RK3588
Kever Yang
kever.yang at rock-chips.com
Thu Apr 20 12:03:12 CEST 2023
On 2023/4/19 00:46, Jonas Karlman wrote:
> Add support for RK3588 to the rockchip sdhci driver.
>
> Use driver data to handle differences between RK3568 and RK3588:
>
> - Set "Receive original clock source is auto gating" for RK3588.
> - Set "Receive clock source is no-inverted" only on RK3568 and "Transmit
> clock source is invertion of original clock input" for RK3588.
> - Use different txclk_tapnum for HS400 modes on RK3588.
> - Configure the CMDOUT reg for HS400 modes for RK3588.
>
> This is based on the mainline linux and vendor kernel driver and have
> successfully been tested with rock5b-rk3588_defconfig and
>
> CONFIG_MMC_HS200_SUPPORT=y
> CONFIG_MMC_HS400_SUPPORT=y
> CONFIG_MMC_HS400_ES_SUPPORT=y
> CONFIG_MMC_SPEED_MODE_SET=y
>
> using the following command to switch mode and then read 512 MiB of data
> from eMMC into memory,
>
> => mmc dev 0 0 <mode> && mmc info && mmc read 10000000 2000 10000
>
> for each of the modes below.
>
> 0 = MMC legacy
> 1 = MMC High Speed (26MHz)
> 3 = MMC High Speed (52MHz)
> 4 = MMC DDR52 (52MHz)
> 10 = HS200 (200MHz)
> 11 = HS400 (200MHz)
> 12 = HS400ES (200MHz)
>
> Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
> Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
> Reviewed-by: Shawn Lin <shawn.lin at rock-chips.com>
Reviewed-by: Kever Yang <kever.yang at rock-chips.com>
Thanks,
- Kever
> ---
> v2:
> - Add Signed-off-by tag
> - Update commit message
> - Rename quirks to flags
> - Save HS200/HS400 txclk_tapnum as driver data
> - Remove use of rockchip,txclk-tapnum prop
> - Collect r-b tag
>
> drivers/mmc/rockchip_sdhci.c | 57 +++++++++++++++++++++++++++++++++---
> 1 file changed, 53 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
> index 12a616d3dfb8..2857dcc9ec4f 100644
> --- a/drivers/mmc/rockchip_sdhci.c
> +++ b/drivers/mmc/rockchip_sdhci.c
> @@ -56,6 +56,7 @@
> #define DWCMSHC_EMMC_DLL_RXCLK 0x804
> #define DWCMSHC_EMMC_DLL_TXCLK 0x808
> #define DWCMSHC_EMMC_DLL_STRBIN 0x80c
> +#define DWCMSHC_EMMC_DLL_CMDOUT 0x810
> #define DWCMSHC_EMMC_DLL_STATUS0 0x840
> #define DWCMSHC_EMMC_DLL_STATUS1 0x844
> #define DWCMSHC_EMMC_DLL_START BIT(0)
> @@ -70,18 +71,27 @@
> #define DLL_RXCLK_NO_INVERTER BIT(29)
> #define DLL_RXCLK_ORI_GATE BIT(31)
> #define DLL_TXCLK_TAPNUM_DEFAULT 0x10
> +#define DLL_TXCLK_TAPNUM_90_DEGREES 0x9
> #define DLL_TXCLK_TAPNUM_FROM_SW BIT(24)
> +#define DLL_TXCLK_NO_INVERTER BIT(29)
> #define DLL_STRBIN_TAPNUM_DEFAULT 0x4
> #define DLL_STRBIN_TAPNUM_FROM_SW BIT(24)
> #define DLL_STRBIN_DELAY_NUM_SEL BIT(26)
> #define DLL_STRBIN_DELAY_NUM_OFFSET 16
> #define DLL_STRBIN_DELAY_NUM_DEFAULT 0x10
> +#define DLL_CMDOUT_TAPNUM_90_DEGREES 0x8
> +#define DLL_CMDOUT_TAPNUM_FROM_SW BIT(24)
> +#define DLL_CMDOUT_SRC_CLK_NEG BIT(28)
> +#define DLL_CMDOUT_EN_SRC_CLK_NEG BIT(29)
> +#define DLL_CMDOUT_BOTH_CLK_EDGE BIT(30)
>
> #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
>
> +#define FLAG_INVERTER_FLAG_IN_RXCLK BIT(0)
> +
> struct rockchip_sdhc_plat {
> struct mmc_config cfg;
> struct mmc mmc;
> @@ -144,6 +154,10 @@ struct sdhci_data {
> * Return: 0 if successful, -ve on error
> */
> int (*set_enhanced_strobe)(struct sdhci_host *host);
> +
> + u32 flags;
> + u8 hs200_txclk_tapnum;
> + u8 hs400_txclk_tapnum;
> };
>
> static void rk3399_emmc_phy_power_on(struct rockchip_emmc_phy *phy, u32 clock)
> @@ -294,8 +308,11 @@ static void rk3568_sdhci_set_clock(struct sdhci_host *host, u32 div)
>
> static int rk3568_sdhci_config_dll(struct sdhci_host *host, u32 clock, bool enable)
> {
> + struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
> + struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
> + struct mmc *mmc = host->mmc;
> int val, ret;
> - u32 extra;
> + u32 extra, txclk_tapnum;
>
> if (!enable)
> return 0;
> @@ -318,12 +335,28 @@ static int rk3568_sdhci_config_dll(struct sdhci_host *host, u32 clock, bool enab
> if (ret)
> return ret;
>
> - extra = DWCMSHC_EMMC_DLL_DLYENA | DLL_RXCLK_NO_INVERTER;
> + extra = DWCMSHC_EMMC_DLL_DLYENA | DLL_RXCLK_ORI_GATE;
> + if (data->flags & FLAG_INVERTER_FLAG_IN_RXCLK)
> + extra |= DLL_RXCLK_NO_INVERTER;
> sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK);
>
> + txclk_tapnum = data->hs200_txclk_tapnum;
> + if (mmc->selected_mode == MMC_HS_400 ||
> + mmc->selected_mode == MMC_HS_400_ES) {
> + txclk_tapnum = data->hs400_txclk_tapnum;
> +
> + extra = DLL_CMDOUT_SRC_CLK_NEG |
> + DLL_CMDOUT_BOTH_CLK_EDGE |
> + DWCMSHC_EMMC_DLL_DLYENA |
> + DLL_CMDOUT_TAPNUM_90_DEGREES |
> + DLL_CMDOUT_TAPNUM_FROM_SW;
> + sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_CMDOUT);
> + }
> +
> extra = DWCMSHC_EMMC_DLL_DLYENA |
> - DLL_TXCLK_TAPNUM_DEFAULT |
> - DLL_TXCLK_TAPNUM_FROM_SW;
> + DLL_TXCLK_TAPNUM_FROM_SW |
> + DLL_TXCLK_NO_INVERTER |
> + txclk_tapnum;
> sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_TXCLK);
>
> extra = DWCMSHC_EMMC_DLL_DLYENA |
> @@ -339,6 +372,7 @@ static int rk3568_sdhci_config_dll(struct sdhci_host *host, u32 clock, bool enab
> sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_CTRL);
> sdhci_writel(host, DLL_RXCLK_ORI_GATE, DWCMSHC_EMMC_DLL_RXCLK);
> sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK);
> + sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CMDOUT);
> /*
> * Before switching to hs400es mode, the driver will enable
> * enhanced strobe first. PHY needs to configure the parameters
> @@ -594,6 +628,17 @@ static const struct sdhci_data rk3568_data = {
> .set_ios_post = rk3568_sdhci_set_ios_post,
> .set_clock = rk3568_sdhci_set_clock,
> .config_dll = rk3568_sdhci_config_dll,
> + .flags = FLAG_INVERTER_FLAG_IN_RXCLK,
> + .hs200_txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT,
> + .hs400_txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT,
> +};
> +
> +static const struct sdhci_data rk3588_data = {
> + .set_ios_post = rk3568_sdhci_set_ios_post,
> + .set_clock = rk3568_sdhci_set_clock,
> + .config_dll = rk3568_sdhci_config_dll,
> + .hs200_txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT,
> + .hs400_txclk_tapnum = DLL_TXCLK_TAPNUM_90_DEGREES,
> };
>
> static const struct udevice_id sdhci_ids[] = {
> @@ -605,6 +650,10 @@ static const struct udevice_id sdhci_ids[] = {
> .compatible = "rockchip,rk3568-dwcmshc",
> .data = (ulong)&rk3568_data,
> },
> + {
> + .compatible = "rockchip,rk3588-dwcmshc",
> + .data = (ulong)&rk3588_data,
> + },
> { }
> };
>
More information about the U-Boot
mailing list