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