From a910f251ee084230e2f8d214f1621346cec94e69 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 16 Mar 2018 22:02:11 +0800 Subject: clk: sunxi-ng: Support fixed post-dividers on NKMP style clocks On the new Allwinner H6 SoC, multiple PLL's are NMP style clocks (modelled as NKMP with no K) and have fixed post-dividers. Add fixed post divider support to the NKMP style clocks. Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu_nkmp.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers/clk/sunxi-ng/ccu_nkmp.c') diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index c3f6fe7be565..ebd9436d2c7c 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c @@ -95,7 +95,7 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); - unsigned long n, m, k, p; + unsigned long n, m, k, p, rate; u32 reg; reg = readl(nkmp->common.base + nkmp->common.reg); @@ -121,7 +121,11 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw, p = reg >> nkmp->p.shift; p &= (1 << nkmp->p.width) - 1; - return ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p); + rate = ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p); + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) + rate /= nkmp->fixed_post_div; + + return rate; } static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, @@ -130,6 +134,9 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); struct _ccu_nkmp _nkmp; + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) + rate *= nkmp->fixed_post_div; + _nkmp.min_n = nkmp->n.min ?: 1; _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; _nkmp.min_k = nkmp->k.min ?: 1; @@ -141,8 +148,12 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); - return ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, + rate = ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, _nkmp.m, _nkmp.p); + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) + rate = rate / nkmp->fixed_post_div; + + return rate; } static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, @@ -154,6 +165,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long flags; u32 reg; + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) + rate = rate * nkmp->fixed_post_div; + _nkmp.min_n = nkmp->n.min ?: 1; _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; _nkmp.min_k = nkmp->k.min ?: 1; -- cgit v1.2.3