Lines Matching +full:max +full:- +full:bit +full:- +full:rate

1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
8 * https://www.nxp.com/docs/en/reference-manual/IMX8MDQLQRM.pdf#page=834
11 #include <linux/clk-provider.h>
33 #define PLL_LOCK_MASK BIT(31)
34 #define PLL_PD_MASK BIT(7)
65 #define SSCG_PLL_BYPASS1_MASK BIT(5)
66 #define SSCG_PLL_BYPASS2_MASK BIT(4)
102 val = readl_relaxed(pll->base + PLL_CFG0); in clk_sscg_pll_wait_lock()
106 return readl_poll_timeout(pll->base, val, val & PLL_LOCK_MASK, in clk_sscg_pll_wait_lock()
115 int new_diff = temp_setup->fout - temp_setup->fout_request; in clk_sscg_pll2_check_match()
116 int diff = temp_setup->fout_error; in clk_sscg_pll2_check_match()
119 temp_setup->fout_error = new_diff; in clk_sscg_pll2_check_match()
122 if (temp_setup->fout_request == temp_setup->fout) in clk_sscg_pll2_check_match()
125 return -1; in clk_sscg_pll2_check_match()
131 int ret = -EINVAL; in clk_sscg_divq_lookup()
133 for (temp_setup->divq = 0; temp_setup->divq <= PLL_DIVQ_MAX; in clk_sscg_divq_lookup()
134 temp_setup->divq++) { in clk_sscg_divq_lookup()
135 temp_setup->vco2 = temp_setup->vco1; in clk_sscg_divq_lookup()
136 do_div(temp_setup->vco2, temp_setup->divr2 + 1); in clk_sscg_divq_lookup()
137 temp_setup->vco2 *= 2; in clk_sscg_divq_lookup()
138 temp_setup->vco2 *= temp_setup->divf2 + 1; in clk_sscg_divq_lookup()
139 if (temp_setup->vco2 >= PLL_STAGE2_MIN_FREQ && in clk_sscg_divq_lookup()
140 temp_setup->vco2 <= PLL_STAGE2_MAX_FREQ) { in clk_sscg_divq_lookup()
141 temp_setup->fout = temp_setup->vco2; in clk_sscg_divq_lookup()
142 do_div(temp_setup->fout, 2 * (temp_setup->divq + 1)); in clk_sscg_divq_lookup()
146 temp_setup->bypass = PLL_BYPASS1; in clk_sscg_divq_lookup()
158 int ret = -EINVAL; in clk_sscg_divf2_lookup()
160 for (temp_setup->divf2 = 0; temp_setup->divf2 <= PLL_DIVF2_MAX; in clk_sscg_divf2_lookup()
161 temp_setup->divf2++) { in clk_sscg_divf2_lookup()
173 int ret = -EINVAL; in clk_sscg_divr2_lookup()
175 for (temp_setup->divr2 = 0; temp_setup->divr2 <= PLL_DIVR2_MAX; in clk_sscg_divr2_lookup()
176 temp_setup->divr2++) { in clk_sscg_divr2_lookup()
177 temp_setup->ref_div2 = temp_setup->vco1; in clk_sscg_divr2_lookup()
178 do_div(temp_setup->ref_div2, temp_setup->divr2 + 1); in clk_sscg_divr2_lookup()
179 if (temp_setup->ref_div2 >= PLL_STAGE2_REF_MIN_FREQ && in clk_sscg_divr2_lookup()
180 temp_setup->ref_div2 <= PLL_STAGE2_REF_MAX_FREQ) { in clk_sscg_divr2_lookup()
197 return -EINVAL; in clk_sscg_pll2_find_setup()
199 temp_setup->vco1 = ref; in clk_sscg_pll2_find_setup()
208 int ret = -EINVAL; in clk_sscg_divf1_lookup()
210 for (temp_setup->divf1 = 0; temp_setup->divf1 <= PLL_DIVF1_MAX; in clk_sscg_divf1_lookup()
211 temp_setup->divf1++) { in clk_sscg_divf1_lookup()
212 uint64_t vco1 = temp_setup->ref; in clk_sscg_divf1_lookup()
214 do_div(vco1, temp_setup->divr1 + 1); in clk_sscg_divf1_lookup()
216 vco1 *= temp_setup->divf1 + 1; in clk_sscg_divf1_lookup()
220 temp_setup->bypass = PLL_BYPASS_NONE; in clk_sscg_divf1_lookup()
231 int ret = -EINVAL; in clk_sscg_divr1_lookup()
233 for (temp_setup->divr1 = 0; temp_setup->divr1 <= PLL_DIVR1_MAX; in clk_sscg_divr1_lookup()
234 temp_setup->divr1++) { in clk_sscg_divr1_lookup()
235 temp_setup->ref_div1 = temp_setup->ref; in clk_sscg_divr1_lookup()
236 do_div(temp_setup->ref_div1, temp_setup->divr1 + 1); in clk_sscg_divr1_lookup()
237 if (temp_setup->ref_div1 >= PLL_STAGE1_REF_MIN_FREQ && in clk_sscg_divr1_lookup()
238 temp_setup->ref_div1 <= PLL_STAGE1_REF_MAX_FREQ) { in clk_sscg_divr1_lookup()
255 return -EINVAL; in clk_sscg_pll1_find_setup()
257 temp_setup->ref = ref; in clk_sscg_pll1_find_setup()
266 uint64_t rate, int try_bypass) in clk_sscg_pll_find_setup() argument
269 int ret = -EINVAL; in clk_sscg_pll_find_setup()
275 temp_setup.fout_request = rate; in clk_sscg_pll_find_setup()
279 if (prate == rate) { in clk_sscg_pll_find_setup()
280 setup->bypass = PLL_BYPASS2; in clk_sscg_pll_find_setup()
281 setup->fout = rate; in clk_sscg_pll_find_setup()
300 u32 val = readl_relaxed(pll->base + PLL_CFG0); in clk_sscg_pll_is_prepared()
310 val = readl_relaxed(pll->base + PLL_CFG0); in clk_sscg_pll_prepare()
312 writel_relaxed(val, pll->base + PLL_CFG0); in clk_sscg_pll_prepare()
322 val = readl_relaxed(pll->base + PLL_CFG0); in clk_sscg_pll_unprepare()
324 writel_relaxed(val, pll->base + PLL_CFG0); in clk_sscg_pll_unprepare()
334 val = readl_relaxed(pll->base + PLL_CFG2); in clk_sscg_pll_recalc_rate()
343 val = readl(pll->base + PLL_CFG0); in clk_sscg_pll_recalc_rate()
358 static int clk_sscg_pll_set_rate(struct clk_hw *hw, unsigned long rate, in clk_sscg_pll_set_rate() argument
362 struct clk_sscg_pll_setup *setup = &pll->setup; in clk_sscg_pll_set_rate()
366 val = readl(pll->base + PLL_CFG0); in clk_sscg_pll_set_rate()
368 val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, setup->bypass); in clk_sscg_pll_set_rate()
369 writel(val, pll->base + PLL_CFG0); in clk_sscg_pll_set_rate()
371 val = readl_relaxed(pll->base + PLL_CFG2); in clk_sscg_pll_set_rate()
374 val |= FIELD_PREP(PLL_DIVF1_MASK, setup->divf1); in clk_sscg_pll_set_rate()
375 val |= FIELD_PREP(PLL_DIVF2_MASK, setup->divf2); in clk_sscg_pll_set_rate()
376 val |= FIELD_PREP(PLL_DIVR1_MASK, setup->divr1); in clk_sscg_pll_set_rate()
377 val |= FIELD_PREP(PLL_DIVR2_MASK, setup->divr2); in clk_sscg_pll_set_rate()
378 val |= FIELD_PREP(PLL_DIVQ_MASK, setup->divq); in clk_sscg_pll_set_rate()
379 writel_relaxed(val, pll->base + PLL_CFG2); in clk_sscg_pll_set_rate()
388 u8 ret = pll->parent; in clk_sscg_pll_get_parent()
390 val = readl(pll->base + PLL_CFG0); in clk_sscg_pll_get_parent()
392 ret = pll->bypass2; in clk_sscg_pll_get_parent()
394 ret = pll->bypass1; in clk_sscg_pll_get_parent()
403 val = readl(pll->base + PLL_CFG0); in clk_sscg_pll_set_parent()
405 val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, pll->setup.bypass); in clk_sscg_pll_set_parent()
406 writel(val, pll->base + PLL_CFG0); in clk_sscg_pll_set_parent()
414 uint64_t max, in __clk_sscg_pll_determine_rate() argument
415 uint64_t rate, in __clk_sscg_pll_determine_rate() argument
419 struct clk_sscg_pll_setup *setup = &pll->setup; in __clk_sscg_pll_determine_rate()
424 req->max_rate = max; in __clk_sscg_pll_determine_rate()
425 req->min_rate = min; in __clk_sscg_pll_determine_rate()
429 bypass_parent_index = pll->bypass2; in __clk_sscg_pll_determine_rate()
432 bypass_parent_index = pll->bypass1; in __clk_sscg_pll_determine_rate()
435 bypass_parent_index = pll->parent; in __clk_sscg_pll_determine_rate()
442 ret = clk_sscg_pll_find_setup(setup, req->rate, in __clk_sscg_pll_determine_rate()
443 rate, bypass); in __clk_sscg_pll_determine_rate()
446 req->best_parent_hw = parent_hw; in __clk_sscg_pll_determine_rate()
447 req->best_parent_rate = req->rate; in __clk_sscg_pll_determine_rate()
448 req->rate = setup->fout; in __clk_sscg_pll_determine_rate()
457 struct clk_sscg_pll_setup *setup = &pll->setup; in clk_sscg_pll_determine_rate()
458 uint64_t rate = req->rate; in clk_sscg_pll_determine_rate() local
459 uint64_t min = req->min_rate; in clk_sscg_pll_determine_rate()
460 uint64_t max = req->max_rate; in clk_sscg_pll_determine_rate() local
463 if (rate < PLL_OUT_MIN_FREQ || rate > PLL_OUT_MAX_FREQ) in clk_sscg_pll_determine_rate()
464 return -EINVAL; in clk_sscg_pll_determine_rate()
466 ret = __clk_sscg_pll_determine_rate(hw, req, req->rate, req->rate, in clk_sscg_pll_determine_rate()
467 rate, PLL_BYPASS2); in clk_sscg_pll_determine_rate()
472 PLL_STAGE1_REF_MAX_FREQ, rate, in clk_sscg_pll_determine_rate()
478 PLL_REF_MAX_FREQ, rate, in clk_sscg_pll_determine_rate()
483 if (setup->fout >= min && setup->fout <= max) in clk_sscg_pll_determine_rate()
514 return ERR_PTR(-ENOMEM); in imx_clk_hw_sscg_pll()
516 pll->parent = parent; in imx_clk_hw_sscg_pll()
517 pll->bypass1 = bypass1; in imx_clk_hw_sscg_pll()
518 pll->bypass2 = bypass2; in imx_clk_hw_sscg_pll()
520 pll->base = base; in imx_clk_hw_sscg_pll()
528 pll->hw.init = &init; in imx_clk_hw_sscg_pll()
530 hw = &pll->hw; in imx_clk_hw_sscg_pll()