rockchip: clk: update dwmmc clock div
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@rock-chips.com>
Reviewed-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Acked-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
[fixup for 'missing DIV_ROUND_UP' conflict for clk_rk3288.c:]
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
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 @@
}
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 792ee76..adb4e1c 100644
--- a/drivers/clk/rockchip/clk_rk3288.c
+++ b/drivers/clk/rockchip/clk_rk3288.c
@@ -530,10 +530,11 @@
int mux;
debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
- src_clk_div = RATE_TO_DIV(gclk_rate, freq);
+ /* mmc clock default div 2 internal, need provide double in cru */
+ src_clk_div = DIV_ROUND_UP(gclk_rate / 2, freq);
if (src_clk_div > 0x3f) {
- src_clk_div = RATE_TO_DIV(OSC_HZ, freq);
+ src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, freq);
mux = EMMC_PLL_SELECT_24MHZ;
assert((int)EMMC_PLL_SELECT_24MHZ ==
(int)MMC0_PLL_SELECT_24MHZ);
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 @@
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 @@
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 53d2a3f..ec149c8 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -750,18 +750,21 @@
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 @@
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 |