Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <icenowy@aosc.io>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>

authored by

Icenowy Zheng and committed by
Maxime Ripard
a910f251 55de0f31

+19 -3
+17 -3
drivers/clk/sunxi-ng/ccu_nkmp.c
··· 95 95 unsigned long parent_rate) 96 96 { 97 97 struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); 98 - unsigned long n, m, k, p; 98 + unsigned long n, m, k, p, rate; 99 99 u32 reg; 100 100 101 101 reg = readl(nkmp->common.base + nkmp->common.reg); ··· 121 121 p = reg >> nkmp->p.shift; 122 122 p &= (1 << nkmp->p.width) - 1; 123 123 124 - return ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p); 124 + rate = ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p); 125 + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) 126 + rate /= nkmp->fixed_post_div; 127 + 128 + return rate; 125 129 } 126 130 127 131 static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, ··· 133 129 { 134 130 struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); 135 131 struct _ccu_nkmp _nkmp; 132 + 133 + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) 134 + rate *= nkmp->fixed_post_div; 136 135 137 136 _nkmp.min_n = nkmp->n.min ?: 1; 138 137 _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; ··· 148 141 149 142 ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); 150 143 151 - return ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, 144 + rate = ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, 152 145 _nkmp.m, _nkmp.p); 146 + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) 147 + rate = rate / nkmp->fixed_post_div; 148 + 149 + return rate; 153 150 } 154 151 155 152 static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, ··· 164 153 struct _ccu_nkmp _nkmp; 165 154 unsigned long flags; 166 155 u32 reg; 156 + 157 + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) 158 + rate = rate * nkmp->fixed_post_div; 167 159 168 160 _nkmp.min_n = nkmp->n.min ?: 1; 169 161 _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
+2
drivers/clk/sunxi-ng/ccu_nkmp.h
··· 34 34 struct ccu_div_internal m; 35 35 struct ccu_div_internal p; 36 36 37 + unsigned int fixed_post_div; 38 + 37 39 struct ccu_common common; 38 40 }; 39 41