[U-Boot] [RESENT PATCH v2 3/4] rockchip: clk: update dwmmc clock div

Kever Yang kever.yang at rock-chips.com
Thu Jul 27 04:54:01 UTC 2017


dwmmc controller has default internal divider by 2,
and we always provide double of the clock rate request by
dwmmc controller. Sync code for all Rockchip SoC with:
4055b46 rockchip: clk: rk3288: fix mmc clock setting

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

Changes in v2:
- add comment for mmc clock div 2 internal
- update the commit message

 drivers/clk/rockchip/clk_rk3036.c |  6 +++---
 drivers/clk/rockchip/clk_rk3188.c |  5 +++--
 drivers/clk/rockchip/clk_rk322x.c |  8 ++++----
 drivers/clk/rockchip/clk_rk3288.c |  1 +
 drivers/clk/rockchip/clk_rk3328.c |  9 +++++----
 drivers/clk/rockchip/clk_rk3399.c | 12 ++++++++----
 6 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/drivers/clk/rockchip/clk_rk3036.c b/drivers/clk/rockchip/clk_rk3036.c
index 5ecf512..514ea88 100644
--- a/drivers/clk/rockchip/clk_rk3036.c
+++ b/drivers/clk/rockchip/clk_rk3036.c
@@ -235,7 +235,7 @@ static ulong rockchip_mmc_get_clk(struct rk3036_cru *cru, uint clk_general_rate,
 	}
 
 	src_rate = mux == EMMC_SEL_24M ? OSC_HZ : clk_general_rate;
-	return DIV_TO_RATE(src_rate, div);
+	return DIV_TO_RATE(src_rate, div) / 2;
 }
 
 static ulong rockchip_mmc_set_clk(struct rk3036_cru *cru, uint clk_general_rate,
@@ -247,10 +247,10 @@ static ulong rockchip_mmc_set_clk(struct rk3036_cru *cru, uint clk_general_rate,
 	debug("%s: clk_general_rate=%u\n", __func__, clk_general_rate);
 
 	/* mmc clock auto divide 2 in internal */
-	src_clk_div = (clk_general_rate / 2 + freq - 1) / freq;
+	src_clk_div = DIV_ROUND_UP(clk_general_rate / 2, freq);
 
 	if (src_clk_div > 0x7f) {
-		src_clk_div = (OSC_HZ / 2 + freq - 1) / freq;
+		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, freq);
 		mux = EMMC_SEL_24M;
 	} else {
 		mux = EMMC_SEL_GPLL;
diff --git a/drivers/clk/rockchip/clk_rk3188.c b/drivers/clk/rockchip/clk_rk3188.c
index 6f30332..cbf31d7 100644
--- a/drivers/clk/rockchip/clk_rk3188.c
+++ b/drivers/clk/rockchip/clk_rk3188.c
@@ -287,7 +287,7 @@ static ulong rockchip_mmc_get_clk(struct rk3188_cru *cru, uint gclk_rate,
 		return -EINVAL;
 	}
 
-	return DIV_TO_RATE(gclk_rate, div);
+	return DIV_TO_RATE(gclk_rate, div) / 2;
 }
 
 static ulong rockchip_mmc_set_clk(struct rk3188_cru *cru, uint gclk_rate,
@@ -296,7 +296,8 @@ static ulong rockchip_mmc_set_clk(struct rk3188_cru *cru, uint gclk_rate,
 	int src_clk_div;
 
 	debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
-	src_clk_div = RATE_TO_DIV(gclk_rate, freq);
+	/* mmc clock defaulg div 2 internal, need provide double in cru */
+	src_clk_div = DIV_ROUND_UP(gclk_rate / 2, freq);
 	assert(src_clk_div <= 0x3f);
 
 	switch (periph) {
diff --git a/drivers/clk/rockchip/clk_rk322x.c b/drivers/clk/rockchip/clk_rk322x.c
index fdeb816..a1a0aff 100644
--- a/drivers/clk/rockchip/clk_rk322x.c
+++ b/drivers/clk/rockchip/clk_rk322x.c
@@ -239,7 +239,7 @@ static ulong rockchip_mmc_get_clk(struct rk322x_cru *cru, uint clk_general_rate,
 	}
 
 	src_rate = mux == EMMC_SEL_24M ? OSC_HZ : clk_general_rate;
-	return DIV_TO_RATE(src_rate, div);
+	return DIV_TO_RATE(src_rate, div) / 2;
 }
 
 static ulong rockchip_mmc_set_clk(struct rk322x_cru *cru, uint clk_general_rate,
@@ -250,11 +250,11 @@ static ulong rockchip_mmc_set_clk(struct rk322x_cru *cru, uint clk_general_rate,
 
 	debug("%s: clk_general_rate=%u\n", __func__, clk_general_rate);
 
-	/* mmc clock auto divide 2 in internal */
-	src_clk_div = (clk_general_rate / 2 + freq - 1) / freq;
+	/* mmc clock defaulg div 2 internal, need provide double in cru */
+	src_clk_div = DIV_ROUND_UP(clk_general_rate / 2, freq);
 
 	if (src_clk_div > 0x7f) {
-		src_clk_div = (OSC_HZ / 2 + freq - 1) / freq;
+		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, freq);
 		mux = EMMC_SEL_24M;
 	} else {
 		mux = EMMC_SEL_GPLL;
diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c
index adcc0a6..209075a 100644
--- a/drivers/clk/rockchip/clk_rk3288.c
+++ b/drivers/clk/rockchip/clk_rk3288.c
@@ -531,6 +531,7 @@ static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint gclk_rate,
 	int mux;
 
 	debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
+	/* mmc clock defaulg div 2 internal, need provide double in cru */
 	src_clk_div = DIV_ROUND_UP(gclk_rate / 2, freq);
 
 	if (src_clk_div > 0x3f) {
diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c
index 2065a8a..c3a6650 100644
--- a/drivers/clk/rockchip/clk_rk3328.c
+++ b/drivers/clk/rockchip/clk_rk3328.c
@@ -412,9 +412,9 @@ static ulong rk3328_mmc_get_clk(struct rk3328_cru *cru, uint clk_id)
 
 	if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT
 	    == CLK_EMMC_PLL_SEL_24M)
-		return DIV_TO_RATE(OSC_HZ, div);
+		return DIV_TO_RATE(OSC_HZ, div) / 2;
 	else
-		return DIV_TO_RATE(GPLL_HZ, div);
+		return DIV_TO_RATE(GPLL_HZ, div) / 2;
 }
 
 static ulong rk3328_mmc_set_clk(struct rk3328_cru *cru,
@@ -436,11 +436,12 @@ static ulong rk3328_mmc_set_clk(struct rk3328_cru *cru,
 		return -EINVAL;
 	}
 	/* Select clk_sdmmc/emmc source from GPLL by default */
-	src_clk_div = GPLL_HZ / set_rate;
+	/* mmc clock defaulg div 2 internal, need provide double in cru */
+	src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate);
 
 	if (src_clk_div > 127) {
 		/* use 24MHz source for 400KHz clock */
-		src_clk_div = OSC_HZ / set_rate;
+		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
 		rk_clrsetreg(&cru->clksel_con[con_id],
 			     CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
 			     CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT |
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index 54079cd..d2abda5 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -750,18 +750,21 @@ static ulong rk3399_mmc_get_clk(struct rk3399_cru *cru, uint clk_id)
 	case HCLK_SDMMC:
 	case SCLK_SDMMC:
 		con = readl(&cru->clksel_con[16]);
+		/* dwmmc controller have internal div 2 */
+		div = 2;
 		break;
 	case SCLK_EMMC:
 		con = readl(&cru->clksel_con[21]);
+		div = 1;
 		break;
 	default:
 		return -EINVAL;
 	}
-	div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT;
 
+	div *= (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT;
 	if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT
 			== CLK_EMMC_PLL_SEL_24M)
-		return DIV_TO_RATE(24*1000*1000, div);
+		return DIV_TO_RATE(OSC_HZ, div);
 	else
 		return DIV_TO_RATE(GPLL_HZ, div);
 }
@@ -776,11 +779,12 @@ static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
 	case HCLK_SDMMC:
 	case SCLK_SDMMC:
 		/* Select clk_sdmmc source from GPLL by default */
-		src_clk_div = GPLL_HZ / set_rate;
+		/* mmc clock defaulg div 2 internal, provide double in cru */
+		src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate);
 
 		if (src_clk_div > 127) {
 			/* use 24MHz source for 400KHz clock */
-			src_clk_div = 24*1000*1000 / set_rate;
+			src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, 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 |
-- 
1.9.1



More information about the U-Boot mailing list