diff options
Diffstat (limited to 'drivers/clk/rockchip/clk_rk3588.c')
-rw-r--r-- | drivers/clk/rockchip/clk_rk3588.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/clk/rockchip/clk_rk3588.c b/drivers/clk/rockchip/clk_rk3588.c index 119b1337bd..a995dd5591 100644 --- a/drivers/clk/rockchip/clk_rk3588.c +++ b/drivers/clk/rockchip/clk_rk3588.c @@ -36,6 +36,7 @@ static struct rockchip_pll_rate_table rk3588_pll_rates[] = { RK3588_PLL_RATE(816000000, 2, 272, 2, 0), RK3588_PLL_RATE(786432000, 2, 262, 2, 9437), RK3588_PLL_RATE(786000000, 1, 131, 2, 0), + RK3588_PLL_RATE(742500000, 4, 495, 2, 0), RK3588_PLL_RATE(722534400, 8, 963, 2, 24850), RK3588_PLL_RATE(600000000, 2, 200, 2, 0), RK3588_PLL_RATE(594000000, 2, 198, 2, 0), @@ -305,12 +306,18 @@ static ulong rk3588_top_set_clk(struct rk3588_clk_priv *priv, switch (clk_id) { case ACLK_TOP_ROOT: - src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + if (!(priv->cpll_hz % rate)) { + src_clk = ACLK_TOP_ROOT_SRC_SEL_CPLL; + src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); + } else { + src_clk = ACLK_TOP_ROOT_SRC_SEL_GPLL; + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + } assert(src_clk_div - 1 <= 31); rk_clrsetreg(&cru->clksel_con[8], ACLK_TOP_ROOT_DIV_MASK | ACLK_TOP_ROOT_SRC_SEL_MASK, - (ACLK_TOP_ROOT_SRC_SEL_GPLL << + (src_clk << ACLK_TOP_ROOT_SRC_SEL_SHIFT) | (src_clk_div - 1) << ACLK_TOP_ROOT_DIV_SHIFT); break; @@ -1123,13 +1130,23 @@ static ulong rk3588_dclk_vop_set_clk(struct rk3588_clk_priv *priv, } if (sel == DCLK_VOP_SRC_SEL_V0PLL) { - div = DIV_ROUND_UP(RK3588_VOP_PLL_LIMIT_FREQ, rate); - rk_clrsetreg(&cru->clksel_con[conid], - mask, - DCLK_VOP_SRC_SEL_V0PLL << sel_shift | - ((div - 1) << div_shift)); - rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], - priv->cru, V0PLL, div * rate); + pll_rate = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL], + priv->cru, V0PLL); + if (pll_rate >= RK3588_VOP_PLL_LIMIT_FREQ && pll_rate % rate == 0) { + div = DIV_ROUND_UP(pll_rate, rate); + rk_clrsetreg(&cru->clksel_con[conid], + mask, + DCLK_VOP_SRC_SEL_V0PLL << sel_shift | + ((div - 1) << div_shift)); + } else { + div = DIV_ROUND_UP(RK3588_VOP_PLL_LIMIT_FREQ, rate); + rk_clrsetreg(&cru->clksel_con[conid], + mask, + DCLK_VOP_SRC_SEL_V0PLL << sel_shift | + ((div - 1) << div_shift)); + rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], + priv->cru, V0PLL, div * rate); + } } else { for (i = 0; i <= DCLK_VOP_SRC_SEL_AUPLL; i++) { switch (i) { |