Skip to content

Commit 2b0efe8

Browse files
BOUGH CHENstorulf
authored andcommitted
mmc: sdhci-esdhc-imx: remove the 100MHz limitation for Strobe DLL
For some eMMC, after switch to HS400ES mode, it need to config the strobe dll target dealy even if the clock is 50MHZ or 25MHz, otherwise will meet CMD index/crc error when send CMD13 to check the switch status. [ 2.473915] IRQ status 0x000a8001 [ 2.473934] mmc2: mmc_select_hs400es failed, error -84 [ 2.473938] mmc2: error -84 whilst initialising MMC card Signed-off-by: Haibo Chen <[email protected]> Acked-by: Adrian Hunter <[email protected]> Signed-off-by: Ulf Hansson <[email protected]>
1 parent bb60023 commit 2b0efe8

File tree

1 file changed

+23
-29
lines changed

1 file changed

+23
-29
lines changed

drivers/mmc/host/sdhci-esdhc-imx.c

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,6 @@
144144
* exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz.
145145
*/
146146
#define ESDHC_FLAG_ERR010450 BIT(10)
147-
/* A clock frequency higher than this rate requires strobe dll control */
148-
#define ESDHC_STROBE_DLL_CLK_FREQ 100000000
149147

150148
struct esdhc_soc_data {
151149
u32 flags;
@@ -939,39 +937,35 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
939937
* edge of data_strobe line. Due to the time delay between CLK line and
940938
* data_strobe line, if the delay time is larger than one clock cycle,
941939
* then CLK and data_strobe line will be misaligned, read error shows up.
942-
* So when the CLK is higher than 100MHz, each clock cycle is short enough,
943-
* host should configure the delay target.
944940
*/
945941
static void esdhc_set_strobe_dll(struct sdhci_host *host)
946942
{
947943
u32 v;
948944

949-
if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ) {
950-
/* disable clock before enabling strobe dll */
951-
writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) &
952-
~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
953-
host->ioaddr + ESDHC_VENDOR_SPEC);
945+
/* disable clock before enabling strobe dll */
946+
writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) &
947+
~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
948+
host->ioaddr + ESDHC_VENDOR_SPEC);
954949

955-
/* force a reset on strobe dll */
956-
writel(ESDHC_STROBE_DLL_CTRL_RESET,
957-
host->ioaddr + ESDHC_STROBE_DLL_CTRL);
958-
/*
959-
* enable strobe dll ctrl and adjust the delay target
960-
* for the uSDHC loopback read clock
961-
*/
962-
v = ESDHC_STROBE_DLL_CTRL_ENABLE |
963-
(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
964-
writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
965-
/* wait 1us to make sure strobe dll status register stable */
966-
udelay(1);
967-
v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
968-
if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
969-
dev_warn(mmc_dev(host->mmc),
970-
"warning! HS400 strobe DLL status REF not lock!\n");
971-
if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
972-
dev_warn(mmc_dev(host->mmc),
973-
"warning! HS400 strobe DLL status SLV not lock!\n");
974-
}
950+
/* force a reset on strobe dll */
951+
writel(ESDHC_STROBE_DLL_CTRL_RESET,
952+
host->ioaddr + ESDHC_STROBE_DLL_CTRL);
953+
/*
954+
* enable strobe dll ctrl and adjust the delay target
955+
* for the uSDHC loopback read clock
956+
*/
957+
v = ESDHC_STROBE_DLL_CTRL_ENABLE |
958+
(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
959+
writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
960+
/* wait 1us to make sure strobe dll status register stable */
961+
udelay(1);
962+
v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
963+
if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
964+
dev_warn(mmc_dev(host->mmc),
965+
"warning! HS400 strobe DLL status REF not lock!\n");
966+
if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
967+
dev_warn(mmc_dev(host->mmc),
968+
"warning! HS400 strobe DLL status SLV not lock!\n");
975969
}
976970

977971
static void esdhc_reset_tuning(struct sdhci_host *host)

0 commit comments

Comments
 (0)