Lines Matching +full:dco +full:- +full:check

1 // SPDX-License-Identifier: GPL-2.0
14 * +--------------------------------+
16 * | +--+ |
17 * in >>-----[ /N ]--->| | +-----+ |
18 * | | |------| DCO |---->> out
19 * | +--------->| | +--v--+ |
20 * | | +--+ | |
22 * | +--[ *(M + (F/Fmax) ]<--+ |
24 * +--------------------------------+
29 #include <linux/clk-provider.h>
36 #include "clk-regmap.h"
37 #include "clk-pll.h"
42 return (struct meson_clk_pll_data *)clk->data; in meson_clk_pll_data()
47 if ((pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) && in __pll_round_closest_mult()
48 !MESON_PARM_APPLICABLE(&pll->frac)) in __pll_round_closest_mult()
60 unsigned int frac_max = pll->frac_max ? pll->frac_max : in __pll_params_to_rate()
61 (1 << pll->frac.width); in __pll_params_to_rate()
63 if (frac && MESON_PARM_APPLICABLE(&pll->frac)) { in __pll_params_to_rate()
79 n = meson_parm_read(clk->map, &pll->n); in meson_clk_pll_recalc_rate()
89 m = meson_parm_read(clk->map, &pll->m); in meson_clk_pll_recalc_rate()
91 frac = MESON_PARM_APPLICABLE(&pll->frac) ? in meson_clk_pll_recalc_rate()
92 meson_parm_read(clk->map, &pll->frac) : in meson_clk_pll_recalc_rate()
104 unsigned int frac_max = pll->frac_max ? pll->frac_max : in __pll_params_with_frac()
105 (1 << pll->frac.width); in __pll_params_with_frac()
112 if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) in __pll_params_with_frac()
117 val -= m * frac_max; in __pll_params_with_frac()
119 return min((unsigned int)val, (frac_max - 1)); in __pll_params_with_frac()
129 if (abs(now - rate) < abs(best - rate)) in meson_clk_pll_is_better()
145 if (!pll->table[index].n) in meson_clk_get_pll_table_index()
146 return -EINVAL; in meson_clk_get_pll_table_index()
148 *m = pll->table[index].m; in meson_clk_get_pll_table_index()
149 *n = pll->table[index].n; in meson_clk_get_pll_table_index()
176 /* Check the predivider range */ in meson_clk_get_pll_range_index()
177 if (*n >= (1 << pll->n.width)) in meson_clk_get_pll_range_index()
178 return -EINVAL; in meson_clk_get_pll_range_index()
182 if (rate <= pll->range->min * parent_rate) { in meson_clk_get_pll_range_index()
183 *m = pll->range->min; in meson_clk_get_pll_range_index()
184 return -ENODATA; in meson_clk_get_pll_range_index()
185 } else if (rate >= pll->range->max * parent_rate) { in meson_clk_get_pll_range_index()
186 *m = pll->range->max; in meson_clk_get_pll_range_index()
187 return -ENODATA; in meson_clk_get_pll_range_index()
193 /* the pre-divider gives a multiplier too big - stop */ in meson_clk_get_pll_range_index()
194 if (*m >= (1 << pll->m.width)) in meson_clk_get_pll_range_index()
195 return -EINVAL; in meson_clk_get_pll_range_index()
207 if (pll->range) in meson_clk_get_pll_get_index()
210 else if (pll->table) in meson_clk_get_pll_get_index()
213 return -EINVAL; in meson_clk_get_pll_get_index()
229 if (ret == -EINVAL) in meson_clk_get_pll_settings()
243 return best ? 0 : -EINVAL; in meson_clk_get_pll_settings()
255 ret = meson_clk_get_pll_settings(req->rate, req->best_parent_rate, in meson_clk_pll_determine_rate()
260 round = __pll_params_to_rate(req->best_parent_rate, m, n, 0, pll); in meson_clk_pll_determine_rate()
262 if (!MESON_PARM_APPLICABLE(&pll->frac) || req->rate == round) { in meson_clk_pll_determine_rate()
263 req->rate = round; in meson_clk_pll_determine_rate()
271 frac = __pll_params_with_frac(req->rate, req->best_parent_rate, m, n, pll); in meson_clk_pll_determine_rate()
272 req->rate = __pll_params_to_rate(req->best_parent_rate, m, n, frac, pll); in meson_clk_pll_determine_rate()
285 if (meson_parm_read(clk->map, &pll->l)) in meson_clk_pll_wait_lock()
289 } while (--delay); in meson_clk_pll_wait_lock()
291 return -ETIMEDOUT; in meson_clk_pll_wait_lock()
299 if (MESON_PARM_APPLICABLE(&pll->rst) && in meson_clk_pll_is_enabled()
300 meson_parm_read(clk->map, &pll->rst)) in meson_clk_pll_is_enabled()
303 if (!meson_parm_read(clk->map, &pll->en) || in meson_clk_pll_is_enabled()
304 !meson_parm_read(clk->map, &pll->l)) in meson_clk_pll_is_enabled()
319 if ((pll->flags & CLK_MESON_PLL_NOINIT_ENABLED) && in meson_clk_pll_init()
323 if (pll->init_count) { in meson_clk_pll_init()
324 if (MESON_PARM_APPLICABLE(&pll->rst)) in meson_clk_pll_init()
325 meson_parm_write(clk->map, &pll->rst, 1); in meson_clk_pll_init()
327 regmap_multi_reg_write(clk->map, pll->init_regs, in meson_clk_pll_init()
328 pll->init_count); in meson_clk_pll_init()
330 if (MESON_PARM_APPLICABLE(&pll->rst)) in meson_clk_pll_init()
331 meson_parm_write(clk->map, &pll->rst, 0); in meson_clk_pll_init()
346 } while (--retries); in meson_clk_pcie_pll_enable()
348 return -EIO; in meson_clk_pcie_pll_enable()
361 if (MESON_PARM_APPLICABLE(&pll->rst)) in meson_clk_pll_enable()
362 meson_parm_write(clk->map, &pll->rst, 1); in meson_clk_pll_enable()
365 meson_parm_write(clk->map, &pll->en, 1); in meson_clk_pll_enable()
368 if (MESON_PARM_APPLICABLE(&pll->rst)) in meson_clk_pll_enable()
369 meson_parm_write(clk->map, &pll->rst, 0); in meson_clk_pll_enable()
372 * Compared with the previous SoCs, self-adaption current module in meson_clk_pll_enable()
373 * is newly added for A1, keep the new power-on sequence to enable the in meson_clk_pll_enable()
376 * 2. enable the pll self-adaption current module, delay for 40us in meson_clk_pll_enable()
379 if (MESON_PARM_APPLICABLE(&pll->current_en)) { in meson_clk_pll_enable()
381 meson_parm_write(clk->map, &pll->current_en, 1); in meson_clk_pll_enable()
385 if (MESON_PARM_APPLICABLE(&pll->l_detect)) { in meson_clk_pll_enable()
386 meson_parm_write(clk->map, &pll->l_detect, 1); in meson_clk_pll_enable()
387 meson_parm_write(clk->map, &pll->l_detect, 0); in meson_clk_pll_enable()
391 return -EIO; in meson_clk_pll_enable()
402 if (MESON_PARM_APPLICABLE(&pll->rst)) in meson_clk_pll_disable()
403 meson_parm_write(clk->map, &pll->rst, 1); in meson_clk_pll_disable()
406 meson_parm_write(clk->map, &pll->en, 0); in meson_clk_pll_disable()
408 /* Disable PLL internal self-adaption current module */ in meson_clk_pll_disable()
409 if (MESON_PARM_APPLICABLE(&pll->current_en)) in meson_clk_pll_disable()
410 meson_parm_write(clk->map, &pll->current_en, 0); in meson_clk_pll_disable()
423 return -EINVAL; in meson_clk_pll_set_rate()
431 enabled = meson_parm_read(clk->map, &pll->en); in meson_clk_pll_set_rate()
435 meson_parm_write(clk->map, &pll->n, n); in meson_clk_pll_set_rate()
436 meson_parm_write(clk->map, &pll->m, m); in meson_clk_pll_set_rate()
438 if (MESON_PARM_APPLICABLE(&pll->frac)) { in meson_clk_pll_set_rate()
440 meson_parm_write(clk->map, &pll->frac, frac); in meson_clk_pll_set_rate()
467 * To simplify, re-use the _init() op to enable the PLL and keep