summaryrefslogtreecommitdiff
path: root/drivers/mmc/host
diff options
context:
space:
mode:
authorHaibo Chen <haibo.chen@nxp.com>2018-08-13 11:37:38 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commitcb08ede376b4886c022864845a8db1dd26f55342 (patch)
treedba5f3be36b6498115db5f26155ba279dce8fefc /drivers/mmc/host
parent00ac333b5771ec45d062e97bebe5660884816ad0 (diff)
MLK-19201 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. Take imx8MM-EVK board as example, without this patch, it will meet: [ 2.473915] IRQ status 0x000a8001 [ 2.473930] the mmc send status get -84 [ 2.473934] mmc2: mmc_select_hs400es failed, error -84 [ 2.473938] mmc2: error -84 whilst initialising MMC card And we also meet some customer require to let eMMC work at 80MHz HS400ES mode, so here remove the 100MHz limitation for Strobe DLL target delay setting. Signed-off-by: Haibo Chen <haibo.chen@nxp.com> (cherry picked from commit e24b2bbd1090b41badefa074e0884510657fb0d7) Conflicts: drivers/mmc/host/sdhci-esdhc-imx.c
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c65
1 files changed, 29 insertions, 36 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index ddc67ef017f7..9299bc91de97 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -172,9 +172,6 @@
/* The IP has Host Controller Interface for Command Queuing */
#define ESDHC_FLAG_CQHCI BIT(16)
-/* A higher clock ferquency than this rate requires strobell dll control */
-#define ESDHC_STROBE_DLL_CLK_FREQ 100000000
-
static struct mmc_host *wifi_mmc_host;
void wifi_card_detect(bool on)
{
@@ -956,9 +953,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
* CLK generated by host. Host receive the data which is aligned to the
* edge of data_strobe line. Due to the time delay between CLK line and
* data_strobe line, if the delay time is larger than one clock cycle,
- * then CLK and data_strobe line will misaligned, read error shows up.
- * So when the CLK is higher than 100MHz, each clock cycle is short enough,
- * host should config the delay target.
+ * then CLK and data_strobe line will be misaligned, read error shows up.
*/
static void esdhc_set_strobe_dll(struct sdhci_host *host)
{
@@ -967,40 +962,38 @@ static void esdhc_set_strobe_dll(struct sdhci_host *host)
u32 v;
u32 strobe_delay;
- if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ) {
- /* disable clock before enabling strobe dll */
- writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) &
- ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
- host->ioaddr + ESDHC_VENDOR_SPEC);
+ /* disable clock before enabling strobe dll */
+ writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) &
+ ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
+ host->ioaddr + ESDHC_VENDOR_SPEC);
- /* force a reset on strobe dll */
- writel(ESDHC_STROBE_DLL_CTRL_RESET,
- host->ioaddr + ESDHC_STROBE_DLL_CTRL);
- /* clear the reset bit on strobe dll before any setting */
- writel(0, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+ /* force a reset on strobe dll */
+ writel(ESDHC_STROBE_DLL_CTRL_RESET,
+ host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+ /* clear the reset bit on strobe dll before any setting */
+ writel(0, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
- /*
- * enable strobe dll ctrl and adjust the delay target
- * for the uSDHC loopback read clock
- */
- if (imx_data->boarddata.strobe_dll_delay_target)
- strobe_delay = imx_data->boarddata.strobe_dll_delay_target;
- else
- strobe_delay = ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT;
- v = ESDHC_STROBE_DLL_CTRL_ENABLE |
- ESDHC_STROBE_DLL_CTRL_SLV_UPDATE_INT_DEFAULT |
- (strobe_delay << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
- writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
- /* wait 5us to make sure strobe dll status register stable */
- udelay(5);
- v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
- if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
- dev_warn(mmc_dev(host->mmc),
- "warning! HS400 strobe DLL status REF not lock!\n");
- if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
+ /*
+ * enable strobe dll ctrl and adjust the delay target
+ * for the uSDHC loopback read clock
+ */
+ if (imx_data->boarddata.strobe_dll_delay_target)
+ strobe_delay = imx_data->boarddata.strobe_dll_delay_target;
+ else
+ strobe_delay = ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT;
+ v = ESDHC_STROBE_DLL_CTRL_ENABLE |
+ ESDHC_STROBE_DLL_CTRL_SLV_UPDATE_INT_DEFAULT |
+ (strobe_delay << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
+ writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+ /* wait 5us to make sure strobe dll status register stable */
+ udelay(5);
+ v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
+ if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
+ dev_warn(mmc_dev(host->mmc),
+ "warning! HS400 strobe DLL status REF not lock!\n");
+ if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
dev_warn(mmc_dev(host->mmc),
"warning! HS400 strobe DLL status SLV not lock!\n");
- }
}
static void esdhc_reset_tuning(struct sdhci_host *host)