Lines Matching +full:pll +full:- +full:0
1 // SPDX-License-Identifier: GPL-2.0-or-later
15 #include <linux/clk-provider.h>
24 * PLL configuration register bits for PLL3200 C32
26 #define C32_NDIV_MASK (0xff)
27 #define C32_IDF_MASK (0x7)
28 #define C32_ODF_MASK (0x3f)
29 #define C32_LDF_MASK (0x7f)
30 #define C32_CP_MASK (0x1f)
35 * PLL configuration register bits for PLL4600 C28
37 #define C28_NDIV_MASK (0xff)
38 #define C28_IDF_MASK (0x7)
39 #define C28_ODF_MASK (0x3f)
77 .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8),
78 .pdn_ctrl = CLKGEN_FIELD(0x2a0, 0x1, 8),
79 .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24),
80 .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16),
81 .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0),
83 .odf = { CLKGEN_FIELD(0x2b4, C32_ODF_MASK, 0) },
84 .odf_gate = { CLKGEN_FIELD(0x2b4, 0x1, 6) },
93 { .name = "clk-s-a0-pll-odf-0", },
102 { .name = "clk-s-c0-pll0-odf-0", },
112 .pdn_status = CLKGEN_FIELD(0x2c8, 0x1, 8),
113 .pdn_ctrl = CLKGEN_FIELD(0x2c8, 0x1, 8),
114 .locked_status = CLKGEN_FIELD(0x2c8, 0x1, 24),
115 .ndiv = CLKGEN_FIELD(0x2cc, C32_NDIV_MASK, 16),
116 .idf = CLKGEN_FIELD(0x2cc, C32_IDF_MASK, 0x0),
118 .odf = { CLKGEN_FIELD(0x2dc, C32_ODF_MASK, 0) },
119 .odf_gate = { CLKGEN_FIELD(0x2dc, 0x1, 6) },
128 { .name = "clk-s-c0-pll1-odf-0", },
138 .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0),
139 .pdn_ctrl = CLKGEN_FIELD(0x1a8, 0x1, 0),
140 .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0),
141 .ndiv = CLKGEN_FIELD(0x1b0, C32_NDIV_MASK, 0),
142 .idf = CLKGEN_FIELD(0x1a8, C32_IDF_MASK, 25),
144 .odf = { CLKGEN_FIELD(0x1b0, C32_ODF_MASK, 8) },
145 .odf_gate = { CLKGEN_FIELD(0x1ac, 0x1, 28) },
147 .cp = CLKGEN_FIELD(0x1a8, C32_CP_MASK, 1),
148 .switch2pll = CLKGEN_FIELD(0x1a4, 0x1, 1),
154 { .name = "clockgen-a9-pll-odf", },
164 .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0),
165 .pdn_ctrl = CLKGEN_FIELD(0x1a8, 0x1, 0),
166 .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0),
167 .ndiv = CLKGEN_FIELD(0x1b0, C28_NDIV_MASK, 0),
168 .idf = CLKGEN_FIELD(0x1a8, C28_IDF_MASK, 25),
170 .odf = { CLKGEN_FIELD(0x1b0, C28_ODF_MASK, 8) },
171 .odf_gate = { CLKGEN_FIELD(0x1ac, 0x1, 28) },
173 .switch2pll = CLKGEN_FIELD(0x1a4, 0x1, 1),
179 { .name = "clockgen-a9-pll-odf", },
188 * DOC: Clock Generated by PLL, rate set and enabled by bootloader
191 * prepare - clk_(un)prepare only ensures parent is (un)prepared
192 * enable - clk_enable/disable only ensures parent is enabled
193 * rate - rate is fixed. No clk_set_rate support
194 * parent - fixed parent. No clk_set_parent support
198 * PLL clock that is integrated in the ClockGenA instances on the STiH415
201 * @hw: handle between common and hardware-specific interfaces.
202 * @regs_base: base of the PLL configuration register(s).
230 struct clkgen_pll *pll = to_clkgen_pll(hw); in clkgen_pll_is_locked() local
231 u32 locked = CLKGEN_READ(pll, locked_status); in clkgen_pll_is_locked()
238 struct clkgen_pll *pll = to_clkgen_pll(hw); in clkgen_pll_is_enabled() local
239 u32 poweroff = CLKGEN_READ(pll, pdn_status); in clkgen_pll_is_enabled()
245 struct clkgen_pll *pll = to_clkgen_pll(hw); in __clkgen_pll_enable() local
246 void __iomem *base = pll->regs_base; in __clkgen_pll_enable()
247 struct clkgen_field *field = &pll->data->locked_status; in __clkgen_pll_enable()
248 int ret = 0; in __clkgen_pll_enable()
252 return 0; in __clkgen_pll_enable()
254 CLKGEN_WRITE(pll, pdn_ctrl, 0); in __clkgen_pll_enable()
256 ret = readl_relaxed_poll_timeout(base + field->offset, reg, in __clkgen_pll_enable()
257 !!((reg >> field->shift) & field->mask), 0, 10000); in __clkgen_pll_enable()
260 if (pll->data->switch2pll_en) in __clkgen_pll_enable()
261 CLKGEN_WRITE(pll, switch2pll, 0); in __clkgen_pll_enable()
263 pr_debug("%s:%s enabled\n", __clk_get_name(hw->clk), __func__); in __clkgen_pll_enable()
271 struct clkgen_pll *pll = to_clkgen_pll(hw); in clkgen_pll_enable() local
272 unsigned long flags = 0; in clkgen_pll_enable()
273 int ret = 0; in clkgen_pll_enable()
275 if (pll->lock) in clkgen_pll_enable()
276 spin_lock_irqsave(pll->lock, flags); in clkgen_pll_enable()
280 if (pll->lock) in clkgen_pll_enable()
281 spin_unlock_irqrestore(pll->lock, flags); in clkgen_pll_enable()
288 struct clkgen_pll *pll = to_clkgen_pll(hw); in __clkgen_pll_disable() local
293 if (pll->data->switch2pll_en) in __clkgen_pll_disable()
294 CLKGEN_WRITE(pll, switch2pll, 1); in __clkgen_pll_disable()
296 CLKGEN_WRITE(pll, pdn_ctrl, 1); in __clkgen_pll_disable()
298 pr_debug("%s:%s disabled\n", __clk_get_name(hw->clk), __func__); in __clkgen_pll_disable()
303 struct clkgen_pll *pll = to_clkgen_pll(hw); in clkgen_pll_disable() local
304 unsigned long flags = 0; in clkgen_pll_disable()
306 if (pll->lock) in clkgen_pll_disable()
307 spin_lock_irqsave(pll->lock, flags); in clkgen_pll_disable()
311 if (pll->lock) in clkgen_pll_disable()
312 spin_unlock_irqrestore(pll->lock, flags); in clkgen_pll_disable()
316 struct stm_pll *pll) in clk_pll3200c32_get_params() argument
319 unsigned long deviation = ~0; in clk_pll3200c32_get_params()
330 return -EINVAL; in clk_pll3200c32_get_params()
346 new_deviation = abs(new_freq - output); in clk_pll3200c32_get_params()
349 pll->idf = i; in clk_pll3200c32_get_params()
350 pll->ndiv = n; in clk_pll3200c32_get_params()
355 if (deviation == ~0) /* No solution found */ in clk_pll3200c32_get_params()
356 return -EINVAL; in clk_pll3200c32_get_params()
359 for (pll->cp = 6; pll->ndiv > cp_table[pll->cp-6]; (pll->cp)++) in clk_pll3200c32_get_params()
362 return 0; in clk_pll3200c32_get_params()
365 static int clk_pll3200c32_get_rate(unsigned long input, struct stm_pll *pll, in clk_pll3200c32_get_rate() argument
368 if (!pll->idf) in clk_pll3200c32_get_rate()
369 pll->idf = 1; in clk_pll3200c32_get_rate()
371 *rate = ((2 * (input / 1000) * pll->ndiv) / pll->idf) * 1000; in clk_pll3200c32_get_rate()
373 return 0; in clk_pll3200c32_get_rate()
379 struct clkgen_pll *pll = to_clkgen_pll(hw); in recalc_stm_pll3200c32() local
381 unsigned long rate = 0; in recalc_stm_pll3200c32()
384 return 0; in recalc_stm_pll3200c32()
386 ndiv = CLKGEN_READ(pll, ndiv); in recalc_stm_pll3200c32()
387 idf = CLKGEN_READ(pll, idf); in recalc_stm_pll3200c32()
407 __clk_get_name(hw->clk), rate); in round_rate_stm_pll3200c32()
408 return 0; in round_rate_stm_pll3200c32()
412 __func__, __clk_get_name(hw->clk), in round_rate_stm_pll3200c32()
422 struct clkgen_pll *pll = to_clkgen_pll(hw); in set_rate_stm_pll3200c32() local
424 long hwrate = 0; in set_rate_stm_pll3200c32()
425 unsigned long flags = 0; in set_rate_stm_pll3200c32()
428 return -EINVAL; in set_rate_stm_pll3200c32()
433 pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n", in set_rate_stm_pll3200c32()
434 __func__, __clk_get_name(hw->clk), in set_rate_stm_pll3200c32()
439 return -EINVAL; in set_rate_stm_pll3200c32()
441 pll->ndiv = params.ndiv; in set_rate_stm_pll3200c32()
442 pll->idf = params.idf; in set_rate_stm_pll3200c32()
443 pll->cp = params.cp; in set_rate_stm_pll3200c32()
447 if (pll->lock) in set_rate_stm_pll3200c32()
448 spin_lock_irqsave(pll->lock, flags); in set_rate_stm_pll3200c32()
450 CLKGEN_WRITE(pll, ndiv, pll->ndiv); in set_rate_stm_pll3200c32()
451 CLKGEN_WRITE(pll, idf, pll->idf); in set_rate_stm_pll3200c32()
452 CLKGEN_WRITE(pll, cp, pll->cp); in set_rate_stm_pll3200c32()
454 if (pll->lock) in set_rate_stm_pll3200c32()
455 spin_unlock_irqrestore(pll->lock, flags); in set_rate_stm_pll3200c32()
459 return 0; in set_rate_stm_pll3200c32()
462 /* PLL output structure
477 struct stm_pll *pll) in clk_pll4600c28_get_params() argument
481 unsigned long deviation = ~0; in clk_pll4600c28_get_params()
486 return -EINVAL; in clk_pll4600c28_get_params()
501 for (; n >= 8 && deviation; n--) { in clk_pll4600c28_get_params()
506 new_deviation = new_freq - output; in clk_pll4600c28_get_params()
508 pll->idf = i; in clk_pll4600c28_get_params()
509 pll->ndiv = n; in clk_pll4600c28_get_params()
515 if (deviation == ~0) /* No solution found */ in clk_pll4600c28_get_params()
516 return -EINVAL; in clk_pll4600c28_get_params()
518 return 0; in clk_pll4600c28_get_params()
521 static int clk_pll4600c28_get_rate(unsigned long input, struct stm_pll *pll, in clk_pll4600c28_get_rate() argument
524 if (!pll->idf) in clk_pll4600c28_get_rate()
525 pll->idf = 1; in clk_pll4600c28_get_rate()
527 *rate = (input / pll->idf) * 2 * pll->ndiv; in clk_pll4600c28_get_rate()
529 return 0; in clk_pll4600c28_get_rate()
535 struct clkgen_pll *pll = to_clkgen_pll(hw); in recalc_stm_pll4600c28() local
540 return 0; in recalc_stm_pll4600c28()
542 params.ndiv = CLKGEN_READ(pll, ndiv); in recalc_stm_pll4600c28()
543 params.idf = CLKGEN_READ(pll, idf); in recalc_stm_pll4600c28()
547 pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate); in recalc_stm_pll4600c28()
561 __clk_get_name(hw->clk), rate); in round_rate_stm_pll4600c28()
562 return 0; in round_rate_stm_pll4600c28()
566 __func__, __clk_get_name(hw->clk), in round_rate_stm_pll4600c28()
576 struct clkgen_pll *pll = to_clkgen_pll(hw); in set_rate_stm_pll4600c28() local
579 unsigned long flags = 0; in set_rate_stm_pll4600c28()
582 return -EINVAL; in set_rate_stm_pll4600c28()
588 __clk_get_name(hw->clk), rate); in set_rate_stm_pll4600c28()
589 return -EINVAL; in set_rate_stm_pll4600c28()
592 pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n", in set_rate_stm_pll4600c28()
593 __func__, __clk_get_name(hw->clk), in set_rate_stm_pll4600c28()
598 return -EINVAL; in set_rate_stm_pll4600c28()
600 pll->ndiv = params.ndiv; in set_rate_stm_pll4600c28()
601 pll->idf = params.idf; in set_rate_stm_pll4600c28()
605 if (pll->lock) in set_rate_stm_pll4600c28()
606 spin_lock_irqsave(pll->lock, flags); in set_rate_stm_pll4600c28()
608 CLKGEN_WRITE(pll, ndiv, pll->ndiv); in set_rate_stm_pll4600c28()
609 CLKGEN_WRITE(pll, idf, pll->idf); in set_rate_stm_pll4600c28()
611 if (pll->lock) in set_rate_stm_pll4600c28()
612 spin_unlock_irqrestore(pll->lock, flags); in set_rate_stm_pll4600c28()
616 return 0; in set_rate_stm_pll4600c28()
649 struct clkgen_pll *pll; in clkgen_pll_register() local
653 pll = kzalloc(sizeof(*pll), GFP_KERNEL); in clkgen_pll_register()
654 if (!pll) in clkgen_pll_register()
655 return ERR_PTR(-ENOMEM); in clkgen_pll_register()
658 init.ops = pll_data->ops; in clkgen_pll_register()
664 pll->data = pll_data; in clkgen_pll_register()
665 pll->regs_base = reg; in clkgen_pll_register()
666 pll->hw.init = &init; in clkgen_pll_register()
667 pll->lock = lock; in clkgen_pll_register()
669 clk = clk_register(NULL, &pll->hw); in clkgen_pll_register()
671 kfree(pll); in clkgen_pll_register()
693 reg = of_iomap(pnode, 0); in clkgen_get_register_base()
715 return ERR_PTR(-ENOMEM); in clkgen_odf_register()
717 gate->flags = CLK_GATE_SET_TO_DISABLE; in clkgen_odf_register()
718 gate->reg = reg + pll_data->odf_gate[odf].offset; in clkgen_odf_register()
719 gate->bit_idx = pll_data->odf_gate[odf].shift; in clkgen_odf_register()
720 gate->lock = odf_lock; in clkgen_odf_register()
725 return ERR_PTR(-ENOMEM); in clkgen_odf_register()
728 div->flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO; in clkgen_odf_register()
729 div->reg = reg + pll_data->odf[odf].offset; in clkgen_odf_register()
730 div->shift = pll_data->odf[odf].shift; in clkgen_odf_register()
731 div->width = fls(pll_data->odf[odf].mask); in clkgen_odf_register()
732 div->lock = odf_lock; in clkgen_odf_register()
736 &div->hw, &clk_divider_ops, in clkgen_odf_register()
737 &gate->hw, &clk_gate_ops, in clkgen_odf_register()
758 unsigned long pll_flags = 0; in clkgen_c32_pll_setup()
761 parent_name = of_clk_get_parent_name(np, 0); in clkgen_c32_pll_setup()
769 of_clk_detect_critical(np, 0, &pll_flags); in clkgen_c32_pll_setup()
771 clk = clkgen_pll_register(parent_name, datac->data, pll_base, pll_flags, in clkgen_c32_pll_setup()
772 np->name, datac->data->lock); in clkgen_c32_pll_setup()
778 num_odfs = datac->data->num_odfs; in clkgen_c32_pll_setup()
784 clk_data->clk_num = num_odfs; in clkgen_c32_pll_setup()
785 clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), in clkgen_c32_pll_setup()
788 if (!clk_data->clks) in clkgen_c32_pll_setup()
791 for (odf = 0; odf < num_odfs; odf++) { in clkgen_c32_pll_setup()
794 unsigned long odf_flags = 0; in clkgen_c32_pll_setup()
796 if (datac->outputs) { in clkgen_c32_pll_setup()
797 clk_name = datac->outputs[odf].name; in clkgen_c32_pll_setup()
798 odf_flags = datac->outputs[odf].flags; in clkgen_c32_pll_setup()
801 "clock-output-names", in clkgen_c32_pll_setup()
808 clk = clkgen_odf_register(pll_name, pll_base, datac->data, in clkgen_c32_pll_setup()
814 clk_data->clks[odf] = clk; in clkgen_c32_pll_setup()
822 kfree(clk_data->clks); in clkgen_c32_pll_setup()
830 CLK_OF_DECLARE(c32_pll0, "st,clkgen-pll0", clkgen_c32_pll0_setup);
837 CLK_OF_DECLARE(c32_pll0_a0, "st,clkgen-pll0-a0", clkgen_c32_pll0_a0_setup);
844 CLK_OF_DECLARE(c32_pll0_c0, "st,clkgen-pll0-c0", clkgen_c32_pll0_c0_setup);
851 CLK_OF_DECLARE(c32_pll1, "st,clkgen-pll1", clkgen_c32_pll1_setup);
858 CLK_OF_DECLARE(c32_pll1_c0, "st,clkgen-pll1-c0", clkgen_c32_pll1_c0_setup);
865 CLK_OF_DECLARE(c32_plla9, "st,stih407-clkgen-plla9", clkgen_c32_plla9_setup);
872 CLK_OF_DECLARE(c28_plla9, "st,stih418-clkgen-plla9", clkgen_c28_plla9_setup);