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 |