Lines Matching +full:pll +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0-only
6 * VCO-PLL clock implementation
9 #define pr_fmt(fmt) "clk-vco-pll: " fmt
11 #include <linux/clk-provider.h>
18 * DOC: VCO-PLL clock
20 * VCO and PLL rate are derived from following equations:
22 * In normal mode
25 * In Dithered mode
28 * pll_rate = pll/2^p
30 * vco and pll are very closely bound to each other, "vco needs to program:
31 * mode, m & n" and "pll needs to program p", both share common enable/disable
34 * clk_register_vco_pll() registers instances of both vco & pll.
35 * CLK_SET_RATE_PARENT flag is forced for pll, as it will always pass its
52 /* PLL FRQ register masks */
65 /* Calculates pll clk rate for specific value of mode, m, n and p */
70 unsigned int mode; in pll_calc_rate() local
72 mode = rtbl[index].mode ? 256 : 1; in pll_calc_rate()
73 rate = (((2 * rate / 10000) * rtbl[index].m) / (mode * rtbl[index].n)); in pll_calc_rate()
84 struct clk_pll *pll = to_clk_pll(hw); in clk_pll_round_rate_index() local
90 pr_err("%s: prate is must for pll clk\n", __func__); in clk_pll_round_rate_index()
91 return -EINVAL; in clk_pll_round_rate_index()
94 for (*index = 0; *index < pll->vco->rtbl_cnt; (*index)++) { in clk_pll_round_rate_index()
97 *prate = pll_calc_rate(pll->vco->rtbl, vco_parent_rate, *index, in clk_pll_round_rate_index()
104 (*index)--; in clk_pll_round_rate_index()
124 struct clk_pll *pll = to_clk_pll(hw); in clk_pll_recalc_rate() local
128 if (pll->vco->lock) in clk_pll_recalc_rate()
129 spin_lock_irqsave(pll->vco->lock, flags); in clk_pll_recalc_rate()
131 p = readl_relaxed(pll->vco->cfg_reg); in clk_pll_recalc_rate()
133 if (pll->vco->lock) in clk_pll_recalc_rate()
134 spin_unlock_irqrestore(pll->vco->lock, flags); in clk_pll_recalc_rate()
144 struct clk_pll *pll = to_clk_pll(hw); in clk_pll_set_rate() local
145 struct pll_rate_tbl *rtbl = pll->vco->rtbl; in clk_pll_set_rate()
151 if (pll->vco->lock) in clk_pll_set_rate()
152 spin_lock_irqsave(pll->vco->lock, flags); in clk_pll_set_rate()
154 val = readl_relaxed(pll->vco->cfg_reg); in clk_pll_set_rate()
157 writel_relaxed(val, pll->vco->cfg_reg); in clk_pll_set_rate()
159 if (pll->vco->lock) in clk_pll_set_rate()
160 spin_unlock_irqrestore(pll->vco->lock, flags); in clk_pll_set_rate()
176 return pll_calc_rate(vco->rtbl, prate, index, NULL); in vco_calc_rate()
186 vco->rtbl_cnt, &unused); in clk_vco_round_rate()
194 unsigned int num = 2, den = 0, val, mode = 0; in clk_vco_recalc_rate() local
196 if (vco->lock) in clk_vco_recalc_rate()
197 spin_lock_irqsave(vco->lock, flags); in clk_vco_recalc_rate()
199 mode = (readl_relaxed(vco->mode_reg) >> PLL_MODE_SHIFT) & PLL_MODE_MASK; in clk_vco_recalc_rate()
201 val = readl_relaxed(vco->cfg_reg); in clk_vco_recalc_rate()
203 if (vco->lock) in clk_vco_recalc_rate()
204 spin_unlock_irqrestore(vco->lock, flags); in clk_vco_recalc_rate()
209 if (!mode) { in clk_vco_recalc_rate()
210 /* Normal mode */ in clk_vco_recalc_rate()
213 /* Dithered mode */ in clk_vco_recalc_rate()
231 struct pll_rate_tbl *rtbl = vco->rtbl; in clk_vco_set_rate()
235 clk_round_rate_index(hw, drate, prate, vco_calc_rate, vco->rtbl_cnt, in clk_vco_set_rate()
238 if (vco->lock) in clk_vco_set_rate()
239 spin_lock_irqsave(vco->lock, flags); in clk_vco_set_rate()
241 val = readl_relaxed(vco->mode_reg); in clk_vco_set_rate()
243 val |= (rtbl[i].mode & PLL_MODE_MASK) << PLL_MODE_SHIFT; in clk_vco_set_rate()
244 writel_relaxed(val, vco->mode_reg); in clk_vco_set_rate()
246 val = readl_relaxed(vco->cfg_reg); in clk_vco_set_rate()
251 if (rtbl[i].mode) in clk_vco_set_rate()
258 writel_relaxed(val, vco->cfg_reg); in clk_vco_set_rate()
260 if (vco->lock) in clk_vco_set_rate()
261 spin_unlock_irqrestore(vco->lock, flags); in clk_vco_set_rate()
280 struct clk_pll *pll; in clk_register_vco_pll() local
288 return ERR_PTR(-EINVAL); in clk_register_vco_pll()
293 return ERR_PTR(-ENOMEM); in clk_register_vco_pll()
295 pll = kzalloc(sizeof(*pll), GFP_KERNEL); in clk_register_vco_pll()
296 if (!pll) in clk_register_vco_pll()
300 vco->mode_reg = mode_reg; in clk_register_vco_pll()
301 vco->cfg_reg = cfg_reg; in clk_register_vco_pll()
302 vco->rtbl = rtbl; in clk_register_vco_pll()
303 vco->rtbl_cnt = rtbl_cnt; in clk_register_vco_pll()
304 vco->lock = lock; in clk_register_vco_pll()
305 vco->hw.init = &vco_init; in clk_register_vco_pll()
307 pll->vco = vco; in clk_register_vco_pll()
308 pll->hw.init = &pll_init; in clk_register_vco_pll()
335 vco_clk = clk_register(NULL, &vco->hw); in clk_register_vco_pll()
339 tpll_clk = clk_register(NULL, &pll->hw); in clk_register_vco_pll()
349 kfree(pll); in clk_register_vco_pll()
353 pr_err("Failed to register vco pll clock\n"); in clk_register_vco_pll()
355 return ERR_PTR(-ENOMEM); in clk_register_vco_pll()