[U-Boot] [PATCH 1/3] clock: rk3399: add support for dwmmc 400K

Kever Yang kever.yang at rock-chips.com
Tue Aug 2 04:47:14 CEST 2016


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 at rock-chips.com>
---

 drivers/clk/clk_rk3399.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/clk_rk3399.c b/drivers/clk/clk_rk3399.c
index 5d9bce0..802b8a1 100644
--- a/drivers/clk/clk_rk3399.c
+++ b/drivers/clk/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,
 
@@ -640,9 +641,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,
@@ -653,14 +658,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 */
-- 
1.9.1




More information about the U-Boot mailing list