[PATCH 13/17] mmc: rockchip_sdhci: Add support for RK3588

Shawn Lin shawn.lin at rock-chips.com
Fri Apr 7 05:27:26 CEST 2023


在 2023/4/4 18:01, Kever Yang 写道:
> Add Shawn and Yifeng.
> 
> Please help review this patch.
> 
> 
> Thanks,
> - Kever
> On 2023/4/4 04:48, Jonas Karlman wrote:
>> Add support for RK3588 to the sdhci driver. RK3588 has the inverter flag
>> in TXCLK reg instead of RXCLK and also make use of a new CMDOUT reg.
>> Add and use a quirks field to support such quirks.
>>
>> Signed-off-by: Jonas Karlman <jonas at kwiboo.se>

Reviewed-by: Shawn Lin <shawn.lin at rock-chips.com>


>> ---
>>   drivers/mmc/rockchip_sdhci.c | 62 ++++++++++++++++++++++++++++++++++--
>>   1 file changed, 59 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
>> index 12a616d3dfb8..9178bc00b6b8 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,28 @@
>>   #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 QUIRK_INVERTER_FLAG_IN_RXCLK    BIT(0)
>> +#define QUIRK_HAS_DLL_CMDOUT        BIT(1)
>> +
>>   struct rockchip_sdhc_plat {
>>       struct mmc_config cfg;
>>       struct mmc mmc;
>> @@ -99,6 +110,7 @@ struct rockchip_sdhc {
>>       void *base;
>>       struct rockchip_emmc_phy *phy;
>>       struct clk emmc_clk;
>> +    u8 txclk_tapnum;
>>   };
>>   struct sdhci_data {
>> @@ -144,6 +156,8 @@ struct sdhci_data {
>>        * Return: 0 if successful, -ve on error
>>        */
>>       int (*set_enhanced_strobe)(struct sdhci_host *host);
>> +
>> +    u32 quirks;
>>   };
>>   static void rk3399_emmc_phy_power_on(struct rockchip_emmc_phy *phy, 
>> u32 clock)
>> @@ -294,6 +308,10 @@ 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;
>> +    u8 txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT;
>>       int val, ret;
>>       u32 extra;
>> @@ -318,12 +336,33 @@ 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->quirks & QUIRK_INVERTER_FLAG_IN_RXCLK)
>> +            extra |= DLL_RXCLK_NO_INVERTER;
>>           sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK);
>> +        if (mmc->selected_mode == MMC_HS_200 ||
>> +            mmc->selected_mode == MMC_HS_400 ||
>> +            mmc->selected_mode == MMC_HS_400_ES)
>> +            txclk_tapnum = priv->txclk_tapnum;
>> +
>> +        if ((data->quirks & QUIRK_HAS_DLL_CMDOUT) &&
>> +            (mmc->selected_mode == MMC_HS_400 ||
>> +             mmc->selected_mode == MMC_HS_400_ES)) {
>> +            txclk_tapnum = DLL_TXCLK_TAPNUM_90_DEGREES;
>> +
>> +            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 +378,8 @@ 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);
>> +        if (data->quirks & QUIRK_HAS_DLL_CMDOUT)
>> +            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
>> @@ -573,6 +614,9 @@ static int rockchip_sdhci_of_to_plat(struct 
>> udevice *dev)
>>       if (ret)
>>           return ret;
>> +    priv->txclk_tapnum = dev_read_u8_default(dev, 
>> "rockchip,txclk-tapnum",
>> +                         DLL_TXCLK_TAPNUM_DEFAULT);
>> +
>>       return 0;
>>   }
>> @@ -594,6 +638,14 @@ 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,
>> +    .quirks = QUIRK_INVERTER_FLAG_IN_RXCLK,
>> +};
>> +
>> +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,
>> +    .quirks = QUIRK_HAS_DLL_CMDOUT,
>>   };
>>   static const struct udevice_id sdhci_ids[] = {
>> @@ -605,6 +657,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