Lines Matching +full:mux +full:-
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()
51 req->rate = req->best_parent_rate; in gate_determine_rate()
92 return cv1800_clk_setbit(&div->common, &div->gate); in div_enable()
99 cv1800_clk_clearbit(&div->common, &div->gate); in div_disable()
106 return cv1800_clk_checkbit(&div->common, &div->gate); in div_is_enabled()
116 if (div->width == 0) in div_helper_set_rate()
119 spin_lock_irqsave(common->lock, flags); in div_helper_set_rate()
121 reg = readl(common->base + div->reg); in div_helper_set_rate()
123 if (div->initval > 0) in div_helper_set_rate()
126 writel(reg, common->base + div->reg); in div_helper_set_rate()
128 spin_unlock_irqrestore(common->lock, flags); in div_helper_set_rate()
139 if (!div || div->initval < 0 || (div->width == 0 && div->initval <= 0)) in div_helper_get_clockdiv()
142 if (div->width == 0 && div->initval > 0) in div_helper_get_clockdiv()
143 return div->initval; in div_helper_get_clockdiv()
145 reg = readl(common->base + div->reg); in div_helper_get_clockdiv()
147 if (div->initval == 0 || DIV_GET_EN_CLK_DIV_FACTOR(reg)) in div_helper_get_clockdiv()
149 else if (div->initval > 0) in div_helper_get_clockdiv()
150 clockdiv = div->initval; in div_helper_get_clockdiv()
159 if (div->width == 0) { in div_helper_round_rate()
160 if (div->initval <= 0) in div_helper_round_rate()
163 return DIV_ROUND_UP_ULL(*prate, div->initval); in div_helper_round_rate()
167 div->width, div->flags); in div_helper_round_rate()
175 return div_helper_round_rate(&div->div, &div->common.hw, parent, in div_round_rate()
183 if (common->features & CLK_DIVIDER_ROUND_CLOSEST) in div_is_better_rate()
199 struct clk_hw *best_parent, *hw = &common->hw; in mux_helper_determine_rate()
209 req->rate, -1, data); in mux_helper_determine_rate()
224 tmp_rate = round(parent, &parent_rate, req->rate, i, data); in mux_helper_determine_rate()
226 if (tmp_rate == req->rate) { in mux_helper_determine_rate()
233 if (div_is_better_rate(common, req->rate, in mux_helper_determine_rate()
242 return -EINVAL; in mux_helper_determine_rate()
245 req->best_parent_hw = best_parent; in mux_helper_determine_rate()
246 req->best_parent_rate = best_parent_rate; in mux_helper_determine_rate()
247 req->rate = best_rate; in mux_helper_determine_rate()
256 return mux_helper_determine_rate(&div->common, req, in div_determine_rate()
266 val = div_helper_get_clockdiv(&div->common, &div->div); in div_recalc_rate()
271 div->div.flags, div->div.width); in div_recalc_rate()
281 div->div.width, div->div.flags); in div_set_rate()
283 return div_helper_set_rate(&div->common, &div->div, val); in div_set_rate()
310 if (id == -1) { in bypass_div_round_rate()
311 if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) in bypass_div_round_rate()
315 -1, &div->div); in bypass_div_round_rate()
321 return div_round_rate(parent, parent_rate, rate, id - 1, &div->div); in bypass_div_round_rate()
329 return mux_helper_determine_rate(&div->div.common, req, in bypass_div_determine_rate()
338 if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) in bypass_div_recalc_rate()
349 if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) in bypass_div_set_rate()
359 if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) in bypass_div_get_parent()
370 return cv1800_clk_clearbit(&div->div.common, &div->bypass); in bypass_div_set_parent()
372 return cv1800_clk_setbit(&div->div.common, &div->bypass); in bypass_div_set_parent()
388 /* MUX */
398 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_enable() local
400 return cv1800_clk_setbit(&mux->common, &mux->gate); in mux_enable()
405 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_disable() local
407 cv1800_clk_clearbit(&mux->common, &mux->gate); in mux_disable()
412 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_is_enabled() local
414 return cv1800_clk_checkbit(&mux->common, &mux->gate); in mux_is_enabled()
420 struct cv1800_clk_mux *mux = data; in mux_round_rate() local
422 return div_helper_round_rate(&mux->div, &mux->common.hw, parent, in mux_round_rate()
429 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_determine_rate() local
431 return mux_helper_determine_rate(&mux->common, req, in mux_determine_rate()
432 mux_round_rate, mux); in mux_determine_rate()
438 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_recalc_rate() local
441 val = div_helper_get_clockdiv(&mux->common, &mux->div); in mux_recalc_rate()
446 mux->div.flags, mux->div.width); in mux_recalc_rate()
452 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_set_rate() local
456 mux->div.width, mux->div.flags); in mux_set_rate()
458 return div_helper_set_rate(&mux->common, &mux->div, val); in mux_set_rate()
463 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_get_parent() local
464 u32 reg = readl(mux->common.base + mux->mux.reg); in mux_get_parent()
466 return cv1800_clk_regfield_get(reg, &mux->mux); in mux_get_parent()
469 static int _mux_set_parent(struct cv1800_clk_mux *mux, u8 index) in _mux_set_parent() argument
473 reg = readl(mux->common.base + mux->mux.reg); in _mux_set_parent()
474 reg = cv1800_clk_regfield_set(reg, index, &mux->mux); in _mux_set_parent()
475 writel(reg, mux->common.base + mux->mux.reg); in _mux_set_parent()
482 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in mux_set_parent() local
485 spin_lock_irqsave(mux->common.lock, flags); in mux_set_parent()
487 _mux_set_parent(mux, index); in mux_set_parent()
489 spin_unlock_irqrestore(mux->common.lock, flags); in mux_set_parent()
510 struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); in hw_to_cv1800_clk_bypass_mux() local
512 return container_of(mux, struct cv1800_clk_bypass_mux, mux); in hw_to_cv1800_clk_bypass_mux()
519 struct cv1800_clk_bypass_mux *mux = data; in bypass_mux_round_rate() local
521 if (id == -1) { in bypass_mux_round_rate()
522 if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) in bypass_mux_round_rate()
526 -1, &mux->mux); in bypass_mux_round_rate()
532 return mux_round_rate(parent, parent_rate, rate, id - 1, &mux->mux); in bypass_mux_round_rate()
538 struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw); in bypass_mux_determine_rate() local
540 return mux_helper_determine_rate(&mux->mux.common, req, in bypass_mux_determine_rate()
541 bypass_mux_round_rate, mux); in bypass_mux_determine_rate()
547 struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw); in bypass_mux_recalc_rate() local
549 if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) in bypass_mux_recalc_rate()
558 struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw); in bypass_mux_set_rate() local
560 if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) in bypass_mux_set_rate()
568 struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw); in bypass_mux_get_parent() local
570 if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) in bypass_mux_get_parent()
578 struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw); in bypass_mux_set_parent() local
581 return cv1800_clk_setbit(&mux->mux.common, &mux->bypass); in bypass_mux_set_parent()
583 return cv1800_clk_clearbit(&mux->mux.common, &mux->bypass); in bypass_mux_set_parent()
609 struct clk_hw *hw = &mmux->common.hw; in mmux_get_parent_id()
625 return cv1800_clk_setbit(&mmux->common, &mmux->gate); in mmux_enable()
632 cv1800_clk_clearbit(&mmux->common, &mmux->gate); in mmux_disable()
639 return cv1800_clk_checkbit(&mmux->common, &mmux->gate); in mmux_is_enabled()
648 if (id == -1) { in mmux_round_rate()
649 if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) in mmux_round_rate()
655 div_id = mmux->parent2sel[id]; in mmux_round_rate()
660 return div_helper_round_rate(&mmux->div[div_id], in mmux_round_rate()
661 &mmux->common.hw, parent, in mmux_round_rate()
670 return mux_helper_determine_rate(&mmux->common, req, in mmux_determine_rate()
681 if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) in mmux_recalc_rate()
684 if (cv1800_clk_checkbit(&mmux->common, &mmux->clk_sel)) in mmux_recalc_rate()
685 div = &mmux->div[0]; in mmux_recalc_rate()
687 div = &mmux->div[1]; in mmux_recalc_rate()
689 val = div_helper_get_clockdiv(&mmux->common, div); in mmux_recalc_rate()
694 div->flags, div->width); in mmux_recalc_rate()
704 if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) in mmux_set_rate()
707 if (cv1800_clk_checkbit(&mmux->common, &mmux->clk_sel)) in mmux_set_rate()
708 div = &mmux->div[0]; in mmux_set_rate()
710 div = &mmux->div[1]; in mmux_set_rate()
713 div->width, div->flags); in mmux_set_rate()
715 return div_helper_set_rate(&mmux->common, div, val); in mmux_set_rate()
721 struct cv1800_clk_regfield *mux; in mmux_get_parent() local
725 if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) in mmux_get_parent()
728 if (cv1800_clk_checkbit(&mmux->common, &mmux->clk_sel)) in mmux_get_parent()
732 mux = &mmux->mux[clk_sel]; in mmux_get_parent()
734 reg = readl(mmux->common.base + mux->reg); in mmux_get_parent()
736 return mmux->sel2parent[clk_sel][cv1800_clk_regfield_get(reg, mux)]; in mmux_get_parent()
742 struct cv1800_clk_regfield *mux; in mmux_set_parent() local
745 s8 clk_sel = mmux->parent2sel[index]; in mmux_set_parent()
747 if (index == 0 || clk_sel == -1) { in mmux_set_parent()
748 cv1800_clk_setbit(&mmux->common, &mmux->bypass); in mmux_set_parent()
752 cv1800_clk_clearbit(&mmux->common, &mmux->bypass); in mmux_set_parent()
755 cv1800_clk_clearbit(&mmux->common, &mmux->clk_sel); in mmux_set_parent()
757 cv1800_clk_setbit(&mmux->common, &mmux->clk_sel); in mmux_set_parent()
759 spin_lock_irqsave(mmux->common.lock, flags); in mmux_set_parent()
761 mux = &mmux->mux[clk_sel]; in mmux_set_parent()
762 reg = readl(mmux->common.base + mux->reg); in mmux_set_parent()
763 reg = cv1800_clk_regfield_set(reg, index, mux); in mmux_set_parent()
765 writel(reg, mmux->common.base + mux->reg); in mmux_set_parent()
767 spin_unlock_irqrestore(mmux->common.lock, flags); in mmux_set_parent()
799 cv1800_clk_setbit(&aclk->common, &aclk->src_en); in aclk_enable()
800 return cv1800_clk_setbit(&aclk->common, &aclk->output_en); in aclk_enable()
807 cv1800_clk_clearbit(&aclk->common, &aclk->output_en); in aclk_disable()
808 cv1800_clk_clearbit(&aclk->common, &aclk->src_en); in aclk_disable()
815 return cv1800_clk_checkbit(&aclk->common, &aclk->output_en); in aclk_is_enabled()
823 req->rate = aclk->target_rate; in aclk_determine_rate()
836 if (!cv1800_clk_checkbit(&aclk->common, &aclk->div_en)) in aclk_recalc_rate()
839 regval = readl(aclk->common.base + aclk->m.reg); in aclk_recalc_rate()
840 factor *= cv1800_clk_regfield_get(regval, &aclk->m); in aclk_recalc_rate()
842 regval = readl(aclk->common.base + aclk->n.reg); in aclk_recalc_rate()
843 rate *= cv1800_clk_regfield_get(regval, &aclk->n); in aclk_recalc_rate()
868 spin_lock_irqsave(aclk->common.lock, flags); in aclk_set_rate()
870 writel(m, aclk->common.base + aclk->m.reg); in aclk_set_rate()
871 writel(n, aclk->common.base + aclk->n.reg); in aclk_set_rate()
873 cv1800_clk_setbit(&aclk->common, &aclk->div_en); in aclk_set_rate()
874 cv1800_clk_setbit(&aclk->common, &aclk->div_up); in aclk_set_rate()
876 spin_unlock_irqrestore(aclk->common.lock, flags); in aclk_set_rate()