From f103c112660217f8875398435e47d545ba934a5c Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Sun, 21 Aug 2022 09:17:24 +0200 Subject: [PATCH] clk: rockchip: rk3399: Fix Unknown clock 77 on mmc@fe310000 Adding some debug prints I can see: MMC: mmc@fe320000: Got clock clock-controller@ff760000 76 mmc@fe310000: Got clock clock-controller@ff760000 77 Unknown clock 77 rockchip_dwmmc_get_mmc_clk: err=-2 mmc@fe310000: 3, mmc@fe320000: 1, mmc@fe330000: 0 According to kernel code the SDIO clock is identical to SDMMC clock except for the con 16->15 change. Add support for the clock to avoid the error. Signed-off-by: Michal Suchanek Reviewed-by: Kever Yang --- drivers/clk/rockchip/clk_rk3399.c | 66 +++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index 7d31a9f..97bf1c6 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -728,6 +728,12 @@ static ulong rk3399_mmc_get_clk(struct rockchip_cru *cru, uint clk_id) u32 div, con; switch (clk_id) { + case HCLK_SDIO: + case SCLK_SDIO: + con = readl(&cru->clksel_con[15]); + /* dwmmc controller have internal div 2 */ + div = 2; + break; case HCLK_SDMMC: case SCLK_SDMMC: con = readl(&cru->clksel_con[16]); @@ -750,37 +756,46 @@ static ulong rk3399_mmc_get_clk(struct rockchip_cru *cru, uint clk_id) return DIV_TO_RATE(GPLL_HZ, div); } +static void rk3399_dwmmc_set_clk(struct rockchip_cru *cru, + unsigned int con, ulong set_rate) +{ + /* Select clk_sdmmc source from GPLL by default */ + /* mmc clock defaulg div 2 internal, provide double in cru */ + int src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate); + + if (src_clk_div > 128) { + /* use 24MHz source for 400KHz clock */ + src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); + assert(src_clk_div - 1 < 128); + rk_clrsetreg(&cru->clksel_con[con], + 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[con], + 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); + } +} + static ulong rk3399_mmc_set_clk(struct rockchip_cru *cru, ulong clk_id, ulong set_rate) { - int src_clk_div; - int aclk_emmc = 198 * MHz; - switch (clk_id) { + case HCLK_SDIO: + case SCLK_SDIO: + rk3399_dwmmc_set_clk(cru, 15, set_rate); + break; case HCLK_SDMMC: case SCLK_SDMMC: - /* Select clk_sdmmc source from GPLL by default */ - /* 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 > 128) { - /* use 24MHz source for 400KHz clock */ - src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); - assert(src_clk_div - 1 < 128); - 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); - } + rk3399_dwmmc_set_clk(cru, 16, set_rate); break; - case SCLK_EMMC: + case SCLK_EMMC: { + int aclk_emmc = 198 * MHz; /* Select aclk_emmc source from GPLL */ - src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc); + int src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc); + assert(src_clk_div - 1 < 32); rk_clrsetreg(&cru->clksel_con[21], @@ -797,6 +812,7 @@ static ulong rk3399_mmc_set_clk(struct rockchip_cru *cru, CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); break; + } default: return -EINVAL; } @@ -918,6 +934,8 @@ static ulong rk3399_clk_get_rate(struct clk *clk) switch (clk->id) { case 0 ... 63: return 0; + case HCLK_SDIO: + case SCLK_SDIO: case HCLK_SDMMC: case SCLK_SDMMC: case SCLK_EMMC: @@ -992,6 +1010,8 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate) case PCLK_PERILP1: return 0; + case HCLK_SDIO: + case SCLK_SDIO: case HCLK_SDMMC: case SCLK_SDMMC: case SCLK_EMMC: -- 2.7.4