]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
clk: sunxi-ng: Support fixed post-dividers on NKMP style clocks
authorIcenowy Zheng <icenowy@aosc.io>
Fri, 16 Mar 2018 14:02:11 +0000 (22:02 +0800)
committerMaxime Ripard <maxime.ripard@bootlin.com>
Sun, 18 Mar 2018 20:16:54 +0000 (21:16 +0100)
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 <icenowy@aosc.io>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
drivers/clk/sunxi-ng/ccu_nkmp.c
drivers/clk/sunxi-ng/ccu_nkmp.h

index c3f6fe7be565964abcf98ee3ac2b7a6f2c1af40c..ebd9436d2c7cd382ed86a3bee1957a5db48b7530 100644 (file)
@@ -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;
index a82facbc61446d6c0cc36f4771c70aaf17090574..6940503e7fc4665d36fd889e3ec25fa258a14f40 100644 (file)
@@ -34,6 +34,8 @@ struct ccu_nkmp {
        struct ccu_div_internal         m;
        struct ccu_div_internal         p;
 
+       unsigned int            fixed_post_div;
+
        struct ccu_common       common;
 };