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

Configure Feed

Select the types of activity you want to include in your feed.

clk: ingenic: Make PLL clock "od" field optional

Add support for defining PLL clocks with od_bits = 0, meaning that
OD is fixed to 1 and there is no OD field in the register. In this
case od_max must also be 0, which is enforced with BUG_ON().

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
Link: https://lore.kernel.org/r/20221026194345.243007-2-aidanmacdonald.0x0@gmail.com
Reviewed-by: Paul Cercueil <paul@crapouillou.net>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>

authored by

Aidan MacDonald and committed by
Stephen Boyd
83b975b5 9abf2313

+19 -9
+17 -8
drivers/clk/ingenic/cgu.c
··· 83 83 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk); 84 84 struct ingenic_cgu *cgu = ingenic_clk->cgu; 85 85 const struct ingenic_cgu_pll_info *pll_info; 86 - unsigned m, n, od_enc, od; 86 + unsigned m, n, od, od_enc = 0; 87 87 bool bypass; 88 88 u32 ctl; 89 89 ··· 96 96 m += pll_info->m_offset; 97 97 n = (ctl >> pll_info->n_shift) & GENMASK(pll_info->n_bits - 1, 0); 98 98 n += pll_info->n_offset; 99 - od_enc = ctl >> pll_info->od_shift; 100 - od_enc &= GENMASK(pll_info->od_bits - 1, 0); 99 + 100 + if (pll_info->od_bits > 0) { 101 + od_enc = ctl >> pll_info->od_shift; 102 + od_enc &= GENMASK(pll_info->od_bits - 1, 0); 103 + } 101 104 102 105 if (pll_info->bypass_bit >= 0) { 103 106 ctl = readl(cgu->base + pll_info->bypass_reg); ··· 111 108 return parent_rate; 112 109 } 113 110 114 - for (od = 0; od < pll_info->od_max; od++) { 111 + for (od = 0; od < pll_info->od_max; od++) 115 112 if (pll_info->od_encoding[od] == od_enc) 116 113 break; 117 - } 118 - BUG_ON(od == pll_info->od_max); 114 + 115 + /* if od_max = 0, od_bits should be 0 and od is fixed to 1. */ 116 + if (pll_info->od_max == 0) 117 + BUG_ON(pll_info->od_bits != 0); 118 + else 119 + BUG_ON(od == pll_info->od_max); 119 120 od++; 120 121 121 122 return div_u64((u64)parent_rate * m * pll_info->rate_multiplier, ··· 222 215 ctl &= ~(GENMASK(pll_info->n_bits - 1, 0) << pll_info->n_shift); 223 216 ctl |= (n - pll_info->n_offset) << pll_info->n_shift; 224 217 225 - ctl &= ~(GENMASK(pll_info->od_bits - 1, 0) << pll_info->od_shift); 226 - ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift; 218 + if (pll_info->od_bits > 0) { 219 + ctl &= ~(GENMASK(pll_info->od_bits - 1, 0) << pll_info->od_shift); 220 + ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift; 221 + } 227 222 228 223 writel(ctl, cgu->base + pll_info->reg); 229 224
+2 -1
drivers/clk/ingenic/cgu.h
··· 33 33 * @od_shift: the number of bits to shift the post-VCO divider value by (ie. 34 34 * the index of the lowest bit of the post-VCO divider value in 35 35 * the PLL's control register) 36 - * @od_bits: the size of the post-VCO divider field in bits 36 + * @od_bits: the size of the post-VCO divider field in bits, or 0 if no 37 + * OD field exists (then the OD is fixed to 1) 37 38 * @od_max: the maximum post-VCO divider value 38 39 * @od_encoding: a pointer to an array mapping post-VCO divider values to 39 40 * their encoded values in the PLL control register, or -1 for