From 3a94d75d0e2a3b2519de51dfa1f369d976d9cccc Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Thu, 27 Jul 2017 12:54:01 +0800 Subject: [PATCH] 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 Reviewed-by: Philipp Tomsich Acked-by: Philipp Tomsich [fixup for 'missing DIV_ROUND_UP' conflict for clk_rk3288.c:] Signed-off-by: Philipp Tomsich --- 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 | 5 +++-- drivers/clk/rockchip/clk_rk3328.c | 9 +++++---- drivers/clk/rockchip/clk_rk3399.c | 12 ++++++++---- 6 files changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/clk/rockchip/clk_rk3036.c b/drivers/clk/rockchip/clk_rk3036.c index 5ecf5129d8..514ea88f3b 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 6f30332878..cbf31d7de1 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 fdeb816e23..a1a0aff8a9 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 792ee76509..adb4e1cd9d 100644 --- a/drivers/clk/rockchip/clk_rk3288.c +++ b/drivers/clk/rockchip/clk_rk3288.c @@ -530,10 +530,11 @@ static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint gclk_rate, 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 2065a8a65b..c3a6650de0 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 53d2a3f85d..ec149c8be8 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 |