[PATCH] clk: rockchip: rk3399: Fix Unknown clock 77 on mmc at fe310000

Michal Suchanek msuchanek at suse.de
Sun Aug 21 09:17:24 CEST 2022


Adding some debug prints I can see:

MMC:   mmc at fe320000: Got clock clock-controller at ff760000 76
mmc at fe310000: Got clock clock-controller at ff760000 77
Unknown clock 77
rockchip_dwmmc_get_mmc_clk: err=-2
mmc at fe310000: 3, mmc at fe320000: 1, mmc at 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 <msuchanek at suse.de>
---
 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 7d31a9f22a..97bf1c6e15 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.37.1



More information about the U-Boot mailing list