Lines Matching +full:wide +full:- +full:range
1 // SPDX-License-Identifier: GPL-2.0
19 * the CLN28HPC variant of the Analog Bits Wide Range PLL. The
27 * pre-determined set of performance points.
30 * - Analog Bits "Wide Range PLL Datasheet", version 2015.10.01
31 * - SiFive FU540-C000 Manual v1p0, Chapter 7 "Clocking and Reset"
39 #include "analogbits-wrpll-cln28hpc.h"
47 /* MIN_POST_DIVIDE_REF_FREQ: minimum post-divider reference frequency, in Hz */
50 /* MAX_POST_DIVIDE_REF_FREQ: maximum post-divider reference frequency, in Hz */
79 * __wrpll_calc_filter_range() - determine PLL loop filter bandwidth
82 * Select the value to be presented to the PLL RANGE input signals, based
83 * on the input clock frequency after the post-R-divider @post_divr_freq.
85 * range selection.
87 * Return: The RANGE value to be presented to the PLL configuration inputs,
88 * or -1 upon error.
92 u8 range; in __wrpll_calc_filter_range() local
96 WARN(1, "%s: post-divider reference freq out of range: %lu", in __wrpll_calc_filter_range()
98 return -1; in __wrpll_calc_filter_range()
102 range = 1; in __wrpll_calc_filter_range()
104 range = 2; in __wrpll_calc_filter_range()
106 range = 3; in __wrpll_calc_filter_range()
108 range = 4; in __wrpll_calc_filter_range()
110 range = 5; in __wrpll_calc_filter_range()
112 range = 6; in __wrpll_calc_filter_range()
114 range = 7; in __wrpll_calc_filter_range()
116 return range; in __wrpll_calc_filter_range()
120 * __wrpll_calc_fbdiv() - return feedback fixed divide value
123 * The internal feedback path includes a fixed by-two divider; the
138 return (c->flags & WRPLL_FLAGS_INT_FEEDBACK_MASK) ? 2 : 1; in __wrpll_calc_fbdiv()
142 * __wrpll_calc_divq() - determine DIVQ based on target PLL output clock rate
146 * Determine a reasonable value for the PLL Q post-divider, based on the
184 * __wrpll_update_parent_rate() - update PLL data when parent rate changes
186 * @parent_rate: PLL input refclk rate (pre-R-divider)
188 * Pre-compute some data used by the PLL configuration algorithm when
190 * computation when the parent rate remains constant - expected to be
193 * Returns: 0 upon success or -1 if the reference clock rate is out of range.
201 return -1; in __wrpll_update_parent_rate()
203 c->_parent_rate = parent_rate; in __wrpll_update_parent_rate()
205 c->_max_r = min_t(u8, MAX_DIVR_DIVISOR, max_r_for_parent); in __wrpll_update_parent_rate()
208 c->_init_r = div_u64(parent_rate + MAX_POST_DIVR_FREQ - 1, in __wrpll_update_parent_rate()
219 * analogbits_wrpll_configure() - compute PLL configuration for a target rate
221 * @target_rate: target PLL output clock rate (post-Q-divider)
222 * @parent_rate: PLL input refclk rate (pre-R-divider)
228 * downstream logic to a different clock source or clock-gate it
231 * The caller must pass this function a pre-initialized struct
250 return -1; in analogbits_wrpll_configure_for_rate()
252 if (c->flags == 0) { in analogbits_wrpll_configure_for_rate()
254 return -1; in analogbits_wrpll_configure_for_rate()
258 if ((c->flags & fbcfg) == fbcfg) { in analogbits_wrpll_configure_for_rate()
260 return -1; in analogbits_wrpll_configure_for_rate()
263 if (c->flags == WRPLL_FLAGS_EXT_FEEDBACK_MASK) { in analogbits_wrpll_configure_for_rate()
266 return -1; in analogbits_wrpll_configure_for_rate()
270 if (parent_rate != c->_parent_rate) { in analogbits_wrpll_configure_for_rate()
272 pr_err("%s: PLL input rate is out of range\n", in analogbits_wrpll_configure_for_rate()
274 return -1; in analogbits_wrpll_configure_for_rate()
278 c->flags &= ~WRPLL_FLAGS_RESET_MASK; in analogbits_wrpll_configure_for_rate()
282 c->flags |= WRPLL_FLAGS_BYPASS_MASK; in analogbits_wrpll_configure_for_rate()
285 c->flags &= ~WRPLL_FLAGS_BYPASS_MASK; in analogbits_wrpll_configure_for_rate()
290 return -1; in analogbits_wrpll_configure_for_rate()
291 c->divq = divq; in analogbits_wrpll_configure_for_rate()
293 /* Precalculate the pre-Q divider target ratio */ in analogbits_wrpll_configure_for_rate()
305 for (r = c->_init_r; r <= c->_max_r; ++r) { in analogbits_wrpll_configure_for_rate()
309 f >>= (fbdiv - 1); in analogbits_wrpll_configure_for_rate()
315 /* Ensure rounding didn't take us out of range */ in analogbits_wrpll_configure_for_rate()
317 --f; in analogbits_wrpll_configure_for_rate()
324 delta = abs(target_rate - vco); in analogbits_wrpll_configure_for_rate()
332 c->divr = best_r - 1; in analogbits_wrpll_configure_for_rate()
333 c->divf = best_f - 1; in analogbits_wrpll_configure_for_rate()
338 c->range = __wrpll_calc_filter_range(post_divr_freq); in analogbits_wrpll_configure_for_rate()
344 * analogbits_wrpll_calc_output_rate() - calculate the PLL's target output rate
350 * pre-divider), calculate the PLL's output clock rate (after the Q
351 * post-divider)
364 WARN(c->flags & WRPLL_FLAGS_EXT_FEEDBACK_MASK, in analogbits_wrpll_calc_output_rate()
368 n = parent_rate * fbdiv * (c->divf + 1); in analogbits_wrpll_calc_output_rate()
369 n = div_u64(n, (c->divr + 1)); in analogbits_wrpll_calc_output_rate()
370 n >>= c->divq; in analogbits_wrpll_calc_output_rate()
376 * analogbits_wrpll_calc_max_lock_us() - return the time for the PLL to lock