mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
mmc: sdhci-of-dwcmshc: enable HS400 for rk3588
1. set CARD_IS_EMMC bit to enable Data Strobe for HS400 2. config the transmit clock source (DLL TX) is original clock input 3. config Command output source and Command output enable are from register output triggered by clock falling edge Signed-off-by: Yifeng Zhao <yifeng.zhao@rock-chips.com> Change-Id: I5b34fecde7bb1d05211c7d9c42f54c8e154d367e
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user