diff options
author | Haibo Chen <haibo.chen@nxp.com> | 2017-12-19 14:46:55 +0800 |
---|---|---|
committer | Haibo Chen <haibo.chen@nxp.com> | 2017-12-19 16:32:02 +0800 |
commit | f2663f7c17f1af71a0381ccd2136df83457ede1b (patch) | |
tree | a64359a5a04da519af63580d909102eaaf4cf23f | |
parent | f195c3878189a3be91afa89950e8978223eac0c6 (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.c | 15 |
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(®s->mixctrl) | MIX_CTRL_DDREN, ®s->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(®s->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, ®s->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, ®s->mixctrl); - priv->is_ddr = 1; break; default: printf("Not supported %d\n", mmc->selected_mode); |