Lines Matching +full:clock +full:- +full:div

1 // SPDX-License-Identifier: GPL-2.0-only
14 #include "aptina-pll.h"
25 unsigned int div; in aptina_pll_calculate() local
27 dev_dbg(dev, "PLL: ext clock %u pix clock %u\n", in aptina_pll_calculate()
28 pll->ext_clock, pll->pix_clock); in aptina_pll_calculate()
30 if (pll->ext_clock < limits->ext_clock_min || in aptina_pll_calculate()
31 pll->ext_clock > limits->ext_clock_max) { in aptina_pll_calculate()
32 dev_err(dev, "pll: invalid external clock frequency.\n"); in aptina_pll_calculate()
33 return -EINVAL; in aptina_pll_calculate()
36 if (pll->pix_clock == 0 || pll->pix_clock > limits->pix_clock_max) { in aptina_pll_calculate()
37 dev_err(dev, "pll: invalid pixel clock frequency.\n"); in aptina_pll_calculate()
38 return -EINVAL; in aptina_pll_calculate()
42 div = gcd(pll->pix_clock, pll->ext_clock); in aptina_pll_calculate()
43 pll->m = pll->pix_clock / div; in aptina_pll_calculate()
44 div = pll->ext_clock / div; in aptina_pll_calculate()
47 * desired pixel clock frequency, but they might be out of the valid in aptina_pll_calculate()
51 * - minimum/maximum multiplier in aptina_pll_calculate()
52 * - minimum/maximum multiplier output clock frequency assuming the in aptina_pll_calculate()
54 * - minimum/maximum combined N*P1 divisor in aptina_pll_calculate()
56 mf_min = DIV_ROUND_UP(limits->m_min, pll->m); in aptina_pll_calculate()
57 mf_min = max(mf_min, limits->out_clock_min / in aptina_pll_calculate()
58 (pll->ext_clock / limits->n_min * pll->m)); in aptina_pll_calculate()
59 mf_min = max(mf_min, limits->n_min * limits->p1_min / div); in aptina_pll_calculate()
60 mf_max = limits->m_max / pll->m; in aptina_pll_calculate()
61 mf_max = min(mf_max, limits->out_clock_max / in aptina_pll_calculate()
62 (pll->ext_clock / limits->n_max * pll->m)); in aptina_pll_calculate()
63 mf_max = min(mf_max, DIV_ROUND_UP(limits->n_max * limits->p1_max, div)); in aptina_pll_calculate()
68 return -EINVAL; in aptina_pll_calculate()
78 * 3. div * mf is a multiple of p1, in order to compute in aptina_pll_calculate()
79 * n = div * mf / p1 in aptina_pll_calculate()
80 * m = pll->m * mf in aptina_pll_calculate()
81 * 4. the internal clock frequency, given by ext_clock / n, is in the in aptina_pll_calculate()
83 * 5. the output clock frequency, given by ext_clock / n * m, is in the in aptina_pll_calculate()
95 * mf_inc = p1 / gcd(div, p1) (6) in aptina_pll_calculate()
104 * ext_clock / (div * mf / p1) * m * mf >= out_clock_min in aptina_pll_calculate()
105 * ext_clock / (div * mf / p1) * m * mf <= out_clock_max in aptina_pll_calculate()
109 * p1 >= out_clock_min * div / (ext_clock * m) (7) in aptina_pll_calculate()
110 * p1 <= out_clock_max * div / (ext_clock * m) in aptina_pll_calculate()
114 * mf >= ext_clock * p1 / (int_clock_max * div) (8) in aptina_pll_calculate()
115 * mf <= ext_clock * p1 / (int_clock_min * div) in aptina_pll_calculate()
123 if (limits->p1_min == 0) { in aptina_pll_calculate()
125 return -EINVAL; in aptina_pll_calculate()
128 p1_min = max(limits->p1_min, DIV_ROUND_UP(limits->out_clock_min * div, in aptina_pll_calculate()
129 pll->ext_clock * pll->m)); in aptina_pll_calculate()
130 p1_max = min(limits->p1_max, limits->out_clock_max * div / in aptina_pll_calculate()
131 (pll->ext_clock * pll->m)); in aptina_pll_calculate()
133 for (p1 = p1_max & ~1; p1 >= p1_min; p1 -= 2) { in aptina_pll_calculate()
134 unsigned int mf_inc = p1 / gcd(div, p1); in aptina_pll_calculate()
138 mf_low = roundup(max(mf_min, DIV_ROUND_UP(pll->ext_clock * p1, in aptina_pll_calculate()
139 limits->int_clock_max * div)), mf_inc); in aptina_pll_calculate()
140 mf_high = min(mf_max, pll->ext_clock * p1 / in aptina_pll_calculate()
141 (limits->int_clock_min * div)); in aptina_pll_calculate()
146 pll->n = div * mf_low / p1; in aptina_pll_calculate()
147 pll->m *= mf_low; in aptina_pll_calculate()
148 pll->p1 = p1; in aptina_pll_calculate()
149 dev_dbg(dev, "PLL: N %u M %u P1 %u\n", pll->n, pll->m, pll->p1); in aptina_pll_calculate()
154 return -EINVAL; in aptina_pll_calculate()