Lines Matching +full:bypass +full:- +full:enable
1 // SPDX-License-Identifier: GPL-2.0-only
3 * OMAP3/4 - specific DPLL control functions
5 * Copyright (C) 2009-2010 Texas Instruments, Inc.
6 * Copyright (C) 2009-2010 Nokia Corporation
46 /* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
52 dd = clk->dpll_data; in _omap3_dpll_write_clken()
54 v = ti_clk_ll_ops->clk_readl(&dd->control_reg); in _omap3_dpll_write_clken()
55 v &= ~dd->enable_mask; in _omap3_dpll_write_clken()
56 v |= clken_bits << __ffs(dd->enable_mask); in _omap3_dpll_write_clken()
57 ti_clk_ll_ops->clk_writel(v, &dd->control_reg); in _omap3_dpll_write_clken()
65 int ret = -EINVAL; in _omap3_wait_dpll_status()
68 dd = clk->dpll_data; in _omap3_wait_dpll_status()
69 clk_name = clk_hw_get_name(&clk->hw); in _omap3_wait_dpll_status()
71 state <<= __ffs(dd->idlest_mask); in _omap3_wait_dpll_status()
73 while (((ti_clk_ll_ops->clk_readl(&dd->idlest_reg) & dd->idlest_mask) in _omap3_wait_dpll_status()
98 fint = clk_hw_get_rate(clk->dpll_data->clk_ref) / n; in _omap3_dpll_compute_freqsel()
129 * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness
132 * Instructs a non-CORE DPLL to lock. Waits for the DPLL to report
134 * autoidle state across the enable, per the CDP code. If the DPLL
136 * allotted, or DPLL3 was passed in, return -EINVAL.
145 pr_debug("clock: locking DPLL %s\n", clk_hw_get_name(&clk->hw)); in _omap3_noncore_dpll_lock()
147 dd = clk->dpll_data; in _omap3_noncore_dpll_lock()
148 state <<= __ffs(dd->idlest_mask); in _omap3_noncore_dpll_lock()
151 if ((ti_clk_ll_ops->clk_readl(&dd->idlest_reg) & dd->idlest_mask) == in _omap3_noncore_dpll_lock()
172 * _omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
175 * Instructs a non-CORE DPLL to enter low-power bypass mode. In
176 * bypass mode, the DPLL's rate is set equal to its parent clock's
178 * Will save and restore the DPLL's autoidle state across the enable,
179 * per the CDP code. If the DPLL entered bypass mode successfully,
180 * return 0; if the DPLL did not enter bypass in the time allotted, or
181 * DPLL3 was passed in, or the DPLL does not support low-power bypass,
182 * return -EINVAL.
189 if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) in _omap3_noncore_dpll_bypass()
190 return -EINVAL; in _omap3_noncore_dpll_bypass()
192 pr_debug("clock: configuring DPLL %s for low-power bypass\n", in _omap3_noncore_dpll_bypass()
193 clk_hw_get_name(&clk->hw)); in _omap3_noncore_dpll_bypass()
208 * _omap3_noncore_dpll_stop - instruct a DPLL to stop
211 * Instructs a non-CORE DPLL to enter low-power stop. Will save and
214 * low-power stop, return -EINVAL; otherwise, return 0.
220 if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP))) in _omap3_noncore_dpll_stop()
221 return -EINVAL; in _omap3_noncore_dpll_stop()
223 pr_debug("clock: stopping DPLL %s\n", clk_hw_get_name(&clk->hw)); in _omap3_noncore_dpll_stop()
236 * _lookup_dco - Lookup DCO used by j-type DPLL
242 * See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)"
245 * out in non-multi-OMAP builds for those chips?
251 clkinp = clk_hw_get_rate(clk_hw_get_parent(&clk->hw)); in _lookup_dco()
261 * _lookup_sddiv - Calculate sigma delta divider for j-type DPLL
263 * @sd_div: target sigma-delta divider
267 * See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)"
270 * out in non-multi-OMAP builds for those chips?
277 clkinp = clk_hw_get_rate(clk_hw_get_parent(&clk->hw)); in _lookup_sddiv()
280 * target sigma-delta to near 250MHz in _lookup_sddiv()
295 * _omap3_noncore_dpll_program - set non-core DPLL M,N values directly
300 * the DPLL to lock. Returns -EINVAL upon error, or 0 upon success.
304 struct dpll_data *dd = clk->dpll_data; in omap3_noncore_dpll_program()
316 if (ti_clk_get_features()->flags & TI_CLK_DPLL_HAS_FREQSEL) { in omap3_noncore_dpll_program()
317 v = ti_clk_ll_ops->clk_readl(&dd->control_reg); in omap3_noncore_dpll_program()
318 v &= ~dd->freqsel_mask; in omap3_noncore_dpll_program()
319 v |= freqsel << __ffs(dd->freqsel_mask); in omap3_noncore_dpll_program()
320 ti_clk_ll_ops->clk_writel(v, &dd->control_reg); in omap3_noncore_dpll_program()
324 v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg); in omap3_noncore_dpll_program()
327 if (dd->dcc_mask) { in omap3_noncore_dpll_program()
328 if (dd->last_rounded_rate >= dd->dcc_rate) in omap3_noncore_dpll_program()
329 v |= dd->dcc_mask; /* Enable DCC */ in omap3_noncore_dpll_program()
331 v &= ~dd->dcc_mask; /* Disable DCC */ in omap3_noncore_dpll_program()
334 v &= ~(dd->mult_mask | dd->div1_mask); in omap3_noncore_dpll_program()
335 v |= dd->last_rounded_m << __ffs(dd->mult_mask); in omap3_noncore_dpll_program()
336 v |= (dd->last_rounded_n - 1) << __ffs(dd->div1_mask); in omap3_noncore_dpll_program()
339 if (dd->dco_mask) { in omap3_noncore_dpll_program()
340 _lookup_dco(clk, &dco, dd->last_rounded_m, dd->last_rounded_n); in omap3_noncore_dpll_program()
341 v &= ~(dd->dco_mask); in omap3_noncore_dpll_program()
342 v |= dco << __ffs(dd->dco_mask); in omap3_noncore_dpll_program()
344 if (dd->sddiv_mask) { in omap3_noncore_dpll_program()
345 _lookup_sddiv(clk, &sd_div, dd->last_rounded_m, in omap3_noncore_dpll_program()
346 dd->last_rounded_n); in omap3_noncore_dpll_program()
347 v &= ~(dd->sddiv_mask); in omap3_noncore_dpll_program()
348 v |= sd_div << __ffs(dd->sddiv_mask); in omap3_noncore_dpll_program()
352 * Errata i810 - DPLL controller can get stuck while transitioning in omap3_noncore_dpll_program()
356 * before doing the M/N re-program. in omap3_noncore_dpll_program()
358 errata_i810 = ti_clk_get_features()->flags & TI_CLK_ERRATA_I810; in omap3_noncore_dpll_program()
370 ti_clk_ll_ops->clk_writel(v, &dd->mult_div1_reg); in omap3_noncore_dpll_program()
372 /* Set 4X multiplier and low-power mode */ in omap3_noncore_dpll_program()
373 if (dd->m4xen_mask || dd->lpmode_mask) { in omap3_noncore_dpll_program()
374 v = ti_clk_ll_ops->clk_readl(&dd->control_reg); in omap3_noncore_dpll_program()
376 if (dd->m4xen_mask) { in omap3_noncore_dpll_program()
377 if (dd->last_rounded_m4xen) in omap3_noncore_dpll_program()
378 v |= dd->m4xen_mask; in omap3_noncore_dpll_program()
380 v &= ~dd->m4xen_mask; in omap3_noncore_dpll_program()
383 if (dd->lpmode_mask) { in omap3_noncore_dpll_program()
384 if (dd->last_rounded_lpmode) in omap3_noncore_dpll_program()
385 v |= dd->lpmode_mask; in omap3_noncore_dpll_program()
387 v &= ~dd->lpmode_mask; in omap3_noncore_dpll_program()
390 ti_clk_ll_ops->clk_writel(v, &dd->control_reg); in omap3_noncore_dpll_program()
395 /* REVISIT: Set ramp-up delay? */ in omap3_noncore_dpll_program()
408 * omap3_dpll_recalc - recalculate DPLL rate
420 /* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
423 * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
426 * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock.
428 * the same as the DPLL's parent clock, it will enter bypass;
432 * enable function. If DPLL3 was passed in, or the DPLL does not
433 * support low-power stop, or if the DPLL took too long to enter
434 * bypass or lock, return -EINVAL; otherwise, return 0.
443 dd = clk->dpll_data; in omap3_noncore_dpll_enable()
445 return -EINVAL; in omap3_noncore_dpll_enable()
447 if (clk->clkdm) { in omap3_noncore_dpll_enable()
448 r = ti_clk_ll_ops->clkdm_clk_enable(clk->clkdm, hw->clk); in omap3_noncore_dpll_enable()
451 "%s: could not enable %s's clockdomain %s: %d\n", in omap3_noncore_dpll_enable()
453 clk->clkdm_name, r); in omap3_noncore_dpll_enable()
460 if (clk_hw_get_rate(hw) == clk_hw_get_rate(dd->clk_bypass)) { in omap3_noncore_dpll_enable()
461 WARN_ON(parent != dd->clk_bypass); in omap3_noncore_dpll_enable()
464 WARN_ON(parent != dd->clk_ref); in omap3_noncore_dpll_enable()
472 * omap3_noncore_dpll_disable - instruct a DPLL to enter low-power stop
475 * Instructs a non-CORE DPLL to enter low-power stop. This function is
483 if (clk->clkdm) in omap3_noncore_dpll_disable()
484 ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk); in omap3_noncore_dpll_disable()
487 /* Non-CORE DPLL rate set code */
490 * omap3_noncore_dpll_determine_rate - determine rate for a DPLL
495 * Checks whether the DPLL shall be in bypass or locked mode, and if
496 * locked, calculates the M,N values for the DPLL via round-rate.
505 if (!req->rate) in omap3_noncore_dpll_determine_rate()
506 return -EINVAL; in omap3_noncore_dpll_determine_rate()
508 dd = clk->dpll_data; in omap3_noncore_dpll_determine_rate()
510 return -EINVAL; in omap3_noncore_dpll_determine_rate()
512 if (clk_hw_get_rate(dd->clk_bypass) == req->rate && in omap3_noncore_dpll_determine_rate()
513 (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { in omap3_noncore_dpll_determine_rate()
514 req->best_parent_hw = dd->clk_bypass; in omap3_noncore_dpll_determine_rate()
516 req->rate = omap2_dpll_round_rate(hw, req->rate, in omap3_noncore_dpll_determine_rate()
517 &req->best_parent_rate); in omap3_noncore_dpll_determine_rate()
518 req->best_parent_hw = dd->clk_ref; in omap3_noncore_dpll_determine_rate()
521 req->best_parent_rate = req->rate; in omap3_noncore_dpll_determine_rate()
527 * omap3_noncore_dpll_set_parent - set parent for a DPLL clock
531 * Sets parent for a DPLL clock. This sets the DPLL into bypass or
540 return -EINVAL; in omap3_noncore_dpll_set_parent()
551 * omap3_noncore_dpll_set_rate - set rate for a DPLL clock
557 * reference clock (in bypass mode, the rate of the clock can't be
570 return -EINVAL; in omap3_noncore_dpll_set_rate()
572 dd = clk->dpll_data; in omap3_noncore_dpll_set_rate()
574 return -EINVAL; in omap3_noncore_dpll_set_rate()
576 if (clk_hw_get_parent(hw) != dd->clk_ref) in omap3_noncore_dpll_set_rate()
577 return -EINVAL; in omap3_noncore_dpll_set_rate()
579 if (dd->last_rounded_rate == 0) in omap3_noncore_dpll_set_rate()
580 return -EINVAL; in omap3_noncore_dpll_set_rate()
583 if (ti_clk_get_features()->flags & TI_CLK_DPLL_HAS_FREQSEL) { in omap3_noncore_dpll_set_rate()
584 freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n); in omap3_noncore_dpll_set_rate()
597 * omap3_noncore_dpll_set_rate_and_parent - set rate and parent for a DPLL clock
601 * @index: new parent index for the DPLL, 0 - reference, 1 - bypass
603 * Sets rate and parent for a DPLL clock. If new parent is the bypass
617 return -EINVAL; in omap3_noncore_dpll_set_rate_and_parent()
620 * clk-ref at index[0], in which case we only need to set rate, in omap3_noncore_dpll_set_rate_and_parent()
622 * With clk-bypass case we only need to change parent. in omap3_noncore_dpll_set_rate_and_parent()
635 * omap3_dpll_autoidle_read - read a DPLL's autoidle bits
639 * -EINVAL if passed a null pointer or if the struct clk does not
647 if (!clk || !clk->dpll_data) in omap3_dpll_autoidle_read()
648 return -EINVAL; in omap3_dpll_autoidle_read()
650 dd = clk->dpll_data; in omap3_dpll_autoidle_read()
652 if (!dd->autoidle_mask) in omap3_dpll_autoidle_read()
653 return -EINVAL; in omap3_dpll_autoidle_read()
655 v = ti_clk_ll_ops->clk_readl(&dd->autoidle_reg); in omap3_dpll_autoidle_read()
656 v &= dd->autoidle_mask; in omap3_dpll_autoidle_read()
657 v >>= __ffs(dd->autoidle_mask); in omap3_dpll_autoidle_read()
663 * omap3_dpll_allow_idle - enable DPLL autoidle bits
666 * Enable DPLL automatic idle control. This automatic idle mode
668 * OMAP3430. The DPLL will enter low-power stop when its downstream
676 if (!clk || !clk->dpll_data) in omap3_dpll_allow_idle()
679 dd = clk->dpll_data; in omap3_dpll_allow_idle()
681 if (!dd->autoidle_mask) in omap3_dpll_allow_idle()
685 * REVISIT: CORE DPLL can optionally enter low-power bypass in omap3_dpll_allow_idle()
689 v = ti_clk_ll_ops->clk_readl(&dd->autoidle_reg); in omap3_dpll_allow_idle()
690 v &= ~dd->autoidle_mask; in omap3_dpll_allow_idle()
691 v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask); in omap3_dpll_allow_idle()
692 ti_clk_ll_ops->clk_writel(v, &dd->autoidle_reg); in omap3_dpll_allow_idle()
696 * omap3_dpll_deny_idle - prevent DPLL from automatically idling
706 if (!clk || !clk->dpll_data) in omap3_dpll_deny_idle()
709 dd = clk->dpll_data; in omap3_dpll_deny_idle()
711 if (!dd->autoidle_mask) in omap3_dpll_deny_idle()
714 v = ti_clk_ll_ops->clk_readl(&dd->autoidle_reg); in omap3_dpll_deny_idle()
715 v &= ~dd->autoidle_mask; in omap3_dpll_deny_idle()
716 v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask); in omap3_dpll_deny_idle()
717 ti_clk_ll_ops->clk_writel(v, &dd->autoidle_reg); in omap3_dpll_deny_idle()
735 } while (pclk && !pclk->dpll_data); in omap3_find_clkoutx2_dpll()
747 * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate
769 dd = pclk->dpll_data; in omap3_clkoutx2_recalc()
771 WARN_ON(!dd->enable_mask); in omap3_clkoutx2_recalc()
773 v = ti_clk_ll_ops->clk_readl(&dd->control_reg) & dd->enable_mask; in omap3_clkoutx2_recalc()
774 v >>= __ffs(dd->enable_mask); in omap3_clkoutx2_recalc()
775 if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE)) in omap3_clkoutx2_recalc()
783 * omap3_core_dpll_save_context - Save the m and n values of the divider
787 * and the enable mask.
795 dd = clk->dpll_data; in omap3_core_dpll_save_context()
797 v = ti_clk_ll_ops->clk_readl(&dd->control_reg); in omap3_core_dpll_save_context()
798 clk->context = (v & dd->enable_mask) >> __ffs(dd->enable_mask); in omap3_core_dpll_save_context()
800 if (clk->context == DPLL_LOCKED) { in omap3_core_dpll_save_context()
801 v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg); in omap3_core_dpll_save_context()
802 dd->last_rounded_m = (v & dd->mult_mask) >> in omap3_core_dpll_save_context()
803 __ffs(dd->mult_mask); in omap3_core_dpll_save_context()
804 dd->last_rounded_n = ((v & dd->div1_mask) >> in omap3_core_dpll_save_context()
805 __ffs(dd->div1_mask)) + 1; in omap3_core_dpll_save_context()
812 * omap3_core_dpll_restore_context - restore the m and n values of the divider
816 * and the enable mask.
824 dd = clk->dpll_data; in omap3_core_dpll_restore_context()
826 if (clk->context == DPLL_LOCKED) { in omap3_core_dpll_restore_context()
830 v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg); in omap3_core_dpll_restore_context()
831 v &= ~(dd->mult_mask | dd->div1_mask); in omap3_core_dpll_restore_context()
832 v |= dd->last_rounded_m << __ffs(dd->mult_mask); in omap3_core_dpll_restore_context()
833 v |= (dd->last_rounded_n - 1) << __ffs(dd->div1_mask); in omap3_core_dpll_restore_context()
834 ti_clk_ll_ops->clk_writel(v, &dd->mult_div1_reg); in omap3_core_dpll_restore_context()
839 _omap3_dpll_write_clken(clk, clk->context); in omap3_core_dpll_restore_context()
844 * omap3_non_core_dpll_save_context - Save the m and n values of the divider
848 * and the enable mask.
856 dd = clk->dpll_data; in omap3_noncore_dpll_save_context()
858 v = ti_clk_ll_ops->clk_readl(&dd->control_reg); in omap3_noncore_dpll_save_context()
859 clk->context = (v & dd->enable_mask) >> __ffs(dd->enable_mask); in omap3_noncore_dpll_save_context()
861 if (clk->context == DPLL_LOCKED) { in omap3_noncore_dpll_save_context()
862 v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg); in omap3_noncore_dpll_save_context()
863 dd->last_rounded_m = (v & dd->mult_mask) >> in omap3_noncore_dpll_save_context()
864 __ffs(dd->mult_mask); in omap3_noncore_dpll_save_context()
865 dd->last_rounded_n = ((v & dd->div1_mask) >> in omap3_noncore_dpll_save_context()
866 __ffs(dd->div1_mask)) + 1; in omap3_noncore_dpll_save_context()
873 * omap3_core_dpll_restore_context - restore the m and n values of the divider
877 * and the enable mask.
885 dd = clk->dpll_data; in omap3_noncore_dpll_restore_context()
887 ctrl = ti_clk_ll_ops->clk_readl(&dd->control_reg); in omap3_noncore_dpll_restore_context()
888 mult_div1 = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg); in omap3_noncore_dpll_restore_context()
890 if (clk->context == ((ctrl & dd->enable_mask) >> in omap3_noncore_dpll_restore_context()
891 __ffs(dd->enable_mask)) && in omap3_noncore_dpll_restore_context()
892 dd->last_rounded_m == ((mult_div1 & dd->mult_mask) >> in omap3_noncore_dpll_restore_context()
893 __ffs(dd->mult_mask)) && in omap3_noncore_dpll_restore_context()
894 dd->last_rounded_n == ((mult_div1 & dd->div1_mask) >> in omap3_noncore_dpll_restore_context()
895 __ffs(dd->div1_mask)) + 1) { in omap3_noncore_dpll_restore_context()
900 if (clk->context == DPLL_LOCKED) in omap3_noncore_dpll_restore_context()
903 _omap3_dpll_write_clken(clk, clk->context); in omap3_noncore_dpll_restore_context()
906 /* OMAP3/4 non-CORE DPLL clkops */
913 * omap3_dpll4_set_rate - set rate for omap3 per-dpll
918 * Check if the current SoC supports the per-dpll reprogram operation
919 * or not, and then do the rate change if supported. Returns -EINVAL
927 * According to the 12-5 CDP code from TI, "Limitation 2.5" in omap3_dpll4_set_rate()
931 if (ti_clk_get_features()->flags & TI_CLK_DPLL4_DENY_REPROGRAM) { in omap3_dpll4_set_rate()
933 return -EINVAL; in omap3_dpll4_set_rate()
940 * omap3_dpll4_set_rate_and_parent - set rate and parent for omap3 per-dpll
944 * @index: parent index, 0 - reference clock, 1 - bypass clock
946 * Check if the current SoC support the per-dpll reprogram operation
948 * -EINVAL if not supported, 0 for success, and potential error codes
954 if (ti_clk_get_features()->flags & TI_CLK_DPLL4_DENY_REPROGRAM) { in omap3_dpll4_set_rate_and_parent()
956 return -EINVAL; in omap3_dpll4_set_rate_and_parent()
1001 dd = clk->dpll_data; in omap3_dpll5_apply_errata()
1002 dd->last_rounded_m = d->m; in omap3_dpll5_apply_errata()
1003 dd->last_rounded_n = d->n; in omap3_dpll5_apply_errata()
1004 dd->last_rounded_rate = div_u64((u64)parent_rate * d->m, d->n); in omap3_dpll5_apply_errata()
1011 * omap3_dpll5_set_rate - set rate for omap3 dpll5