mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-26 06:30:39 +00:00
mmc: rockchip_sdhci: Add support for RK3588
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@rock-chips.com> Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
This commit is contained in:
parent
72b05764c3
commit
a3cab289f6
1 changed files with 53 additions and 4 deletions
|
@ -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,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue