This source file includes following definitions.
- imx_get_pll_settings
- clk_pll14xx_round_rate
- clk_pll1416x_recalc_rate
- clk_pll1443x_recalc_rate
- clk_pll14xx_mp_change
- clk_pll14xx_wait_lock
- clk_pll1416x_set_rate
- clk_pll1443x_set_rate
- clk_pll14xx_prepare
- clk_pll14xx_is_prepared
- clk_pll14xx_unprepare
- imx_clk_pll14xx
1
2
3
4
5
6 #include <linux/bitops.h>
7 #include <linux/clk-provider.h>
8 #include <linux/err.h>
9 #include <linux/io.h>
10 #include <linux/iopoll.h>
11 #include <linux/slab.h>
12 #include <linux/jiffies.h>
13
14 #include "clk.h"
15
16 #define GNRL_CTL 0x0
17 #define DIV_CTL 0x4
18 #define LOCK_STATUS BIT(31)
19 #define LOCK_SEL_MASK BIT(29)
20 #define CLKE_MASK BIT(11)
21 #define RST_MASK BIT(9)
22 #define BYPASS_MASK BIT(4)
23 #define MDIV_SHIFT 12
24 #define MDIV_MASK GENMASK(21, 12)
25 #define PDIV_SHIFT 4
26 #define PDIV_MASK GENMASK(9, 4)
27 #define SDIV_SHIFT 0
28 #define SDIV_MASK GENMASK(2, 0)
29 #define KDIV_SHIFT 0
30 #define KDIV_MASK GENMASK(15, 0)
31
32 #define LOCK_TIMEOUT_US 10000
33
34 struct clk_pll14xx {
35 struct clk_hw hw;
36 void __iomem *base;
37 enum imx_pll14xx_type type;
38 const struct imx_pll14xx_rate_table *rate_table;
39 int rate_count;
40 };
41
42 #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
43
44 static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
45 struct clk_pll14xx *pll, unsigned long rate)
46 {
47 const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
48 int i;
49
50 for (i = 0; i < pll->rate_count; i++)
51 if (rate == rate_table[i].rate)
52 return &rate_table[i];
53
54 return NULL;
55 }
56
57 static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate,
58 unsigned long *prate)
59 {
60 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
61 const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
62 int i;
63
64
65 for (i = 0; i < pll->rate_count; i++)
66 if (rate >= rate_table[i].rate)
67 return rate_table[i].rate;
68
69
70 return rate_table[i - 1].rate;
71 }
72
73 static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw,
74 unsigned long parent_rate)
75 {
76 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
77 u32 mdiv, pdiv, sdiv, pll_div;
78 u64 fvco = parent_rate;
79
80 pll_div = readl_relaxed(pll->base + 4);
81 mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
82 pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
83 sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT;
84
85 fvco *= mdiv;
86 do_div(fvco, pdiv << sdiv);
87
88 return fvco;
89 }
90
91 static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw,
92 unsigned long parent_rate)
93 {
94 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
95 u32 mdiv, pdiv, sdiv, pll_div_ctl0, pll_div_ctl1;
96 short int kdiv;
97 u64 fvco = parent_rate;
98
99 pll_div_ctl0 = readl_relaxed(pll->base + 4);
100 pll_div_ctl1 = readl_relaxed(pll->base + 8);
101 mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
102 pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
103 sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT;
104 kdiv = pll_div_ctl1 & KDIV_MASK;
105
106
107 fvco *= (mdiv * 65536 + kdiv);
108 pdiv *= 65536;
109
110 do_div(fvco, pdiv << sdiv);
111
112 return fvco;
113 }
114
115 static inline bool clk_pll14xx_mp_change(const struct imx_pll14xx_rate_table *rate,
116 u32 pll_div)
117 {
118 u32 old_mdiv, old_pdiv;
119
120 old_mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
121 old_pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
122
123 return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv;
124 }
125
126 static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
127 {
128 u32 val;
129
130 return readl_poll_timeout(pll->base, val, val & LOCK_STATUS, 0,
131 LOCK_TIMEOUT_US);
132 }
133
134 static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
135 unsigned long prate)
136 {
137 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
138 const struct imx_pll14xx_rate_table *rate;
139 u32 tmp, div_val;
140 int ret;
141
142 rate = imx_get_pll_settings(pll, drate);
143 if (!rate) {
144 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
145 drate, clk_hw_get_name(hw));
146 return -EINVAL;
147 }
148
149 tmp = readl_relaxed(pll->base + 4);
150
151 if (!clk_pll14xx_mp_change(rate, tmp)) {
152 tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
153 tmp |= rate->sdiv << SDIV_SHIFT;
154 writel_relaxed(tmp, pll->base + 4);
155
156 return 0;
157 }
158
159
160 tmp = readl_relaxed(pll->base);
161 tmp |= LOCK_SEL_MASK;
162 writel_relaxed(tmp, pll->base);
163
164
165 tmp &= ~RST_MASK;
166 writel_relaxed(tmp, pll->base);
167
168
169 tmp |= BYPASS_MASK;
170 writel(tmp, pll->base);
171
172 div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
173 (rate->sdiv << SDIV_SHIFT);
174 writel_relaxed(div_val, pll->base + 0x4);
175
176
177
178
179
180
181
182 udelay(3);
183
184
185 tmp |= RST_MASK;
186 writel_relaxed(tmp, pll->base);
187
188
189 ret = clk_pll14xx_wait_lock(pll);
190 if (ret)
191 return ret;
192
193
194 tmp &= ~BYPASS_MASK;
195 writel_relaxed(tmp, pll->base);
196
197 return 0;
198 }
199
200 static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
201 unsigned long prate)
202 {
203 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
204 const struct imx_pll14xx_rate_table *rate;
205 u32 tmp, div_val;
206 int ret;
207
208 rate = imx_get_pll_settings(pll, drate);
209 if (!rate) {
210 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
211 drate, clk_hw_get_name(hw));
212 return -EINVAL;
213 }
214
215 tmp = readl_relaxed(pll->base + 4);
216
217 if (!clk_pll14xx_mp_change(rate, tmp)) {
218 tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
219 tmp |= rate->sdiv << SDIV_SHIFT;
220 writel_relaxed(tmp, pll->base + 4);
221
222 tmp = rate->kdiv << KDIV_SHIFT;
223 writel_relaxed(tmp, pll->base + 8);
224
225 return 0;
226 }
227
228
229 tmp = readl_relaxed(pll->base);
230 tmp &= ~RST_MASK;
231 writel_relaxed(tmp, pll->base);
232
233
234 tmp |= BYPASS_MASK;
235 writel_relaxed(tmp, pll->base);
236
237 div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
238 (rate->sdiv << SDIV_SHIFT);
239 writel_relaxed(div_val, pll->base + 0x4);
240 writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + 0x8);
241
242
243
244
245
246
247
248 udelay(3);
249
250
251 tmp |= RST_MASK;
252 writel_relaxed(tmp, pll->base);
253
254
255 ret = clk_pll14xx_wait_lock(pll);
256 if (ret)
257 return ret;
258
259
260 tmp &= ~BYPASS_MASK;
261 writel_relaxed(tmp, pll->base);
262
263 return 0;
264 }
265
266 static int clk_pll14xx_prepare(struct clk_hw *hw)
267 {
268 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
269 u32 val;
270 int ret;
271
272
273
274
275
276 val = readl_relaxed(pll->base + GNRL_CTL);
277 if (val & RST_MASK)
278 return 0;
279 val |= BYPASS_MASK;
280 writel_relaxed(val, pll->base + GNRL_CTL);
281 val |= RST_MASK;
282 writel_relaxed(val, pll->base + GNRL_CTL);
283
284 ret = clk_pll14xx_wait_lock(pll);
285 if (ret)
286 return ret;
287
288 val &= ~BYPASS_MASK;
289 writel_relaxed(val, pll->base + GNRL_CTL);
290
291 return 0;
292 }
293
294 static int clk_pll14xx_is_prepared(struct clk_hw *hw)
295 {
296 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
297 u32 val;
298
299 val = readl_relaxed(pll->base + GNRL_CTL);
300
301 return (val & RST_MASK) ? 1 : 0;
302 }
303
304 static void clk_pll14xx_unprepare(struct clk_hw *hw)
305 {
306 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
307 u32 val;
308
309
310
311
312
313 val = readl_relaxed(pll->base + GNRL_CTL);
314 val &= ~RST_MASK;
315 writel_relaxed(val, pll->base + GNRL_CTL);
316 }
317
318 static const struct clk_ops clk_pll1416x_ops = {
319 .prepare = clk_pll14xx_prepare,
320 .unprepare = clk_pll14xx_unprepare,
321 .is_prepared = clk_pll14xx_is_prepared,
322 .recalc_rate = clk_pll1416x_recalc_rate,
323 .round_rate = clk_pll14xx_round_rate,
324 .set_rate = clk_pll1416x_set_rate,
325 };
326
327 static const struct clk_ops clk_pll1416x_min_ops = {
328 .recalc_rate = clk_pll1416x_recalc_rate,
329 };
330
331 static const struct clk_ops clk_pll1443x_ops = {
332 .prepare = clk_pll14xx_prepare,
333 .unprepare = clk_pll14xx_unprepare,
334 .is_prepared = clk_pll14xx_is_prepared,
335 .recalc_rate = clk_pll1443x_recalc_rate,
336 .round_rate = clk_pll14xx_round_rate,
337 .set_rate = clk_pll1443x_set_rate,
338 };
339
340 struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
341 void __iomem *base,
342 const struct imx_pll14xx_clk *pll_clk)
343 {
344 struct clk_pll14xx *pll;
345 struct clk *clk;
346 struct clk_init_data init;
347 u32 val;
348
349 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
350 if (!pll)
351 return ERR_PTR(-ENOMEM);
352
353 init.name = name;
354 init.flags = pll_clk->flags;
355 init.parent_names = &parent_name;
356 init.num_parents = 1;
357
358 switch (pll_clk->type) {
359 case PLL_1416X:
360 if (!pll_clk->rate_table)
361 init.ops = &clk_pll1416x_min_ops;
362 else
363 init.ops = &clk_pll1416x_ops;
364 break;
365 case PLL_1443X:
366 init.ops = &clk_pll1443x_ops;
367 break;
368 default:
369 pr_err("%s: Unknown pll type for pll clk %s\n",
370 __func__, name);
371 };
372
373 pll->base = base;
374 pll->hw.init = &init;
375 pll->type = pll_clk->type;
376 pll->rate_table = pll_clk->rate_table;
377 pll->rate_count = pll_clk->rate_count;
378
379 val = readl_relaxed(pll->base + GNRL_CTL);
380 val &= ~BYPASS_MASK;
381 writel_relaxed(val, pll->base + GNRL_CTL);
382
383 clk = clk_register(NULL, &pll->hw);
384 if (IS_ERR(clk)) {
385 pr_err("%s: failed to register pll %s %lu\n",
386 __func__, name, PTR_ERR(clk));
387 kfree(pll);
388 }
389
390 return clk;
391 }