1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 * Copyright (c) 2013 Linaro Ltd.
5 *
6 * This file contains the utility functions to register the pll clocks.
7 */
8
9 #include <linux/errno.h>
10 #include <linux/hrtimer.h>
11 #include <linux/iopoll.h>
12 #include <linux/delay.h>
13 #include <linux/slab.h>
14 #include <linux/timekeeping.h>
15 #include <linux/clk-provider.h>
16 #include <linux/io.h>
17 #include "clk.h"
18 #include "clk-pll.h"
19
20 #define PLL_TIMEOUT_US 20000U
21 #define PLL_TIMEOUT_LOOPS 1000000U
22
23 struct samsung_clk_pll {
24 struct clk_hw hw;
25 void __iomem *lock_reg;
26 void __iomem *con_reg;
27 /* PLL enable control bit offset in @con_reg register */
28 unsigned short enable_offs;
29 /* PLL lock status bit offset in @con_reg register */
30 unsigned short lock_offs;
31 enum samsung_pll_type type;
32 unsigned int rate_count;
33 const struct samsung_pll_rate_table *rate_table;
34 };
35
36 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
37
samsung_get_pll_settings(struct samsung_clk_pll * pll,unsigned long rate)38 static const struct samsung_pll_rate_table *samsung_get_pll_settings(
39 struct samsung_clk_pll *pll, unsigned long rate)
40 {
41 const struct samsung_pll_rate_table *rate_table = pll->rate_table;
42 int i;
43
44 for (i = 0; i < pll->rate_count; i++) {
45 if (rate == rate_table[i].rate)
46 return &rate_table[i];
47 }
48
49 return NULL;
50 }
51
samsung_pll_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)52 static int samsung_pll_determine_rate(struct clk_hw *hw,
53 struct clk_rate_request *req)
54 {
55 struct samsung_clk_pll *pll = to_clk_pll(hw);
56 const struct samsung_pll_rate_table *rate_table = pll->rate_table;
57 int i;
58
59 /* Assuming rate_table is in descending order */
60 for (i = 0; i < pll->rate_count; i++) {
61 if (req->rate >= rate_table[i].rate) {
62 req->rate = rate_table[i].rate;
63
64 return 0;
65 }
66 }
67
68 /* return minimum supported value */
69 req->rate = rate_table[i - 1].rate;
70
71 return 0;
72 }
73
74 static bool pll_early_timeout = true;
75
samsung_pll_disable_early_timeout(void)76 static int __init samsung_pll_disable_early_timeout(void)
77 {
78 pll_early_timeout = false;
79 return 0;
80 }
81 arch_initcall(samsung_pll_disable_early_timeout);
82
83 /* Wait until the PLL is locked */
samsung_pll_lock_wait(struct samsung_clk_pll * pll,unsigned int reg_mask)84 static int samsung_pll_lock_wait(struct samsung_clk_pll *pll,
85 unsigned int reg_mask)
86 {
87 int i, ret;
88 u32 val;
89
90 /*
91 * This function might be called when the timekeeping API can't be used
92 * to detect timeouts. One situation is when the clocksource is not yet
93 * initialized, another when the timekeeping is suspended. udelay() also
94 * cannot be used when the clocksource is not running on arm64, since
95 * the current timer is used as cycle counter. So a simple busy loop
96 * is used here in that special cases. The limit of iterations has been
97 * derived from experimental measurements of various PLLs on multiple
98 * Exynos SoC variants. Single register read time was usually in range
99 * 0.4...1.5 us, never less than 0.4 us.
100 */
101 if (pll_early_timeout || timekeeping_suspended) {
102 i = PLL_TIMEOUT_LOOPS;
103 while (i-- > 0) {
104 if (readl_relaxed(pll->con_reg) & reg_mask)
105 return 0;
106
107 cpu_relax();
108 }
109 ret = -ETIMEDOUT;
110 } else {
111 ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val,
112 val & reg_mask, 0, PLL_TIMEOUT_US);
113 }
114
115 if (ret < 0)
116 pr_err("Could not lock PLL %s\n", clk_hw_get_name(&pll->hw));
117
118 return ret;
119 }
120
samsung_pll3xxx_enable(struct clk_hw * hw)121 static int samsung_pll3xxx_enable(struct clk_hw *hw)
122 {
123 struct samsung_clk_pll *pll = to_clk_pll(hw);
124 u32 tmp;
125
126 tmp = readl_relaxed(pll->con_reg);
127 tmp |= BIT(pll->enable_offs);
128 writel_relaxed(tmp, pll->con_reg);
129
130 return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
131 }
132
samsung_pll3xxx_disable(struct clk_hw * hw)133 static void samsung_pll3xxx_disable(struct clk_hw *hw)
134 {
135 struct samsung_clk_pll *pll = to_clk_pll(hw);
136 u32 tmp;
137
138 tmp = readl_relaxed(pll->con_reg);
139 tmp &= ~BIT(pll->enable_offs);
140 writel_relaxed(tmp, pll->con_reg);
141 }
142
143 /*
144 * PLL2126 Clock Type
145 */
146
147 #define PLL2126_MDIV_MASK (0xff)
148 #define PLL2126_PDIV_MASK (0x3f)
149 #define PLL2126_SDIV_MASK (0x3)
150 #define PLL2126_MDIV_SHIFT (16)
151 #define PLL2126_PDIV_SHIFT (8)
152 #define PLL2126_SDIV_SHIFT (0)
153
samsung_pll2126_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)154 static unsigned long samsung_pll2126_recalc_rate(struct clk_hw *hw,
155 unsigned long parent_rate)
156 {
157 struct samsung_clk_pll *pll = to_clk_pll(hw);
158 u32 pll_con, mdiv, pdiv, sdiv;
159 u64 fvco = parent_rate;
160
161 pll_con = readl_relaxed(pll->con_reg);
162 mdiv = (pll_con >> PLL2126_MDIV_SHIFT) & PLL2126_MDIV_MASK;
163 pdiv = (pll_con >> PLL2126_PDIV_SHIFT) & PLL2126_PDIV_MASK;
164 sdiv = (pll_con >> PLL2126_SDIV_SHIFT) & PLL2126_SDIV_MASK;
165
166 fvco *= (mdiv + 8);
167 do_div(fvco, (pdiv + 2) << sdiv);
168
169 return (unsigned long)fvco;
170 }
171
172 static const struct clk_ops samsung_pll2126_clk_ops = {
173 .recalc_rate = samsung_pll2126_recalc_rate,
174 };
175
176 /*
177 * PLL3000 Clock Type
178 */
179
180 #define PLL3000_MDIV_MASK (0xff)
181 #define PLL3000_PDIV_MASK (0x3)
182 #define PLL3000_SDIV_MASK (0x3)
183 #define PLL3000_MDIV_SHIFT (16)
184 #define PLL3000_PDIV_SHIFT (8)
185 #define PLL3000_SDIV_SHIFT (0)
186
samsung_pll3000_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)187 static unsigned long samsung_pll3000_recalc_rate(struct clk_hw *hw,
188 unsigned long parent_rate)
189 {
190 struct samsung_clk_pll *pll = to_clk_pll(hw);
191 u32 pll_con, mdiv, pdiv, sdiv;
192 u64 fvco = parent_rate;
193
194 pll_con = readl_relaxed(pll->con_reg);
195 mdiv = (pll_con >> PLL3000_MDIV_SHIFT) & PLL3000_MDIV_MASK;
196 pdiv = (pll_con >> PLL3000_PDIV_SHIFT) & PLL3000_PDIV_MASK;
197 sdiv = (pll_con >> PLL3000_SDIV_SHIFT) & PLL3000_SDIV_MASK;
198
199 fvco *= (2 * (mdiv + 8));
200 do_div(fvco, pdiv << sdiv);
201
202 return (unsigned long)fvco;
203 }
204
205 static const struct clk_ops samsung_pll3000_clk_ops = {
206 .recalc_rate = samsung_pll3000_recalc_rate,
207 };
208
209 /*
210 * PLL35xx Clock Type
211 */
212 /* Maximum lock time can be 270 * PDIV cycles */
213 #define PLL35XX_LOCK_FACTOR (270)
214 #define PLL142XX_LOCK_FACTOR (150)
215
216 #define PLL35XX_MDIV_MASK (0x3FF)
217 #define PLL35XX_PDIV_MASK (0x3F)
218 #define PLL35XX_SDIV_MASK (0x7)
219 #define PLL35XX_MDIV_SHIFT (16)
220 #define PLL35XX_PDIV_SHIFT (8)
221 #define PLL35XX_SDIV_SHIFT (0)
222 #define PLL35XX_LOCK_STAT_SHIFT (29)
223 #define PLL35XX_ENABLE_SHIFT (31)
224
samsung_pll35xx_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)225 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
226 unsigned long parent_rate)
227 {
228 struct samsung_clk_pll *pll = to_clk_pll(hw);
229 u32 mdiv, pdiv, sdiv, pll_con;
230 u64 fvco = parent_rate;
231
232 pll_con = readl_relaxed(pll->con_reg);
233 mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
234 pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
235 sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
236
237 fvco *= mdiv;
238 do_div(fvco, (pdiv << sdiv));
239
240 return (unsigned long)fvco;
241 }
242
samsung_pll35xx_mp_change(const struct samsung_pll_rate_table * rate,u32 pll_con)243 static inline bool samsung_pll35xx_mp_change(
244 const struct samsung_pll_rate_table *rate, u32 pll_con)
245 {
246 u32 old_mdiv, old_pdiv;
247
248 old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
249 old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
250
251 return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
252 }
253
samsung_pll35xx_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)254 static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
255 unsigned long prate)
256 {
257 struct samsung_clk_pll *pll = to_clk_pll(hw);
258 const struct samsung_pll_rate_table *rate;
259 u32 tmp;
260
261 /* Get required rate settings from table */
262 rate = samsung_get_pll_settings(pll, drate);
263 if (!rate) {
264 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
265 drate, clk_hw_get_name(hw));
266 return -EINVAL;
267 }
268
269 tmp = readl_relaxed(pll->con_reg);
270
271 if (!(samsung_pll35xx_mp_change(rate, tmp))) {
272 /* If only s change, change just s value only*/
273 tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
274 tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
275 writel_relaxed(tmp, pll->con_reg);
276
277 return 0;
278 }
279
280 /* Set PLL lock time. */
281 if (pll->type == pll_142xx || pll->type == pll_1017x)
282 writel_relaxed(rate->pdiv * PLL142XX_LOCK_FACTOR,
283 pll->lock_reg);
284 else
285 writel_relaxed(rate->pdiv * PLL35XX_LOCK_FACTOR,
286 pll->lock_reg);
287
288 /* Change PLL PMS values */
289 tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
290 (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
291 (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
292 tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
293 (rate->pdiv << PLL35XX_PDIV_SHIFT) |
294 (rate->sdiv << PLL35XX_SDIV_SHIFT);
295 writel_relaxed(tmp, pll->con_reg);
296
297 /* Wait for PLL lock if the PLL is enabled */
298 if (tmp & BIT(pll->enable_offs))
299 return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
300
301 return 0;
302 }
303
304 static const struct clk_ops samsung_pll35xx_clk_ops = {
305 .recalc_rate = samsung_pll35xx_recalc_rate,
306 .determine_rate = samsung_pll_determine_rate,
307 .set_rate = samsung_pll35xx_set_rate,
308 .enable = samsung_pll3xxx_enable,
309 .disable = samsung_pll3xxx_disable,
310 };
311
312 static const struct clk_ops samsung_pll35xx_clk_min_ops = {
313 .recalc_rate = samsung_pll35xx_recalc_rate,
314 };
315
316 /*
317 * PLL36xx Clock Type
318 */
319 /* Maximum lock time can be 3000 * PDIV cycles */
320 #define PLL36XX_LOCK_FACTOR (3000)
321
322 #define PLL36XX_KDIV_MASK (0xFFFF)
323 #define PLL36XX_MDIV_MASK (0x1FF)
324 #define PLL36XX_PDIV_MASK (0x3F)
325 #define PLL36XX_SDIV_MASK (0x7)
326 #define PLL36XX_MDIV_SHIFT (16)
327 #define PLL36XX_PDIV_SHIFT (8)
328 #define PLL36XX_SDIV_SHIFT (0)
329 #define PLL36XX_KDIV_SHIFT (0)
330 #define PLL36XX_LOCK_STAT_SHIFT (29)
331 #define PLL36XX_ENABLE_SHIFT (31)
332
samsung_pll36xx_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)333 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
334 unsigned long parent_rate)
335 {
336 struct samsung_clk_pll *pll = to_clk_pll(hw);
337 u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
338 s16 kdiv;
339 u64 fvco = parent_rate;
340
341 pll_con0 = readl_relaxed(pll->con_reg);
342 pll_con1 = readl_relaxed(pll->con_reg + 4);
343 mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
344 pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
345 sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
346 kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK);
347
348 fvco *= (mdiv << 16) + kdiv;
349 do_div(fvco, (pdiv << sdiv));
350 fvco >>= 16;
351
352 return (unsigned long)fvco;
353 }
354
samsung_pll36xx_mpk_change(const struct samsung_pll_rate_table * rate,u32 pll_con0,u32 pll_con1)355 static inline bool samsung_pll36xx_mpk_change(
356 const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
357 {
358 u32 old_mdiv, old_pdiv, old_kdiv;
359
360 old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
361 old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
362 old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
363
364 return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
365 rate->kdiv != old_kdiv);
366 }
367
samsung_pll36xx_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long parent_rate)368 static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
369 unsigned long parent_rate)
370 {
371 struct samsung_clk_pll *pll = to_clk_pll(hw);
372 u32 pll_con0, pll_con1;
373 const struct samsung_pll_rate_table *rate;
374
375 rate = samsung_get_pll_settings(pll, drate);
376 if (!rate) {
377 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
378 drate, clk_hw_get_name(hw));
379 return -EINVAL;
380 }
381
382 pll_con0 = readl_relaxed(pll->con_reg);
383 pll_con1 = readl_relaxed(pll->con_reg + 4);
384
385 if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
386 /* If only s change, change just s value only*/
387 pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
388 pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
389 writel_relaxed(pll_con0, pll->con_reg);
390
391 return 0;
392 }
393
394 /* Set PLL lock time. */
395 writel_relaxed(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
396
397 /* Change PLL PMS values */
398 pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
399 (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
400 (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
401 pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
402 (rate->pdiv << PLL36XX_PDIV_SHIFT) |
403 (rate->sdiv << PLL36XX_SDIV_SHIFT);
404 writel_relaxed(pll_con0, pll->con_reg);
405
406 pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
407 pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
408 writel_relaxed(pll_con1, pll->con_reg + 4);
409
410 if (pll_con0 & BIT(pll->enable_offs))
411 return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
412
413 return 0;
414 }
415
416 static const struct clk_ops samsung_pll36xx_clk_ops = {
417 .recalc_rate = samsung_pll36xx_recalc_rate,
418 .set_rate = samsung_pll36xx_set_rate,
419 .determine_rate = samsung_pll_determine_rate,
420 .enable = samsung_pll3xxx_enable,
421 .disable = samsung_pll3xxx_disable,
422 };
423
424 static const struct clk_ops samsung_pll36xx_clk_min_ops = {
425 .recalc_rate = samsung_pll36xx_recalc_rate,
426 };
427
428 /*
429 * PLL0822x Clock Type
430 */
431 /* Maximum lock time can be 150 * PDIV cycles */
432 #define PLL0822X_LOCK_FACTOR (150)
433
434 #define PLL0822X_MDIV_MASK (0x3FF)
435 #define PLL0822X_PDIV_MASK (0x3F)
436 #define PLL0822X_SDIV_MASK (0x7)
437 #define PLL0822X_MDIV_SHIFT (16)
438 #define PLL0822X_PDIV_SHIFT (8)
439 #define PLL0822X_SDIV_SHIFT (0)
440 #define PLL0822X_LOCK_STAT_SHIFT (29)
441 #define PLL0822X_ENABLE_SHIFT (31)
442
443 /*
444 * PLL1418x, PLL0717x and PLL0718x are similar
445 * to PLL0822x, except that MDIV is one bit smaller
446 */
447 #define PLL1418X_MDIV_MASK (0x1FF)
448
samsung_pll0822x_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)449 static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
450 unsigned long parent_rate)
451 {
452 struct samsung_clk_pll *pll = to_clk_pll(hw);
453 u32 mdiv, pdiv, sdiv, pll_con3;
454 u64 fvco = parent_rate;
455
456 pll_con3 = readl_relaxed(pll->con_reg);
457
458 if (pll->type != pll_1418x &&
459 pll->type != pll_0717x &&
460 pll->type != pll_0718x)
461 mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK;
462 else
463 mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL1418X_MDIV_MASK;
464
465 pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK;
466 sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK;
467
468 fvco *= mdiv;
469 if (pll->type == pll_0516x)
470 fvco *= 2;
471
472 do_div(fvco, (pdiv << sdiv));
473
474 return (unsigned long)fvco;
475 }
476
samsung_pll0822x_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)477 static int samsung_pll0822x_set_rate(struct clk_hw *hw, unsigned long drate,
478 unsigned long prate)
479 {
480 const struct samsung_pll_rate_table *rate;
481 struct samsung_clk_pll *pll = to_clk_pll(hw);
482 u32 mdiv_mask, pll_con3;
483
484 if (pll->type != pll_1418x)
485 mdiv_mask = PLL0822X_MDIV_MASK;
486 else
487 mdiv_mask = PLL1418X_MDIV_MASK;
488
489 /* Get required rate settings from table */
490 rate = samsung_get_pll_settings(pll, drate);
491 if (!rate) {
492 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
493 drate, clk_hw_get_name(hw));
494 return -EINVAL;
495 }
496
497 /* Change PLL PMS values */
498 pll_con3 = readl_relaxed(pll->con_reg);
499 pll_con3 &= ~((mdiv_mask << PLL0822X_MDIV_SHIFT) |
500 (PLL0822X_PDIV_MASK << PLL0822X_PDIV_SHIFT) |
501 (PLL0822X_SDIV_MASK << PLL0822X_SDIV_SHIFT));
502 pll_con3 |= (rate->mdiv << PLL0822X_MDIV_SHIFT) |
503 (rate->pdiv << PLL0822X_PDIV_SHIFT) |
504 (rate->sdiv << PLL0822X_SDIV_SHIFT);
505
506 /* Set PLL lock time */
507 writel_relaxed(rate->pdiv * PLL0822X_LOCK_FACTOR,
508 pll->lock_reg);
509
510 /* Write PMS values */
511 writel_relaxed(pll_con3, pll->con_reg);
512
513 /* Wait for PLL lock if the PLL is enabled */
514 if (pll_con3 & BIT(pll->enable_offs))
515 return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
516
517 return 0;
518 }
519
520 static const struct clk_ops samsung_pll0822x_clk_ops = {
521 .recalc_rate = samsung_pll0822x_recalc_rate,
522 .determine_rate = samsung_pll_determine_rate,
523 .set_rate = samsung_pll0822x_set_rate,
524 .enable = samsung_pll3xxx_enable,
525 .disable = samsung_pll3xxx_disable,
526 };
527
528 static const struct clk_ops samsung_pll0822x_clk_min_ops = {
529 .recalc_rate = samsung_pll0822x_recalc_rate,
530 };
531
532 /*
533 * PLL0831x Clock Type
534 */
535 /* Maximum lock time can be 500 * PDIV cycles */
536 #define PLL0831X_LOCK_FACTOR (500)
537
538 #define PLL0831X_KDIV_MASK (0xFFFF)
539 #define PLL0831X_MDIV_MASK (0x1FF)
540 #define PLL0831X_PDIV_MASK (0x3F)
541 #define PLL0831X_SDIV_MASK (0x7)
542 #define PLL0831X_MDIV_SHIFT (16)
543 #define PLL0831X_PDIV_SHIFT (8)
544 #define PLL0831X_SDIV_SHIFT (0)
545 #define PLL0831X_KDIV_SHIFT (0)
546 #define PLL0831X_LOCK_STAT_SHIFT (29)
547 #define PLL0831X_ENABLE_SHIFT (31)
548
samsung_pll0831x_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)549 static unsigned long samsung_pll0831x_recalc_rate(struct clk_hw *hw,
550 unsigned long parent_rate)
551 {
552 struct samsung_clk_pll *pll = to_clk_pll(hw);
553 u32 mdiv, pdiv, sdiv, pll_con3, pll_con5;
554 s16 kdiv;
555 u64 fvco = parent_rate;
556
557 pll_con3 = readl_relaxed(pll->con_reg);
558 pll_con5 = readl_relaxed(pll->con_reg + 8);
559 mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK;
560 pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK;
561 sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK;
562 kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) & PLL0831X_KDIV_MASK);
563
564 fvco *= (mdiv << 16) + kdiv;
565 do_div(fvco, (pdiv << sdiv));
566 fvco >>= 16;
567
568 return (unsigned long)fvco;
569 }
570
samsung_pll0831x_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long parent_rate)571 static int samsung_pll0831x_set_rate(struct clk_hw *hw, unsigned long drate,
572 unsigned long parent_rate)
573 {
574 const struct samsung_pll_rate_table *rate;
575 struct samsung_clk_pll *pll = to_clk_pll(hw);
576 u32 pll_con3, pll_con5;
577
578 /* Get required rate settings from table */
579 rate = samsung_get_pll_settings(pll, drate);
580 if (!rate) {
581 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
582 drate, clk_hw_get_name(hw));
583 return -EINVAL;
584 }
585
586 pll_con3 = readl_relaxed(pll->con_reg);
587 pll_con5 = readl_relaxed(pll->con_reg + 8);
588
589 /* Change PLL PMSK values */
590 pll_con3 &= ~((PLL0831X_MDIV_MASK << PLL0831X_MDIV_SHIFT) |
591 (PLL0831X_PDIV_MASK << PLL0831X_PDIV_SHIFT) |
592 (PLL0831X_SDIV_MASK << PLL0831X_SDIV_SHIFT));
593 pll_con3 |= (rate->mdiv << PLL0831X_MDIV_SHIFT) |
594 (rate->pdiv << PLL0831X_PDIV_SHIFT) |
595 (rate->sdiv << PLL0831X_SDIV_SHIFT);
596 pll_con5 &= ~(PLL0831X_KDIV_MASK << PLL0831X_KDIV_SHIFT);
597 /*
598 * kdiv is 16-bit 2's complement (s16), but stored as unsigned int.
599 * Cast it to u16 to avoid leading 0xffff's in case of negative value.
600 */
601 pll_con5 |= ((u16)rate->kdiv << PLL0831X_KDIV_SHIFT);
602
603 /* Set PLL lock time */
604 writel_relaxed(rate->pdiv * PLL0831X_LOCK_FACTOR, pll->lock_reg);
605
606 /* Write PMSK values */
607 writel_relaxed(pll_con3, pll->con_reg);
608 writel_relaxed(pll_con5, pll->con_reg + 8);
609
610 /* Wait for PLL lock if the PLL is enabled */
611 if (pll_con3 & BIT(pll->enable_offs))
612 return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
613
614 return 0;
615 }
616
617 static const struct clk_ops samsung_pll0831x_clk_ops = {
618 .recalc_rate = samsung_pll0831x_recalc_rate,
619 .set_rate = samsung_pll0831x_set_rate,
620 .determine_rate = samsung_pll_determine_rate,
621 .enable = samsung_pll3xxx_enable,
622 .disable = samsung_pll3xxx_disable,
623 };
624
625 static const struct clk_ops samsung_pll0831x_clk_min_ops = {
626 .recalc_rate = samsung_pll0831x_recalc_rate,
627 };
628
629 /*
630 * PLL45xx Clock Type
631 */
632 #define PLL4502_LOCK_FACTOR 400
633 #define PLL4508_LOCK_FACTOR 240
634
635 #define PLL45XX_MDIV_MASK (0x3FF)
636 #define PLL45XX_PDIV_MASK (0x3F)
637 #define PLL45XX_SDIV_MASK (0x7)
638 #define PLL45XX_AFC_MASK (0x1F)
639 #define PLL45XX_MDIV_SHIFT (16)
640 #define PLL45XX_PDIV_SHIFT (8)
641 #define PLL45XX_SDIV_SHIFT (0)
642 #define PLL45XX_AFC_SHIFT (0)
643
644 #define PLL45XX_ENABLE BIT(31)
645 #define PLL45XX_LOCKED BIT(29)
646
samsung_pll45xx_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)647 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
648 unsigned long parent_rate)
649 {
650 struct samsung_clk_pll *pll = to_clk_pll(hw);
651 u32 mdiv, pdiv, sdiv, pll_con;
652 u64 fvco = parent_rate;
653
654 pll_con = readl_relaxed(pll->con_reg);
655 mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
656 pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
657 sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
658
659 if (pll->type == pll_4508)
660 sdiv = sdiv - 1;
661
662 fvco *= mdiv;
663 do_div(fvco, (pdiv << sdiv));
664
665 return (unsigned long)fvco;
666 }
667
samsung_pll45xx_mp_change(u32 pll_con0,u32 pll_con1,const struct samsung_pll_rate_table * rate)668 static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
669 const struct samsung_pll_rate_table *rate)
670 {
671 u32 old_mdiv, old_pdiv, old_afc;
672
673 old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
674 old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
675 old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK;
676
677 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
678 || old_afc != rate->afc);
679 }
680
samsung_pll45xx_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)681 static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
682 unsigned long prate)
683 {
684 struct samsung_clk_pll *pll = to_clk_pll(hw);
685 const struct samsung_pll_rate_table *rate;
686 u32 con0, con1;
687
688 /* Get required rate settings from table */
689 rate = samsung_get_pll_settings(pll, drate);
690 if (!rate) {
691 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
692 drate, clk_hw_get_name(hw));
693 return -EINVAL;
694 }
695
696 con0 = readl_relaxed(pll->con_reg);
697 con1 = readl_relaxed(pll->con_reg + 0x4);
698
699 if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
700 /* If only s change, change just s value only*/
701 con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
702 con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
703 writel_relaxed(con0, pll->con_reg);
704
705 return 0;
706 }
707
708 /* Set PLL PMS values. */
709 con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
710 (PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
711 (PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
712 con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) |
713 (rate->pdiv << PLL45XX_PDIV_SHIFT) |
714 (rate->sdiv << PLL45XX_SDIV_SHIFT);
715
716 /* Set PLL AFC value. */
717 con1 = readl_relaxed(pll->con_reg + 0x4);
718 con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
719 con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
720
721 /* Set PLL lock time. */
722 switch (pll->type) {
723 case pll_4502:
724 writel_relaxed(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
725 break;
726 case pll_4508:
727 writel_relaxed(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
728 break;
729 default:
730 break;
731 }
732
733 /* Set new configuration. */
734 writel_relaxed(con1, pll->con_reg + 0x4);
735 writel_relaxed(con0, pll->con_reg);
736
737 /* Wait for PLL lock */
738 return samsung_pll_lock_wait(pll, PLL45XX_LOCKED);
739 }
740
741 static const struct clk_ops samsung_pll45xx_clk_ops = {
742 .recalc_rate = samsung_pll45xx_recalc_rate,
743 .determine_rate = samsung_pll_determine_rate,
744 .set_rate = samsung_pll45xx_set_rate,
745 };
746
747 static const struct clk_ops samsung_pll45xx_clk_min_ops = {
748 .recalc_rate = samsung_pll45xx_recalc_rate,
749 };
750
751 /*
752 * PLL46xx Clock Type
753 */
754 #define PLL46XX_LOCK_FACTOR 3000
755
756 #define PLL46XX_VSEL_MASK (1)
757 #define PLL46XX_MDIV_MASK (0x1FF)
758 #define PLL1460X_MDIV_MASK (0x3FF)
759
760 #define PLL46XX_PDIV_MASK (0x3F)
761 #define PLL46XX_SDIV_MASK (0x7)
762 #define PLL46XX_VSEL_SHIFT (27)
763 #define PLL46XX_MDIV_SHIFT (16)
764 #define PLL46XX_PDIV_SHIFT (8)
765 #define PLL46XX_SDIV_SHIFT (0)
766
767 #define PLL46XX_KDIV_MASK (0xFFFF)
768 #define PLL4650C_KDIV_MASK (0xFFF)
769 #define PLL46XX_KDIV_SHIFT (0)
770 #define PLL46XX_MFR_MASK (0x3F)
771 #define PLL46XX_MRR_MASK (0x1F)
772 #define PLL46XX_KDIV_SHIFT (0)
773 #define PLL46XX_MFR_SHIFT (16)
774 #define PLL46XX_MRR_SHIFT (24)
775
776 #define PLL46XX_ENABLE BIT(31)
777 #define PLL46XX_LOCKED BIT(29)
778 #define PLL46XX_VSEL BIT(27)
779
samsung_pll46xx_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)780 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
781 unsigned long parent_rate)
782 {
783 struct samsung_clk_pll *pll = to_clk_pll(hw);
784 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
785 u64 fvco = parent_rate;
786
787 pll_con0 = readl_relaxed(pll->con_reg);
788 pll_con1 = readl_relaxed(pll->con_reg + 4);
789 mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & ((pll->type == pll_1460x) ?
790 PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK);
791 pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
792 sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
793 kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
794 pll_con1 & PLL46XX_KDIV_MASK;
795
796 shift = ((pll->type == pll_4600) || (pll->type == pll_1460x)) ? 16 : 10;
797
798 fvco *= (mdiv << shift) + kdiv;
799 do_div(fvco, (pdiv << sdiv));
800 fvco >>= shift;
801
802 return (unsigned long)fvco;
803 }
804
samsung_pll46xx_mpk_change(u32 pll_con0,u32 pll_con1,const struct samsung_pll_rate_table * rate)805 static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
806 const struct samsung_pll_rate_table *rate)
807 {
808 u32 old_mdiv, old_pdiv, old_kdiv;
809
810 old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
811 old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
812 old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
813
814 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
815 || old_kdiv != rate->kdiv);
816 }
817
samsung_pll46xx_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)818 static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
819 unsigned long prate)
820 {
821 struct samsung_clk_pll *pll = to_clk_pll(hw);
822 const struct samsung_pll_rate_table *rate;
823 u32 con0, con1, lock;
824
825 /* Get required rate settings from table */
826 rate = samsung_get_pll_settings(pll, drate);
827 if (!rate) {
828 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
829 drate, clk_hw_get_name(hw));
830 return -EINVAL;
831 }
832
833 con0 = readl_relaxed(pll->con_reg);
834 con1 = readl_relaxed(pll->con_reg + 0x4);
835
836 if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
837 /* If only s change, change just s value only*/
838 con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
839 con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
840 writel_relaxed(con0, pll->con_reg);
841
842 return 0;
843 }
844
845 /* Set PLL lock time. */
846 lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
847 if (lock > 0xffff)
848 /* Maximum lock time bitfield is 16-bit. */
849 lock = 0xffff;
850
851 /* Set PLL PMS and VSEL values. */
852 if (pll->type == pll_1460x) {
853 con0 &= ~((PLL1460X_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
854 (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
855 (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT));
856 } else {
857 con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
858 (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
859 (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
860 (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
861 con0 |= rate->vsel << PLL46XX_VSEL_SHIFT;
862 }
863
864 con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
865 (rate->pdiv << PLL46XX_PDIV_SHIFT) |
866 (rate->sdiv << PLL46XX_SDIV_SHIFT);
867
868 /* Set PLL K, MFR and MRR values. */
869 con1 = readl_relaxed(pll->con_reg + 0x4);
870 con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
871 (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
872 (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
873 con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) |
874 (rate->mfr << PLL46XX_MFR_SHIFT) |
875 (rate->mrr << PLL46XX_MRR_SHIFT);
876
877 /* Write configuration to PLL */
878 writel_relaxed(lock, pll->lock_reg);
879 writel_relaxed(con0, pll->con_reg);
880 writel_relaxed(con1, pll->con_reg + 0x4);
881
882 /* Wait for PLL lock */
883 return samsung_pll_lock_wait(pll, PLL46XX_LOCKED);
884 }
885
886 static const struct clk_ops samsung_pll46xx_clk_ops = {
887 .recalc_rate = samsung_pll46xx_recalc_rate,
888 .determine_rate = samsung_pll_determine_rate,
889 .set_rate = samsung_pll46xx_set_rate,
890 };
891
892 static const struct clk_ops samsung_pll46xx_clk_min_ops = {
893 .recalc_rate = samsung_pll46xx_recalc_rate,
894 };
895
896 /*
897 * PLL6552 Clock Type
898 */
899
900 #define PLL6552_MDIV_MASK 0x3ff
901 #define PLL6552_PDIV_MASK 0x3f
902 #define PLL6552_SDIV_MASK 0x7
903 #define PLL6552_MDIV_SHIFT 16
904 #define PLL6552_MDIV_SHIFT_2416 14
905 #define PLL6552_PDIV_SHIFT 8
906 #define PLL6552_PDIV_SHIFT_2416 5
907 #define PLL6552_SDIV_SHIFT 0
908
samsung_pll6552_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)909 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
910 unsigned long parent_rate)
911 {
912 struct samsung_clk_pll *pll = to_clk_pll(hw);
913 u32 mdiv, pdiv, sdiv, pll_con;
914 u64 fvco = parent_rate;
915
916 pll_con = readl_relaxed(pll->con_reg);
917 if (pll->type == pll_6552_s3c2416) {
918 mdiv = (pll_con >> PLL6552_MDIV_SHIFT_2416) & PLL6552_MDIV_MASK;
919 pdiv = (pll_con >> PLL6552_PDIV_SHIFT_2416) & PLL6552_PDIV_MASK;
920 } else {
921 mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
922 pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
923 }
924 sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
925
926 fvco *= mdiv;
927 do_div(fvco, (pdiv << sdiv));
928
929 return (unsigned long)fvco;
930 }
931
932 static const struct clk_ops samsung_pll6552_clk_ops = {
933 .recalc_rate = samsung_pll6552_recalc_rate,
934 };
935
936 /*
937 * PLL6553 Clock Type
938 */
939
940 #define PLL6553_MDIV_MASK 0xff
941 #define PLL6553_PDIV_MASK 0x3f
942 #define PLL6553_SDIV_MASK 0x7
943 #define PLL6553_KDIV_MASK 0xffff
944 #define PLL6553_MDIV_SHIFT 16
945 #define PLL6553_PDIV_SHIFT 8
946 #define PLL6553_SDIV_SHIFT 0
947 #define PLL6553_KDIV_SHIFT 0
948
samsung_pll6553_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)949 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
950 unsigned long parent_rate)
951 {
952 struct samsung_clk_pll *pll = to_clk_pll(hw);
953 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
954 u64 fvco = parent_rate;
955
956 pll_con0 = readl_relaxed(pll->con_reg);
957 pll_con1 = readl_relaxed(pll->con_reg + 0x4);
958 mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
959 pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
960 sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
961 kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
962
963 fvco *= (mdiv << 16) + kdiv;
964 do_div(fvco, (pdiv << sdiv));
965 fvco >>= 16;
966
967 return (unsigned long)fvco;
968 }
969
970 static const struct clk_ops samsung_pll6553_clk_ops = {
971 .recalc_rate = samsung_pll6553_recalc_rate,
972 };
973
974 /*
975 * PLL2550x Clock Type
976 */
977
978 #define PLL2550X_R_MASK (0x1)
979 #define PLL2550X_P_MASK (0x3F)
980 #define PLL2550X_M_MASK (0x3FF)
981 #define PLL2550X_S_MASK (0x7)
982 #define PLL2550X_R_SHIFT (20)
983 #define PLL2550X_P_SHIFT (14)
984 #define PLL2550X_M_SHIFT (4)
985 #define PLL2550X_S_SHIFT (0)
986
samsung_pll2550x_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)987 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
988 unsigned long parent_rate)
989 {
990 struct samsung_clk_pll *pll = to_clk_pll(hw);
991 u32 r, p, m, s, pll_stat;
992 u64 fvco = parent_rate;
993
994 pll_stat = readl_relaxed(pll->con_reg);
995 r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
996 if (!r)
997 return 0;
998 p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK;
999 m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK;
1000 s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK;
1001
1002 fvco *= m;
1003 do_div(fvco, (p << s));
1004
1005 return (unsigned long)fvco;
1006 }
1007
1008 static const struct clk_ops samsung_pll2550x_clk_ops = {
1009 .recalc_rate = samsung_pll2550x_recalc_rate,
1010 };
1011
1012 /*
1013 * PLL2550xx Clock Type
1014 */
1015
1016 /* Maximum lock time can be 270 * PDIV cycles */
1017 #define PLL2550XX_LOCK_FACTOR 270
1018
1019 #define PLL2550XX_M_MASK 0x3FF
1020 #define PLL2550XX_P_MASK 0x3F
1021 #define PLL2550XX_S_MASK 0x7
1022 #define PLL2550XX_LOCK_STAT_MASK 0x1
1023 #define PLL2550XX_M_SHIFT 9
1024 #define PLL2550XX_P_SHIFT 3
1025 #define PLL2550XX_S_SHIFT 0
1026 #define PLL2550XX_LOCK_STAT_SHIFT 21
1027
samsung_pll2550xx_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)1028 static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw *hw,
1029 unsigned long parent_rate)
1030 {
1031 struct samsung_clk_pll *pll = to_clk_pll(hw);
1032 u32 mdiv, pdiv, sdiv, pll_con;
1033 u64 fvco = parent_rate;
1034
1035 pll_con = readl_relaxed(pll->con_reg);
1036 mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
1037 pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
1038 sdiv = (pll_con >> PLL2550XX_S_SHIFT) & PLL2550XX_S_MASK;
1039
1040 fvco *= mdiv;
1041 do_div(fvco, (pdiv << sdiv));
1042
1043 return (unsigned long)fvco;
1044 }
1045
samsung_pll2550xx_mp_change(u32 mdiv,u32 pdiv,u32 pll_con)1046 static inline bool samsung_pll2550xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con)
1047 {
1048 u32 old_mdiv, old_pdiv;
1049
1050 old_mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
1051 old_pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
1052
1053 return mdiv != old_mdiv || pdiv != old_pdiv;
1054 }
1055
samsung_pll2550xx_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)1056 static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
1057 unsigned long prate)
1058 {
1059 struct samsung_clk_pll *pll = to_clk_pll(hw);
1060 const struct samsung_pll_rate_table *rate;
1061 u32 tmp;
1062
1063 /* Get required rate settings from table */
1064 rate = samsung_get_pll_settings(pll, drate);
1065 if (!rate) {
1066 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1067 drate, clk_hw_get_name(hw));
1068 return -EINVAL;
1069 }
1070
1071 tmp = readl_relaxed(pll->con_reg);
1072
1073 if (!(samsung_pll2550xx_mp_change(rate->mdiv, rate->pdiv, tmp))) {
1074 /* If only s change, change just s value only*/
1075 tmp &= ~(PLL2550XX_S_MASK << PLL2550XX_S_SHIFT);
1076 tmp |= rate->sdiv << PLL2550XX_S_SHIFT;
1077 writel_relaxed(tmp, pll->con_reg);
1078
1079 return 0;
1080 }
1081
1082 /* Set PLL lock time. */
1083 writel_relaxed(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg);
1084
1085 /* Change PLL PMS values */
1086 tmp &= ~((PLL2550XX_M_MASK << PLL2550XX_M_SHIFT) |
1087 (PLL2550XX_P_MASK << PLL2550XX_P_SHIFT) |
1088 (PLL2550XX_S_MASK << PLL2550XX_S_SHIFT));
1089 tmp |= (rate->mdiv << PLL2550XX_M_SHIFT) |
1090 (rate->pdiv << PLL2550XX_P_SHIFT) |
1091 (rate->sdiv << PLL2550XX_S_SHIFT);
1092 writel_relaxed(tmp, pll->con_reg);
1093
1094 /* Wait for PLL lock */
1095 return samsung_pll_lock_wait(pll,
1096 PLL2550XX_LOCK_STAT_MASK << PLL2550XX_LOCK_STAT_SHIFT);
1097 }
1098
1099 static const struct clk_ops samsung_pll2550xx_clk_ops = {
1100 .recalc_rate = samsung_pll2550xx_recalc_rate,
1101 .determine_rate = samsung_pll_determine_rate,
1102 .set_rate = samsung_pll2550xx_set_rate,
1103 };
1104
1105 static const struct clk_ops samsung_pll2550xx_clk_min_ops = {
1106 .recalc_rate = samsung_pll2550xx_recalc_rate,
1107 };
1108
1109 /*
1110 * PLL2650x Clock Type
1111 */
1112
1113 /* Maximum lock time can be 3000 * PDIV cycles */
1114 #define PLL2650X_LOCK_FACTOR 3000
1115
1116 #define PLL2650X_M_MASK 0x1ff
1117 #define PLL2650X_P_MASK 0x3f
1118 #define PLL2650X_S_MASK 0x7
1119 #define PLL2650X_K_MASK 0xffff
1120 #define PLL2650X_LOCK_STAT_MASK 0x1
1121 #define PLL2650X_M_SHIFT 16
1122 #define PLL2650X_P_SHIFT 8
1123 #define PLL2650X_S_SHIFT 0
1124 #define PLL2650X_K_SHIFT 0
1125 #define PLL2650X_LOCK_STAT_SHIFT 29
1126 #define PLL2650X_PLL_ENABLE_SHIFT 31
1127
samsung_pll2650x_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)1128 static unsigned long samsung_pll2650x_recalc_rate(struct clk_hw *hw,
1129 unsigned long parent_rate)
1130 {
1131 struct samsung_clk_pll *pll = to_clk_pll(hw);
1132 u64 fout = parent_rate;
1133 u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
1134 s16 kdiv;
1135
1136 pll_con0 = readl_relaxed(pll->con_reg);
1137 mdiv = (pll_con0 >> PLL2650X_M_SHIFT) & PLL2650X_M_MASK;
1138 pdiv = (pll_con0 >> PLL2650X_P_SHIFT) & PLL2650X_P_MASK;
1139 sdiv = (pll_con0 >> PLL2650X_S_SHIFT) & PLL2650X_S_MASK;
1140
1141 pll_con1 = readl_relaxed(pll->con_reg + 4);
1142 kdiv = (s16)((pll_con1 >> PLL2650X_K_SHIFT) & PLL2650X_K_MASK);
1143
1144 fout *= (mdiv << 16) + kdiv;
1145 do_div(fout, (pdiv << sdiv));
1146 fout >>= 16;
1147
1148 return (unsigned long)fout;
1149 }
1150
samsung_pll2650x_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)1151 static int samsung_pll2650x_set_rate(struct clk_hw *hw, unsigned long drate,
1152 unsigned long prate)
1153 {
1154 struct samsung_clk_pll *pll = to_clk_pll(hw);
1155 const struct samsung_pll_rate_table *rate;
1156 u32 con0, con1;
1157
1158 /* Get required rate settings from table */
1159 rate = samsung_get_pll_settings(pll, drate);
1160 if (!rate) {
1161 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1162 drate, clk_hw_get_name(hw));
1163 return -EINVAL;
1164 }
1165
1166 con0 = readl_relaxed(pll->con_reg);
1167 con1 = readl_relaxed(pll->con_reg + 4);
1168
1169 /* Set PLL lock time. */
1170 writel_relaxed(rate->pdiv * PLL2650X_LOCK_FACTOR, pll->lock_reg);
1171
1172 /* Change PLL PMS values */
1173 con0 &= ~((PLL2650X_M_MASK << PLL2650X_M_SHIFT) |
1174 (PLL2650X_P_MASK << PLL2650X_P_SHIFT) |
1175 (PLL2650X_S_MASK << PLL2650X_S_SHIFT));
1176 con0 |= (rate->mdiv << PLL2650X_M_SHIFT) |
1177 (rate->pdiv << PLL2650X_P_SHIFT) |
1178 (rate->sdiv << PLL2650X_S_SHIFT);
1179 con0 |= (1 << PLL2650X_PLL_ENABLE_SHIFT);
1180 writel_relaxed(con0, pll->con_reg);
1181
1182 con1 &= ~(PLL2650X_K_MASK << PLL2650X_K_SHIFT);
1183 con1 |= ((rate->kdiv & PLL2650X_K_MASK) << PLL2650X_K_SHIFT);
1184 writel_relaxed(con1, pll->con_reg + 4);
1185
1186 /* Wait for PLL lock */
1187 return samsung_pll_lock_wait(pll,
1188 PLL2650X_LOCK_STAT_MASK << PLL2650X_LOCK_STAT_SHIFT);
1189 }
1190
1191 static const struct clk_ops samsung_pll2650x_clk_ops = {
1192 .recalc_rate = samsung_pll2650x_recalc_rate,
1193 .determine_rate = samsung_pll_determine_rate,
1194 .set_rate = samsung_pll2650x_set_rate,
1195 };
1196
1197 static const struct clk_ops samsung_pll2650x_clk_min_ops = {
1198 .recalc_rate = samsung_pll2650x_recalc_rate,
1199 };
1200
1201 /*
1202 * PLL2650XX Clock Type
1203 */
1204
1205 /* Maximum lock time can be 3000 * PDIV cycles */
1206 #define PLL2650XX_LOCK_FACTOR 3000
1207
1208 #define PLL2650XX_MDIV_SHIFT 9
1209 #define PLL2650XX_PDIV_SHIFT 3
1210 #define PLL2650XX_SDIV_SHIFT 0
1211 #define PLL2650XX_KDIV_SHIFT 0
1212 #define PLL2650XX_MDIV_MASK 0x1ff
1213 #define PLL2650XX_PDIV_MASK 0x3f
1214 #define PLL2650XX_SDIV_MASK 0x7
1215 #define PLL2650XX_KDIV_MASK 0xffff
1216 #define PLL2650XX_PLL_ENABLE_SHIFT 23
1217 #define PLL2650XX_PLL_LOCKTIME_SHIFT 21
1218 #define PLL2650XX_PLL_FOUTMASK_SHIFT 31
1219
samsung_pll2650xx_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)1220 static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw,
1221 unsigned long parent_rate)
1222 {
1223 struct samsung_clk_pll *pll = to_clk_pll(hw);
1224 u32 mdiv, pdiv, sdiv, pll_con0, pll_con2;
1225 s16 kdiv;
1226 u64 fvco = parent_rate;
1227
1228 pll_con0 = readl_relaxed(pll->con_reg);
1229 pll_con2 = readl_relaxed(pll->con_reg + 8);
1230 mdiv = (pll_con0 >> PLL2650XX_MDIV_SHIFT) & PLL2650XX_MDIV_MASK;
1231 pdiv = (pll_con0 >> PLL2650XX_PDIV_SHIFT) & PLL2650XX_PDIV_MASK;
1232 sdiv = (pll_con0 >> PLL2650XX_SDIV_SHIFT) & PLL2650XX_SDIV_MASK;
1233 kdiv = (s16)(pll_con2 & PLL2650XX_KDIV_MASK);
1234
1235 fvco *= (mdiv << 16) + kdiv;
1236 do_div(fvco, (pdiv << sdiv));
1237 fvco >>= 16;
1238
1239 return (unsigned long)fvco;
1240 }
1241
samsung_pll2650xx_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long parent_rate)1242 static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
1243 unsigned long parent_rate)
1244 {
1245 struct samsung_clk_pll *pll = to_clk_pll(hw);
1246 u32 pll_con0, pll_con2;
1247 const struct samsung_pll_rate_table *rate;
1248
1249 rate = samsung_get_pll_settings(pll, drate);
1250 if (!rate) {
1251 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1252 drate, clk_hw_get_name(hw));
1253 return -EINVAL;
1254 }
1255
1256 pll_con0 = readl_relaxed(pll->con_reg);
1257 pll_con2 = readl_relaxed(pll->con_reg + 8);
1258
1259 /* Change PLL PMS values */
1260 pll_con0 &= ~(PLL2650XX_MDIV_MASK << PLL2650XX_MDIV_SHIFT |
1261 PLL2650XX_PDIV_MASK << PLL2650XX_PDIV_SHIFT |
1262 PLL2650XX_SDIV_MASK << PLL2650XX_SDIV_SHIFT);
1263 pll_con0 |= rate->mdiv << PLL2650XX_MDIV_SHIFT;
1264 pll_con0 |= rate->pdiv << PLL2650XX_PDIV_SHIFT;
1265 pll_con0 |= rate->sdiv << PLL2650XX_SDIV_SHIFT;
1266 pll_con0 |= 1 << PLL2650XX_PLL_ENABLE_SHIFT;
1267 pll_con0 |= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT;
1268
1269 pll_con2 &= ~(PLL2650XX_KDIV_MASK << PLL2650XX_KDIV_SHIFT);
1270 pll_con2 |= ((~(rate->kdiv) + 1) & PLL2650XX_KDIV_MASK)
1271 << PLL2650XX_KDIV_SHIFT;
1272
1273 /* Set PLL lock time. */
1274 writel_relaxed(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg);
1275
1276 writel_relaxed(pll_con0, pll->con_reg);
1277 writel_relaxed(pll_con2, pll->con_reg + 8);
1278
1279 return samsung_pll_lock_wait(pll, 0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT);
1280 }
1281
1282 static const struct clk_ops samsung_pll2650xx_clk_ops = {
1283 .recalc_rate = samsung_pll2650xx_recalc_rate,
1284 .set_rate = samsung_pll2650xx_set_rate,
1285 .determine_rate = samsung_pll_determine_rate,
1286 };
1287
1288 static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
1289 .recalc_rate = samsung_pll2650xx_recalc_rate,
1290 };
1291
1292 /*
1293 * PLL531X Clock Type
1294 */
1295 /* Maximum lock time can be 500 * PDIV cycles */
1296 #define PLL531X_LOCK_FACTOR (500)
1297 #define PLL531X_MDIV_MASK (0x3FF)
1298 #define PLL531X_PDIV_MASK (0x3F)
1299 #define PLL531X_SDIV_MASK (0x7)
1300 #define PLL531X_FDIV_MASK (0xFFFFFFFF)
1301 #define PLL531X_MDIV_SHIFT (16)
1302 #define PLL531X_PDIV_SHIFT (8)
1303 #define PLL531X_SDIV_SHIFT (0)
1304
samsung_pll531x_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)1305 static unsigned long samsung_pll531x_recalc_rate(struct clk_hw *hw,
1306 unsigned long parent_rate)
1307 {
1308 struct samsung_clk_pll *pll = to_clk_pll(hw);
1309 u32 pdiv, sdiv, fdiv, pll_con0, pll_con8;
1310 u64 mdiv, fout = parent_rate;
1311
1312 pll_con0 = readl_relaxed(pll->con_reg);
1313 pll_con8 = readl_relaxed(pll->con_reg + 20);
1314 mdiv = (pll_con0 >> PLL531X_MDIV_SHIFT) & PLL531X_MDIV_MASK;
1315 pdiv = (pll_con0 >> PLL531X_PDIV_SHIFT) & PLL531X_PDIV_MASK;
1316 sdiv = (pll_con0 >> PLL531X_SDIV_SHIFT) & PLL531X_SDIV_MASK;
1317 fdiv = (pll_con8 & PLL531X_FDIV_MASK);
1318
1319 if (fdiv >> 31)
1320 mdiv--;
1321
1322 fout *= (mdiv << 24) + (fdiv >> 8);
1323 do_div(fout, (pdiv << sdiv));
1324 fout >>= 24;
1325
1326 return (unsigned long)fout;
1327 }
1328
1329 static const struct clk_ops samsung_pll531x_clk_ops = {
1330 .recalc_rate = samsung_pll531x_recalc_rate,
1331 };
1332
1333 /*
1334 * PLL1031x Clock Type
1335 */
1336 #define PLL1031X_LOCK_FACTOR (500)
1337
1338 #define PLL1031X_MDIV_MASK (0x3ff)
1339 #define PLL1031X_PDIV_MASK (0x3f)
1340 #define PLL1031X_SDIV_MASK (0x7)
1341 #define PLL1031X_MDIV_SHIFT (16)
1342 #define PLL1031X_PDIV_SHIFT (8)
1343 #define PLL1031X_SDIV_SHIFT (0)
1344
1345 #define PLL1031X_KDIV_MASK (0xffff)
1346 #define PLL1031X_KDIV_SHIFT (0)
1347 #define PLL1031X_MFR_MASK (0x3f)
1348 #define PLL1031X_MRR_MASK (0x1f)
1349 #define PLL1031X_MFR_SHIFT (16)
1350 #define PLL1031X_MRR_SHIFT (24)
1351
samsung_pll1031x_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)1352 static unsigned long samsung_pll1031x_recalc_rate(struct clk_hw *hw,
1353 unsigned long parent_rate)
1354 {
1355 struct samsung_clk_pll *pll = to_clk_pll(hw);
1356 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con3;
1357 u64 fvco = parent_rate;
1358
1359 pll_con0 = readl_relaxed(pll->con_reg);
1360 pll_con3 = readl_relaxed(pll->con_reg + 0xc);
1361 mdiv = (pll_con0 >> PLL1031X_MDIV_SHIFT) & PLL1031X_MDIV_MASK;
1362 pdiv = (pll_con0 >> PLL1031X_PDIV_SHIFT) & PLL1031X_PDIV_MASK;
1363 sdiv = (pll_con0 >> PLL1031X_SDIV_SHIFT) & PLL1031X_SDIV_MASK;
1364 kdiv = (pll_con3 & PLL1031X_KDIV_MASK);
1365
1366 fvco *= (mdiv << PLL1031X_MDIV_SHIFT) + kdiv;
1367 do_div(fvco, (pdiv << sdiv));
1368 fvco >>= PLL1031X_MDIV_SHIFT;
1369
1370 return (unsigned long)fvco;
1371 }
1372
samsung_pll1031x_mpk_change(u32 pll_con0,u32 pll_con3,const struct samsung_pll_rate_table * rate)1373 static bool samsung_pll1031x_mpk_change(u32 pll_con0, u32 pll_con3,
1374 const struct samsung_pll_rate_table *rate)
1375 {
1376 u32 old_mdiv, old_pdiv, old_kdiv;
1377
1378 old_mdiv = (pll_con0 >> PLL1031X_MDIV_SHIFT) & PLL1031X_MDIV_MASK;
1379 old_pdiv = (pll_con0 >> PLL1031X_PDIV_SHIFT) & PLL1031X_PDIV_MASK;
1380 old_kdiv = (pll_con3 >> PLL1031X_KDIV_SHIFT) & PLL1031X_KDIV_MASK;
1381
1382 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv ||
1383 old_kdiv != rate->kdiv);
1384 }
1385
samsung_pll1031x_set_rate(struct clk_hw * hw,unsigned long drate,unsigned long prate)1386 static int samsung_pll1031x_set_rate(struct clk_hw *hw, unsigned long drate,
1387 unsigned long prate)
1388 {
1389 struct samsung_clk_pll *pll = to_clk_pll(hw);
1390 const struct samsung_pll_rate_table *rate;
1391 u32 con0, con3;
1392
1393 /* Get required rate settings from table */
1394 rate = samsung_get_pll_settings(pll, drate);
1395 if (!rate) {
1396 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1397 drate, clk_hw_get_name(hw));
1398 return -EINVAL;
1399 }
1400
1401 con0 = readl_relaxed(pll->con_reg);
1402 con3 = readl_relaxed(pll->con_reg + 0xc);
1403
1404 if (!(samsung_pll1031x_mpk_change(con0, con3, rate))) {
1405 /* If only s change, change just s value only */
1406 con0 &= ~(PLL1031X_SDIV_MASK << PLL1031X_SDIV_SHIFT);
1407 con0 |= rate->sdiv << PLL1031X_SDIV_SHIFT;
1408 writel_relaxed(con0, pll->con_reg);
1409
1410 return 0;
1411 }
1412
1413 /* Set PLL lock time. */
1414 writel_relaxed(rate->pdiv * PLL1031X_LOCK_FACTOR, pll->lock_reg);
1415
1416 /* Set PLL M, P, and S values. */
1417 con0 &= ~((PLL1031X_MDIV_MASK << PLL1031X_MDIV_SHIFT) |
1418 (PLL1031X_PDIV_MASK << PLL1031X_PDIV_SHIFT) |
1419 (PLL1031X_SDIV_MASK << PLL1031X_SDIV_SHIFT));
1420
1421 con0 |= (rate->mdiv << PLL1031X_MDIV_SHIFT) |
1422 (rate->pdiv << PLL1031X_PDIV_SHIFT) |
1423 (rate->sdiv << PLL1031X_SDIV_SHIFT);
1424
1425 /* Set PLL K, MFR and MRR values. */
1426 con3 = readl_relaxed(pll->con_reg + 0xc);
1427 con3 &= ~((PLL1031X_KDIV_MASK << PLL1031X_KDIV_SHIFT) |
1428 (PLL1031X_MFR_MASK << PLL1031X_MFR_SHIFT) |
1429 (PLL1031X_MRR_MASK << PLL1031X_MRR_SHIFT));
1430 con3 |= (rate->kdiv << PLL1031X_KDIV_SHIFT) |
1431 (rate->mfr << PLL1031X_MFR_SHIFT) |
1432 (rate->mrr << PLL1031X_MRR_SHIFT);
1433
1434 /* Write configuration to PLL */
1435 writel_relaxed(con0, pll->con_reg);
1436 writel_relaxed(con3, pll->con_reg + 0xc);
1437
1438 /* Wait for PLL lock if the PLL is enabled */
1439 return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
1440 }
1441
1442 static const struct clk_ops samsung_pll1031x_clk_ops = {
1443 .recalc_rate = samsung_pll1031x_recalc_rate,
1444 .determine_rate = samsung_pll_determine_rate,
1445 .set_rate = samsung_pll1031x_set_rate,
1446 };
1447
1448 static const struct clk_ops samsung_pll1031x_clk_min_ops = {
1449 .recalc_rate = samsung_pll1031x_recalc_rate,
1450 };
1451
_samsung_clk_register_pll(struct samsung_clk_provider * ctx,const struct samsung_pll_clock * pll_clk)1452 static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1453 const struct samsung_pll_clock *pll_clk)
1454 {
1455 struct samsung_clk_pll *pll;
1456 struct clk_init_data init;
1457 int ret, len;
1458
1459 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
1460 if (!pll) {
1461 pr_err("%s: could not allocate pll clk %s\n",
1462 __func__, pll_clk->name);
1463 return;
1464 }
1465
1466 init.name = pll_clk->name;
1467 init.flags = pll_clk->flags;
1468 init.parent_names = &pll_clk->parent_name;
1469 init.num_parents = 1;
1470
1471 if (pll_clk->rate_table) {
1472 /* find count of rates in rate_table */
1473 for (len = 0; pll_clk->rate_table[len].rate != 0; )
1474 len++;
1475
1476 pll->rate_count = len;
1477 pll->rate_table = kmemdup_array(pll_clk->rate_table,
1478 pll->rate_count,
1479 sizeof(*pll->rate_table),
1480 GFP_KERNEL);
1481 WARN(!pll->rate_table,
1482 "%s: could not allocate rate table for %s\n",
1483 __func__, pll_clk->name);
1484 }
1485
1486 switch (pll_clk->type) {
1487 case pll_2126:
1488 init.ops = &samsung_pll2126_clk_ops;
1489 break;
1490 case pll_3000:
1491 init.ops = &samsung_pll3000_clk_ops;
1492 break;
1493 /* clk_ops for 35xx and 2550 are similar */
1494 case pll_35xx:
1495 case pll_2550:
1496 case pll_1450x:
1497 case pll_1451x:
1498 case pll_1452x:
1499 case pll_142xx:
1500 case pll_1017x:
1501 pll->enable_offs = PLL35XX_ENABLE_SHIFT;
1502 pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
1503 if (!pll->rate_table)
1504 init.ops = &samsung_pll35xx_clk_min_ops;
1505 else
1506 init.ops = &samsung_pll35xx_clk_ops;
1507 break;
1508 case pll_1417x:
1509 case pll_1418x:
1510 case pll_1051x:
1511 case pll_1052x:
1512 case pll_0818x:
1513 case pll_0822x:
1514 case pll_0516x:
1515 case pll_0517x:
1516 case pll_0518x:
1517 case pll_0717x:
1518 case pll_0718x:
1519 case pll_0732x:
1520 pll->enable_offs = PLL0822X_ENABLE_SHIFT;
1521 pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
1522 if (!pll->rate_table)
1523 init.ops = &samsung_pll0822x_clk_min_ops;
1524 else
1525 init.ops = &samsung_pll0822x_clk_ops;
1526 break;
1527 case pll_4500:
1528 init.ops = &samsung_pll45xx_clk_min_ops;
1529 break;
1530 case pll_4502:
1531 case pll_4508:
1532 if (!pll->rate_table)
1533 init.ops = &samsung_pll45xx_clk_min_ops;
1534 else
1535 init.ops = &samsung_pll45xx_clk_ops;
1536 break;
1537 /* clk_ops for 36xx and 2650 are similar */
1538 case pll_36xx:
1539 case pll_2650:
1540 pll->enable_offs = PLL36XX_ENABLE_SHIFT;
1541 pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT;
1542 if (!pll->rate_table)
1543 init.ops = &samsung_pll36xx_clk_min_ops;
1544 else
1545 init.ops = &samsung_pll36xx_clk_ops;
1546 break;
1547 case pll_0831x:
1548 pll->enable_offs = PLL0831X_ENABLE_SHIFT;
1549 pll->lock_offs = PLL0831X_LOCK_STAT_SHIFT;
1550 if (!pll->rate_table)
1551 init.ops = &samsung_pll0831x_clk_min_ops;
1552 else
1553 init.ops = &samsung_pll0831x_clk_ops;
1554 break;
1555 case pll_6552:
1556 case pll_6552_s3c2416:
1557 init.ops = &samsung_pll6552_clk_ops;
1558 break;
1559 case pll_6553:
1560 init.ops = &samsung_pll6553_clk_ops;
1561 break;
1562 case pll_4600:
1563 case pll_4650:
1564 case pll_4650c:
1565 case pll_1460x:
1566 if (!pll->rate_table)
1567 init.ops = &samsung_pll46xx_clk_min_ops;
1568 else
1569 init.ops = &samsung_pll46xx_clk_ops;
1570 break;
1571 case pll_2550x:
1572 init.ops = &samsung_pll2550x_clk_ops;
1573 break;
1574 case pll_2550xx:
1575 if (!pll->rate_table)
1576 init.ops = &samsung_pll2550xx_clk_min_ops;
1577 else
1578 init.ops = &samsung_pll2550xx_clk_ops;
1579 break;
1580 case pll_2650x:
1581 if (!pll->rate_table)
1582 init.ops = &samsung_pll2650x_clk_min_ops;
1583 else
1584 init.ops = &samsung_pll2650x_clk_ops;
1585 break;
1586 case pll_2650xx:
1587 if (!pll->rate_table)
1588 init.ops = &samsung_pll2650xx_clk_min_ops;
1589 else
1590 init.ops = &samsung_pll2650xx_clk_ops;
1591 break;
1592 case pll_531x:
1593 case pll_4311:
1594 init.ops = &samsung_pll531x_clk_ops;
1595 break;
1596 case pll_1031x:
1597 if (!pll->rate_table)
1598 init.ops = &samsung_pll1031x_clk_min_ops;
1599 else
1600 init.ops = &samsung_pll1031x_clk_ops;
1601 break;
1602 default:
1603 pr_warn("%s: Unknown pll type for pll clk %s\n",
1604 __func__, pll_clk->name);
1605 }
1606
1607 pll->hw.init = &init;
1608 pll->type = pll_clk->type;
1609 pll->lock_reg = ctx->reg_base + pll_clk->lock_offset;
1610 pll->con_reg = ctx->reg_base + pll_clk->con_offset;
1611
1612 ret = clk_hw_register(ctx->dev, &pll->hw);
1613 if (ret) {
1614 pr_err("%s: failed to register pll clock %s : %d\n",
1615 __func__, pll_clk->name, ret);
1616 kfree(pll->rate_table);
1617 kfree(pll);
1618 return;
1619 }
1620
1621 samsung_clk_add_lookup(ctx, &pll->hw, pll_clk->id);
1622 }
1623
samsung_clk_register_pll(struct samsung_clk_provider * ctx,const struct samsung_pll_clock * pll_list,unsigned int nr_pll)1624 void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1625 const struct samsung_pll_clock *pll_list,
1626 unsigned int nr_pll)
1627 {
1628 int cnt;
1629
1630 for (cnt = 0; cnt < nr_pll; cnt++)
1631 _samsung_clk_register_pll(ctx, &pll_list[cnt]);
1632 }
1633