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.y...@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


_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to