1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 * Copyright (c) 2013 Linaro Ltd.
6 * This file contains the utility functions to register the pll clocks.
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>
20 #define PLL_TIMEOUT_US 20000U
21 #define PLL_TIMEOUT_LOOPS 1000000U
23 struct samsung_clk_pll
{
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
;
36 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
38 static const struct samsung_pll_rate_table
*samsung_get_pll_settings(
39 struct samsung_clk_pll
*pll
, unsigned long rate
)
41 const struct samsung_pll_rate_table
*rate_table
= pll
->rate_table
;
44 for (i
= 0; i
< pll
->rate_count
; i
++) {
45 if (rate
== rate_table
[i
].rate
)
46 return &rate_table
[i
];
52 static long samsung_pll_round_rate(struct clk_hw
*hw
,
53 unsigned long drate
, unsigned long *prate
)
55 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
56 const struct samsung_pll_rate_table
*rate_table
= pll
->rate_table
;
59 /* Assumming rate_table is in descending order */
60 for (i
= 0; i
< pll
->rate_count
; i
++) {
61 if (drate
>= rate_table
[i
].rate
)
62 return rate_table
[i
].rate
;
65 /* return minimum supported value */
66 return rate_table
[i
- 1].rate
;
69 static bool pll_early_timeout
= true;
71 static int __init
samsung_pll_disable_early_timeout(void)
73 pll_early_timeout
= false;
76 arch_initcall(samsung_pll_disable_early_timeout
);
78 /* Wait until the PLL is locked */
79 static int samsung_pll_lock_wait(struct samsung_clk_pll
*pll
,
80 unsigned int reg_mask
)
86 * This function might be called when the timekeeping API can't be used
87 * to detect timeouts. One situation is when the clocksource is not yet
88 * initialized, another when the timekeeping is suspended. udelay() also
89 * cannot be used when the clocksource is not running on arm64, since
90 * the current timer is used as cycle counter. So a simple busy loop
91 * is used here in that special cases. The limit of iterations has been
92 * derived from experimental measurements of various PLLs on multiple
93 * Exynos SoC variants. Single register read time was usually in range
94 * 0.4...1.5 us, never less than 0.4 us.
96 if (pll_early_timeout
|| timekeeping_suspended
) {
97 i
= PLL_TIMEOUT_LOOPS
;
99 if (readl_relaxed(pll
->con_reg
) & reg_mask
)
106 ret
= readl_relaxed_poll_timeout_atomic(pll
->con_reg
, val
,
107 val
& reg_mask
, 0, PLL_TIMEOUT_US
);
111 pr_err("Could not lock PLL %s\n", clk_hw_get_name(&pll
->hw
));
116 static int samsung_pll3xxx_enable(struct clk_hw
*hw
)
118 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
121 tmp
= readl_relaxed(pll
->con_reg
);
122 tmp
|= BIT(pll
->enable_offs
);
123 writel_relaxed(tmp
, pll
->con_reg
);
125 return samsung_pll_lock_wait(pll
, BIT(pll
->lock_offs
));
128 static void samsung_pll3xxx_disable(struct clk_hw
*hw
)
130 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
133 tmp
= readl_relaxed(pll
->con_reg
);
134 tmp
&= ~BIT(pll
->enable_offs
);
135 writel_relaxed(tmp
, pll
->con_reg
);
142 #define PLL2126_MDIV_MASK (0xff)
143 #define PLL2126_PDIV_MASK (0x3f)
144 #define PLL2126_SDIV_MASK (0x3)
145 #define PLL2126_MDIV_SHIFT (16)
146 #define PLL2126_PDIV_SHIFT (8)
147 #define PLL2126_SDIV_SHIFT (0)
149 static unsigned long samsung_pll2126_recalc_rate(struct clk_hw
*hw
,
150 unsigned long parent_rate
)
152 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
153 u32 pll_con
, mdiv
, pdiv
, sdiv
;
154 u64 fvco
= parent_rate
;
156 pll_con
= readl_relaxed(pll
->con_reg
);
157 mdiv
= (pll_con
>> PLL2126_MDIV_SHIFT
) & PLL2126_MDIV_MASK
;
158 pdiv
= (pll_con
>> PLL2126_PDIV_SHIFT
) & PLL2126_PDIV_MASK
;
159 sdiv
= (pll_con
>> PLL2126_SDIV_SHIFT
) & PLL2126_SDIV_MASK
;
162 do_div(fvco
, (pdiv
+ 2) << sdiv
);
164 return (unsigned long)fvco
;
167 static const struct clk_ops samsung_pll2126_clk_ops
= {
168 .recalc_rate
= samsung_pll2126_recalc_rate
,
175 #define PLL3000_MDIV_MASK (0xff)
176 #define PLL3000_PDIV_MASK (0x3)
177 #define PLL3000_SDIV_MASK (0x3)
178 #define PLL3000_MDIV_SHIFT (16)
179 #define PLL3000_PDIV_SHIFT (8)
180 #define PLL3000_SDIV_SHIFT (0)
182 static unsigned long samsung_pll3000_recalc_rate(struct clk_hw
*hw
,
183 unsigned long parent_rate
)
185 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
186 u32 pll_con
, mdiv
, pdiv
, sdiv
;
187 u64 fvco
= parent_rate
;
189 pll_con
= readl_relaxed(pll
->con_reg
);
190 mdiv
= (pll_con
>> PLL3000_MDIV_SHIFT
) & PLL3000_MDIV_MASK
;
191 pdiv
= (pll_con
>> PLL3000_PDIV_SHIFT
) & PLL3000_PDIV_MASK
;
192 sdiv
= (pll_con
>> PLL3000_SDIV_SHIFT
) & PLL3000_SDIV_MASK
;
194 fvco
*= (2 * (mdiv
+ 8));
195 do_div(fvco
, pdiv
<< sdiv
);
197 return (unsigned long)fvco
;
200 static const struct clk_ops samsung_pll3000_clk_ops
= {
201 .recalc_rate
= samsung_pll3000_recalc_rate
,
207 /* Maximum lock time can be 270 * PDIV cycles */
208 #define PLL35XX_LOCK_FACTOR (270)
210 #define PLL35XX_MDIV_MASK (0x3FF)
211 #define PLL35XX_PDIV_MASK (0x3F)
212 #define PLL35XX_SDIV_MASK (0x7)
213 #define PLL35XX_MDIV_SHIFT (16)
214 #define PLL35XX_PDIV_SHIFT (8)
215 #define PLL35XX_SDIV_SHIFT (0)
216 #define PLL35XX_LOCK_STAT_SHIFT (29)
217 #define PLL35XX_ENABLE_SHIFT (31)
219 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw
*hw
,
220 unsigned long parent_rate
)
222 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
223 u32 mdiv
, pdiv
, sdiv
, pll_con
;
224 u64 fvco
= parent_rate
;
226 pll_con
= readl_relaxed(pll
->con_reg
);
227 mdiv
= (pll_con
>> PLL35XX_MDIV_SHIFT
) & PLL35XX_MDIV_MASK
;
228 pdiv
= (pll_con
>> PLL35XX_PDIV_SHIFT
) & PLL35XX_PDIV_MASK
;
229 sdiv
= (pll_con
>> PLL35XX_SDIV_SHIFT
) & PLL35XX_SDIV_MASK
;
232 do_div(fvco
, (pdiv
<< sdiv
));
234 return (unsigned long)fvco
;
237 static inline bool samsung_pll35xx_mp_change(
238 const struct samsung_pll_rate_table
*rate
, u32 pll_con
)
240 u32 old_mdiv
, old_pdiv
;
242 old_mdiv
= (pll_con
>> PLL35XX_MDIV_SHIFT
) & PLL35XX_MDIV_MASK
;
243 old_pdiv
= (pll_con
>> PLL35XX_PDIV_SHIFT
) & PLL35XX_PDIV_MASK
;
245 return (rate
->mdiv
!= old_mdiv
|| rate
->pdiv
!= old_pdiv
);
248 static int samsung_pll35xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
251 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
252 const struct samsung_pll_rate_table
*rate
;
255 /* Get required rate settings from table */
256 rate
= samsung_get_pll_settings(pll
, drate
);
258 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
259 drate
, clk_hw_get_name(hw
));
263 tmp
= readl_relaxed(pll
->con_reg
);
265 if (!(samsung_pll35xx_mp_change(rate
, tmp
))) {
266 /* If only s change, change just s value only*/
267 tmp
&= ~(PLL35XX_SDIV_MASK
<< PLL35XX_SDIV_SHIFT
);
268 tmp
|= rate
->sdiv
<< PLL35XX_SDIV_SHIFT
;
269 writel_relaxed(tmp
, pll
->con_reg
);
274 /* Set PLL lock time. */
275 writel_relaxed(rate
->pdiv
* PLL35XX_LOCK_FACTOR
,
278 /* Change PLL PMS values */
279 tmp
&= ~((PLL35XX_MDIV_MASK
<< PLL35XX_MDIV_SHIFT
) |
280 (PLL35XX_PDIV_MASK
<< PLL35XX_PDIV_SHIFT
) |
281 (PLL35XX_SDIV_MASK
<< PLL35XX_SDIV_SHIFT
));
282 tmp
|= (rate
->mdiv
<< PLL35XX_MDIV_SHIFT
) |
283 (rate
->pdiv
<< PLL35XX_PDIV_SHIFT
) |
284 (rate
->sdiv
<< PLL35XX_SDIV_SHIFT
);
285 writel_relaxed(tmp
, pll
->con_reg
);
287 /* Wait for PLL lock if the PLL is enabled */
288 if (tmp
& BIT(pll
->enable_offs
))
289 return samsung_pll_lock_wait(pll
, BIT(pll
->lock_offs
));
294 static const struct clk_ops samsung_pll35xx_clk_ops
= {
295 .recalc_rate
= samsung_pll35xx_recalc_rate
,
296 .round_rate
= samsung_pll_round_rate
,
297 .set_rate
= samsung_pll35xx_set_rate
,
298 .enable
= samsung_pll3xxx_enable
,
299 .disable
= samsung_pll3xxx_disable
,
302 static const struct clk_ops samsung_pll35xx_clk_min_ops
= {
303 .recalc_rate
= samsung_pll35xx_recalc_rate
,
309 /* Maximum lock time can be 3000 * PDIV cycles */
310 #define PLL36XX_LOCK_FACTOR (3000)
312 #define PLL36XX_KDIV_MASK (0xFFFF)
313 #define PLL36XX_MDIV_MASK (0x1FF)
314 #define PLL36XX_PDIV_MASK (0x3F)
315 #define PLL36XX_SDIV_MASK (0x7)
316 #define PLL36XX_MDIV_SHIFT (16)
317 #define PLL36XX_PDIV_SHIFT (8)
318 #define PLL36XX_SDIV_SHIFT (0)
319 #define PLL36XX_KDIV_SHIFT (0)
320 #define PLL36XX_LOCK_STAT_SHIFT (29)
321 #define PLL36XX_ENABLE_SHIFT (31)
323 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw
*hw
,
324 unsigned long parent_rate
)
326 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
327 u32 mdiv
, pdiv
, sdiv
, pll_con0
, pll_con1
;
329 u64 fvco
= parent_rate
;
331 pll_con0
= readl_relaxed(pll
->con_reg
);
332 pll_con1
= readl_relaxed(pll
->con_reg
+ 4);
333 mdiv
= (pll_con0
>> PLL36XX_MDIV_SHIFT
) & PLL36XX_MDIV_MASK
;
334 pdiv
= (pll_con0
>> PLL36XX_PDIV_SHIFT
) & PLL36XX_PDIV_MASK
;
335 sdiv
= (pll_con0
>> PLL36XX_SDIV_SHIFT
) & PLL36XX_SDIV_MASK
;
336 kdiv
= (s16
)(pll_con1
& PLL36XX_KDIV_MASK
);
338 fvco
*= (mdiv
<< 16) + kdiv
;
339 do_div(fvco
, (pdiv
<< sdiv
));
342 return (unsigned long)fvco
;
345 static inline bool samsung_pll36xx_mpk_change(
346 const struct samsung_pll_rate_table
*rate
, u32 pll_con0
, u32 pll_con1
)
348 u32 old_mdiv
, old_pdiv
, old_kdiv
;
350 old_mdiv
= (pll_con0
>> PLL36XX_MDIV_SHIFT
) & PLL36XX_MDIV_MASK
;
351 old_pdiv
= (pll_con0
>> PLL36XX_PDIV_SHIFT
) & PLL36XX_PDIV_MASK
;
352 old_kdiv
= (pll_con1
>> PLL36XX_KDIV_SHIFT
) & PLL36XX_KDIV_MASK
;
354 return (rate
->mdiv
!= old_mdiv
|| rate
->pdiv
!= old_pdiv
||
355 rate
->kdiv
!= old_kdiv
);
358 static int samsung_pll36xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
359 unsigned long parent_rate
)
361 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
362 u32 pll_con0
, pll_con1
;
363 const struct samsung_pll_rate_table
*rate
;
365 rate
= samsung_get_pll_settings(pll
, drate
);
367 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
368 drate
, clk_hw_get_name(hw
));
372 pll_con0
= readl_relaxed(pll
->con_reg
);
373 pll_con1
= readl_relaxed(pll
->con_reg
+ 4);
375 if (!(samsung_pll36xx_mpk_change(rate
, pll_con0
, pll_con1
))) {
376 /* If only s change, change just s value only*/
377 pll_con0
&= ~(PLL36XX_SDIV_MASK
<< PLL36XX_SDIV_SHIFT
);
378 pll_con0
|= (rate
->sdiv
<< PLL36XX_SDIV_SHIFT
);
379 writel_relaxed(pll_con0
, pll
->con_reg
);
384 /* Set PLL lock time. */
385 writel_relaxed(rate
->pdiv
* PLL36XX_LOCK_FACTOR
, pll
->lock_reg
);
387 /* Change PLL PMS values */
388 pll_con0
&= ~((PLL36XX_MDIV_MASK
<< PLL36XX_MDIV_SHIFT
) |
389 (PLL36XX_PDIV_MASK
<< PLL36XX_PDIV_SHIFT
) |
390 (PLL36XX_SDIV_MASK
<< PLL36XX_SDIV_SHIFT
));
391 pll_con0
|= (rate
->mdiv
<< PLL36XX_MDIV_SHIFT
) |
392 (rate
->pdiv
<< PLL36XX_PDIV_SHIFT
) |
393 (rate
->sdiv
<< PLL36XX_SDIV_SHIFT
);
394 writel_relaxed(pll_con0
, pll
->con_reg
);
396 pll_con1
&= ~(PLL36XX_KDIV_MASK
<< PLL36XX_KDIV_SHIFT
);
397 pll_con1
|= rate
->kdiv
<< PLL36XX_KDIV_SHIFT
;
398 writel_relaxed(pll_con1
, pll
->con_reg
+ 4);
400 if (pll_con0
& BIT(pll
->enable_offs
))
401 return samsung_pll_lock_wait(pll
, BIT(pll
->lock_offs
));
406 static const struct clk_ops samsung_pll36xx_clk_ops
= {
407 .recalc_rate
= samsung_pll36xx_recalc_rate
,
408 .set_rate
= samsung_pll36xx_set_rate
,
409 .round_rate
= samsung_pll_round_rate
,
410 .enable
= samsung_pll3xxx_enable
,
411 .disable
= samsung_pll3xxx_disable
,
414 static const struct clk_ops samsung_pll36xx_clk_min_ops
= {
415 .recalc_rate
= samsung_pll36xx_recalc_rate
,
419 * PLL0822x Clock Type
421 /* Maximum lock time can be 150 * PDIV cycles */
422 #define PLL0822X_LOCK_FACTOR (150)
424 #define PLL0822X_MDIV_MASK (0x3FF)
425 #define PLL0822X_PDIV_MASK (0x3F)
426 #define PLL0822X_SDIV_MASK (0x7)
427 #define PLL0822X_MDIV_SHIFT (16)
428 #define PLL0822X_PDIV_SHIFT (8)
429 #define PLL0822X_SDIV_SHIFT (0)
430 #define PLL0822X_LOCK_STAT_SHIFT (29)
431 #define PLL0822X_ENABLE_SHIFT (31)
433 /* PLL1418x is similar to PLL0822x, except that MDIV is one bit smaller */
434 #define PLL1418X_MDIV_MASK (0x1FF)
436 static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw
*hw
,
437 unsigned long parent_rate
)
439 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
440 u32 mdiv
, pdiv
, sdiv
, pll_con3
;
441 u64 fvco
= parent_rate
;
443 pll_con3
= readl_relaxed(pll
->con_reg
);
444 if (pll
->type
!= pll_1418x
)
445 mdiv
= (pll_con3
>> PLL0822X_MDIV_SHIFT
) & PLL0822X_MDIV_MASK
;
447 mdiv
= (pll_con3
>> PLL0822X_MDIV_SHIFT
) & PLL1418X_MDIV_MASK
;
448 pdiv
= (pll_con3
>> PLL0822X_PDIV_SHIFT
) & PLL0822X_PDIV_MASK
;
449 sdiv
= (pll_con3
>> PLL0822X_SDIV_SHIFT
) & PLL0822X_SDIV_MASK
;
452 if (pll
->type
== pll_0516x
)
455 do_div(fvco
, (pdiv
<< sdiv
));
457 return (unsigned long)fvco
;
460 static int samsung_pll0822x_set_rate(struct clk_hw
*hw
, unsigned long drate
,
463 const struct samsung_pll_rate_table
*rate
;
464 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
465 u32 mdiv_mask
, pll_con3
;
467 if (pll
->type
!= pll_1418x
)
468 mdiv_mask
= PLL0822X_MDIV_MASK
;
470 mdiv_mask
= PLL1418X_MDIV_MASK
;
472 /* Get required rate settings from table */
473 rate
= samsung_get_pll_settings(pll
, drate
);
475 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
476 drate
, clk_hw_get_name(hw
));
480 /* Change PLL PMS values */
481 pll_con3
= readl_relaxed(pll
->con_reg
);
482 pll_con3
&= ~((mdiv_mask
<< PLL0822X_MDIV_SHIFT
) |
483 (PLL0822X_PDIV_MASK
<< PLL0822X_PDIV_SHIFT
) |
484 (PLL0822X_SDIV_MASK
<< PLL0822X_SDIV_SHIFT
));
485 pll_con3
|= (rate
->mdiv
<< PLL0822X_MDIV_SHIFT
) |
486 (rate
->pdiv
<< PLL0822X_PDIV_SHIFT
) |
487 (rate
->sdiv
<< PLL0822X_SDIV_SHIFT
);
489 /* Set PLL lock time */
490 writel_relaxed(rate
->pdiv
* PLL0822X_LOCK_FACTOR
,
493 /* Write PMS values */
494 writel_relaxed(pll_con3
, pll
->con_reg
);
496 /* Wait for PLL lock if the PLL is enabled */
497 if (pll_con3
& BIT(pll
->enable_offs
))
498 return samsung_pll_lock_wait(pll
, BIT(pll
->lock_offs
));
503 static const struct clk_ops samsung_pll0822x_clk_ops
= {
504 .recalc_rate
= samsung_pll0822x_recalc_rate
,
505 .round_rate
= samsung_pll_round_rate
,
506 .set_rate
= samsung_pll0822x_set_rate
,
507 .enable
= samsung_pll3xxx_enable
,
508 .disable
= samsung_pll3xxx_disable
,
511 static const struct clk_ops samsung_pll0822x_clk_min_ops
= {
512 .recalc_rate
= samsung_pll0822x_recalc_rate
,
516 * PLL0831x Clock Type
518 /* Maximum lock time can be 500 * PDIV cycles */
519 #define PLL0831X_LOCK_FACTOR (500)
521 #define PLL0831X_KDIV_MASK (0xFFFF)
522 #define PLL0831X_MDIV_MASK (0x1FF)
523 #define PLL0831X_PDIV_MASK (0x3F)
524 #define PLL0831X_SDIV_MASK (0x7)
525 #define PLL0831X_MDIV_SHIFT (16)
526 #define PLL0831X_PDIV_SHIFT (8)
527 #define PLL0831X_SDIV_SHIFT (0)
528 #define PLL0831X_KDIV_SHIFT (0)
529 #define PLL0831X_LOCK_STAT_SHIFT (29)
530 #define PLL0831X_ENABLE_SHIFT (31)
532 static unsigned long samsung_pll0831x_recalc_rate(struct clk_hw
*hw
,
533 unsigned long parent_rate
)
535 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
536 u32 mdiv
, pdiv
, sdiv
, pll_con3
, pll_con5
;
538 u64 fvco
= parent_rate
;
540 pll_con3
= readl_relaxed(pll
->con_reg
);
541 pll_con5
= readl_relaxed(pll
->con_reg
+ 8);
542 mdiv
= (pll_con3
>> PLL0831X_MDIV_SHIFT
) & PLL0831X_MDIV_MASK
;
543 pdiv
= (pll_con3
>> PLL0831X_PDIV_SHIFT
) & PLL0831X_PDIV_MASK
;
544 sdiv
= (pll_con3
>> PLL0831X_SDIV_SHIFT
) & PLL0831X_SDIV_MASK
;
545 kdiv
= (s16
)((pll_con5
>> PLL0831X_KDIV_SHIFT
) & PLL0831X_KDIV_MASK
);
547 fvco
*= (mdiv
<< 16) + kdiv
;
548 do_div(fvco
, (pdiv
<< sdiv
));
551 return (unsigned long)fvco
;
554 static int samsung_pll0831x_set_rate(struct clk_hw
*hw
, unsigned long drate
,
555 unsigned long parent_rate
)
557 const struct samsung_pll_rate_table
*rate
;
558 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
559 u32 pll_con3
, pll_con5
;
561 /* Get required rate settings from table */
562 rate
= samsung_get_pll_settings(pll
, drate
);
564 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
565 drate
, clk_hw_get_name(hw
));
569 pll_con3
= readl_relaxed(pll
->con_reg
);
570 pll_con5
= readl_relaxed(pll
->con_reg
+ 8);
572 /* Change PLL PMSK values */
573 pll_con3
&= ~((PLL0831X_MDIV_MASK
<< PLL0831X_MDIV_SHIFT
) |
574 (PLL0831X_PDIV_MASK
<< PLL0831X_PDIV_SHIFT
) |
575 (PLL0831X_SDIV_MASK
<< PLL0831X_SDIV_SHIFT
));
576 pll_con3
|= (rate
->mdiv
<< PLL0831X_MDIV_SHIFT
) |
577 (rate
->pdiv
<< PLL0831X_PDIV_SHIFT
) |
578 (rate
->sdiv
<< PLL0831X_SDIV_SHIFT
);
579 pll_con5
&= ~(PLL0831X_KDIV_MASK
<< PLL0831X_KDIV_SHIFT
);
581 * kdiv is 16-bit 2's complement (s16), but stored as unsigned int.
582 * Cast it to u16 to avoid leading 0xffff's in case of negative value.
584 pll_con5
|= ((u16
)rate
->kdiv
<< PLL0831X_KDIV_SHIFT
);
586 /* Set PLL lock time */
587 writel_relaxed(rate
->pdiv
* PLL0831X_LOCK_FACTOR
, pll
->lock_reg
);
589 /* Write PMSK values */
590 writel_relaxed(pll_con3
, pll
->con_reg
);
591 writel_relaxed(pll_con5
, pll
->con_reg
+ 8);
593 /* Wait for PLL lock if the PLL is enabled */
594 if (pll_con3
& BIT(pll
->enable_offs
))
595 return samsung_pll_lock_wait(pll
, BIT(pll
->lock_offs
));
600 static const struct clk_ops samsung_pll0831x_clk_ops
= {
601 .recalc_rate
= samsung_pll0831x_recalc_rate
,
602 .set_rate
= samsung_pll0831x_set_rate
,
603 .round_rate
= samsung_pll_round_rate
,
604 .enable
= samsung_pll3xxx_enable
,
605 .disable
= samsung_pll3xxx_disable
,
608 static const struct clk_ops samsung_pll0831x_clk_min_ops
= {
609 .recalc_rate
= samsung_pll0831x_recalc_rate
,
615 #define PLL4502_LOCK_FACTOR 400
616 #define PLL4508_LOCK_FACTOR 240
618 #define PLL45XX_MDIV_MASK (0x3FF)
619 #define PLL45XX_PDIV_MASK (0x3F)
620 #define PLL45XX_SDIV_MASK (0x7)
621 #define PLL45XX_AFC_MASK (0x1F)
622 #define PLL45XX_MDIV_SHIFT (16)
623 #define PLL45XX_PDIV_SHIFT (8)
624 #define PLL45XX_SDIV_SHIFT (0)
625 #define PLL45XX_AFC_SHIFT (0)
627 #define PLL45XX_ENABLE BIT(31)
628 #define PLL45XX_LOCKED BIT(29)
630 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw
*hw
,
631 unsigned long parent_rate
)
633 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
634 u32 mdiv
, pdiv
, sdiv
, pll_con
;
635 u64 fvco
= parent_rate
;
637 pll_con
= readl_relaxed(pll
->con_reg
);
638 mdiv
= (pll_con
>> PLL45XX_MDIV_SHIFT
) & PLL45XX_MDIV_MASK
;
639 pdiv
= (pll_con
>> PLL45XX_PDIV_SHIFT
) & PLL45XX_PDIV_MASK
;
640 sdiv
= (pll_con
>> PLL45XX_SDIV_SHIFT
) & PLL45XX_SDIV_MASK
;
642 if (pll
->type
== pll_4508
)
646 do_div(fvco
, (pdiv
<< sdiv
));
648 return (unsigned long)fvco
;
651 static bool samsung_pll45xx_mp_change(u32 pll_con0
, u32 pll_con1
,
652 const struct samsung_pll_rate_table
*rate
)
654 u32 old_mdiv
, old_pdiv
, old_afc
;
656 old_mdiv
= (pll_con0
>> PLL45XX_MDIV_SHIFT
) & PLL45XX_MDIV_MASK
;
657 old_pdiv
= (pll_con0
>> PLL45XX_PDIV_SHIFT
) & PLL45XX_PDIV_MASK
;
658 old_afc
= (pll_con1
>> PLL45XX_AFC_SHIFT
) & PLL45XX_AFC_MASK
;
660 return (old_mdiv
!= rate
->mdiv
|| old_pdiv
!= rate
->pdiv
661 || old_afc
!= rate
->afc
);
664 static int samsung_pll45xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
667 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
668 const struct samsung_pll_rate_table
*rate
;
671 /* Get required rate settings from table */
672 rate
= samsung_get_pll_settings(pll
, drate
);
674 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
675 drate
, clk_hw_get_name(hw
));
679 con0
= readl_relaxed(pll
->con_reg
);
680 con1
= readl_relaxed(pll
->con_reg
+ 0x4);
682 if (!(samsung_pll45xx_mp_change(con0
, con1
, rate
))) {
683 /* If only s change, change just s value only*/
684 con0
&= ~(PLL45XX_SDIV_MASK
<< PLL45XX_SDIV_SHIFT
);
685 con0
|= rate
->sdiv
<< PLL45XX_SDIV_SHIFT
;
686 writel_relaxed(con0
, pll
->con_reg
);
691 /* Set PLL PMS values. */
692 con0
&= ~((PLL45XX_MDIV_MASK
<< PLL45XX_MDIV_SHIFT
) |
693 (PLL45XX_PDIV_MASK
<< PLL45XX_PDIV_SHIFT
) |
694 (PLL45XX_SDIV_MASK
<< PLL45XX_SDIV_SHIFT
));
695 con0
|= (rate
->mdiv
<< PLL45XX_MDIV_SHIFT
) |
696 (rate
->pdiv
<< PLL45XX_PDIV_SHIFT
) |
697 (rate
->sdiv
<< PLL45XX_SDIV_SHIFT
);
699 /* Set PLL AFC value. */
700 con1
= readl_relaxed(pll
->con_reg
+ 0x4);
701 con1
&= ~(PLL45XX_AFC_MASK
<< PLL45XX_AFC_SHIFT
);
702 con1
|= (rate
->afc
<< PLL45XX_AFC_SHIFT
);
704 /* Set PLL lock time. */
707 writel_relaxed(rate
->pdiv
* PLL4502_LOCK_FACTOR
, pll
->lock_reg
);
710 writel_relaxed(rate
->pdiv
* PLL4508_LOCK_FACTOR
, pll
->lock_reg
);
716 /* Set new configuration. */
717 writel_relaxed(con1
, pll
->con_reg
+ 0x4);
718 writel_relaxed(con0
, pll
->con_reg
);
720 /* Wait for PLL lock */
721 return samsung_pll_lock_wait(pll
, PLL45XX_LOCKED
);
724 static const struct clk_ops samsung_pll45xx_clk_ops
= {
725 .recalc_rate
= samsung_pll45xx_recalc_rate
,
726 .round_rate
= samsung_pll_round_rate
,
727 .set_rate
= samsung_pll45xx_set_rate
,
730 static const struct clk_ops samsung_pll45xx_clk_min_ops
= {
731 .recalc_rate
= samsung_pll45xx_recalc_rate
,
737 #define PLL46XX_LOCK_FACTOR 3000
739 #define PLL46XX_VSEL_MASK (1)
740 #define PLL46XX_MDIV_MASK (0x1FF)
741 #define PLL1460X_MDIV_MASK (0x3FF)
743 #define PLL46XX_PDIV_MASK (0x3F)
744 #define PLL46XX_SDIV_MASK (0x7)
745 #define PLL46XX_VSEL_SHIFT (27)
746 #define PLL46XX_MDIV_SHIFT (16)
747 #define PLL46XX_PDIV_SHIFT (8)
748 #define PLL46XX_SDIV_SHIFT (0)
750 #define PLL46XX_KDIV_MASK (0xFFFF)
751 #define PLL4650C_KDIV_MASK (0xFFF)
752 #define PLL46XX_KDIV_SHIFT (0)
753 #define PLL46XX_MFR_MASK (0x3F)
754 #define PLL46XX_MRR_MASK (0x1F)
755 #define PLL46XX_KDIV_SHIFT (0)
756 #define PLL46XX_MFR_SHIFT (16)
757 #define PLL46XX_MRR_SHIFT (24)
759 #define PLL46XX_ENABLE BIT(31)
760 #define PLL46XX_LOCKED BIT(29)
761 #define PLL46XX_VSEL BIT(27)
763 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw
*hw
,
764 unsigned long parent_rate
)
766 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
767 u32 mdiv
, pdiv
, sdiv
, kdiv
, pll_con0
, pll_con1
, shift
;
768 u64 fvco
= parent_rate
;
770 pll_con0
= readl_relaxed(pll
->con_reg
);
771 pll_con1
= readl_relaxed(pll
->con_reg
+ 4);
772 mdiv
= (pll_con0
>> PLL46XX_MDIV_SHIFT
) & ((pll
->type
== pll_1460x
) ?
773 PLL1460X_MDIV_MASK
: PLL46XX_MDIV_MASK
);
774 pdiv
= (pll_con0
>> PLL46XX_PDIV_SHIFT
) & PLL46XX_PDIV_MASK
;
775 sdiv
= (pll_con0
>> PLL46XX_SDIV_SHIFT
) & PLL46XX_SDIV_MASK
;
776 kdiv
= pll
->type
== pll_4650c
? pll_con1
& PLL4650C_KDIV_MASK
:
777 pll_con1
& PLL46XX_KDIV_MASK
;
779 shift
= ((pll
->type
== pll_4600
) || (pll
->type
== pll_1460x
)) ? 16 : 10;
781 fvco
*= (mdiv
<< shift
) + kdiv
;
782 do_div(fvco
, (pdiv
<< sdiv
));
785 return (unsigned long)fvco
;
788 static bool samsung_pll46xx_mpk_change(u32 pll_con0
, u32 pll_con1
,
789 const struct samsung_pll_rate_table
*rate
)
791 u32 old_mdiv
, old_pdiv
, old_kdiv
;
793 old_mdiv
= (pll_con0
>> PLL46XX_MDIV_SHIFT
) & PLL46XX_MDIV_MASK
;
794 old_pdiv
= (pll_con0
>> PLL46XX_PDIV_SHIFT
) & PLL46XX_PDIV_MASK
;
795 old_kdiv
= (pll_con1
>> PLL46XX_KDIV_SHIFT
) & PLL46XX_KDIV_MASK
;
797 return (old_mdiv
!= rate
->mdiv
|| old_pdiv
!= rate
->pdiv
798 || old_kdiv
!= rate
->kdiv
);
801 static int samsung_pll46xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
804 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
805 const struct samsung_pll_rate_table
*rate
;
806 u32 con0
, con1
, lock
;
808 /* Get required rate settings from table */
809 rate
= samsung_get_pll_settings(pll
, drate
);
811 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
812 drate
, clk_hw_get_name(hw
));
816 con0
= readl_relaxed(pll
->con_reg
);
817 con1
= readl_relaxed(pll
->con_reg
+ 0x4);
819 if (!(samsung_pll46xx_mpk_change(con0
, con1
, rate
))) {
820 /* If only s change, change just s value only*/
821 con0
&= ~(PLL46XX_SDIV_MASK
<< PLL46XX_SDIV_SHIFT
);
822 con0
|= rate
->sdiv
<< PLL46XX_SDIV_SHIFT
;
823 writel_relaxed(con0
, pll
->con_reg
);
828 /* Set PLL lock time. */
829 lock
= rate
->pdiv
* PLL46XX_LOCK_FACTOR
;
831 /* Maximum lock time bitfield is 16-bit. */
834 /* Set PLL PMS and VSEL values. */
835 if (pll
->type
== pll_1460x
) {
836 con0
&= ~((PLL1460X_MDIV_MASK
<< PLL46XX_MDIV_SHIFT
) |
837 (PLL46XX_PDIV_MASK
<< PLL46XX_PDIV_SHIFT
) |
838 (PLL46XX_SDIV_MASK
<< PLL46XX_SDIV_SHIFT
));
840 con0
&= ~((PLL46XX_MDIV_MASK
<< PLL46XX_MDIV_SHIFT
) |
841 (PLL46XX_PDIV_MASK
<< PLL46XX_PDIV_SHIFT
) |
842 (PLL46XX_SDIV_MASK
<< PLL46XX_SDIV_SHIFT
) |
843 (PLL46XX_VSEL_MASK
<< PLL46XX_VSEL_SHIFT
));
844 con0
|= rate
->vsel
<< PLL46XX_VSEL_SHIFT
;
847 con0
|= (rate
->mdiv
<< PLL46XX_MDIV_SHIFT
) |
848 (rate
->pdiv
<< PLL46XX_PDIV_SHIFT
) |
849 (rate
->sdiv
<< PLL46XX_SDIV_SHIFT
);
851 /* Set PLL K, MFR and MRR values. */
852 con1
= readl_relaxed(pll
->con_reg
+ 0x4);
853 con1
&= ~((PLL46XX_KDIV_MASK
<< PLL46XX_KDIV_SHIFT
) |
854 (PLL46XX_MFR_MASK
<< PLL46XX_MFR_SHIFT
) |
855 (PLL46XX_MRR_MASK
<< PLL46XX_MRR_SHIFT
));
856 con1
|= (rate
->kdiv
<< PLL46XX_KDIV_SHIFT
) |
857 (rate
->mfr
<< PLL46XX_MFR_SHIFT
) |
858 (rate
->mrr
<< PLL46XX_MRR_SHIFT
);
860 /* Write configuration to PLL */
861 writel_relaxed(lock
, pll
->lock_reg
);
862 writel_relaxed(con0
, pll
->con_reg
);
863 writel_relaxed(con1
, pll
->con_reg
+ 0x4);
865 /* Wait for PLL lock */
866 return samsung_pll_lock_wait(pll
, PLL46XX_LOCKED
);
869 static const struct clk_ops samsung_pll46xx_clk_ops
= {
870 .recalc_rate
= samsung_pll46xx_recalc_rate
,
871 .round_rate
= samsung_pll_round_rate
,
872 .set_rate
= samsung_pll46xx_set_rate
,
875 static const struct clk_ops samsung_pll46xx_clk_min_ops
= {
876 .recalc_rate
= samsung_pll46xx_recalc_rate
,
883 #define PLL6552_MDIV_MASK 0x3ff
884 #define PLL6552_PDIV_MASK 0x3f
885 #define PLL6552_SDIV_MASK 0x7
886 #define PLL6552_MDIV_SHIFT 16
887 #define PLL6552_MDIV_SHIFT_2416 14
888 #define PLL6552_PDIV_SHIFT 8
889 #define PLL6552_PDIV_SHIFT_2416 5
890 #define PLL6552_SDIV_SHIFT 0
892 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw
*hw
,
893 unsigned long parent_rate
)
895 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
896 u32 mdiv
, pdiv
, sdiv
, pll_con
;
897 u64 fvco
= parent_rate
;
899 pll_con
= readl_relaxed(pll
->con_reg
);
900 if (pll
->type
== pll_6552_s3c2416
) {
901 mdiv
= (pll_con
>> PLL6552_MDIV_SHIFT_2416
) & PLL6552_MDIV_MASK
;
902 pdiv
= (pll_con
>> PLL6552_PDIV_SHIFT_2416
) & PLL6552_PDIV_MASK
;
904 mdiv
= (pll_con
>> PLL6552_MDIV_SHIFT
) & PLL6552_MDIV_MASK
;
905 pdiv
= (pll_con
>> PLL6552_PDIV_SHIFT
) & PLL6552_PDIV_MASK
;
907 sdiv
= (pll_con
>> PLL6552_SDIV_SHIFT
) & PLL6552_SDIV_MASK
;
910 do_div(fvco
, (pdiv
<< sdiv
));
912 return (unsigned long)fvco
;
915 static const struct clk_ops samsung_pll6552_clk_ops
= {
916 .recalc_rate
= samsung_pll6552_recalc_rate
,
923 #define PLL6553_MDIV_MASK 0xff
924 #define PLL6553_PDIV_MASK 0x3f
925 #define PLL6553_SDIV_MASK 0x7
926 #define PLL6553_KDIV_MASK 0xffff
927 #define PLL6553_MDIV_SHIFT 16
928 #define PLL6553_PDIV_SHIFT 8
929 #define PLL6553_SDIV_SHIFT 0
930 #define PLL6553_KDIV_SHIFT 0
932 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw
*hw
,
933 unsigned long parent_rate
)
935 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
936 u32 mdiv
, pdiv
, sdiv
, kdiv
, pll_con0
, pll_con1
;
937 u64 fvco
= parent_rate
;
939 pll_con0
= readl_relaxed(pll
->con_reg
);
940 pll_con1
= readl_relaxed(pll
->con_reg
+ 0x4);
941 mdiv
= (pll_con0
>> PLL6553_MDIV_SHIFT
) & PLL6553_MDIV_MASK
;
942 pdiv
= (pll_con0
>> PLL6553_PDIV_SHIFT
) & PLL6553_PDIV_MASK
;
943 sdiv
= (pll_con0
>> PLL6553_SDIV_SHIFT
) & PLL6553_SDIV_MASK
;
944 kdiv
= (pll_con1
>> PLL6553_KDIV_SHIFT
) & PLL6553_KDIV_MASK
;
946 fvco
*= (mdiv
<< 16) + kdiv
;
947 do_div(fvco
, (pdiv
<< sdiv
));
950 return (unsigned long)fvco
;
953 static const struct clk_ops samsung_pll6553_clk_ops
= {
954 .recalc_rate
= samsung_pll6553_recalc_rate
,
958 * PLL2550x Clock Type
961 #define PLL2550X_R_MASK (0x1)
962 #define PLL2550X_P_MASK (0x3F)
963 #define PLL2550X_M_MASK (0x3FF)
964 #define PLL2550X_S_MASK (0x7)
965 #define PLL2550X_R_SHIFT (20)
966 #define PLL2550X_P_SHIFT (14)
967 #define PLL2550X_M_SHIFT (4)
968 #define PLL2550X_S_SHIFT (0)
970 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw
*hw
,
971 unsigned long parent_rate
)
973 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
974 u32 r
, p
, m
, s
, pll_stat
;
975 u64 fvco
= parent_rate
;
977 pll_stat
= readl_relaxed(pll
->con_reg
);
978 r
= (pll_stat
>> PLL2550X_R_SHIFT
) & PLL2550X_R_MASK
;
981 p
= (pll_stat
>> PLL2550X_P_SHIFT
) & PLL2550X_P_MASK
;
982 m
= (pll_stat
>> PLL2550X_M_SHIFT
) & PLL2550X_M_MASK
;
983 s
= (pll_stat
>> PLL2550X_S_SHIFT
) & PLL2550X_S_MASK
;
986 do_div(fvco
, (p
<< s
));
988 return (unsigned long)fvco
;
991 static const struct clk_ops samsung_pll2550x_clk_ops
= {
992 .recalc_rate
= samsung_pll2550x_recalc_rate
,
996 * PLL2550xx Clock Type
999 /* Maximum lock time can be 270 * PDIV cycles */
1000 #define PLL2550XX_LOCK_FACTOR 270
1002 #define PLL2550XX_M_MASK 0x3FF
1003 #define PLL2550XX_P_MASK 0x3F
1004 #define PLL2550XX_S_MASK 0x7
1005 #define PLL2550XX_LOCK_STAT_MASK 0x1
1006 #define PLL2550XX_M_SHIFT 9
1007 #define PLL2550XX_P_SHIFT 3
1008 #define PLL2550XX_S_SHIFT 0
1009 #define PLL2550XX_LOCK_STAT_SHIFT 21
1011 static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw
*hw
,
1012 unsigned long parent_rate
)
1014 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1015 u32 mdiv
, pdiv
, sdiv
, pll_con
;
1016 u64 fvco
= parent_rate
;
1018 pll_con
= readl_relaxed(pll
->con_reg
);
1019 mdiv
= (pll_con
>> PLL2550XX_M_SHIFT
) & PLL2550XX_M_MASK
;
1020 pdiv
= (pll_con
>> PLL2550XX_P_SHIFT
) & PLL2550XX_P_MASK
;
1021 sdiv
= (pll_con
>> PLL2550XX_S_SHIFT
) & PLL2550XX_S_MASK
;
1024 do_div(fvco
, (pdiv
<< sdiv
));
1026 return (unsigned long)fvco
;
1029 static inline bool samsung_pll2550xx_mp_change(u32 mdiv
, u32 pdiv
, u32 pll_con
)
1031 u32 old_mdiv
, old_pdiv
;
1033 old_mdiv
= (pll_con
>> PLL2550XX_M_SHIFT
) & PLL2550XX_M_MASK
;
1034 old_pdiv
= (pll_con
>> PLL2550XX_P_SHIFT
) & PLL2550XX_P_MASK
;
1036 return mdiv
!= old_mdiv
|| pdiv
!= old_pdiv
;
1039 static int samsung_pll2550xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
1040 unsigned long prate
)
1042 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1043 const struct samsung_pll_rate_table
*rate
;
1046 /* Get required rate settings from table */
1047 rate
= samsung_get_pll_settings(pll
, drate
);
1049 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
1050 drate
, clk_hw_get_name(hw
));
1054 tmp
= readl_relaxed(pll
->con_reg
);
1056 if (!(samsung_pll2550xx_mp_change(rate
->mdiv
, rate
->pdiv
, tmp
))) {
1057 /* If only s change, change just s value only*/
1058 tmp
&= ~(PLL2550XX_S_MASK
<< PLL2550XX_S_SHIFT
);
1059 tmp
|= rate
->sdiv
<< PLL2550XX_S_SHIFT
;
1060 writel_relaxed(tmp
, pll
->con_reg
);
1065 /* Set PLL lock time. */
1066 writel_relaxed(rate
->pdiv
* PLL2550XX_LOCK_FACTOR
, pll
->lock_reg
);
1068 /* Change PLL PMS values */
1069 tmp
&= ~((PLL2550XX_M_MASK
<< PLL2550XX_M_SHIFT
) |
1070 (PLL2550XX_P_MASK
<< PLL2550XX_P_SHIFT
) |
1071 (PLL2550XX_S_MASK
<< PLL2550XX_S_SHIFT
));
1072 tmp
|= (rate
->mdiv
<< PLL2550XX_M_SHIFT
) |
1073 (rate
->pdiv
<< PLL2550XX_P_SHIFT
) |
1074 (rate
->sdiv
<< PLL2550XX_S_SHIFT
);
1075 writel_relaxed(tmp
, pll
->con_reg
);
1077 /* Wait for PLL lock */
1078 return samsung_pll_lock_wait(pll
,
1079 PLL2550XX_LOCK_STAT_MASK
<< PLL2550XX_LOCK_STAT_SHIFT
);
1082 static const struct clk_ops samsung_pll2550xx_clk_ops
= {
1083 .recalc_rate
= samsung_pll2550xx_recalc_rate
,
1084 .round_rate
= samsung_pll_round_rate
,
1085 .set_rate
= samsung_pll2550xx_set_rate
,
1088 static const struct clk_ops samsung_pll2550xx_clk_min_ops
= {
1089 .recalc_rate
= samsung_pll2550xx_recalc_rate
,
1093 * PLL2650x Clock Type
1096 /* Maximum lock time can be 3000 * PDIV cycles */
1097 #define PLL2650X_LOCK_FACTOR 3000
1099 #define PLL2650X_M_MASK 0x1ff
1100 #define PLL2650X_P_MASK 0x3f
1101 #define PLL2650X_S_MASK 0x7
1102 #define PLL2650X_K_MASK 0xffff
1103 #define PLL2650X_LOCK_STAT_MASK 0x1
1104 #define PLL2650X_M_SHIFT 16
1105 #define PLL2650X_P_SHIFT 8
1106 #define PLL2650X_S_SHIFT 0
1107 #define PLL2650X_K_SHIFT 0
1108 #define PLL2650X_LOCK_STAT_SHIFT 29
1109 #define PLL2650X_PLL_ENABLE_SHIFT 31
1111 static unsigned long samsung_pll2650x_recalc_rate(struct clk_hw
*hw
,
1112 unsigned long parent_rate
)
1114 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1115 u64 fout
= parent_rate
;
1116 u32 mdiv
, pdiv
, sdiv
, pll_con0
, pll_con1
;
1119 pll_con0
= readl_relaxed(pll
->con_reg
);
1120 mdiv
= (pll_con0
>> PLL2650X_M_SHIFT
) & PLL2650X_M_MASK
;
1121 pdiv
= (pll_con0
>> PLL2650X_P_SHIFT
) & PLL2650X_P_MASK
;
1122 sdiv
= (pll_con0
>> PLL2650X_S_SHIFT
) & PLL2650X_S_MASK
;
1124 pll_con1
= readl_relaxed(pll
->con_reg
+ 4);
1125 kdiv
= (s16
)((pll_con1
>> PLL2650X_K_SHIFT
) & PLL2650X_K_MASK
);
1127 fout
*= (mdiv
<< 16) + kdiv
;
1128 do_div(fout
, (pdiv
<< sdiv
));
1131 return (unsigned long)fout
;
1134 static int samsung_pll2650x_set_rate(struct clk_hw
*hw
, unsigned long drate
,
1135 unsigned long prate
)
1137 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1138 const struct samsung_pll_rate_table
*rate
;
1141 /* Get required rate settings from table */
1142 rate
= samsung_get_pll_settings(pll
, drate
);
1144 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
1145 drate
, clk_hw_get_name(hw
));
1149 con0
= readl_relaxed(pll
->con_reg
);
1150 con1
= readl_relaxed(pll
->con_reg
+ 4);
1152 /* Set PLL lock time. */
1153 writel_relaxed(rate
->pdiv
* PLL2650X_LOCK_FACTOR
, pll
->lock_reg
);
1155 /* Change PLL PMS values */
1156 con0
&= ~((PLL2650X_M_MASK
<< PLL2650X_M_SHIFT
) |
1157 (PLL2650X_P_MASK
<< PLL2650X_P_SHIFT
) |
1158 (PLL2650X_S_MASK
<< PLL2650X_S_SHIFT
));
1159 con0
|= (rate
->mdiv
<< PLL2650X_M_SHIFT
) |
1160 (rate
->pdiv
<< PLL2650X_P_SHIFT
) |
1161 (rate
->sdiv
<< PLL2650X_S_SHIFT
);
1162 con0
|= (1 << PLL2650X_PLL_ENABLE_SHIFT
);
1163 writel_relaxed(con0
, pll
->con_reg
);
1165 con1
&= ~(PLL2650X_K_MASK
<< PLL2650X_K_SHIFT
);
1166 con1
|= ((rate
->kdiv
& PLL2650X_K_MASK
) << PLL2650X_K_SHIFT
);
1167 writel_relaxed(con1
, pll
->con_reg
+ 4);
1169 /* Wait for PLL lock */
1170 return samsung_pll_lock_wait(pll
,
1171 PLL2650X_LOCK_STAT_MASK
<< PLL2650X_LOCK_STAT_SHIFT
);
1174 static const struct clk_ops samsung_pll2650x_clk_ops
= {
1175 .recalc_rate
= samsung_pll2650x_recalc_rate
,
1176 .round_rate
= samsung_pll_round_rate
,
1177 .set_rate
= samsung_pll2650x_set_rate
,
1180 static const struct clk_ops samsung_pll2650x_clk_min_ops
= {
1181 .recalc_rate
= samsung_pll2650x_recalc_rate
,
1185 * PLL2650XX Clock Type
1188 /* Maximum lock time can be 3000 * PDIV cycles */
1189 #define PLL2650XX_LOCK_FACTOR 3000
1191 #define PLL2650XX_MDIV_SHIFT 9
1192 #define PLL2650XX_PDIV_SHIFT 3
1193 #define PLL2650XX_SDIV_SHIFT 0
1194 #define PLL2650XX_KDIV_SHIFT 0
1195 #define PLL2650XX_MDIV_MASK 0x1ff
1196 #define PLL2650XX_PDIV_MASK 0x3f
1197 #define PLL2650XX_SDIV_MASK 0x7
1198 #define PLL2650XX_KDIV_MASK 0xffff
1199 #define PLL2650XX_PLL_ENABLE_SHIFT 23
1200 #define PLL2650XX_PLL_LOCKTIME_SHIFT 21
1201 #define PLL2650XX_PLL_FOUTMASK_SHIFT 31
1203 static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw
*hw
,
1204 unsigned long parent_rate
)
1206 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1207 u32 mdiv
, pdiv
, sdiv
, pll_con0
, pll_con2
;
1209 u64 fvco
= parent_rate
;
1211 pll_con0
= readl_relaxed(pll
->con_reg
);
1212 pll_con2
= readl_relaxed(pll
->con_reg
+ 8);
1213 mdiv
= (pll_con0
>> PLL2650XX_MDIV_SHIFT
) & PLL2650XX_MDIV_MASK
;
1214 pdiv
= (pll_con0
>> PLL2650XX_PDIV_SHIFT
) & PLL2650XX_PDIV_MASK
;
1215 sdiv
= (pll_con0
>> PLL2650XX_SDIV_SHIFT
) & PLL2650XX_SDIV_MASK
;
1216 kdiv
= (s16
)(pll_con2
& PLL2650XX_KDIV_MASK
);
1218 fvco
*= (mdiv
<< 16) + kdiv
;
1219 do_div(fvco
, (pdiv
<< sdiv
));
1222 return (unsigned long)fvco
;
1225 static int samsung_pll2650xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
1226 unsigned long parent_rate
)
1228 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1229 u32 pll_con0
, pll_con2
;
1230 const struct samsung_pll_rate_table
*rate
;
1232 rate
= samsung_get_pll_settings(pll
, drate
);
1234 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
1235 drate
, clk_hw_get_name(hw
));
1239 pll_con0
= readl_relaxed(pll
->con_reg
);
1240 pll_con2
= readl_relaxed(pll
->con_reg
+ 8);
1242 /* Change PLL PMS values */
1243 pll_con0
&= ~(PLL2650XX_MDIV_MASK
<< PLL2650XX_MDIV_SHIFT
|
1244 PLL2650XX_PDIV_MASK
<< PLL2650XX_PDIV_SHIFT
|
1245 PLL2650XX_SDIV_MASK
<< PLL2650XX_SDIV_SHIFT
);
1246 pll_con0
|= rate
->mdiv
<< PLL2650XX_MDIV_SHIFT
;
1247 pll_con0
|= rate
->pdiv
<< PLL2650XX_PDIV_SHIFT
;
1248 pll_con0
|= rate
->sdiv
<< PLL2650XX_SDIV_SHIFT
;
1249 pll_con0
|= 1 << PLL2650XX_PLL_ENABLE_SHIFT
;
1250 pll_con0
|= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT
;
1252 pll_con2
&= ~(PLL2650XX_KDIV_MASK
<< PLL2650XX_KDIV_SHIFT
);
1253 pll_con2
|= ((~(rate
->kdiv
) + 1) & PLL2650XX_KDIV_MASK
)
1254 << PLL2650XX_KDIV_SHIFT
;
1256 /* Set PLL lock time. */
1257 writel_relaxed(PLL2650XX_LOCK_FACTOR
* rate
->pdiv
, pll
->lock_reg
);
1259 writel_relaxed(pll_con0
, pll
->con_reg
);
1260 writel_relaxed(pll_con2
, pll
->con_reg
+ 8);
1262 return samsung_pll_lock_wait(pll
, 0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT
);
1265 static const struct clk_ops samsung_pll2650xx_clk_ops
= {
1266 .recalc_rate
= samsung_pll2650xx_recalc_rate
,
1267 .set_rate
= samsung_pll2650xx_set_rate
,
1268 .round_rate
= samsung_pll_round_rate
,
1271 static const struct clk_ops samsung_pll2650xx_clk_min_ops
= {
1272 .recalc_rate
= samsung_pll2650xx_recalc_rate
,
1276 * PLL531X Clock Type
1278 /* Maximum lock time can be 500 * PDIV cycles */
1279 #define PLL531X_LOCK_FACTOR (500)
1280 #define PLL531X_MDIV_MASK (0x3FF)
1281 #define PLL531X_PDIV_MASK (0x3F)
1282 #define PLL531X_SDIV_MASK (0x7)
1283 #define PLL531X_FDIV_MASK (0xFFFFFFFF)
1284 #define PLL531X_MDIV_SHIFT (16)
1285 #define PLL531X_PDIV_SHIFT (8)
1286 #define PLL531X_SDIV_SHIFT (0)
1288 static unsigned long samsung_pll531x_recalc_rate(struct clk_hw
*hw
,
1289 unsigned long parent_rate
)
1291 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1292 u32 pdiv
, sdiv
, fdiv
, pll_con0
, pll_con8
;
1293 u64 mdiv
, fout
= parent_rate
;
1295 pll_con0
= readl_relaxed(pll
->con_reg
);
1296 pll_con8
= readl_relaxed(pll
->con_reg
+ 20);
1297 mdiv
= (pll_con0
>> PLL531X_MDIV_SHIFT
) & PLL531X_MDIV_MASK
;
1298 pdiv
= (pll_con0
>> PLL531X_PDIV_SHIFT
) & PLL531X_PDIV_MASK
;
1299 sdiv
= (pll_con0
>> PLL531X_SDIV_SHIFT
) & PLL531X_SDIV_MASK
;
1300 fdiv
= (pll_con8
& PLL531X_FDIV_MASK
);
1305 fout
*= (mdiv
<< 24) + (fdiv
>> 8);
1306 do_div(fout
, (pdiv
<< sdiv
));
1309 return (unsigned long)fout
;
1312 static const struct clk_ops samsung_pll531x_clk_ops
= {
1313 .recalc_rate
= samsung_pll531x_recalc_rate
,
1316 static void __init
_samsung_clk_register_pll(struct samsung_clk_provider
*ctx
,
1317 const struct samsung_pll_clock
*pll_clk
)
1319 struct samsung_clk_pll
*pll
;
1320 struct clk_init_data init
;
1323 pll
= kzalloc(sizeof(*pll
), GFP_KERNEL
);
1325 pr_err("%s: could not allocate pll clk %s\n",
1326 __func__
, pll_clk
->name
);
1330 init
.name
= pll_clk
->name
;
1331 init
.flags
= pll_clk
->flags
;
1332 init
.parent_names
= &pll_clk
->parent_name
;
1333 init
.num_parents
= 1;
1335 if (pll_clk
->rate_table
) {
1336 /* find count of rates in rate_table */
1337 for (len
= 0; pll_clk
->rate_table
[len
].rate
!= 0; )
1340 pll
->rate_count
= len
;
1341 pll
->rate_table
= kmemdup_array(pll_clk
->rate_table
,
1343 sizeof(*pll
->rate_table
),
1345 WARN(!pll
->rate_table
,
1346 "%s: could not allocate rate table for %s\n",
1347 __func__
, pll_clk
->name
);
1350 switch (pll_clk
->type
) {
1352 init
.ops
= &samsung_pll2126_clk_ops
;
1355 init
.ops
= &samsung_pll3000_clk_ops
;
1357 /* clk_ops for 35xx and 2550 are similar */
1364 pll
->enable_offs
= PLL35XX_ENABLE_SHIFT
;
1365 pll
->lock_offs
= PLL35XX_LOCK_STAT_SHIFT
;
1366 if (!pll
->rate_table
)
1367 init
.ops
= &samsung_pll35xx_clk_min_ops
;
1369 init
.ops
= &samsung_pll35xx_clk_ops
;
1378 pll
->enable_offs
= PLL0822X_ENABLE_SHIFT
;
1379 pll
->lock_offs
= PLL0822X_LOCK_STAT_SHIFT
;
1380 if (!pll
->rate_table
)
1381 init
.ops
= &samsung_pll0822x_clk_min_ops
;
1383 init
.ops
= &samsung_pll0822x_clk_ops
;
1386 init
.ops
= &samsung_pll45xx_clk_min_ops
;
1390 if (!pll
->rate_table
)
1391 init
.ops
= &samsung_pll45xx_clk_min_ops
;
1393 init
.ops
= &samsung_pll45xx_clk_ops
;
1395 /* clk_ops for 36xx and 2650 are similar */
1398 pll
->enable_offs
= PLL36XX_ENABLE_SHIFT
;
1399 pll
->lock_offs
= PLL36XX_LOCK_STAT_SHIFT
;
1400 if (!pll
->rate_table
)
1401 init
.ops
= &samsung_pll36xx_clk_min_ops
;
1403 init
.ops
= &samsung_pll36xx_clk_ops
;
1406 pll
->enable_offs
= PLL0831X_ENABLE_SHIFT
;
1407 pll
->lock_offs
= PLL0831X_LOCK_STAT_SHIFT
;
1408 if (!pll
->rate_table
)
1409 init
.ops
= &samsung_pll0831x_clk_min_ops
;
1411 init
.ops
= &samsung_pll0831x_clk_ops
;
1414 case pll_6552_s3c2416
:
1415 init
.ops
= &samsung_pll6552_clk_ops
;
1418 init
.ops
= &samsung_pll6553_clk_ops
;
1424 if (!pll
->rate_table
)
1425 init
.ops
= &samsung_pll46xx_clk_min_ops
;
1427 init
.ops
= &samsung_pll46xx_clk_ops
;
1430 init
.ops
= &samsung_pll2550x_clk_ops
;
1433 if (!pll
->rate_table
)
1434 init
.ops
= &samsung_pll2550xx_clk_min_ops
;
1436 init
.ops
= &samsung_pll2550xx_clk_ops
;
1439 if (!pll
->rate_table
)
1440 init
.ops
= &samsung_pll2650x_clk_min_ops
;
1442 init
.ops
= &samsung_pll2650x_clk_ops
;
1445 if (!pll
->rate_table
)
1446 init
.ops
= &samsung_pll2650xx_clk_min_ops
;
1448 init
.ops
= &samsung_pll2650xx_clk_ops
;
1451 init
.ops
= &samsung_pll531x_clk_ops
;
1454 pr_warn("%s: Unknown pll type for pll clk %s\n",
1455 __func__
, pll_clk
->name
);
1458 pll
->hw
.init
= &init
;
1459 pll
->type
= pll_clk
->type
;
1460 pll
->lock_reg
= ctx
->reg_base
+ pll_clk
->lock_offset
;
1461 pll
->con_reg
= ctx
->reg_base
+ pll_clk
->con_offset
;
1463 ret
= clk_hw_register(ctx
->dev
, &pll
->hw
);
1465 pr_err("%s: failed to register pll clock %s : %d\n",
1466 __func__
, pll_clk
->name
, ret
);
1467 kfree(pll
->rate_table
);
1472 samsung_clk_add_lookup(ctx
, &pll
->hw
, pll_clk
->id
);
1475 void __init
samsung_clk_register_pll(struct samsung_clk_provider
*ctx
,
1476 const struct samsung_pll_clock
*pll_list
,
1477 unsigned int nr_pll
)
1481 for (cnt
= 0; cnt
< nr_pll
; cnt
++)
1482 _samsung_clk_register_pll(ctx
, &pll_list
[cnt
]);