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()
174 err = readl_poll_timeout(pb->ctrl_reg, v, v & PB_DIV_READY, in pbclk_set_rate()
182 spin_lock_irqsave(&pb->core->reg_lock, flags); in pbclk_set_rate()
185 v = readl(pb->ctrl_reg); in pbclk_set_rate()
187 v |= (div - 1); in pbclk_set_rate()
191 writel(v, pb->ctrl_reg); in pbclk_set_rate()
193 spin_unlock_irqrestore(&pb->core->reg_lock, flags); in pbclk_set_rate()
196 err = readl_poll_timeout(pb->ctrl_reg, v, v & PB_DIV_READY, in pbclk_set_rate()
202 return (pbclk_read_pbdiv(pb) == div) ? 0 : -EBUSY; in pbclk_set_rate()
214 struct clk *pic32_periph_clk_register(const struct pic32_periph_clk_data *desc, in pic32_periph_clk_register()
215 struct pic32_clk_common *core) in pic32_periph_clk_register() argument
218 struct clk *clk; in pic32_periph_clk_register() local
220 pbclk = devm_kzalloc(core->dev, sizeof(*pbclk), GFP_KERNEL); in pic32_periph_clk_register()
222 return ERR_PTR(-ENOMEM); in pic32_periph_clk_register()
224 pbclk->hw.init = &desc->init_data; in pic32_periph_clk_register()
225 pbclk->core = core; in pic32_periph_clk_register()
226 pbclk->ctrl_reg = desc->ctrl_reg + core->iobase; in pic32_periph_clk_register()
228 clk = devm_clk_register(core->dev, &pbclk->hw); in pic32_periph_clk_register()
229 if (IS_ERR(clk)) { in pic32_periph_clk_register()
230 dev_err(core->dev, "%s: clk_register() failed\n", __func__); in pic32_periph_clk_register()
231 devm_kfree(core->dev, pbclk); in pic32_periph_clk_register()
234 return clk; in pic32_periph_clk_register()
242 struct pic32_clk_common *core; member
251 return readl(refo->ctrl_reg) & REFO_ON; in roclk_is_enabled()
258 writel(REFO_ON | REFO_OE, PIC32_SET(refo->ctrl_reg)); in roclk_enable()
266 writel(REFO_ON | REFO_OE, PIC32_CLR(refo->ctrl_reg)); in roclk_disable()
282 v = (readl(refo->ctrl_reg) >> REFO_SEL_SHIFT) & REFO_SEL_MASK; in roclk_get_parent()
284 if (!refo->parent_map) in roclk_get_parent()
288 if (refo->parent_map[i] == v) in roclk_get_parent()
291 return -EINVAL; in roclk_get_parent()
324 /* Find integer approximation of floating-point arithmetic. in roclk_calc_div_trim()
329 * Since kernel does not perform floating-point arithmatic so in roclk_calc_div_trim()
333 * ie. rotrim = ((fin * 256) / fout) - (512 * DIV) in roclk_calc_div_trim()
345 frac -= (u64)(div << 9); in roclk_calc_div_trim()
365 v = readl(refo->ctrl_reg); in roclk_recalc_rate()
369 v = readl(refo->ctrl_reg + REFO_TRIM_REG); in roclk_recalc_rate()
391 unsigned int i, delta, best_delta = -1; in roclk_determine_rate()
404 if (req->rate > parent_rate) in roclk_determine_rate()
407 nearest_rate = roclk_round_rate(hw, req->rate, &parent_rate); in roclk_determine_rate()
408 delta = abs(nearest_rate - req->rate); in roclk_determine_rate()
409 if ((nearest_rate >= req->rate) && (delta < best_delta)) { in roclk_determine_rate()
423 __func__, clk_hw_get_name(hw), req->rate); in roclk_determine_rate()
428 clk_hw_get_name(hw), req->rate, in roclk_determine_rate()
432 if (req->best_parent_rate) in roclk_determine_rate()
433 req->best_parent_rate = best_parent_rate; in roclk_determine_rate()
435 if (req->best_parent_hw) in roclk_determine_rate()
436 req->best_parent_hw = best_parent_clk; in roclk_determine_rate()
448 if (refo->parent_map) in roclk_set_parent()
449 index = refo->parent_map[index]; in roclk_set_parent()
452 err = readl_poll_timeout(refo->ctrl_reg, v, !(v & REFO_ACTIVE), in roclk_set_parent()
455 pr_err("%s: poll failed, clk active\n", clk_hw_get_name(hw)); in roclk_set_parent()
459 spin_lock_irqsave(&refo->core->reg_lock, flags); in roclk_set_parent()
464 v = readl(refo->ctrl_reg); in roclk_set_parent()
468 writel(v, refo->ctrl_reg); in roclk_set_parent()
470 spin_unlock_irqrestore(&refo->core->reg_lock, flags); in roclk_set_parent()
492 err = readl_poll_timeout(refo->ctrl_reg, v, in roclk_set_rate_and_parent()
500 spin_lock_irqsave(&refo->core->reg_lock, flags); in roclk_set_rate_and_parent()
501 v = readl(refo->ctrl_reg); in roclk_set_rate_and_parent()
506 if (refo->parent_map) in roclk_set_rate_and_parent()
507 index = refo->parent_map[index]; in roclk_set_rate_and_parent()
515 writel(v, refo->ctrl_reg); in roclk_set_rate_and_parent()
518 v = readl(refo->ctrl_reg + REFO_TRIM_REG); in roclk_set_rate_and_parent()
521 writel(v, refo->ctrl_reg + REFO_TRIM_REG); in roclk_set_rate_and_parent()
524 writel(REFO_ON | REFO_DIVSW_EN, PIC32_SET(refo->ctrl_reg)); in roclk_set_rate_and_parent()
526 /* wait till divswen is in-progress */ in roclk_set_rate_and_parent()
527 err = readl_poll_timeout_atomic(refo->ctrl_reg, v, !(v & REFO_DIVSW_EN), in roclk_set_rate_and_parent()
529 /* leave the clk gated as it was */ in roclk_set_rate_and_parent()
530 writel(REFO_ON, PIC32_CLR(refo->ctrl_reg)); in roclk_set_rate_and_parent()
532 spin_unlock_irqrestore(&refo->core->reg_lock, flags); in roclk_set_rate_and_parent()
558 struct clk *pic32_refo_clk_register(const struct pic32_ref_osc_data *data, in pic32_refo_clk_register()
559 struct pic32_clk_common *core) in pic32_refo_clk_register() argument
562 struct clk *clk; in pic32_refo_clk_register() local
564 refo = devm_kzalloc(core->dev, sizeof(*refo), GFP_KERNEL); in pic32_refo_clk_register()
566 return ERR_PTR(-ENOMEM); in pic32_refo_clk_register()
568 refo->core = core; in pic32_refo_clk_register()
569 refo->hw.init = &data->init_data; in pic32_refo_clk_register()
570 refo->ctrl_reg = data->ctrl_reg + core->iobase; in pic32_refo_clk_register()
571 refo->parent_map = data->parent_map; in pic32_refo_clk_register()
573 clk = devm_clk_register(core->dev, &refo->hw); in pic32_refo_clk_register()
574 if (IS_ERR(clk)) in pic32_refo_clk_register()
575 dev_err(core->dev, "%s: clk_register() failed\n", __func__); in pic32_refo_clk_register()
577 return clk; in pic32_refo_clk_register()
586 struct pic32_clk_common *core; member
605 unsigned int best_delta = -1, delta, match_found = 0; in spll_calc_mult_div()
608 parent_rate /= pll->idiv; in spll_calc_mult_div()
616 delta = abs(rate - new_rate); in spll_calc_mult_div()
636 *mult_p = best_mul - 1; in spll_calc_mult_div()
652 v = readl(pll->ctrl_reg); in spll_clk_recalc_rate()
660 pll_in_rate = parent_rate / pll->idiv; in spll_clk_recalc_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()
799 spin_lock_irqsave(&sclk->core->reg_lock, flags); in sclk_set_rate()
802 v = readl(sclk->slew_reg); in sclk_set_rate()
804 v |= (div - 1) << SLEW_SYSDIV_SHIFT; in sclk_set_rate()
808 writel(v, sclk->slew_reg); in sclk_set_rate()
811 err = readl_poll_timeout_atomic(sclk->slew_reg, v, in sclk_set_rate()
814 spin_unlock_irqrestore(&sclk->core->reg_lock, flags); in sclk_set_rate()
824 v = (readl(sclk->mux_reg) >> OSC_CUR_SHIFT) & OSC_CUR_MASK; in sclk_get_parent()
826 if (!sclk->parent_map) in sclk_get_parent()
830 if (sclk->parent_map[i] == v) in sclk_get_parent()
832 return -EINVAL; in sclk_get_parent()
842 spin_lock_irqsave(&sclk->core->reg_lock, flags); in sclk_set_parent()
845 nosc = sclk->parent_map ? sclk->parent_map[index] : index; in sclk_set_parent()
848 v = readl(sclk->mux_reg); in sclk_set_parent()
854 writel(v, sclk->mux_reg); in sclk_set_parent()
857 writel(OSC_SWEN, PIC32_SET(sclk->mux_reg)); in sclk_set_parent()
860 /* add nop to flush pipeline (as cpu_clk is in-flux) */ in sclk_set_parent()
864 err = readl_poll_timeout_atomic(sclk->slew_reg, v, in sclk_set_parent()
867 spin_unlock_irqrestore(&sclk->core->reg_lock, flags); in sclk_set_parent()
870 * SCLK clock-switching logic might reject a clock switching request in sclk_set_parent()
871 * if pre-requisites (like new clk_src not present or unstable) are in sclk_set_parent()
875 cosc = (readl(sclk->mux_reg) >> OSC_CUR_SHIFT) & OSC_CUR_MASK; in sclk_set_parent()
879 err = -EBUSY; in sclk_set_parent()
891 /* Maintain reference to this clk, required in spll_clk_set_rate() */ in sclk_init()
895 if (sclk->slew_div) { in sclk_init()
896 spin_lock_irqsave(&sclk->core->reg_lock, flags); in sclk_init()
897 v = readl(sclk->slew_reg); in sclk_init()
899 v |= sclk->slew_div << SLEW_DIV_SHIFT; in sclk_init()
901 writel(v, sclk->slew_reg); in sclk_init()
902 spin_unlock_irqrestore(&sclk->core->reg_lock, flags); in sclk_init()
908 /* sclk with post-divider */
919 /* sclk with no slew and no post-divider */
927 struct clk *pic32_sys_clk_register(const struct pic32_sys_clk_data *data, in pic32_sys_clk_register()
928 struct pic32_clk_common *core) in pic32_sys_clk_register() argument
931 struct clk *clk; in pic32_sys_clk_register() local
933 sclk = devm_kzalloc(core->dev, sizeof(*sclk), GFP_KERNEL); in pic32_sys_clk_register()
935 return ERR_PTR(-ENOMEM); in pic32_sys_clk_register()
937 sclk->core = core; in pic32_sys_clk_register()
938 sclk->hw.init = &data->init_data; in pic32_sys_clk_register()
939 sclk->mux_reg = data->mux_reg + core->iobase; in pic32_sys_clk_register()
940 sclk->slew_reg = data->slew_reg + core->iobase; in pic32_sys_clk_register()
941 sclk->slew_div = data->slew_div; in pic32_sys_clk_register()
942 sclk->parent_map = data->parent_map; in pic32_sys_clk_register()
944 clk = devm_clk_register(core->dev, &sclk->hw); in pic32_sys_clk_register()
945 if (IS_ERR(clk)) in pic32_sys_clk_register()
946 dev_err(core->dev, "%s: clk register failed\n", __func__); in pic32_sys_clk_register()
948 return clk; in pic32_sys_clk_register()
959 struct pic32_clk_common *core; member
970 writel(sosc->enable_mask, PIC32_SET(sosc->enable_reg)); in sosc_clk_enable()
972 /* wait till warm-up period expires or ready-status is updated */ in sosc_clk_enable()
973 return readl_poll_timeout_atomic(sosc->status_reg, v, in sosc_clk_enable()
974 v & sosc->status_mask, 1, 100); in sosc_clk_enable()
982 writel(sosc->enable_mask, PIC32_CLR(sosc->enable_reg)); in sosc_clk_disable()
991 enabled = readl(sosc->enable_reg) & sosc->enable_mask; in sosc_clk_is_enabled()
992 ready = readl(sosc->status_reg) & sosc->status_mask; in sosc_clk_is_enabled()
1000 return clkhw_to_sosc(hw)->fixed_rate; in sosc_clk_calc_rate()
1010 struct clk *pic32_sosc_clk_register(const struct pic32_sec_osc_data *data, in pic32_sosc_clk_register()
1011 struct pic32_clk_common *core) in pic32_sosc_clk_register() argument
1015 sosc = devm_kzalloc(core->dev, sizeof(*sosc), GFP_KERNEL); in pic32_sosc_clk_register()
1017 return ERR_PTR(-ENOMEM); in pic32_sosc_clk_register()
1019 sosc->core = core; in pic32_sosc_clk_register()
1020 sosc->hw.init = &data->init_data; in pic32_sosc_clk_register()
1021 sosc->fixed_rate = data->fixed_rate; in pic32_sosc_clk_register()
1022 sosc->enable_mask = data->enable_mask; in pic32_sosc_clk_register()
1023 sosc->status_mask = data->status_mask; in pic32_sosc_clk_register()
1024 sosc->enable_reg = data->enable_reg + core->iobase; in pic32_sosc_clk_register()
1025 sosc->status_reg = data->status_reg + core->iobase; in pic32_sosc_clk_register()
1027 return devm_clk_register(core->dev, &sosc->hw); in pic32_sosc_clk_register()