Lines Matching +full:core +full:- +full:clk

1 // SPDX-License-Identifier: GPL-2.0-only
6 #include <linux/clk-provider.h>
12 #include <asm/mach-pic32/pic32.h>
15 #include "clk-core.h"
78 /* add instruction pipeline delay while CPU clock is in-transition. */
92 struct pic32_clk_common *core; member
101 return readl(pb->ctrl_reg) & PB_DIV_ENABLE; in pbclk_is_enabled()
108 writel(PB_DIV_ENABLE, PIC32_SET(pb->ctrl_reg)); in pbclk_enable()
116 writel(PB_DIV_ENABLE, PIC32_CLR(pb->ctrl_reg)); in pbclk_disable()
137 if (abs(rate - divided_rate_down) < abs(rate - divided_rate)) in calc_best_divided_rate()
147 return ((readl(pb->ctrl_reg) >> PB_DIV_SHIFT) & PB_DIV_MASK) + 1; in pbclk_read_pbdiv()
161 req->rate = calc_best_divided_rate(req->rate, req->best_parent_rate, in pbclk_determine_rate()
176 err = readl_poll_timeout(pb->ctrl_reg, v, v & PB_DIV_READY, in pbclk_set_rate()
184 spin_lock_irqsave(&pb->core->reg_lock, flags); in pbclk_set_rate()
187 v = readl(pb->ctrl_reg); in pbclk_set_rate()
189 v |= (div - 1); in pbclk_set_rate()
193 writel(v, pb->ctrl_reg); in pbclk_set_rate()
195 spin_unlock_irqrestore(&pb->core->reg_lock, flags); in pbclk_set_rate()
198 err = readl_poll_timeout(pb->ctrl_reg, v, v & PB_DIV_READY, in pbclk_set_rate()
204 return (pbclk_read_pbdiv(pb) == div) ? 0 : -EBUSY; in pbclk_set_rate()
216 struct clk *pic32_periph_clk_register(const struct pic32_periph_clk_data *desc, in pic32_periph_clk_register()
217 struct pic32_clk_common *core) in pic32_periph_clk_register() argument
220 struct clk *clk; in pic32_periph_clk_register() local
222 pbclk = devm_kzalloc(core->dev, sizeof(*pbclk), GFP_KERNEL); in pic32_periph_clk_register()
224 return ERR_PTR(-ENOMEM); in pic32_periph_clk_register()
226 pbclk->hw.init = &desc->init_data; in pic32_periph_clk_register()
227 pbclk->core = core; in pic32_periph_clk_register()
228 pbclk->ctrl_reg = desc->ctrl_reg + core->iobase; in pic32_periph_clk_register()
230 clk = devm_clk_register(core->dev, &pbclk->hw); in pic32_periph_clk_register()
231 if (IS_ERR(clk)) { in pic32_periph_clk_register()
232 dev_err(core->dev, "%s: clk_register() failed\n", __func__); in pic32_periph_clk_register()
233 devm_kfree(core->dev, pbclk); in pic32_periph_clk_register()
236 return clk; in pic32_periph_clk_register()
244 struct pic32_clk_common *core; member
253 return readl(refo->ctrl_reg) & REFO_ON; in roclk_is_enabled()
260 writel(REFO_ON | REFO_OE, PIC32_SET(refo->ctrl_reg)); in roclk_enable()
268 writel(REFO_ON | REFO_OE, PIC32_CLR(refo->ctrl_reg)); in roclk_disable()
284 v = (readl(refo->ctrl_reg) >> REFO_SEL_SHIFT) & REFO_SEL_MASK; in roclk_get_parent()
286 if (!refo->parent_map) in roclk_get_parent()
290 if (refo->parent_map[i] == v) in roclk_get_parent()
293 return -EINVAL; in roclk_get_parent()
326 /* Find integer approximation of floating-point arithmetic. in roclk_calc_div_trim()
331 * Since kernel does not perform floating-point arithmetic so in roclk_calc_div_trim()
335 * ie. rotrim = ((fin * 256) / fout) - (512 * DIV) in roclk_calc_div_trim()
347 frac -= (u64)(div << 9); in roclk_calc_div_trim()
367 v = readl(refo->ctrl_reg); in roclk_recalc_rate()
371 v = readl(refo->ctrl_reg + REFO_TRIM_REG); in roclk_recalc_rate()
381 unsigned int i, delta, best_delta = -1; in roclk_determine_rate()
396 if (req->rate > parent_rate) in roclk_determine_rate()
400 roclk_calc_div_trim(req->rate, req->best_parent_rate, &rodiv, &rotrim); in roclk_determine_rate()
403 nearest_rate = roclk_calc_rate(req->best_parent_rate, rodiv, rotrim); in roclk_determine_rate()
405 delta = abs(nearest_rate - req->rate); in roclk_determine_rate()
406 if ((nearest_rate >= req->rate) && (delta < best_delta)) { in roclk_determine_rate()
420 __func__, clk_hw_get_name(hw), req->rate); in roclk_determine_rate()
425 clk_hw_get_name(hw), req->rate, in roclk_determine_rate()
429 if (req->best_parent_rate) in roclk_determine_rate()
430 req->best_parent_rate = best_parent_rate; in roclk_determine_rate()
432 if (req->best_parent_hw) in roclk_determine_rate()
433 req->best_parent_hw = best_parent_clk; in roclk_determine_rate()
445 if (refo->parent_map) in roclk_set_parent()
446 index = refo->parent_map[index]; in roclk_set_parent()
449 err = readl_poll_timeout(refo->ctrl_reg, v, !(v & REFO_ACTIVE), in roclk_set_parent()
452 pr_err("%s: poll failed, clk active\n", clk_hw_get_name(hw)); in roclk_set_parent()
456 spin_lock_irqsave(&refo->core->reg_lock, flags); in roclk_set_parent()
461 v = readl(refo->ctrl_reg); in roclk_set_parent()
465 writel(v, refo->ctrl_reg); in roclk_set_parent()
467 spin_unlock_irqrestore(&refo->core->reg_lock, flags); in roclk_set_parent()
489 err = readl_poll_timeout(refo->ctrl_reg, v, in roclk_set_rate_and_parent()
497 spin_lock_irqsave(&refo->core->reg_lock, flags); in roclk_set_rate_and_parent()
498 v = readl(refo->ctrl_reg); in roclk_set_rate_and_parent()
503 if (refo->parent_map) in roclk_set_rate_and_parent()
504 index = refo->parent_map[index]; in roclk_set_rate_and_parent()
512 writel(v, refo->ctrl_reg); in roclk_set_rate_and_parent()
515 v = readl(refo->ctrl_reg + REFO_TRIM_REG); in roclk_set_rate_and_parent()
518 writel(v, refo->ctrl_reg + REFO_TRIM_REG); in roclk_set_rate_and_parent()
521 writel(REFO_ON | REFO_DIVSW_EN, PIC32_SET(refo->ctrl_reg)); in roclk_set_rate_and_parent()
523 /* wait till divswen is in-progress */ in roclk_set_rate_and_parent()
524 err = readl_poll_timeout_atomic(refo->ctrl_reg, v, !(v & REFO_DIVSW_EN), in roclk_set_rate_and_parent()
526 /* leave the clk gated as it was */ in roclk_set_rate_and_parent()
527 writel(REFO_ON, PIC32_CLR(refo->ctrl_reg)); in roclk_set_rate_and_parent()
529 spin_unlock_irqrestore(&refo->core->reg_lock, flags); in roclk_set_rate_and_parent()
555 struct clk *pic32_refo_clk_register(const struct pic32_ref_osc_data *data, in pic32_refo_clk_register()
556 struct pic32_clk_common *core) in pic32_refo_clk_register() argument
559 struct clk *clk; in pic32_refo_clk_register() local
561 refo = devm_kzalloc(core->dev, sizeof(*refo), GFP_KERNEL); in pic32_refo_clk_register()
563 return ERR_PTR(-ENOMEM); in pic32_refo_clk_register()
565 refo->core = core; in pic32_refo_clk_register()
566 refo->hw.init = &data->init_data; in pic32_refo_clk_register()
567 refo->ctrl_reg = data->ctrl_reg + core->iobase; in pic32_refo_clk_register()
568 refo->parent_map = data->parent_map; in pic32_refo_clk_register()
570 clk = devm_clk_register(core->dev, &refo->hw); in pic32_refo_clk_register()
571 if (IS_ERR(clk)) in pic32_refo_clk_register()
572 dev_err(core->dev, "%s: clk_register() failed\n", __func__); in pic32_refo_clk_register()
574 return clk; in pic32_refo_clk_register()
583 struct pic32_clk_common *core; member
602 unsigned int best_delta = -1, delta, match_found = 0; in spll_calc_mult_div()
605 parent_rate /= pll->idiv; in spll_calc_mult_div()
613 delta = abs(rate - new_rate); in spll_calc_mult_div()
633 *mult_p = best_mul - 1; in spll_calc_mult_div()
649 v = readl(pll->ctrl_reg); in spll_clk_recalc_rate()
657 pll_in_rate = parent_rate / pll->idiv; in spll_clk_recalc_rate()
670 req->rate = spll_calc_mult_div(pll, req->rate, req->best_parent_rate, in spll_clk_determine_rate()
686 return -EINVAL; in spll_clk_set_rate()
689 * We can't change SPLL counters when it is in-active use in spll_clk_set_rate()
695 pr_err("%s: failed, clk in-use\n", __func__); in spll_clk_set_rate()
696 return -EBUSY; in spll_clk_set_rate()
699 spin_lock_irqsave(&pll->core->reg_lock, flags); in spll_clk_set_rate()
702 v = readl(pll->ctrl_reg); in spll_clk_set_rate()
710 writel(v, pll->ctrl_reg); in spll_clk_set_rate()
713 /* insert few nops (5-stage) to ensure CPU does not hang */ in spll_clk_set_rate()
718 err = readl_poll_timeout_atomic(pll->status_reg, v, in spll_clk_set_rate()
719 v & pll->lock_mask, 1, 100); in spll_clk_set_rate()
720 spin_unlock_irqrestore(&pll->core->reg_lock, flags); in spll_clk_set_rate()
732 struct clk *pic32_spll_clk_register(const struct pic32_sys_pll_data *data, in pic32_spll_clk_register()
733 struct pic32_clk_common *core) in pic32_spll_clk_register() argument
736 struct clk *clk; in pic32_spll_clk_register() local
738 spll = devm_kzalloc(core->dev, sizeof(*spll), GFP_KERNEL); in pic32_spll_clk_register()
740 return ERR_PTR(-ENOMEM); in pic32_spll_clk_register()
742 spll->core = core; in pic32_spll_clk_register()
743 spll->hw.init = &data->init_data; in pic32_spll_clk_register()
744 spll->ctrl_reg = data->ctrl_reg + core->iobase; in pic32_spll_clk_register()
745 spll->status_reg = data->status_reg + core->iobase; in pic32_spll_clk_register()
746 spll->lock_mask = data->lock_mask; in pic32_spll_clk_register()
749 spll->idiv = (readl(spll->ctrl_reg) >> PLL_IDIV_SHIFT) & PLL_IDIV_MASK; in pic32_spll_clk_register()
750 spll->idiv += 1; in pic32_spll_clk_register()
752 clk = devm_clk_register(core->dev, &spll->hw); in pic32_spll_clk_register()
753 if (IS_ERR(clk)) in pic32_spll_clk_register()
754 dev_err(core->dev, "sys_pll: clk_register() failed\n"); in pic32_spll_clk_register()
756 return clk; in pic32_spll_clk_register()
767 struct pic32_clk_common *core; member
777 div = (readl(sclk->slew_reg) >> SLEW_SYSDIV_SHIFT) & SLEW_SYSDIV; in sclk_get_rate()
778 div += 1; /* sys-div to divider */ in sclk_get_rate()
786 req->rate = calc_best_divided_rate(req->rate, req->best_parent_rate, in sclk_determine_rate()
802 spin_lock_irqsave(&sclk->core->reg_lock, flags); in sclk_set_rate()
805 v = readl(sclk->slew_reg); in sclk_set_rate()
807 v |= (div - 1) << SLEW_SYSDIV_SHIFT; in sclk_set_rate()
811 writel(v, sclk->slew_reg); in sclk_set_rate()
814 err = readl_poll_timeout_atomic(sclk->slew_reg, v, in sclk_set_rate()
817 spin_unlock_irqrestore(&sclk->core->reg_lock, flags); in sclk_set_rate()
827 v = (readl(sclk->mux_reg) >> OSC_CUR_SHIFT) & OSC_CUR_MASK; in sclk_get_parent()
829 if (!sclk->parent_map) in sclk_get_parent()
833 if (sclk->parent_map[i] == v) in sclk_get_parent()
835 return -EINVAL; in sclk_get_parent()
845 spin_lock_irqsave(&sclk->core->reg_lock, flags); in sclk_set_parent()
848 nosc = sclk->parent_map ? sclk->parent_map[index] : index; in sclk_set_parent()
851 v = readl(sclk->mux_reg); in sclk_set_parent()
857 writel(v, sclk->mux_reg); in sclk_set_parent()
860 writel(OSC_SWEN, PIC32_SET(sclk->mux_reg)); in sclk_set_parent()
863 /* add nop to flush pipeline (as cpu_clk is in-flux) */ in sclk_set_parent()
867 err = readl_poll_timeout_atomic(sclk->slew_reg, v, in sclk_set_parent()
870 spin_unlock_irqrestore(&sclk->core->reg_lock, flags); in sclk_set_parent()
873 * SCLK clock-switching logic might reject a clock switching request in sclk_set_parent()
874 * if pre-requisites (like new clk_src not present or unstable) are in sclk_set_parent()
878 cosc = (readl(sclk->mux_reg) >> OSC_CUR_SHIFT) & OSC_CUR_MASK; in sclk_set_parent()
882 err = -EBUSY; in sclk_set_parent()
894 /* Maintain reference to this clk, required in spll_clk_set_rate() */ in sclk_init()
898 if (sclk->slew_div) { in sclk_init()
899 spin_lock_irqsave(&sclk->core->reg_lock, flags); in sclk_init()
900 v = readl(sclk->slew_reg); in sclk_init()
902 v |= sclk->slew_div << SLEW_DIV_SHIFT; in sclk_init()
904 writel(v, sclk->slew_reg); in sclk_init()
905 spin_unlock_irqrestore(&sclk->core->reg_lock, flags); in sclk_init()
911 /* sclk with post-divider */
922 /* sclk with no slew and no post-divider */
930 struct clk *pic32_sys_clk_register(const struct pic32_sys_clk_data *data, in pic32_sys_clk_register()
931 struct pic32_clk_common *core) in pic32_sys_clk_register() argument
934 struct clk *clk; in pic32_sys_clk_register() local
936 sclk = devm_kzalloc(core->dev, sizeof(*sclk), GFP_KERNEL); in pic32_sys_clk_register()
938 return ERR_PTR(-ENOMEM); in pic32_sys_clk_register()
940 sclk->core = core; in pic32_sys_clk_register()
941 sclk->hw.init = &data->init_data; in pic32_sys_clk_register()
942 sclk->mux_reg = data->mux_reg + core->iobase; in pic32_sys_clk_register()
943 sclk->slew_reg = data->slew_reg + core->iobase; in pic32_sys_clk_register()
944 sclk->slew_div = data->slew_div; in pic32_sys_clk_register()
945 sclk->parent_map = data->parent_map; in pic32_sys_clk_register()
947 clk = devm_clk_register(core->dev, &sclk->hw); in pic32_sys_clk_register()
948 if (IS_ERR(clk)) in pic32_sys_clk_register()
949 dev_err(core->dev, "%s: clk register failed\n", __func__); in pic32_sys_clk_register()
951 return clk; in pic32_sys_clk_register()
962 struct pic32_clk_common *core; member
973 writel(sosc->enable_mask, PIC32_SET(sosc->enable_reg)); in sosc_clk_enable()
975 /* wait till warm-up period expires or ready-status is updated */ in sosc_clk_enable()
976 return readl_poll_timeout_atomic(sosc->status_reg, v, in sosc_clk_enable()
977 v & sosc->status_mask, 1, 100); in sosc_clk_enable()
985 writel(sosc->enable_mask, PIC32_CLR(sosc->enable_reg)); in sosc_clk_disable()
994 enabled = readl(sosc->enable_reg) & sosc->enable_mask; in sosc_clk_is_enabled()
995 ready = readl(sosc->status_reg) & sosc->status_mask; in sosc_clk_is_enabled()
1003 return clkhw_to_sosc(hw)->fixed_rate; in sosc_clk_calc_rate()
1013 struct clk *pic32_sosc_clk_register(const struct pic32_sec_osc_data *data, in pic32_sosc_clk_register()
1014 struct pic32_clk_common *core) in pic32_sosc_clk_register() argument
1018 sosc = devm_kzalloc(core->dev, sizeof(*sosc), GFP_KERNEL); in pic32_sosc_clk_register()
1020 return ERR_PTR(-ENOMEM); in pic32_sosc_clk_register()
1022 sosc->core = core; in pic32_sosc_clk_register()
1023 sosc->hw.init = &data->init_data; in pic32_sosc_clk_register()
1024 sosc->fixed_rate = data->fixed_rate; in pic32_sosc_clk_register()
1025 sosc->enable_mask = data->enable_mask; in pic32_sosc_clk_register()
1026 sosc->status_mask = data->status_mask; in pic32_sosc_clk_register()
1027 sosc->enable_reg = data->enable_reg + core->iobase; in pic32_sosc_clk_register()
1028 sosc->status_reg = data->status_reg + core->iobase; in pic32_sosc_clk_register()
1030 return devm_clk_register(core->dev, &sosc->hw); in pic32_sosc_clk_register()