Lines Matching +full:reg +full:- +full:mux
1 // SPDX-License-Identifier: GPL-2.0
6 #include <linux/clk-provider.h>
11 #include "clk-cv18xx-ip.h"
25 return cv1800_clk_setbit(&gate->common, &gate->gate); in gate_enable()
32 cv1800_clk_clearbit(&gate->common, &gate->gate); in gate_disable()
39 return cv1800_clk_checkbit(&gate->common, &gate->gate); in gate_is_enabled()
90 return cv1800_clk_setbit(&div->common, &div->gate); in div_enable()
97 cv1800_clk_clearbit(&div->common, &div->gate); in div_disable()
104 return cv1800_clk_checkbit(&div->common, &div->gate); in div_is_enabled()
112 u32 reg; in div_helper_set_rate() local
114 if (div->width == 0) in div_helper_set_rate()
117 spin_lock_irqsave(common->lock, flags); in div_helper_set_rate()
119 reg = readl(common->base + div->reg); in div_helper_set_rate()
120 reg = cv1800_clk_regfield_set(reg, val, div); in div_helper_set_rate()
121 if (div->initval > 0) in div_helper_set_rate()
122 reg = DIV_SET_EN_DIV_FACTOR(reg); in div_helper_set_rate()
124 writel(reg, common->base + div->reg); in div_helper_set_rate()
126 spin_unlock_irqrestore(common->lock, flags); in div_helper_set_rate()
135 u32 reg; in div_helper_get_clockdiv() local
137 if (!div || div->initval < 0 || (div->width == 0 && div->initval <= 0)) in div_helper_get_clockdiv()
140 if (div->width == 0 && div->initval > 0) in div_helper_get_clockdiv()
141 return div->initval; in div_helper_get_clockdiv()
143 reg = readl(common->base + div->reg); in div_helper_get_clockdiv()
145 if (div->initval == 0 || DIV_GET_EN_CLK_DIV_FACTOR(reg)) in div_helper_get_clockdiv()
146 clockdiv = cv1800_clk_regfield_get(reg, div); in div_helper_get_clockdiv()
147 else if (div->initval > 0) in div_helper_get_clockdiv()
148 clockdiv = div->initval; in div_helper_get_clockdiv()
157 if (div->width == 0) { in div_helper_round_rate()
158 if (div->initval <= 0) in div_helper_round_rate()
161 return DIV_ROUND_UP_ULL(*prate, div->initval); in div_helper_round_rate()
165 div->width, div->flags); in div_helper_round_rate()
173 return div_helper_round_rate(&div->div, &div->common.hw, parent, in div_round_rate()
181 if (common->features & CLK_DIVIDER_ROUND_CLOSEST) in div_is_better_rate()
197 struct clk_hw *best_parent, *hw = &common->hw; in mux_helper_determine_rate()
207 req->rate, -1, data); in mux_helper_determine_rate()
222 tmp_rate = round(parent, &parent_rate, req->rate, i, data); in mux_helper_determine_rate()
224 if (tmp_rate == req->rate) { in mux_helper_determine_rate()
231 if (div_is_better_rate(common, req->rate, in mux_helper_determine_rate()
240 return -EINVAL; in mux_helper_determine_rate()
243 req->best_parent_hw = best_parent; in mux_helper_determine_rate()
244 req->best_parent_rate = best_parent_rate; in mux_helper_determine_rate()
245 req->rate = best_rate; in mux_helper_determine_rate()
254 return mux_helper_determine_rate(&div->common, req, in div_determine_rate()
264 val = div_helper_get_clockdiv(&div->common, &div->div); in div_recalc_rate()
269 div->div.flags, div->div.width); in div_recalc_rate()
279 div->div.width, div->div.flags); in div_set_rate()
281 return div_helper_set_rate(&div->common, &div->div, val); in div_set_rate()
308 if (id == -1) { in bypass_div_round_rate()
309 if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) in bypass_div_round_rate()
313 -1, &div->div); in bypass_div_round_rate()
319 return div_round_rate(parent, parent_rate, rate, id - 1, &div->div); in bypass_div_round_rate()
327 return mux_helper_determine_rate(&div->div.common, req, in bypass_div_determine_rate()
336 if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) in bypass_div_recalc_rate()
347 if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) in bypass_div_set_rate()
357 if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) in bypass_div_get_parent()
368 return cv1800_clk_clearbit(&div->div.common, &div->bypass); in bypass_div_set_parent()
370 return cv1800_clk_setbit(&div->div.common, &div->bypass); in bypass_div_set_parent()
386 /* MUX */
396 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_enable() local
398 return cv1800_clk_setbit(&mux->common, &mux->gate); in mux_enable()
403 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_disable() local
405 cv1800_clk_clearbit(&mux->common, &mux->gate); in mux_disable()
410 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_is_enabled() local
412 return cv1800_clk_checkbit(&mux->common, &mux->gate); in mux_is_enabled()
418 struct cv1800_clk_mux *mux = data; in mux_round_rate() local
420 return div_helper_round_rate(&mux->div, &mux->common.hw, parent, in mux_round_rate()
427 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_determine_rate() local
429 return mux_helper_determine_rate(&mux->common, req, in mux_determine_rate()
430 mux_round_rate, mux); in mux_determine_rate()
436 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_recalc_rate() local
439 val = div_helper_get_clockdiv(&mux->common, &mux->div); in mux_recalc_rate()
444 mux->div.flags, mux->div.width); in mux_recalc_rate()
450 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_set_rate() local
454 mux->div.width, mux->div.flags); in mux_set_rate()
456 return div_helper_set_rate(&mux->common, &mux->div, val); in mux_set_rate()
461 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_get_parent() local
462 u32 reg = readl(mux->common.base + mux->mux.reg); in mux_get_parent() local
464 return cv1800_clk_regfield_get(reg, &mux->mux); in mux_get_parent()
467 static int _mux_set_parent(struct cv1800_clk_mux *mux, u8 index) in _mux_set_parent() argument
469 u32 reg; in _mux_set_parent() local
471 reg = readl(mux->common.base + mux->mux.reg); in _mux_set_parent()
472 reg = cv1800_clk_regfield_set(reg, index, &mux->mux); in _mux_set_parent()
473 writel(reg, mux->common.base + mux->mux.reg); in _mux_set_parent()
480 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_set_parent() local
483 spin_lock_irqsave(mux->common.lock, flags); in mux_set_parent()
485 _mux_set_parent(mux, index); in mux_set_parent()
487 spin_unlock_irqrestore(mux->common.lock, flags); in mux_set_parent()
508 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in hw_to_cv1800_clk_bypass_mux() local
510 return container_of(mux, struct cv1800_clk_bypass_mux, mux); in hw_to_cv1800_clk_bypass_mux()
517 struct cv1800_clk_bypass_mux *mux = data; in bypass_mux_round_rate() local
519 if (id == -1) { in bypass_mux_round_rate()
520 if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) in bypass_mux_round_rate()
524 -1, &mux->mux); in bypass_mux_round_rate()
530 return mux_round_rate(parent, parent_rate, rate, id - 1, &mux->mux); in bypass_mux_round_rate()
536 struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw); in bypass_mux_determine_rate() local
538 return mux_helper_determine_rate(&mux->mux.common, req, in bypass_mux_determine_rate()
539 bypass_mux_round_rate, mux); in bypass_mux_determine_rate()
545 struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw); in bypass_mux_recalc_rate() local
547 if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) in bypass_mux_recalc_rate()
556 struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw); in bypass_mux_set_rate() local
558 if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) in bypass_mux_set_rate()
566 struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw); in bypass_mux_get_parent() local
568 if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) in bypass_mux_get_parent()
576 struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw); in bypass_mux_set_parent() local
579 return cv1800_clk_setbit(&mux->mux.common, &mux->bypass); in bypass_mux_set_parent()
581 return cv1800_clk_clearbit(&mux->mux.common, &mux->bypass); in bypass_mux_set_parent()
607 struct clk_hw *hw = &mmux->common.hw; in mmux_get_parent_id()
623 return cv1800_clk_setbit(&mmux->common, &mmux->gate); in mmux_enable()
630 cv1800_clk_clearbit(&mmux->common, &mmux->gate); in mmux_disable()
637 return cv1800_clk_checkbit(&mmux->common, &mmux->gate); in mmux_is_enabled()
646 if (id == -1) { in mmux_round_rate()
647 if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) in mmux_round_rate()
653 div_id = mmux->parent2sel[id]; in mmux_round_rate()
658 return div_helper_round_rate(&mmux->div[div_id], in mmux_round_rate()
659 &mmux->common.hw, parent, in mmux_round_rate()
668 return mux_helper_determine_rate(&mmux->common, req, in mmux_determine_rate()
679 if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) in mmux_recalc_rate()
682 if (cv1800_clk_checkbit(&mmux->common, &mmux->clk_sel)) in mmux_recalc_rate()
683 div = &mmux->div[0]; in mmux_recalc_rate()
685 div = &mmux->div[1]; in mmux_recalc_rate()
687 val = div_helper_get_clockdiv(&mmux->common, div); in mmux_recalc_rate()
692 div->flags, div->width); in mmux_recalc_rate()
702 if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) in mmux_set_rate()
705 if (cv1800_clk_checkbit(&mmux->common, &mmux->clk_sel)) in mmux_set_rate()
706 div = &mmux->div[0]; in mmux_set_rate()
708 div = &mmux->div[1]; in mmux_set_rate()
711 div->width, div->flags); in mmux_set_rate()
713 return div_helper_set_rate(&mmux->common, div, val); in mmux_set_rate()
719 struct cv1800_clk_regfield *mux; in mmux_get_parent() local
720 u32 reg; in mmux_get_parent() local
723 if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) in mmux_get_parent()
726 if (cv1800_clk_checkbit(&mmux->common, &mmux->clk_sel)) in mmux_get_parent()
730 mux = &mmux->mux[clk_sel]; in mmux_get_parent()
732 reg = readl(mmux->common.base + mux->reg); in mmux_get_parent()
734 return mmux->sel2parent[clk_sel][cv1800_clk_regfield_get(reg, mux)]; in mmux_get_parent()
740 struct cv1800_clk_regfield *mux; in mmux_set_parent() local
742 u32 reg; in mmux_set_parent() local
743 s8 clk_sel = mmux->parent2sel[index]; in mmux_set_parent()
745 if (index == 0 || clk_sel == -1) { in mmux_set_parent()
746 cv1800_clk_setbit(&mmux->common, &mmux->bypass); in mmux_set_parent()
750 cv1800_clk_clearbit(&mmux->common, &mmux->bypass); in mmux_set_parent()
753 cv1800_clk_clearbit(&mmux->common, &mmux->clk_sel); in mmux_set_parent()
755 cv1800_clk_setbit(&mmux->common, &mmux->clk_sel); in mmux_set_parent()
757 spin_lock_irqsave(mmux->common.lock, flags); in mmux_set_parent()
759 mux = &mmux->mux[clk_sel]; in mmux_set_parent()
760 reg = readl(mmux->common.base + mux->reg); in mmux_set_parent()
761 reg = cv1800_clk_regfield_set(reg, index, mux); in mmux_set_parent()
763 writel(reg, mmux->common.base + mux->reg); in mmux_set_parent()
765 spin_unlock_irqrestore(mmux->common.lock, flags); in mmux_set_parent()
797 cv1800_clk_setbit(&aclk->common, &aclk->src_en); in aclk_enable()
798 return cv1800_clk_setbit(&aclk->common, &aclk->output_en); in aclk_enable()
805 cv1800_clk_clearbit(&aclk->common, &aclk->output_en); in aclk_disable()
806 cv1800_clk_clearbit(&aclk->common, &aclk->src_en); in aclk_disable()
813 return cv1800_clk_checkbit(&aclk->common, &aclk->output_en); in aclk_is_enabled()
821 req->rate = aclk->target_rate; in aclk_determine_rate()
834 if (!cv1800_clk_checkbit(&aclk->common, &aclk->div_en)) in aclk_recalc_rate()
837 regval = readl(aclk->common.base + aclk->m.reg); in aclk_recalc_rate()
838 factor *= cv1800_clk_regfield_get(regval, &aclk->m); in aclk_recalc_rate()
840 regval = readl(aclk->common.base + aclk->n.reg); in aclk_recalc_rate()
841 rate *= cv1800_clk_regfield_get(regval, &aclk->n); in aclk_recalc_rate()
866 spin_lock_irqsave(aclk->common.lock, flags); in aclk_set_rate()
868 writel(m, aclk->common.base + aclk->m.reg); in aclk_set_rate()
869 writel(n, aclk->common.base + aclk->n.reg); in aclk_set_rate()
871 cv1800_clk_setbit(&aclk->common, &aclk->div_en); in aclk_set_rate()
872 cv1800_clk_setbit(&aclk->common, &aclk->div_up); in aclk_set_rate()
874 spin_unlock_irqrestore(aclk->common.lock, flags); in aclk_set_rate()