summaryrefslogtreecommitdiff
path: root/drivers/clk/rockchip
diff options
context:
space:
mode:
authorMichal Suchanek <msuchanek@suse.de>2022-08-21 10:17:24 +0300
committerKever Yang <kever.yang@rock-chips.com>2022-09-04 15:00:39 +0300
commitf103c112660217f8875398435e47d545ba934a5c (patch)
tree6e470d64d5f69beee5b7519d7f8dec265dc2c22a /drivers/clk/rockchip
parente1faa535b978958a264c9623a8ca941f0adcb860 (diff)
downloadu-boot-f103c112660217f8875398435e47d545ba934a5c.tar.xz
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 <msuchanek@suse.de> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Diffstat (limited to 'drivers/clk/rockchip')
-rw-r--r--drivers/clk/rockchip/clk_rk3399.c66
1 files 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: