summaryrefslogtreecommitdiff
path: root/drivers/clk
diff options
context:
space:
mode:
authorKever Yang <kever.yang@rock-chips.com>2016-08-04 11:44:58 +0800
committerSimon Glass <sjg@chromium.org>2016-08-05 18:02:51 -0600
commitfd4b2dc05996dad7680442ed574614d3db048f86 (patch)
tree7799ff37f5289cb2641b476f8e40b383c7c15766 /drivers/clk
parent583b1bc029d86d87152d7819cd06cc557de6ddf9 (diff)
clock: rk3399: add support for dwmmc 400K
MMC core will use 400KHz for card initialize first and then switch to higher frequency like 50MHz, we need to support both 400KHz and about 50MHz for dwmmc controller. Signed-off-by: Kever Yang <kever.yang@rock-chips.com> Acked-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/rockchip/clk_rk3399.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index c0bb80c462..0b4ea828f6 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -142,6 +142,7 @@ enum {
CLK_EMMC_PLL_SHIFT = 8,
CLK_EMMC_PLL_MASK = 0x7 << CLK_EMMC_PLL_SHIFT,
CLK_EMMC_PLL_SEL_GPLL = 0x1,
+ CLK_EMMC_PLL_SEL_24M = 0x5,
CLK_EMMC_DIV_CON_SHIFT = 0,
CLK_EMMC_DIV_CON_MASK = 0x7f << CLK_EMMC_DIV_CON_SHIFT,
@@ -642,9 +643,13 @@ static ulong rk3399_mmc_get_clk(struct rk3399_cru *cru, uint clk_id)
default:
return -EINVAL;
}
- div = (con>>CLK_EMMC_DIV_CON_SHIFT) & CLK_EMMC_DIV_CON_MASK;
+ div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT;
- return DIV_TO_RATE(GPLL_HZ, div);
+ if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT
+ == CLK_EMMC_PLL_SEL_24M)
+ return DIV_TO_RATE(24*1024*1024, div);
+ else
+ return DIV_TO_RATE(GPLL_HZ, div);
}
static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
@@ -655,14 +660,22 @@ static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
switch (clk_id) {
case SCLK_SDMMC:
- /* Select clk_sdmmc source from GPLL too */
+ /* Select clk_sdmmc source from GPLL by default */
src_clk_div = GPLL_HZ / set_rate;
- assert(src_clk_div - 1 < 127);
- rk_clrsetreg(&cru->clksel_con[16],
- CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
- CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
- (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
+ if (src_clk_div > 127) {
+ /* use 24MHz source for 400KHz clock */
+ src_clk_div = 24*1024*1024 / set_rate;
+ rk_clrsetreg(&cru->clksel_con[16],
+ CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
+ CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT |
+ (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
+ } else {
+ rk_clrsetreg(&cru->clksel_con[16],
+ CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
+ CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
+ (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
+ }
break;
case SCLK_EMMC:
/* Select aclk_emmc source from GPLL */