diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index 9eef22efd2fa..65ac03066cc0 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -37,24 +37,31 @@ #define DWCMSHC_EMMC_DLL_STRBIN 0x80c #define DECMSHC_EMMC_DLL_CMDOUT 0x810 #define DWCMSHC_EMMC_DLL_STATUS0 0x840 + #define DWCMSHC_EMMC_DLL_START BIT(0) -#define DWCMSHC_EMMC_DLL_RXCLK_SRCSEL 29 +#define DWCMSHC_EMMC_DLL_LOCKED BIT(8) +#define DWCMSHC_EMMC_DLL_TIMEOUT BIT(9) #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_TXCLK_TAPNUM_90_DEGREES 0x8 -#define DLL_STRBIN_TAPNUM_DEFAULT 0x8 #define DLL_TXCLK_TAPNUM_FROM_SW BIT(24) +#define DLL_TXCLK_NO_INVERTER BIT(29) + +#define DLL_STRBIN_TAPNUM_DEFAULT 0x8 #define DLL_STRBIN_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 DLL_RXCLK_NO_INVERTER BIT(29) + +#define DWCMSHC_CARD_IS_EMMC BIT(0) #define DWCMSHC_ENHANCED_STROBE BIT(8) + #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_LOCK_WO_TMOUT(x) \ ((((x) & DWCMSHC_EMMC_DLL_LOCKED) == DWCMSHC_EMMC_DLL_LOCKED) && \ @@ -131,7 +138,7 @@ static void dwcmshc_request(struct mmc_host *mmc, struct mmc_request *mrq) static void dwcmshc_set_uhs_signaling(struct sdhci_host *host, unsigned int timing) { - u16 ctrl_2; + u16 ctrl_2, ctrl; ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); /* Select Bus Speed Mode for host */ @@ -149,8 +156,15 @@ static void dwcmshc_set_uhs_signaling(struct sdhci_host *host, else if ((timing == MMC_TIMING_UHS_DDR50) || (timing == MMC_TIMING_MMC_DDR52)) ctrl_2 |= SDHCI_CTRL_UHS_DDR50; - else if (timing == MMC_TIMING_MMC_HS400) + else if (timing == MMC_TIMING_MMC_HS400) { + /* set CARD_IS_EMMC bit to enable Data Strobe for HS400 */ + ctrl = sdhci_readw(host, DWCMSHC_EMMC_CONTROL); + ctrl |= DWCMSHC_CARD_IS_EMMC; + sdhci_writew(host, ctrl, DWCMSHC_EMMC_CONTROL); + ctrl_2 |= DWCMSHC_CTRL_HS400; + } + sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); } @@ -173,7 +187,7 @@ static void dwcmshc_rk_set_clock(struct sdhci_host *host, unsigned int clock) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host); - u32 txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT, extra; + u32 txclk_tapnum, extra; int err; host->mmc->actual_clock = 0; @@ -216,7 +230,7 @@ static void dwcmshc_rk_set_clock(struct sdhci_host *host, unsigned int clock) */ extra = DWCMSHC_EMMC_DLL_DLYENA; if (priv->flags & RK_RXCLK_NO_INVERTER) - extra |= DLL_RXCLK_NO_INVERTER << DWCMSHC_EMMC_DLL_RXCLK_SRCSEL; + extra |= DLL_RXCLK_NO_INVERTER; sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK); /* Init DLL settings */ @@ -237,23 +251,20 @@ static void dwcmshc_rk_set_clock(struct sdhci_host *host, unsigned int clock) 0x3 << 19; /* post-change delay */ sdhci_writel(host, extra, DWCMSHC_EMMC_ATCTRL); - if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 || - host->mmc->ios.timing == MMC_TIMING_MMC_HS400) - txclk_tapnum = priv->txclk_tapnum; + txclk_tapnum = priv->txclk_tapnum; if ((priv->flags & RK_DLL_CMD_OUT) && host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { txclk_tapnum = DLL_TXCLK_TAPNUM_90_DEGREES; - extra = DWCMSHC_EMMC_DLL_DLYENA | - DLL_CMDOUT_TAPNUM_90_DEGREES | - DLL_CMDOUT_TAPNUM_FROM_SW | - DLL_CMDOUT_SRC_CLK_NEG; + extra = DLL_CMDOUT_SRC_CLK_NEG | + DLL_CMDOUT_EN_SRC_CLK_NEG; sdhci_writel(host, extra, DECMSHC_EMMC_DLL_CMDOUT); } extra = DWCMSHC_EMMC_DLL_DLYENA | DLL_TXCLK_TAPNUM_FROM_SW | + DLL_RXCLK_NO_INVERTER | txclk_tapnum; sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_TXCLK);