Lines Matching full:pll
11 * In the most basic form, a Meson PLL is composed as follows:
13 * PLL
37 #include "clk-pll.h"
45 static int __pll_round_closest_mult(struct meson_clk_pll_data *pll) in __pll_round_closest_mult() argument
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()
57 struct meson_clk_pll_data *pll) in __pll_params_to_rate() argument
61 if (frac && MESON_PARM_APPLICABLE(&pll->frac)) { in __pll_params_to_rate()
65 (1 << pll->frac.width)); in __pll_params_to_rate()
75 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); in meson_clk_pll_recalc_rate() local
78 n = meson_parm_read(clk->map, &pll->n); in meson_clk_pll_recalc_rate()
88 m = meson_parm_read(clk->map, &pll->m); in meson_clk_pll_recalc_rate()
90 frac = MESON_PARM_APPLICABLE(&pll->frac) ? in meson_clk_pll_recalc_rate()
91 meson_parm_read(clk->map, &pll->frac) : in meson_clk_pll_recalc_rate()
94 return __pll_params_to_rate(parent_rate, m, n, frac, pll); in meson_clk_pll_recalc_rate()
101 struct meson_clk_pll_data *pll) in __pll_params_with_frac() argument
103 unsigned int frac_max = (1 << pll->frac.width); in __pll_params_with_frac()
110 if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) in __pll_params_with_frac()
123 struct meson_clk_pll_data *pll) in meson_clk_pll_is_better() argument
125 if (__pll_round_closest_mult(pll)) { in meson_clk_pll_is_better()
141 struct meson_clk_pll_data *pll) in meson_clk_get_pll_table_index() argument
143 if (!pll->table[index].n) in meson_clk_get_pll_table_index()
146 *m = pll->table[index].m; in meson_clk_get_pll_table_index()
147 *n = pll->table[index].n; in meson_clk_get_pll_table_index()
155 struct meson_clk_pll_data *pll) in meson_clk_get_pll_range_m() argument
159 if (__pll_round_closest_mult(pll)) in meson_clk_get_pll_range_m()
170 struct meson_clk_pll_data *pll) in meson_clk_get_pll_range_index() argument
175 if (*n >= (1 << pll->n.width)) in meson_clk_get_pll_range_index()
180 if (rate <= pll->range->min * parent_rate) { in meson_clk_get_pll_range_index()
181 *m = pll->range->min; in meson_clk_get_pll_range_index()
183 } else if (rate >= pll->range->max * parent_rate) { in meson_clk_get_pll_range_index()
184 *m = pll->range->max; in meson_clk_get_pll_range_index()
189 *m = meson_clk_get_pll_range_m(rate, parent_rate, *n, pll); in meson_clk_get_pll_range_index()
192 if (*m >= (1 << pll->m.width)) in meson_clk_get_pll_range_index()
203 struct meson_clk_pll_data *pll) in meson_clk_get_pll_get_index() argument
205 if (pll->range) in meson_clk_get_pll_get_index()
207 index, m, n, pll); in meson_clk_get_pll_get_index()
208 else if (pll->table) in meson_clk_get_pll_get_index()
209 return meson_clk_get_pll_table_index(index, m, n, pll); in meson_clk_get_pll_get_index()
218 struct meson_clk_pll_data *pll) in meson_clk_get_pll_settings() argument
226 i, &m, &n, pll); in meson_clk_get_pll_settings()
230 now = __pll_params_to_rate(parent_rate, m, n, 0, pll); in meson_clk_get_pll_settings()
231 if (meson_clk_pll_is_better(rate, best, now, pll)) { in meson_clk_get_pll_settings()
248 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); in meson_clk_pll_determine_rate() local
254 &m, &n, pll); in meson_clk_pll_determine_rate()
258 round = __pll_params_to_rate(req->best_parent_rate, m, n, 0, pll); in meson_clk_pll_determine_rate()
260 if (!MESON_PARM_APPLICABLE(&pll->frac) || req->rate == round) { in meson_clk_pll_determine_rate()
269 frac = __pll_params_with_frac(req->rate, req->best_parent_rate, m, n, pll); in meson_clk_pll_determine_rate()
270 req->rate = __pll_params_to_rate(req->best_parent_rate, m, n, frac, pll); in meson_clk_pll_determine_rate()
278 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); in meson_clk_pll_wait_lock() local
283 if (meson_parm_read(clk->map, &pll->l)) in meson_clk_pll_wait_lock()
295 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); in meson_clk_pll_is_enabled() local
297 if (MESON_PARM_APPLICABLE(&pll->rst) && in meson_clk_pll_is_enabled()
298 meson_parm_read(clk->map, &pll->rst)) in meson_clk_pll_is_enabled()
301 if (!meson_parm_read(clk->map, &pll->en) || in meson_clk_pll_is_enabled()
302 !meson_parm_read(clk->map, &pll->l)) in meson_clk_pll_is_enabled()
311 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); in meson_clk_pll_init() local
317 if ((pll->flags & CLK_MESON_PLL_NOINIT_ENABLED) && in meson_clk_pll_init()
321 if (pll->init_count) { in meson_clk_pll_init()
322 if (MESON_PARM_APPLICABLE(&pll->rst)) in meson_clk_pll_init()
323 meson_parm_write(clk->map, &pll->rst, 1); in meson_clk_pll_init()
325 regmap_multi_reg_write(clk->map, pll->init_regs, in meson_clk_pll_init()
326 pll->init_count); in meson_clk_pll_init()
328 if (MESON_PARM_APPLICABLE(&pll->rst)) in meson_clk_pll_init()
329 meson_parm_write(clk->map, &pll->rst, 0); in meson_clk_pll_init()
343 pr_info("Retry enabling PCIe PLL clock\n"); in meson_clk_pcie_pll_enable()
352 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); in meson_clk_pll_enable() local
354 /* do nothing if the PLL is already enabled */ in meson_clk_pll_enable()
358 /* Make sure the pll is in reset */ in meson_clk_pll_enable()
359 if (MESON_PARM_APPLICABLE(&pll->rst)) in meson_clk_pll_enable()
360 meson_parm_write(clk->map, &pll->rst, 1); in meson_clk_pll_enable()
362 /* Enable the pll */ in meson_clk_pll_enable()
363 meson_parm_write(clk->map, &pll->en, 1); in meson_clk_pll_enable()
365 /* Take the pll out reset */ in meson_clk_pll_enable()
366 if (MESON_PARM_APPLICABLE(&pll->rst)) in meson_clk_pll_enable()
367 meson_parm_write(clk->map, &pll->rst, 0); in meson_clk_pll_enable()
372 * PLL. The sequence is: in meson_clk_pll_enable()
373 * 1. enable the pll, delay for 10us in meson_clk_pll_enable()
374 * 2. enable the pll self-adaption current module, delay for 40us in meson_clk_pll_enable()
377 if (MESON_PARM_APPLICABLE(&pll->current_en)) { in meson_clk_pll_enable()
379 meson_parm_write(clk->map, &pll->current_en, 1); in meson_clk_pll_enable()
383 if (MESON_PARM_APPLICABLE(&pll->l_detect)) { in meson_clk_pll_enable()
384 meson_parm_write(clk->map, &pll->l_detect, 1); in meson_clk_pll_enable()
385 meson_parm_write(clk->map, &pll->l_detect, 0); in meson_clk_pll_enable()
397 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); in meson_clk_pll_disable() local
399 /* Put the pll is in reset */ in meson_clk_pll_disable()
400 if (MESON_PARM_APPLICABLE(&pll->rst)) in meson_clk_pll_disable()
401 meson_parm_write(clk->map, &pll->rst, 1); in meson_clk_pll_disable()
403 /* Disable the pll */ in meson_clk_pll_disable()
404 meson_parm_write(clk->map, &pll->en, 0); in meson_clk_pll_disable()
406 /* Disable PLL internal self-adaption current module */ in meson_clk_pll_disable()
407 if (MESON_PARM_APPLICABLE(&pll->current_en)) in meson_clk_pll_disable()
408 meson_parm_write(clk->map, &pll->current_en, 0); in meson_clk_pll_disable()
415 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); in meson_clk_pll_set_rate() local
425 ret = meson_clk_get_pll_settings(rate, parent_rate, &m, &n, pll); in meson_clk_pll_set_rate()
429 enabled = meson_parm_read(clk->map, &pll->en); in meson_clk_pll_set_rate()
433 meson_parm_write(clk->map, &pll->n, n); in meson_clk_pll_set_rate()
434 meson_parm_write(clk->map, &pll->m, m); in meson_clk_pll_set_rate()
436 if (MESON_PARM_APPLICABLE(&pll->frac)) { in meson_clk_pll_set_rate()
437 frac = __pll_params_with_frac(rate, parent_rate, m, n, pll); in meson_clk_pll_set_rate()
438 meson_parm_write(clk->map, &pll->frac, frac); in meson_clk_pll_set_rate()
441 /* If the pll is stopped, bail out now */ in meson_clk_pll_set_rate()
447 pr_warn("%s: pll %s didn't lock, trying to set old rate %lu\n", in meson_clk_pll_set_rate()
462 * The Meson G12A PCIE PLL is fined tuned to deliver a very precise
464 * a strict register sequence to enable the PLL.
465 * To simplify, re-use the _init() op to enable the PLL and keep
494 MODULE_DESCRIPTION("Amlogic PLL driver");