Lines Matching +full:pll +full:- +full:0

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Toshiba Visconti PLL driver
12 #include <linux/clk-provider.h>
17 #include "pll.h"
29 #define PLL_CONF_REG 0x0000
30 #define PLL_CTRL_REG 0x0004
31 #define PLL_FRACMODE_REG 0x0010
32 #define PLL_INTIN_REG 0x0014
33 #define PLL_FRACIN_REG 0x0018
34 #define PLL_REFDIV_REG 0x001c
35 #define PLL_POSTDIV_REG 0x0020
37 #define PLL_CONFIG_SEL BIT(0)
40 #define PLL_INTIN_MASK GENMASK(11, 0)
41 #define PLL_FRACIN_MASK GENMASK(23, 0)
42 #define PLL_REFDIV_MASK GENMASK(5, 0)
43 #define PLL_POSTDIV_MASK GENMASK(2, 0)
46 #define PLL0_FRACMODE_DSMEN BIT(0)
48 #define PLL_CREATE_FRACMODE(table) (table->dacen << 4 | table->dsmen)
49 #define PLL_CREATE_OSTDIV(table) (table->postdiv2 << 4 | table->postdiv1)
56 static void visconti_pll_get_params(struct visconti_pll *pll, in visconti_pll_get_params() argument
61 val = readl(pll->pll_base + PLL_FRACMODE_REG); in visconti_pll_get_params()
63 rate_table->dacen = FIELD_GET(PLL0_FRACMODE_DACEN, val); in visconti_pll_get_params()
64 rate_table->dsmen = FIELD_GET(PLL0_FRACMODE_DSMEN, val); in visconti_pll_get_params()
66 rate_table->fracin = readl(pll->pll_base + PLL_FRACIN_REG) & PLL_FRACIN_MASK; in visconti_pll_get_params()
67 rate_table->intin = readl(pll->pll_base + PLL_INTIN_REG) & PLL_INTIN_MASK; in visconti_pll_get_params()
68 rate_table->refdiv = readl(pll->pll_base + PLL_REFDIV_REG) & PLL_REFDIV_MASK; in visconti_pll_get_params()
70 postdiv = readl(pll->pll_base + PLL_POSTDIV_REG); in visconti_pll_get_params()
71 rate_table->postdiv1 = postdiv & PLL_POSTDIV_MASK; in visconti_pll_get_params()
72 rate_table->postdiv2 = (postdiv >> 4) & PLL_POSTDIV_MASK; in visconti_pll_get_params()
75 static const struct visconti_pll_rate_table *visconti_get_pll_settings(struct visconti_pll *pll, in visconti_get_pll_settings() argument
78 const struct visconti_pll_rate_table *rate_table = pll->rate_table; in visconti_get_pll_settings()
81 for (i = 0; i < pll->rate_count; i++) in visconti_get_pll_settings()
88 static unsigned long visconti_get_pll_rate_from_data(struct visconti_pll *pll, in visconti_get_pll_rate_from_data() argument
91 const struct visconti_pll_rate_table *rate_table = pll->rate_table; in visconti_get_pll_rate_from_data()
94 for (i = 0; i < pll->rate_count; i++) in visconti_get_pll_rate_from_data()
95 if (memcmp(&rate_table[i].dacen, &rate->dacen, in visconti_get_pll_rate_from_data()
96 sizeof(*rate) - sizeof(unsigned long)) == 0) in visconti_get_pll_rate_from_data()
100 return rate_table[0].rate; in visconti_get_pll_rate_from_data()
106 struct visconti_pll *pll = to_visconti_pll(hw); in visconti_pll_determine_rate() local
107 const struct visconti_pll_rate_table *rate_table = pll->rate_table; in visconti_pll_determine_rate()
111 for (i = 0; i < pll->rate_count; i++) in visconti_pll_determine_rate()
112 if (req->rate >= rate_table[i].rate) { in visconti_pll_determine_rate()
113 req->rate = rate_table[i].rate; in visconti_pll_determine_rate()
115 return 0; in visconti_pll_determine_rate()
119 req->rate = rate_table[i - 1].rate; in visconti_pll_determine_rate()
121 return 0; in visconti_pll_determine_rate()
127 struct visconti_pll *pll = to_visconti_pll(hw); in visconti_pll_recalc_rate() local
130 memset(&rate_table, 0, sizeof(rate_table)); in visconti_pll_recalc_rate()
131 visconti_pll_get_params(pll, &rate_table); in visconti_pll_recalc_rate()
133 return visconti_get_pll_rate_from_data(pll, &rate_table); in visconti_pll_recalc_rate()
136 static int visconti_pll_set_params(struct visconti_pll *pll, in visconti_pll_set_params() argument
139 writel(PLL_CREATE_FRACMODE(rate_table), pll->pll_base + PLL_FRACMODE_REG); in visconti_pll_set_params()
140 writel(PLL_CREATE_OSTDIV(rate_table), pll->pll_base + PLL_POSTDIV_REG); in visconti_pll_set_params()
141 writel(rate_table->intin, pll->pll_base + PLL_INTIN_REG); in visconti_pll_set_params()
142 writel(rate_table->fracin, pll->pll_base + PLL_FRACIN_REG); in visconti_pll_set_params()
143 writel(rate_table->refdiv, pll->pll_base + PLL_REFDIV_REG); in visconti_pll_set_params()
145 return 0; in visconti_pll_set_params()
151 struct visconti_pll *pll = to_visconti_pll(hw); in visconti_pll_set_rate() local
154 rate_table = visconti_get_pll_settings(pll, rate); in visconti_pll_set_rate()
156 return -EINVAL; in visconti_pll_set_rate()
158 return visconti_pll_set_params(pll, rate_table); in visconti_pll_set_rate()
163 struct visconti_pll *pll = to_visconti_pll(hw); in visconti_pll_is_enabled() local
166 reg = readl(pll->pll_base + PLL_CTRL_REG); in visconti_pll_is_enabled()
173 struct visconti_pll *pll = to_visconti_pll(hw); in visconti_pll_enable() local
174 const struct visconti_pll_rate_table *rate_table = pll->rate_table; in visconti_pll_enable()
179 return 0; in visconti_pll_enable()
181 spin_lock_irqsave(pll->lock, flags); in visconti_pll_enable()
183 writel(PLL_CONFIG_SEL, pll->pll_base + PLL_CONF_REG); in visconti_pll_enable()
185 reg = readl(pll->pll_base + PLL_CTRL_REG); in visconti_pll_enable()
187 writel(reg, pll->pll_base + PLL_CTRL_REG); in visconti_pll_enable()
189 visconti_pll_set_params(pll, &rate_table[0]); in visconti_pll_enable()
191 reg = readl(pll->pll_base + PLL_CTRL_REG); in visconti_pll_enable()
193 writel(reg, pll->pll_base + PLL_CTRL_REG); in visconti_pll_enable()
197 reg = readl(pll->pll_base + PLL_CTRL_REG); in visconti_pll_enable()
199 writel(reg, pll->pll_base + PLL_CTRL_REG); in visconti_pll_enable()
203 reg = readl(pll->pll_base + PLL_CTRL_REG); in visconti_pll_enable()
205 writel(reg, pll->pll_base + PLL_CTRL_REG); in visconti_pll_enable()
207 spin_unlock_irqrestore(pll->lock, flags); in visconti_pll_enable()
209 return 0; in visconti_pll_enable()
214 struct visconti_pll *pll = to_visconti_pll(hw); in visconti_pll_disable() local
221 spin_lock_irqsave(pll->lock, flags); in visconti_pll_disable()
223 writel(PLL_CONFIG_SEL, pll->pll_base + PLL_CONF_REG); in visconti_pll_disable()
225 reg = readl(pll->pll_base + PLL_CTRL_REG); in visconti_pll_disable()
227 writel(reg, pll->pll_base + PLL_CTRL_REG); in visconti_pll_disable()
229 reg = readl(pll->pll_base + PLL_CTRL_REG); in visconti_pll_disable()
231 writel(reg, pll->pll_base + PLL_CTRL_REG); in visconti_pll_disable()
233 spin_unlock_irqrestore(pll->lock, flags); in visconti_pll_disable()
253 struct visconti_pll *pll; in visconti_register_pll() local
258 pll = kzalloc(sizeof(*pll), GFP_KERNEL); in visconti_register_pll()
259 if (!pll) in visconti_register_pll()
260 return ERR_PTR(-ENOMEM); in visconti_register_pll()
267 for (len = 0; rate_table[len].rate != 0; ) in visconti_register_pll()
269 pll->rate_count = len; in visconti_register_pll()
270 pll->rate_table = kmemdup_array(rate_table, in visconti_register_pll()
271 pll->rate_count, sizeof(*pll->rate_table), in visconti_register_pll()
273 WARN(!pll->rate_table, "%s: could not allocate rate table for %s\n", __func__, name); in visconti_register_pll()
276 pll->hw.init = &init; in visconti_register_pll()
277 pll->pll_base = ctx->reg_base + offset; in visconti_register_pll()
278 pll->lock = lock; in visconti_register_pll()
279 pll->ctx = ctx; in visconti_register_pll()
281 pll_hw_clk = &pll->hw; in visconti_register_pll()
282 ret = clk_hw_register(NULL, &pll->hw); in visconti_register_pll()
284 pr_err("failed to register pll clock %s : %d\n", name, ret); in visconti_register_pll()
285 kfree(pll->rate_table); in visconti_register_pll()
286 kfree(pll); in visconti_register_pll()
298 ctx->clk_data.hws[id] = hw_clk; in visconti_pll_add_lookup()
308 for (idx = 0; idx < nr_plls; idx++, list++) { in visconti_register_plls()
312 list->name, in visconti_register_plls()
313 list->parent, in visconti_register_plls()
314 list->base_reg, in visconti_register_plls()
315 list->rate_table, in visconti_register_plls()
318 pr_err("failed to register clock %s\n", list->name); in visconti_register_plls()
322 visconti_pll_add_lookup(ctx, clk, list->id); in visconti_register_plls()
335 return ERR_PTR(-ENOMEM); in visconti_init_pll()
337 ctx->node = np; in visconti_init_pll()
338 ctx->reg_base = base; in visconti_init_pll()
339 ctx->clk_data.num = nr_plls; in visconti_init_pll()
341 for (i = 0; i < nr_plls; ++i) in visconti_init_pll()
342 ctx->clk_data.hws[i] = ERR_PTR(-ENOENT); in visconti_init_pll()