summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaibo Chen <haibo.chen@nxp.com>2017-12-19 14:46:55 +0800
committerHaibo Chen <haibo.chen@nxp.com>2017-12-19 16:32:02 +0800
commitf2663f7c17f1af71a0381ccd2136df83457ede1b (patch)
treea64359a5a04da519af63580d909102eaaf4cf23f
parentf195c3878189a3be91afa89950e8978223eac0c6 (diff)
MLK-17239 mmc: fsl_esdhc: fix sd/mmc ddr mode clock setting issue
When sd/mmc work at DDR mode, like HS400/HS400ES/DDR52/DDR50 mode, the actual clock rate is just half of the expected clock. This patch set the DDR_EN bit first for DDR mode, hardware divide the usdhc clock automatically, then follow the original sdr clock setting method. This patch also remove the unused variable 'is_ddr'. Acked-by: Li Ye <ye.li@nxp.com> Signed-off-by: Haibo Chen <haibo.chen@nxp.com> (cherry picked from commit 2f1eed596782be19eb2c14e708e6db8596876346)
-rw-r--r--drivers/mmc/fsl_esdhc.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index c5f7ccb63c..179b1c004e 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -137,7 +137,6 @@ struct fsl_esdhc_priv {
int non_removable;
int wp_enable;
int vs18_enable;
- int is_ddr;
u32 tuning_step;
u32 tuning_start_tap;
u32 strobe_dll_delay_target;
@@ -620,6 +619,15 @@ static void set_sysctl(struct mmc *mmc, uint clock)
int sdhc_clk = priv->sdhc_clk;
uint clk;
+ /*
+ * For ddr mode, usdhc need to enable DDR mode first, after select
+ * this DDR mode, usdhc will automatically divide the usdhc clock
+ */
+ if (mmc->ddr_mode) {
+ writel(readl(&regs->mixctrl) | MIX_CTRL_DDREN, &regs->mixctrl);
+ sdhc_clk >>= 1;
+ }
+
if (clock < mmc->cfg->f_min)
clock = mmc->cfg->f_min;
@@ -634,7 +642,7 @@ static void set_sysctl(struct mmc *mmc, uint clock)
if ((sdhc_clk / (div * pre_div)) <= clock)
break;
- pre_div >>= mmc->ddr_mode ? 2 : 1;
+ pre_div >>= 1;
div -= 1;
clk = (pre_div << 8) | (div << 4);
@@ -766,7 +774,6 @@ static int esdhc_set_timing(struct mmc *mmc)
m = readl(&regs->mixctrl);
m &= ~(MIX_CTRL_DDREN | MIX_CTRL_HS400_EN);
- priv->is_ddr = 0;
switch (mmc->selected_mode) {
case MMC_LEGACY:
@@ -777,7 +784,6 @@ static int esdhc_set_timing(struct mmc *mmc)
case MMC_HS_400_ES:
m |= MIX_CTRL_DDREN | MIX_CTRL_HS400_EN;
writel(m, &regs->mixctrl);
- priv->is_ddr = 1;
esdhc_set_strobe_dll(mmc);
break;
case MMC_HS:
@@ -794,7 +800,6 @@ static int esdhc_set_timing(struct mmc *mmc)
case MMC_DDR_52:
m |= MIX_CTRL_DDREN;
writel(m, &regs->mixctrl);
- priv->is_ddr = 1;
break;
default:
printf("Not supported %d\n", mmc->selected_mode);