Lines Matching +full:pll +full:- +full:out
1 // SPDX-License-Identifier: GPL-2.0-or-later
6 #include <linux/clk-provider.h>
20 #define PLL_MUL(reg, layout) (((reg) >> (layout)->mul_shift) & \
21 (layout)->mul_mask)
23 #define PLL_MUL_MASK(layout) ((layout)->mul_mask)
57 struct clk_pll *pll = to_clk_pll(hw); in clk_pll_prepare() local
58 struct regmap *regmap = pll->regmap; in clk_pll_prepare()
59 const struct clk_pll_layout *layout = pll->layout; in clk_pll_prepare()
61 pll->characteristics; in clk_pll_prepare()
62 u8 id = pll->id; in clk_pll_prepare()
65 u8 out = 0; in clk_pll_prepare() local
77 (div == pll->div && mul == pll->mul)) in clk_pll_prepare()
80 if (characteristics->out) in clk_pll_prepare()
81 out = characteristics->out[pll->range]; in clk_pll_prepare()
83 if (characteristics->icpll) in clk_pll_prepare()
85 characteristics->icpll[pll->range] << PLL_ICPR_SHIFT(id)); in clk_pll_prepare()
87 regmap_update_bits(regmap, offset, layout->pllr_mask, in clk_pll_prepare()
88 pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) | in clk_pll_prepare()
89 (out << PLL_OUT_SHIFT) | in clk_pll_prepare()
90 ((pll->mul & layout->mul_mask) << layout->mul_shift)); in clk_pll_prepare()
92 while (!clk_pll_ready(regmap, pll->id)) in clk_pll_prepare()
100 struct clk_pll *pll = to_clk_pll(hw); in clk_pll_is_prepared() local
102 return clk_pll_ready(pll->regmap, pll->id); in clk_pll_is_prepared()
107 struct clk_pll *pll = to_clk_pll(hw); in clk_pll_unprepare() local
108 unsigned int mask = pll->layout->pllr_mask; in clk_pll_unprepare()
110 regmap_update_bits(pll->regmap, PLL_REG(pll->id), mask, ~mask); in clk_pll_unprepare()
116 struct clk_pll *pll = to_clk_pll(hw); in clk_pll_recalc_rate() local
118 if (!pll->div || !pll->mul) in clk_pll_recalc_rate()
121 return (parent_rate / pll->div) * (pll->mul + 1); in clk_pll_recalc_rate()
124 static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate, in clk_pll_get_best_div_mul() argument
128 const struct clk_pll_layout *layout = pll->layout; in clk_pll_get_best_div_mul()
130 pll->characteristics; in clk_pll_get_best_div_mul()
133 long bestrate = -ERANGE; in clk_pll_get_best_div_mul()
139 if (parent_rate < characteristics->input.min) in clk_pll_get_best_div_mul()
140 return -ERANGE; in clk_pll_get_best_div_mul()
146 * of the PLL blocks. in clk_pll_get_best_div_mul()
152 if (parent_rate > characteristics->input.max) { in clk_pll_get_best_div_mul()
153 tmpdiv = DIV_ROUND_UP(parent_rate, characteristics->input.max); in clk_pll_get_best_div_mul()
155 return -ERANGE; in clk_pll_get_best_div_mul()
162 * Calculate the maximum divider which is limited by PLL register in clk_pll_get_best_div_mul()
186 remainder = tmprate - rate; in clk_pll_get_best_div_mul()
188 remainder = rate - tmprate; in clk_pll_get_best_div_mul()
210 /* We haven't found any multiplier/divider pair => return -ERANGE */ in clk_pll_get_best_div_mul()
215 for (i = 0; i < characteristics->num_output; i++) { in clk_pll_get_best_div_mul()
216 if (bestrate >= characteristics->output[i].min && in clk_pll_get_best_div_mul()
217 bestrate <= characteristics->output[i].max) in clk_pll_get_best_div_mul()
221 if (i >= characteristics->num_output) in clk_pll_get_best_div_mul()
222 return -ERANGE; in clk_pll_get_best_div_mul()
227 *mul = bestmul - 1; in clk_pll_get_best_div_mul()
237 struct clk_pll *pll = to_clk_pll(hw); in clk_pll_round_rate() local
239 return clk_pll_get_best_div_mul(pll, rate, *parent_rate, in clk_pll_round_rate()
246 struct clk_pll *pll = to_clk_pll(hw); in clk_pll_set_rate() local
252 ret = clk_pll_get_best_div_mul(pll, rate, parent_rate, in clk_pll_set_rate()
257 pll->range = index; in clk_pll_set_rate()
258 pll->div = div; in clk_pll_set_rate()
259 pll->mul = mul; in clk_pll_set_rate()
266 struct clk_pll *pll = to_clk_pll(hw); in clk_pll_save_context() local
269 pll->pms.parent_rate = clk_hw_get_rate(parent_hw); in clk_pll_save_context()
270 pll->pms.rate = clk_pll_recalc_rate(&pll->hw, pll->pms.parent_rate); in clk_pll_save_context()
271 pll->pms.status = clk_pll_ready(pll->regmap, PLL_REG(pll->id)); in clk_pll_save_context()
278 struct clk_pll *pll = to_clk_pll(hw); in clk_pll_restore_context() local
281 u8 out = 0; in clk_pll_restore_context() local
283 if (pll->characteristics->out) in clk_pll_restore_context()
284 out = pll->characteristics->out[pll->range]; in clk_pll_restore_context()
286 regmap_read(pll->regmap, PLL_REG(pll->id), &pllr); in clk_pll_restore_context()
288 calc_rate = (pll->pms.parent_rate / PLL_DIV(pllr)) * in clk_pll_restore_context()
289 (PLL_MUL(pllr, pll->layout) + 1); in clk_pll_restore_context()
291 pllr_out = (pllr >> PLL_OUT_SHIFT) & out; in clk_pll_restore_context()
293 if (pll->pms.rate != calc_rate || in clk_pll_restore_context()
294 pll->pms.status != clk_pll_ready(pll->regmap, PLL_REG(pll->id)) || in clk_pll_restore_context()
296 (out && pllr_out != out)) in clk_pll_restore_context()
317 struct clk_pll *pll; in at91_clk_register_pll() local
325 return ERR_PTR(-EINVAL); in at91_clk_register_pll()
327 pll = kzalloc(sizeof(*pll), GFP_KERNEL); in at91_clk_register_pll()
328 if (!pll) in at91_clk_register_pll()
329 return ERR_PTR(-ENOMEM); in at91_clk_register_pll()
337 pll->id = id; in at91_clk_register_pll()
338 pll->hw.init = &init; in at91_clk_register_pll()
339 pll->layout = layout; in at91_clk_register_pll()
340 pll->characteristics = characteristics; in at91_clk_register_pll()
341 pll->regmap = regmap; in at91_clk_register_pll()
343 pll->div = PLL_DIV(pllr); in at91_clk_register_pll()
344 pll->mul = PLL_MUL(pllr, layout); in at91_clk_register_pll()
346 hw = &pll->hw; in at91_clk_register_pll()
347 ret = clk_hw_register(NULL, &pll->hw); in at91_clk_register_pll()
349 kfree(pll); in at91_clk_register_pll()