2 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
3 * Copyright (c) 2013 Linaro Ltd.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * This file contains the utility functions to register the pll clocks.
12 #include <linux/errno.h>
13 #include <linux/hrtimer.h>
14 #include <linux/delay.h>
15 #include <linux/slab.h>
16 #include <linux/clkdev.h>
20 #define PLL_TIMEOUT_MS 10
22 struct samsung_clk_pll
{
24 void __iomem
*lock_reg
;
25 void __iomem
*con_reg
;
26 /* PLL enable control bit offset in @con_reg register */
27 unsigned short enable_offs
;
28 /* PLL lock status bit offset in @con_reg register */
29 unsigned short lock_offs
;
30 enum samsung_pll_type type
;
31 unsigned int rate_count
;
32 const struct samsung_pll_rate_table
*rate_table
;
35 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
37 static const struct samsung_pll_rate_table
*samsung_get_pll_settings(
38 struct samsung_clk_pll
*pll
, unsigned long rate
)
40 const struct samsung_pll_rate_table
*rate_table
= pll
->rate_table
;
43 for (i
= 0; i
< pll
->rate_count
; i
++) {
44 if (rate
== rate_table
[i
].rate
)
45 return &rate_table
[i
];
51 static long samsung_pll_round_rate(struct clk_hw
*hw
,
52 unsigned long drate
, unsigned long *prate
)
54 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
55 const struct samsung_pll_rate_table
*rate_table
= pll
->rate_table
;
58 /* Assumming rate_table is in descending order */
59 for (i
= 0; i
< pll
->rate_count
; i
++) {
60 if (drate
>= rate_table
[i
].rate
)
61 return rate_table
[i
].rate
;
64 /* return minimum supported value */
65 return rate_table
[i
- 1].rate
;
68 static int samsung_pll3xxx_enable(struct clk_hw
*hw
)
70 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
73 tmp
= readl_relaxed(pll
->con_reg
);
74 tmp
|= BIT(pll
->enable_offs
);
75 writel_relaxed(tmp
, pll
->con_reg
);
80 tmp
= readl_relaxed(pll
->con_reg
);
81 } while (!(tmp
& BIT(pll
->lock_offs
)));
86 static void samsung_pll3xxx_disable(struct clk_hw
*hw
)
88 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
91 tmp
= readl_relaxed(pll
->con_reg
);
92 tmp
&= ~BIT(pll
->enable_offs
);
93 writel_relaxed(tmp
, pll
->con_reg
);
100 #define PLL2126_MDIV_MASK (0xff)
101 #define PLL2126_PDIV_MASK (0x3f)
102 #define PLL2126_SDIV_MASK (0x3)
103 #define PLL2126_MDIV_SHIFT (16)
104 #define PLL2126_PDIV_SHIFT (8)
105 #define PLL2126_SDIV_SHIFT (0)
107 static unsigned long samsung_pll2126_recalc_rate(struct clk_hw
*hw
,
108 unsigned long parent_rate
)
110 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
111 u32 pll_con
, mdiv
, pdiv
, sdiv
;
112 u64 fvco
= parent_rate
;
114 pll_con
= readl_relaxed(pll
->con_reg
);
115 mdiv
= (pll_con
>> PLL2126_MDIV_SHIFT
) & PLL2126_MDIV_MASK
;
116 pdiv
= (pll_con
>> PLL2126_PDIV_SHIFT
) & PLL2126_PDIV_MASK
;
117 sdiv
= (pll_con
>> PLL2126_SDIV_SHIFT
) & PLL2126_SDIV_MASK
;
120 do_div(fvco
, (pdiv
+ 2) << sdiv
);
122 return (unsigned long)fvco
;
125 static const struct clk_ops samsung_pll2126_clk_ops
= {
126 .recalc_rate
= samsung_pll2126_recalc_rate
,
133 #define PLL3000_MDIV_MASK (0xff)
134 #define PLL3000_PDIV_MASK (0x3)
135 #define PLL3000_SDIV_MASK (0x3)
136 #define PLL3000_MDIV_SHIFT (16)
137 #define PLL3000_PDIV_SHIFT (8)
138 #define PLL3000_SDIV_SHIFT (0)
140 static unsigned long samsung_pll3000_recalc_rate(struct clk_hw
*hw
,
141 unsigned long parent_rate
)
143 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
144 u32 pll_con
, mdiv
, pdiv
, sdiv
;
145 u64 fvco
= parent_rate
;
147 pll_con
= readl_relaxed(pll
->con_reg
);
148 mdiv
= (pll_con
>> PLL3000_MDIV_SHIFT
) & PLL3000_MDIV_MASK
;
149 pdiv
= (pll_con
>> PLL3000_PDIV_SHIFT
) & PLL3000_PDIV_MASK
;
150 sdiv
= (pll_con
>> PLL3000_SDIV_SHIFT
) & PLL3000_SDIV_MASK
;
152 fvco
*= (2 * (mdiv
+ 8));
153 do_div(fvco
, pdiv
<< sdiv
);
155 return (unsigned long)fvco
;
158 static const struct clk_ops samsung_pll3000_clk_ops
= {
159 .recalc_rate
= samsung_pll3000_recalc_rate
,
165 /* Maximum lock time can be 270 * PDIV cycles */
166 #define PLL35XX_LOCK_FACTOR (270)
168 #define PLL35XX_MDIV_MASK (0x3FF)
169 #define PLL35XX_PDIV_MASK (0x3F)
170 #define PLL35XX_SDIV_MASK (0x7)
171 #define PLL35XX_MDIV_SHIFT (16)
172 #define PLL35XX_PDIV_SHIFT (8)
173 #define PLL35XX_SDIV_SHIFT (0)
174 #define PLL35XX_LOCK_STAT_SHIFT (29)
175 #define PLL35XX_ENABLE_SHIFT (31)
177 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw
*hw
,
178 unsigned long parent_rate
)
180 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
181 u32 mdiv
, pdiv
, sdiv
, pll_con
;
182 u64 fvco
= parent_rate
;
184 pll_con
= readl_relaxed(pll
->con_reg
);
185 mdiv
= (pll_con
>> PLL35XX_MDIV_SHIFT
) & PLL35XX_MDIV_MASK
;
186 pdiv
= (pll_con
>> PLL35XX_PDIV_SHIFT
) & PLL35XX_PDIV_MASK
;
187 sdiv
= (pll_con
>> PLL35XX_SDIV_SHIFT
) & PLL35XX_SDIV_MASK
;
190 do_div(fvco
, (pdiv
<< sdiv
));
192 return (unsigned long)fvco
;
195 static inline bool samsung_pll35xx_mp_change(
196 const struct samsung_pll_rate_table
*rate
, u32 pll_con
)
198 u32 old_mdiv
, old_pdiv
;
200 old_mdiv
= (pll_con
>> PLL35XX_MDIV_SHIFT
) & PLL35XX_MDIV_MASK
;
201 old_pdiv
= (pll_con
>> PLL35XX_PDIV_SHIFT
) & PLL35XX_PDIV_MASK
;
203 return (rate
->mdiv
!= old_mdiv
|| rate
->pdiv
!= old_pdiv
);
206 static int samsung_pll35xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
209 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
210 const struct samsung_pll_rate_table
*rate
;
213 /* Get required rate settings from table */
214 rate
= samsung_get_pll_settings(pll
, drate
);
216 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
217 drate
, clk_hw_get_name(hw
));
221 tmp
= readl_relaxed(pll
->con_reg
);
223 if (!(samsung_pll35xx_mp_change(rate
, tmp
))) {
224 /* If only s change, change just s value only*/
225 tmp
&= ~(PLL35XX_SDIV_MASK
<< PLL35XX_SDIV_SHIFT
);
226 tmp
|= rate
->sdiv
<< PLL35XX_SDIV_SHIFT
;
227 writel_relaxed(tmp
, pll
->con_reg
);
232 /* Set PLL lock time. */
233 writel_relaxed(rate
->pdiv
* PLL35XX_LOCK_FACTOR
,
236 /* Change PLL PMS values */
237 tmp
&= ~((PLL35XX_MDIV_MASK
<< PLL35XX_MDIV_SHIFT
) |
238 (PLL35XX_PDIV_MASK
<< PLL35XX_PDIV_SHIFT
) |
239 (PLL35XX_SDIV_MASK
<< PLL35XX_SDIV_SHIFT
));
240 tmp
|= (rate
->mdiv
<< PLL35XX_MDIV_SHIFT
) |
241 (rate
->pdiv
<< PLL35XX_PDIV_SHIFT
) |
242 (rate
->sdiv
<< PLL35XX_SDIV_SHIFT
);
243 writel_relaxed(tmp
, pll
->con_reg
);
245 /* Wait until the PLL is locked if it is enabled. */
246 if (tmp
& BIT(pll
->enable_offs
)) {
249 tmp
= readl_relaxed(pll
->con_reg
);
250 } while (!(tmp
& BIT(pll
->lock_offs
)));
255 static const struct clk_ops samsung_pll35xx_clk_ops
= {
256 .recalc_rate
= samsung_pll35xx_recalc_rate
,
257 .round_rate
= samsung_pll_round_rate
,
258 .set_rate
= samsung_pll35xx_set_rate
,
259 .enable
= samsung_pll3xxx_enable
,
260 .disable
= samsung_pll3xxx_disable
,
263 static const struct clk_ops samsung_pll35xx_clk_min_ops
= {
264 .recalc_rate
= samsung_pll35xx_recalc_rate
,
270 /* Maximum lock time can be 3000 * PDIV cycles */
271 #define PLL36XX_LOCK_FACTOR (3000)
273 #define PLL36XX_KDIV_MASK (0xFFFF)
274 #define PLL36XX_MDIV_MASK (0x1FF)
275 #define PLL36XX_PDIV_MASK (0x3F)
276 #define PLL36XX_SDIV_MASK (0x7)
277 #define PLL36XX_MDIV_SHIFT (16)
278 #define PLL36XX_PDIV_SHIFT (8)
279 #define PLL36XX_SDIV_SHIFT (0)
280 #define PLL36XX_KDIV_SHIFT (0)
281 #define PLL36XX_LOCK_STAT_SHIFT (29)
282 #define PLL36XX_ENABLE_SHIFT (31)
284 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw
*hw
,
285 unsigned long parent_rate
)
287 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
288 u32 mdiv
, pdiv
, sdiv
, pll_con0
, pll_con1
;
290 u64 fvco
= parent_rate
;
292 pll_con0
= readl_relaxed(pll
->con_reg
);
293 pll_con1
= readl_relaxed(pll
->con_reg
+ 4);
294 mdiv
= (pll_con0
>> PLL36XX_MDIV_SHIFT
) & PLL36XX_MDIV_MASK
;
295 pdiv
= (pll_con0
>> PLL36XX_PDIV_SHIFT
) & PLL36XX_PDIV_MASK
;
296 sdiv
= (pll_con0
>> PLL36XX_SDIV_SHIFT
) & PLL36XX_SDIV_MASK
;
297 kdiv
= (s16
)(pll_con1
& PLL36XX_KDIV_MASK
);
299 fvco
*= (mdiv
<< 16) + kdiv
;
300 do_div(fvco
, (pdiv
<< sdiv
));
303 return (unsigned long)fvco
;
306 static inline bool samsung_pll36xx_mpk_change(
307 const struct samsung_pll_rate_table
*rate
, u32 pll_con0
, u32 pll_con1
)
309 u32 old_mdiv
, old_pdiv
, old_kdiv
;
311 old_mdiv
= (pll_con0
>> PLL36XX_MDIV_SHIFT
) & PLL36XX_MDIV_MASK
;
312 old_pdiv
= (pll_con0
>> PLL36XX_PDIV_SHIFT
) & PLL36XX_PDIV_MASK
;
313 old_kdiv
= (pll_con1
>> PLL36XX_KDIV_SHIFT
) & PLL36XX_KDIV_MASK
;
315 return (rate
->mdiv
!= old_mdiv
|| rate
->pdiv
!= old_pdiv
||
316 rate
->kdiv
!= old_kdiv
);
319 static int samsung_pll36xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
320 unsigned long parent_rate
)
322 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
323 u32 tmp
, pll_con0
, pll_con1
;
324 const struct samsung_pll_rate_table
*rate
;
326 rate
= samsung_get_pll_settings(pll
, drate
);
328 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
329 drate
, clk_hw_get_name(hw
));
333 pll_con0
= readl_relaxed(pll
->con_reg
);
334 pll_con1
= readl_relaxed(pll
->con_reg
+ 4);
336 if (!(samsung_pll36xx_mpk_change(rate
, pll_con0
, pll_con1
))) {
337 /* If only s change, change just s value only*/
338 pll_con0
&= ~(PLL36XX_SDIV_MASK
<< PLL36XX_SDIV_SHIFT
);
339 pll_con0
|= (rate
->sdiv
<< PLL36XX_SDIV_SHIFT
);
340 writel_relaxed(pll_con0
, pll
->con_reg
);
345 /* Set PLL lock time. */
346 writel_relaxed(rate
->pdiv
* PLL36XX_LOCK_FACTOR
, pll
->lock_reg
);
348 /* Change PLL PMS values */
349 pll_con0
&= ~((PLL36XX_MDIV_MASK
<< PLL36XX_MDIV_SHIFT
) |
350 (PLL36XX_PDIV_MASK
<< PLL36XX_PDIV_SHIFT
) |
351 (PLL36XX_SDIV_MASK
<< PLL36XX_SDIV_SHIFT
));
352 pll_con0
|= (rate
->mdiv
<< PLL36XX_MDIV_SHIFT
) |
353 (rate
->pdiv
<< PLL36XX_PDIV_SHIFT
) |
354 (rate
->sdiv
<< PLL36XX_SDIV_SHIFT
);
355 writel_relaxed(pll_con0
, pll
->con_reg
);
357 pll_con1
&= ~(PLL36XX_KDIV_MASK
<< PLL36XX_KDIV_SHIFT
);
358 pll_con1
|= rate
->kdiv
<< PLL36XX_KDIV_SHIFT
;
359 writel_relaxed(pll_con1
, pll
->con_reg
+ 4);
362 if (pll_con0
& BIT(pll
->enable_offs
)) {
365 tmp
= readl_relaxed(pll
->con_reg
);
366 } while (!(tmp
& BIT(pll
->lock_offs
)));
372 static const struct clk_ops samsung_pll36xx_clk_ops
= {
373 .recalc_rate
= samsung_pll36xx_recalc_rate
,
374 .set_rate
= samsung_pll36xx_set_rate
,
375 .round_rate
= samsung_pll_round_rate
,
376 .enable
= samsung_pll3xxx_enable
,
377 .disable
= samsung_pll3xxx_disable
,
380 static const struct clk_ops samsung_pll36xx_clk_min_ops
= {
381 .recalc_rate
= samsung_pll36xx_recalc_rate
,
387 #define PLL4502_LOCK_FACTOR 400
388 #define PLL4508_LOCK_FACTOR 240
390 #define PLL45XX_MDIV_MASK (0x3FF)
391 #define PLL45XX_PDIV_MASK (0x3F)
392 #define PLL45XX_SDIV_MASK (0x7)
393 #define PLL45XX_AFC_MASK (0x1F)
394 #define PLL45XX_MDIV_SHIFT (16)
395 #define PLL45XX_PDIV_SHIFT (8)
396 #define PLL45XX_SDIV_SHIFT (0)
397 #define PLL45XX_AFC_SHIFT (0)
399 #define PLL45XX_ENABLE BIT(31)
400 #define PLL45XX_LOCKED BIT(29)
402 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw
*hw
,
403 unsigned long parent_rate
)
405 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
406 u32 mdiv
, pdiv
, sdiv
, pll_con
;
407 u64 fvco
= parent_rate
;
409 pll_con
= readl_relaxed(pll
->con_reg
);
410 mdiv
= (pll_con
>> PLL45XX_MDIV_SHIFT
) & PLL45XX_MDIV_MASK
;
411 pdiv
= (pll_con
>> PLL45XX_PDIV_SHIFT
) & PLL45XX_PDIV_MASK
;
412 sdiv
= (pll_con
>> PLL45XX_SDIV_SHIFT
) & PLL45XX_SDIV_MASK
;
414 if (pll
->type
== pll_4508
)
418 do_div(fvco
, (pdiv
<< sdiv
));
420 return (unsigned long)fvco
;
423 static bool samsung_pll45xx_mp_change(u32 pll_con0
, u32 pll_con1
,
424 const struct samsung_pll_rate_table
*rate
)
426 u32 old_mdiv
, old_pdiv
, old_afc
;
428 old_mdiv
= (pll_con0
>> PLL45XX_MDIV_SHIFT
) & PLL45XX_MDIV_MASK
;
429 old_pdiv
= (pll_con0
>> PLL45XX_PDIV_SHIFT
) & PLL45XX_PDIV_MASK
;
430 old_afc
= (pll_con1
>> PLL45XX_AFC_SHIFT
) & PLL45XX_AFC_MASK
;
432 return (old_mdiv
!= rate
->mdiv
|| old_pdiv
!= rate
->pdiv
433 || old_afc
!= rate
->afc
);
436 static int samsung_pll45xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
439 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
440 const struct samsung_pll_rate_table
*rate
;
444 /* Get required rate settings from table */
445 rate
= samsung_get_pll_settings(pll
, drate
);
447 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
448 drate
, clk_hw_get_name(hw
));
452 con0
= readl_relaxed(pll
->con_reg
);
453 con1
= readl_relaxed(pll
->con_reg
+ 0x4);
455 if (!(samsung_pll45xx_mp_change(con0
, con1
, rate
))) {
456 /* If only s change, change just s value only*/
457 con0
&= ~(PLL45XX_SDIV_MASK
<< PLL45XX_SDIV_SHIFT
);
458 con0
|= rate
->sdiv
<< PLL45XX_SDIV_SHIFT
;
459 writel_relaxed(con0
, pll
->con_reg
);
464 /* Set PLL PMS values. */
465 con0
&= ~((PLL45XX_MDIV_MASK
<< PLL45XX_MDIV_SHIFT
) |
466 (PLL45XX_PDIV_MASK
<< PLL45XX_PDIV_SHIFT
) |
467 (PLL45XX_SDIV_MASK
<< PLL45XX_SDIV_SHIFT
));
468 con0
|= (rate
->mdiv
<< PLL45XX_MDIV_SHIFT
) |
469 (rate
->pdiv
<< PLL45XX_PDIV_SHIFT
) |
470 (rate
->sdiv
<< PLL45XX_SDIV_SHIFT
);
472 /* Set PLL AFC value. */
473 con1
= readl_relaxed(pll
->con_reg
+ 0x4);
474 con1
&= ~(PLL45XX_AFC_MASK
<< PLL45XX_AFC_SHIFT
);
475 con1
|= (rate
->afc
<< PLL45XX_AFC_SHIFT
);
477 /* Set PLL lock time. */
480 writel_relaxed(rate
->pdiv
* PLL4502_LOCK_FACTOR
, pll
->lock_reg
);
483 writel_relaxed(rate
->pdiv
* PLL4508_LOCK_FACTOR
, pll
->lock_reg
);
489 /* Set new configuration. */
490 writel_relaxed(con1
, pll
->con_reg
+ 0x4);
491 writel_relaxed(con0
, pll
->con_reg
);
493 /* Wait for locking. */
495 while (!(readl_relaxed(pll
->con_reg
) & PLL45XX_LOCKED
)) {
496 ktime_t delta
= ktime_sub(ktime_get(), start
);
498 if (ktime_to_ms(delta
) > PLL_TIMEOUT_MS
) {
499 pr_err("%s: could not lock PLL %s\n",
500 __func__
, clk_hw_get_name(hw
));
510 static const struct clk_ops samsung_pll45xx_clk_ops
= {
511 .recalc_rate
= samsung_pll45xx_recalc_rate
,
512 .round_rate
= samsung_pll_round_rate
,
513 .set_rate
= samsung_pll45xx_set_rate
,
516 static const struct clk_ops samsung_pll45xx_clk_min_ops
= {
517 .recalc_rate
= samsung_pll45xx_recalc_rate
,
523 #define PLL46XX_LOCK_FACTOR 3000
525 #define PLL46XX_VSEL_MASK (1)
526 #define PLL46XX_MDIV_MASK (0x1FF)
527 #define PLL1460X_MDIV_MASK (0x3FF)
529 #define PLL46XX_PDIV_MASK (0x3F)
530 #define PLL46XX_SDIV_MASK (0x7)
531 #define PLL46XX_VSEL_SHIFT (27)
532 #define PLL46XX_MDIV_SHIFT (16)
533 #define PLL46XX_PDIV_SHIFT (8)
534 #define PLL46XX_SDIV_SHIFT (0)
536 #define PLL46XX_KDIV_MASK (0xFFFF)
537 #define PLL4650C_KDIV_MASK (0xFFF)
538 #define PLL46XX_KDIV_SHIFT (0)
539 #define PLL46XX_MFR_MASK (0x3F)
540 #define PLL46XX_MRR_MASK (0x1F)
541 #define PLL46XX_KDIV_SHIFT (0)
542 #define PLL46XX_MFR_SHIFT (16)
543 #define PLL46XX_MRR_SHIFT (24)
545 #define PLL46XX_ENABLE BIT(31)
546 #define PLL46XX_LOCKED BIT(29)
547 #define PLL46XX_VSEL BIT(27)
549 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw
*hw
,
550 unsigned long parent_rate
)
552 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
553 u32 mdiv
, pdiv
, sdiv
, kdiv
, pll_con0
, pll_con1
, shift
;
554 u64 fvco
= parent_rate
;
556 pll_con0
= readl_relaxed(pll
->con_reg
);
557 pll_con1
= readl_relaxed(pll
->con_reg
+ 4);
558 mdiv
= (pll_con0
>> PLL46XX_MDIV_SHIFT
) & ((pll
->type
== pll_1460x
) ?
559 PLL1460X_MDIV_MASK
: PLL46XX_MDIV_MASK
);
560 pdiv
= (pll_con0
>> PLL46XX_PDIV_SHIFT
) & PLL46XX_PDIV_MASK
;
561 sdiv
= (pll_con0
>> PLL46XX_SDIV_SHIFT
) & PLL46XX_SDIV_MASK
;
562 kdiv
= pll
->type
== pll_4650c
? pll_con1
& PLL4650C_KDIV_MASK
:
563 pll_con1
& PLL46XX_KDIV_MASK
;
565 shift
= ((pll
->type
== pll_4600
) || (pll
->type
== pll_1460x
)) ? 16 : 10;
567 fvco
*= (mdiv
<< shift
) + kdiv
;
568 do_div(fvco
, (pdiv
<< sdiv
));
571 return (unsigned long)fvco
;
574 static bool samsung_pll46xx_mpk_change(u32 pll_con0
, u32 pll_con1
,
575 const struct samsung_pll_rate_table
*rate
)
577 u32 old_mdiv
, old_pdiv
, old_kdiv
;
579 old_mdiv
= (pll_con0
>> PLL46XX_MDIV_SHIFT
) & PLL46XX_MDIV_MASK
;
580 old_pdiv
= (pll_con0
>> PLL46XX_PDIV_SHIFT
) & PLL46XX_PDIV_MASK
;
581 old_kdiv
= (pll_con1
>> PLL46XX_KDIV_SHIFT
) & PLL46XX_KDIV_MASK
;
583 return (old_mdiv
!= rate
->mdiv
|| old_pdiv
!= rate
->pdiv
584 || old_kdiv
!= rate
->kdiv
);
587 static int samsung_pll46xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
590 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
591 const struct samsung_pll_rate_table
*rate
;
592 u32 con0
, con1
, lock
;
595 /* Get required rate settings from table */
596 rate
= samsung_get_pll_settings(pll
, drate
);
598 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
599 drate
, clk_hw_get_name(hw
));
603 con0
= readl_relaxed(pll
->con_reg
);
604 con1
= readl_relaxed(pll
->con_reg
+ 0x4);
606 if (!(samsung_pll46xx_mpk_change(con0
, con1
, rate
))) {
607 /* If only s change, change just s value only*/
608 con0
&= ~(PLL46XX_SDIV_MASK
<< PLL46XX_SDIV_SHIFT
);
609 con0
|= rate
->sdiv
<< PLL46XX_SDIV_SHIFT
;
610 writel_relaxed(con0
, pll
->con_reg
);
615 /* Set PLL lock time. */
616 lock
= rate
->pdiv
* PLL46XX_LOCK_FACTOR
;
618 /* Maximum lock time bitfield is 16-bit. */
621 /* Set PLL PMS and VSEL values. */
622 if (pll
->type
== pll_1460x
) {
623 con0
&= ~((PLL1460X_MDIV_MASK
<< PLL46XX_MDIV_SHIFT
) |
624 (PLL46XX_PDIV_MASK
<< PLL46XX_PDIV_SHIFT
) |
625 (PLL46XX_SDIV_MASK
<< PLL46XX_SDIV_SHIFT
));
627 con0
&= ~((PLL46XX_MDIV_MASK
<< PLL46XX_MDIV_SHIFT
) |
628 (PLL46XX_PDIV_MASK
<< PLL46XX_PDIV_SHIFT
) |
629 (PLL46XX_SDIV_MASK
<< PLL46XX_SDIV_SHIFT
) |
630 (PLL46XX_VSEL_MASK
<< PLL46XX_VSEL_SHIFT
));
631 con0
|= rate
->vsel
<< PLL46XX_VSEL_SHIFT
;
634 con0
|= (rate
->mdiv
<< PLL46XX_MDIV_SHIFT
) |
635 (rate
->pdiv
<< PLL46XX_PDIV_SHIFT
) |
636 (rate
->sdiv
<< PLL46XX_SDIV_SHIFT
);
638 /* Set PLL K, MFR and MRR values. */
639 con1
= readl_relaxed(pll
->con_reg
+ 0x4);
640 con1
&= ~((PLL46XX_KDIV_MASK
<< PLL46XX_KDIV_SHIFT
) |
641 (PLL46XX_MFR_MASK
<< PLL46XX_MFR_SHIFT
) |
642 (PLL46XX_MRR_MASK
<< PLL46XX_MRR_SHIFT
));
643 con1
|= (rate
->kdiv
<< PLL46XX_KDIV_SHIFT
) |
644 (rate
->mfr
<< PLL46XX_MFR_SHIFT
) |
645 (rate
->mrr
<< PLL46XX_MRR_SHIFT
);
647 /* Write configuration to PLL */
648 writel_relaxed(lock
, pll
->lock_reg
);
649 writel_relaxed(con0
, pll
->con_reg
);
650 writel_relaxed(con1
, pll
->con_reg
+ 0x4);
652 /* Wait for locking. */
654 while (!(readl_relaxed(pll
->con_reg
) & PLL46XX_LOCKED
)) {
655 ktime_t delta
= ktime_sub(ktime_get(), start
);
657 if (ktime_to_ms(delta
) > PLL_TIMEOUT_MS
) {
658 pr_err("%s: could not lock PLL %s\n",
659 __func__
, clk_hw_get_name(hw
));
669 static const struct clk_ops samsung_pll46xx_clk_ops
= {
670 .recalc_rate
= samsung_pll46xx_recalc_rate
,
671 .round_rate
= samsung_pll_round_rate
,
672 .set_rate
= samsung_pll46xx_set_rate
,
675 static const struct clk_ops samsung_pll46xx_clk_min_ops
= {
676 .recalc_rate
= samsung_pll46xx_recalc_rate
,
683 #define PLL6552_MDIV_MASK 0x3ff
684 #define PLL6552_PDIV_MASK 0x3f
685 #define PLL6552_SDIV_MASK 0x7
686 #define PLL6552_MDIV_SHIFT 16
687 #define PLL6552_MDIV_SHIFT_2416 14
688 #define PLL6552_PDIV_SHIFT 8
689 #define PLL6552_PDIV_SHIFT_2416 5
690 #define PLL6552_SDIV_SHIFT 0
692 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw
*hw
,
693 unsigned long parent_rate
)
695 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
696 u32 mdiv
, pdiv
, sdiv
, pll_con
;
697 u64 fvco
= parent_rate
;
699 pll_con
= readl_relaxed(pll
->con_reg
);
700 if (pll
->type
== pll_6552_s3c2416
) {
701 mdiv
= (pll_con
>> PLL6552_MDIV_SHIFT_2416
) & PLL6552_MDIV_MASK
;
702 pdiv
= (pll_con
>> PLL6552_PDIV_SHIFT_2416
) & PLL6552_PDIV_MASK
;
704 mdiv
= (pll_con
>> PLL6552_MDIV_SHIFT
) & PLL6552_MDIV_MASK
;
705 pdiv
= (pll_con
>> PLL6552_PDIV_SHIFT
) & PLL6552_PDIV_MASK
;
707 sdiv
= (pll_con
>> PLL6552_SDIV_SHIFT
) & PLL6552_SDIV_MASK
;
710 do_div(fvco
, (pdiv
<< sdiv
));
712 return (unsigned long)fvco
;
715 static const struct clk_ops samsung_pll6552_clk_ops
= {
716 .recalc_rate
= samsung_pll6552_recalc_rate
,
723 #define PLL6553_MDIV_MASK 0xff
724 #define PLL6553_PDIV_MASK 0x3f
725 #define PLL6553_SDIV_MASK 0x7
726 #define PLL6553_KDIV_MASK 0xffff
727 #define PLL6553_MDIV_SHIFT 16
728 #define PLL6553_PDIV_SHIFT 8
729 #define PLL6553_SDIV_SHIFT 0
730 #define PLL6553_KDIV_SHIFT 0
732 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw
*hw
,
733 unsigned long parent_rate
)
735 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
736 u32 mdiv
, pdiv
, sdiv
, kdiv
, pll_con0
, pll_con1
;
737 u64 fvco
= parent_rate
;
739 pll_con0
= readl_relaxed(pll
->con_reg
);
740 pll_con1
= readl_relaxed(pll
->con_reg
+ 0x4);
741 mdiv
= (pll_con0
>> PLL6553_MDIV_SHIFT
) & PLL6553_MDIV_MASK
;
742 pdiv
= (pll_con0
>> PLL6553_PDIV_SHIFT
) & PLL6553_PDIV_MASK
;
743 sdiv
= (pll_con0
>> PLL6553_SDIV_SHIFT
) & PLL6553_SDIV_MASK
;
744 kdiv
= (pll_con1
>> PLL6553_KDIV_SHIFT
) & PLL6553_KDIV_MASK
;
746 fvco
*= (mdiv
<< 16) + kdiv
;
747 do_div(fvco
, (pdiv
<< sdiv
));
750 return (unsigned long)fvco
;
753 static const struct clk_ops samsung_pll6553_clk_ops
= {
754 .recalc_rate
= samsung_pll6553_recalc_rate
,
758 * PLL Clock Type of S3C24XX before S3C2443
761 #define PLLS3C2410_MDIV_MASK (0xff)
762 #define PLLS3C2410_PDIV_MASK (0x1f)
763 #define PLLS3C2410_SDIV_MASK (0x3)
764 #define PLLS3C2410_MDIV_SHIFT (12)
765 #define PLLS3C2410_PDIV_SHIFT (4)
766 #define PLLS3C2410_SDIV_SHIFT (0)
768 #define PLLS3C2410_ENABLE_REG_OFFSET 0x10
770 static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw
*hw
,
771 unsigned long parent_rate
)
773 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
774 u32 pll_con
, mdiv
, pdiv
, sdiv
;
775 u64 fvco
= parent_rate
;
777 pll_con
= readl_relaxed(pll
->con_reg
);
778 mdiv
= (pll_con
>> PLLS3C2410_MDIV_SHIFT
) & PLLS3C2410_MDIV_MASK
;
779 pdiv
= (pll_con
>> PLLS3C2410_PDIV_SHIFT
) & PLLS3C2410_PDIV_MASK
;
780 sdiv
= (pll_con
>> PLLS3C2410_SDIV_SHIFT
) & PLLS3C2410_SDIV_MASK
;
783 do_div(fvco
, (pdiv
+ 2) << sdiv
);
785 return (unsigned int)fvco
;
788 static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw
*hw
,
789 unsigned long parent_rate
)
791 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
792 u32 pll_con
, mdiv
, pdiv
, sdiv
;
793 u64 fvco
= parent_rate
;
795 pll_con
= readl_relaxed(pll
->con_reg
);
796 mdiv
= (pll_con
>> PLLS3C2410_MDIV_SHIFT
) & PLLS3C2410_MDIV_MASK
;
797 pdiv
= (pll_con
>> PLLS3C2410_PDIV_SHIFT
) & PLLS3C2410_PDIV_MASK
;
798 sdiv
= (pll_con
>> PLLS3C2410_SDIV_SHIFT
) & PLLS3C2410_SDIV_MASK
;
800 fvco
*= (2 * (mdiv
+ 8));
801 do_div(fvco
, (pdiv
+ 2) << sdiv
);
803 return (unsigned int)fvco
;
806 static int samsung_s3c2410_pll_set_rate(struct clk_hw
*hw
, unsigned long drate
,
809 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
810 const struct samsung_pll_rate_table
*rate
;
813 /* Get required rate settings from table */
814 rate
= samsung_get_pll_settings(pll
, drate
);
816 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
817 drate
, clk_hw_get_name(hw
));
821 tmp
= readl_relaxed(pll
->con_reg
);
823 /* Change PLL PMS values */
824 tmp
&= ~((PLLS3C2410_MDIV_MASK
<< PLLS3C2410_MDIV_SHIFT
) |
825 (PLLS3C2410_PDIV_MASK
<< PLLS3C2410_PDIV_SHIFT
) |
826 (PLLS3C2410_SDIV_MASK
<< PLLS3C2410_SDIV_SHIFT
));
827 tmp
|= (rate
->mdiv
<< PLLS3C2410_MDIV_SHIFT
) |
828 (rate
->pdiv
<< PLLS3C2410_PDIV_SHIFT
) |
829 (rate
->sdiv
<< PLLS3C2410_SDIV_SHIFT
);
830 writel_relaxed(tmp
, pll
->con_reg
);
832 /* Time to settle according to the manual */
838 static int samsung_s3c2410_pll_enable(struct clk_hw
*hw
, int bit
, bool enable
)
840 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
841 u32 pll_en
= readl_relaxed(pll
->lock_reg
+ PLLS3C2410_ENABLE_REG_OFFSET
);
842 u32 pll_en_orig
= pll_en
;
849 writel_relaxed(pll_en
, pll
->lock_reg
+ PLLS3C2410_ENABLE_REG_OFFSET
);
851 /* if we started the UPLL, then allow to settle */
852 if (enable
&& (pll_en_orig
& BIT(bit
)))
858 static int samsung_s3c2410_mpll_enable(struct clk_hw
*hw
)
860 return samsung_s3c2410_pll_enable(hw
, 5, true);
863 static void samsung_s3c2410_mpll_disable(struct clk_hw
*hw
)
865 samsung_s3c2410_pll_enable(hw
, 5, false);
868 static int samsung_s3c2410_upll_enable(struct clk_hw
*hw
)
870 return samsung_s3c2410_pll_enable(hw
, 7, true);
873 static void samsung_s3c2410_upll_disable(struct clk_hw
*hw
)
875 samsung_s3c2410_pll_enable(hw
, 7, false);
878 static const struct clk_ops samsung_s3c2410_mpll_clk_min_ops
= {
879 .recalc_rate
= samsung_s3c2410_pll_recalc_rate
,
880 .enable
= samsung_s3c2410_mpll_enable
,
881 .disable
= samsung_s3c2410_mpll_disable
,
884 static const struct clk_ops samsung_s3c2410_upll_clk_min_ops
= {
885 .recalc_rate
= samsung_s3c2410_pll_recalc_rate
,
886 .enable
= samsung_s3c2410_upll_enable
,
887 .disable
= samsung_s3c2410_upll_disable
,
890 static const struct clk_ops samsung_s3c2440_mpll_clk_min_ops
= {
891 .recalc_rate
= samsung_s3c2440_mpll_recalc_rate
,
892 .enable
= samsung_s3c2410_mpll_enable
,
893 .disable
= samsung_s3c2410_mpll_disable
,
896 static const struct clk_ops samsung_s3c2410_mpll_clk_ops
= {
897 .recalc_rate
= samsung_s3c2410_pll_recalc_rate
,
898 .enable
= samsung_s3c2410_mpll_enable
,
899 .disable
= samsung_s3c2410_mpll_disable
,
900 .round_rate
= samsung_pll_round_rate
,
901 .set_rate
= samsung_s3c2410_pll_set_rate
,
904 static const struct clk_ops samsung_s3c2410_upll_clk_ops
= {
905 .recalc_rate
= samsung_s3c2410_pll_recalc_rate
,
906 .enable
= samsung_s3c2410_upll_enable
,
907 .disable
= samsung_s3c2410_upll_disable
,
908 .round_rate
= samsung_pll_round_rate
,
909 .set_rate
= samsung_s3c2410_pll_set_rate
,
912 static const struct clk_ops samsung_s3c2440_mpll_clk_ops
= {
913 .recalc_rate
= samsung_s3c2440_mpll_recalc_rate
,
914 .enable
= samsung_s3c2410_mpll_enable
,
915 .disable
= samsung_s3c2410_mpll_disable
,
916 .round_rate
= samsung_pll_round_rate
,
917 .set_rate
= samsung_s3c2410_pll_set_rate
,
921 * PLL2550x Clock Type
924 #define PLL2550X_R_MASK (0x1)
925 #define PLL2550X_P_MASK (0x3F)
926 #define PLL2550X_M_MASK (0x3FF)
927 #define PLL2550X_S_MASK (0x7)
928 #define PLL2550X_R_SHIFT (20)
929 #define PLL2550X_P_SHIFT (14)
930 #define PLL2550X_M_SHIFT (4)
931 #define PLL2550X_S_SHIFT (0)
933 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw
*hw
,
934 unsigned long parent_rate
)
936 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
937 u32 r
, p
, m
, s
, pll_stat
;
938 u64 fvco
= parent_rate
;
940 pll_stat
= readl_relaxed(pll
->con_reg
);
941 r
= (pll_stat
>> PLL2550X_R_SHIFT
) & PLL2550X_R_MASK
;
944 p
= (pll_stat
>> PLL2550X_P_SHIFT
) & PLL2550X_P_MASK
;
945 m
= (pll_stat
>> PLL2550X_M_SHIFT
) & PLL2550X_M_MASK
;
946 s
= (pll_stat
>> PLL2550X_S_SHIFT
) & PLL2550X_S_MASK
;
949 do_div(fvco
, (p
<< s
));
951 return (unsigned long)fvco
;
954 static const struct clk_ops samsung_pll2550x_clk_ops
= {
955 .recalc_rate
= samsung_pll2550x_recalc_rate
,
959 * PLL2550xx Clock Type
962 /* Maximum lock time can be 270 * PDIV cycles */
963 #define PLL2550XX_LOCK_FACTOR 270
965 #define PLL2550XX_M_MASK 0x3FF
966 #define PLL2550XX_P_MASK 0x3F
967 #define PLL2550XX_S_MASK 0x7
968 #define PLL2550XX_LOCK_STAT_MASK 0x1
969 #define PLL2550XX_M_SHIFT 9
970 #define PLL2550XX_P_SHIFT 3
971 #define PLL2550XX_S_SHIFT 0
972 #define PLL2550XX_LOCK_STAT_SHIFT 21
974 static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw
*hw
,
975 unsigned long parent_rate
)
977 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
978 u32 mdiv
, pdiv
, sdiv
, pll_con
;
979 u64 fvco
= parent_rate
;
981 pll_con
= readl_relaxed(pll
->con_reg
);
982 mdiv
= (pll_con
>> PLL2550XX_M_SHIFT
) & PLL2550XX_M_MASK
;
983 pdiv
= (pll_con
>> PLL2550XX_P_SHIFT
) & PLL2550XX_P_MASK
;
984 sdiv
= (pll_con
>> PLL2550XX_S_SHIFT
) & PLL2550XX_S_MASK
;
987 do_div(fvco
, (pdiv
<< sdiv
));
989 return (unsigned long)fvco
;
992 static inline bool samsung_pll2550xx_mp_change(u32 mdiv
, u32 pdiv
, u32 pll_con
)
994 u32 old_mdiv
, old_pdiv
;
996 old_mdiv
= (pll_con
>> PLL2550XX_M_SHIFT
) & PLL2550XX_M_MASK
;
997 old_pdiv
= (pll_con
>> PLL2550XX_P_SHIFT
) & PLL2550XX_P_MASK
;
999 return mdiv
!= old_mdiv
|| pdiv
!= old_pdiv
;
1002 static int samsung_pll2550xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
1003 unsigned long prate
)
1005 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1006 const struct samsung_pll_rate_table
*rate
;
1009 /* Get required rate settings from table */
1010 rate
= samsung_get_pll_settings(pll
, drate
);
1012 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
1013 drate
, clk_hw_get_name(hw
));
1017 tmp
= readl_relaxed(pll
->con_reg
);
1019 if (!(samsung_pll2550xx_mp_change(rate
->mdiv
, rate
->pdiv
, tmp
))) {
1020 /* If only s change, change just s value only*/
1021 tmp
&= ~(PLL2550XX_S_MASK
<< PLL2550XX_S_SHIFT
);
1022 tmp
|= rate
->sdiv
<< PLL2550XX_S_SHIFT
;
1023 writel_relaxed(tmp
, pll
->con_reg
);
1028 /* Set PLL lock time. */
1029 writel_relaxed(rate
->pdiv
* PLL2550XX_LOCK_FACTOR
, pll
->lock_reg
);
1031 /* Change PLL PMS values */
1032 tmp
&= ~((PLL2550XX_M_MASK
<< PLL2550XX_M_SHIFT
) |
1033 (PLL2550XX_P_MASK
<< PLL2550XX_P_SHIFT
) |
1034 (PLL2550XX_S_MASK
<< PLL2550XX_S_SHIFT
));
1035 tmp
|= (rate
->mdiv
<< PLL2550XX_M_SHIFT
) |
1036 (rate
->pdiv
<< PLL2550XX_P_SHIFT
) |
1037 (rate
->sdiv
<< PLL2550XX_S_SHIFT
);
1038 writel_relaxed(tmp
, pll
->con_reg
);
1040 /* wait_lock_time */
1043 tmp
= readl_relaxed(pll
->con_reg
);
1044 } while (!(tmp
& (PLL2550XX_LOCK_STAT_MASK
1045 << PLL2550XX_LOCK_STAT_SHIFT
)));
1050 static const struct clk_ops samsung_pll2550xx_clk_ops
= {
1051 .recalc_rate
= samsung_pll2550xx_recalc_rate
,
1052 .round_rate
= samsung_pll_round_rate
,
1053 .set_rate
= samsung_pll2550xx_set_rate
,
1056 static const struct clk_ops samsung_pll2550xx_clk_min_ops
= {
1057 .recalc_rate
= samsung_pll2550xx_recalc_rate
,
1061 * PLL2650x Clock Type
1064 /* Maximum lock time can be 3000 * PDIV cycles */
1065 #define PLL2650X_LOCK_FACTOR 3000
1067 #define PLL2650X_M_MASK 0x1ff
1068 #define PLL2650X_P_MASK 0x3f
1069 #define PLL2650X_S_MASK 0x7
1070 #define PLL2650X_K_MASK 0xffff
1071 #define PLL2650X_LOCK_STAT_MASK 0x1
1072 #define PLL2650X_M_SHIFT 16
1073 #define PLL2650X_P_SHIFT 8
1074 #define PLL2650X_S_SHIFT 0
1075 #define PLL2650X_K_SHIFT 0
1076 #define PLL2650X_LOCK_STAT_SHIFT 29
1077 #define PLL2650X_PLL_ENABLE_SHIFT 31
1079 static unsigned long samsung_pll2650x_recalc_rate(struct clk_hw
*hw
,
1080 unsigned long parent_rate
)
1082 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1083 u64 fout
= parent_rate
;
1084 u32 mdiv
, pdiv
, sdiv
, pll_con0
, pll_con1
;
1087 pll_con0
= readl_relaxed(pll
->con_reg
);
1088 mdiv
= (pll_con0
>> PLL2650X_M_SHIFT
) & PLL2650X_M_MASK
;
1089 pdiv
= (pll_con0
>> PLL2650X_P_SHIFT
) & PLL2650X_P_MASK
;
1090 sdiv
= (pll_con0
>> PLL2650X_S_SHIFT
) & PLL2650X_S_MASK
;
1092 pll_con1
= readl_relaxed(pll
->con_reg
+ 4);
1093 kdiv
= (s16
)((pll_con1
>> PLL2650X_K_SHIFT
) & PLL2650X_K_MASK
);
1095 fout
*= (mdiv
<< 16) + kdiv
;
1096 do_div(fout
, (pdiv
<< sdiv
));
1099 return (unsigned long)fout
;
1102 static int samsung_pll2650x_set_rate(struct clk_hw
*hw
, unsigned long drate
,
1103 unsigned long prate
)
1105 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1106 const struct samsung_pll_rate_table
*rate
;
1109 /* Get required rate settings from table */
1110 rate
= samsung_get_pll_settings(pll
, drate
);
1112 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
1113 drate
, clk_hw_get_name(hw
));
1117 con0
= readl_relaxed(pll
->con_reg
);
1118 con1
= readl_relaxed(pll
->con_reg
+ 4);
1120 /* Set PLL lock time. */
1121 writel_relaxed(rate
->pdiv
* PLL2650X_LOCK_FACTOR
, pll
->lock_reg
);
1123 /* Change PLL PMS values */
1124 con0
&= ~((PLL2650X_M_MASK
<< PLL2650X_M_SHIFT
) |
1125 (PLL2650X_P_MASK
<< PLL2650X_P_SHIFT
) |
1126 (PLL2650X_S_MASK
<< PLL2650X_S_SHIFT
));
1127 con0
|= (rate
->mdiv
<< PLL2650X_M_SHIFT
) |
1128 (rate
->pdiv
<< PLL2650X_P_SHIFT
) |
1129 (rate
->sdiv
<< PLL2650X_S_SHIFT
);
1130 con0
|= (1 << PLL2650X_PLL_ENABLE_SHIFT
);
1131 writel_relaxed(con0
, pll
->con_reg
);
1133 con1
&= ~(PLL2650X_K_MASK
<< PLL2650X_K_SHIFT
);
1134 con1
|= ((rate
->kdiv
& PLL2650X_K_MASK
) << PLL2650X_K_SHIFT
);
1135 writel_relaxed(con1
, pll
->con_reg
+ 4);
1139 con0
= readl_relaxed(pll
->con_reg
);
1140 } while (!(con0
& (PLL2650X_LOCK_STAT_MASK
1141 << PLL2650X_LOCK_STAT_SHIFT
)));
1146 static const struct clk_ops samsung_pll2650x_clk_ops
= {
1147 .recalc_rate
= samsung_pll2650x_recalc_rate
,
1148 .round_rate
= samsung_pll_round_rate
,
1149 .set_rate
= samsung_pll2650x_set_rate
,
1152 static const struct clk_ops samsung_pll2650x_clk_min_ops
= {
1153 .recalc_rate
= samsung_pll2650x_recalc_rate
,
1157 * PLL2650XX Clock Type
1160 /* Maximum lock time can be 3000 * PDIV cycles */
1161 #define PLL2650XX_LOCK_FACTOR 3000
1163 #define PLL2650XX_MDIV_SHIFT 9
1164 #define PLL2650XX_PDIV_SHIFT 3
1165 #define PLL2650XX_SDIV_SHIFT 0
1166 #define PLL2650XX_KDIV_SHIFT 0
1167 #define PLL2650XX_MDIV_MASK 0x1ff
1168 #define PLL2650XX_PDIV_MASK 0x3f
1169 #define PLL2650XX_SDIV_MASK 0x7
1170 #define PLL2650XX_KDIV_MASK 0xffff
1171 #define PLL2650XX_PLL_ENABLE_SHIFT 23
1172 #define PLL2650XX_PLL_LOCKTIME_SHIFT 21
1173 #define PLL2650XX_PLL_FOUTMASK_SHIFT 31
1175 static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw
*hw
,
1176 unsigned long parent_rate
)
1178 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1179 u32 mdiv
, pdiv
, sdiv
, pll_con0
, pll_con2
;
1181 u64 fvco
= parent_rate
;
1183 pll_con0
= readl_relaxed(pll
->con_reg
);
1184 pll_con2
= readl_relaxed(pll
->con_reg
+ 8);
1185 mdiv
= (pll_con0
>> PLL2650XX_MDIV_SHIFT
) & PLL2650XX_MDIV_MASK
;
1186 pdiv
= (pll_con0
>> PLL2650XX_PDIV_SHIFT
) & PLL2650XX_PDIV_MASK
;
1187 sdiv
= (pll_con0
>> PLL2650XX_SDIV_SHIFT
) & PLL2650XX_SDIV_MASK
;
1188 kdiv
= (s16
)(pll_con2
& PLL2650XX_KDIV_MASK
);
1190 fvco
*= (mdiv
<< 16) + kdiv
;
1191 do_div(fvco
, (pdiv
<< sdiv
));
1194 return (unsigned long)fvco
;
1197 static int samsung_pll2650xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
1198 unsigned long parent_rate
)
1200 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1201 u32 tmp
, pll_con0
, pll_con2
;
1202 const struct samsung_pll_rate_table
*rate
;
1204 rate
= samsung_get_pll_settings(pll
, drate
);
1206 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
1207 drate
, clk_hw_get_name(hw
));
1211 pll_con0
= readl_relaxed(pll
->con_reg
);
1212 pll_con2
= readl_relaxed(pll
->con_reg
+ 8);
1214 /* Change PLL PMS values */
1215 pll_con0
&= ~(PLL2650XX_MDIV_MASK
<< PLL2650XX_MDIV_SHIFT
|
1216 PLL2650XX_PDIV_MASK
<< PLL2650XX_PDIV_SHIFT
|
1217 PLL2650XX_SDIV_MASK
<< PLL2650XX_SDIV_SHIFT
);
1218 pll_con0
|= rate
->mdiv
<< PLL2650XX_MDIV_SHIFT
;
1219 pll_con0
|= rate
->pdiv
<< PLL2650XX_PDIV_SHIFT
;
1220 pll_con0
|= rate
->sdiv
<< PLL2650XX_SDIV_SHIFT
;
1221 pll_con0
|= 1 << PLL2650XX_PLL_ENABLE_SHIFT
;
1222 pll_con0
|= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT
;
1224 pll_con2
&= ~(PLL2650XX_KDIV_MASK
<< PLL2650XX_KDIV_SHIFT
);
1225 pll_con2
|= ((~(rate
->kdiv
) + 1) & PLL2650XX_KDIV_MASK
)
1226 << PLL2650XX_KDIV_SHIFT
;
1228 /* Set PLL lock time. */
1229 writel_relaxed(PLL2650XX_LOCK_FACTOR
* rate
->pdiv
, pll
->lock_reg
);
1231 writel_relaxed(pll_con0
, pll
->con_reg
);
1232 writel_relaxed(pll_con2
, pll
->con_reg
+ 8);
1235 tmp
= readl_relaxed(pll
->con_reg
);
1236 } while (!(tmp
& (0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT
)));
1241 static const struct clk_ops samsung_pll2650xx_clk_ops
= {
1242 .recalc_rate
= samsung_pll2650xx_recalc_rate
,
1243 .set_rate
= samsung_pll2650xx_set_rate
,
1244 .round_rate
= samsung_pll_round_rate
,
1247 static const struct clk_ops samsung_pll2650xx_clk_min_ops
= {
1248 .recalc_rate
= samsung_pll2650xx_recalc_rate
,
1251 static void __init
_samsung_clk_register_pll(struct samsung_clk_provider
*ctx
,
1252 const struct samsung_pll_clock
*pll_clk
,
1255 struct samsung_clk_pll
*pll
;
1256 struct clk_init_data init
;
1259 pll
= kzalloc(sizeof(*pll
), GFP_KERNEL
);
1261 pr_err("%s: could not allocate pll clk %s\n",
1262 __func__
, pll_clk
->name
);
1266 init
.name
= pll_clk
->name
;
1267 init
.flags
= pll_clk
->flags
;
1268 init
.parent_names
= &pll_clk
->parent_name
;
1269 init
.num_parents
= 1;
1271 if (pll_clk
->rate_table
) {
1272 /* find count of rates in rate_table */
1273 for (len
= 0; pll_clk
->rate_table
[len
].rate
!= 0; )
1276 pll
->rate_count
= len
;
1277 pll
->rate_table
= kmemdup(pll_clk
->rate_table
,
1279 sizeof(struct samsung_pll_rate_table
),
1281 WARN(!pll
->rate_table
,
1282 "%s: could not allocate rate table for %s\n",
1283 __func__
, pll_clk
->name
);
1286 switch (pll_clk
->type
) {
1288 init
.ops
= &samsung_pll2126_clk_ops
;
1291 init
.ops
= &samsung_pll3000_clk_ops
;
1293 /* clk_ops for 35xx and 2550 are similar */
1299 pll
->enable_offs
= PLL35XX_ENABLE_SHIFT
;
1300 pll
->lock_offs
= PLL35XX_LOCK_STAT_SHIFT
;
1301 if (!pll
->rate_table
)
1302 init
.ops
= &samsung_pll35xx_clk_min_ops
;
1304 init
.ops
= &samsung_pll35xx_clk_ops
;
1307 init
.ops
= &samsung_pll45xx_clk_min_ops
;
1311 if (!pll
->rate_table
)
1312 init
.ops
= &samsung_pll45xx_clk_min_ops
;
1314 init
.ops
= &samsung_pll45xx_clk_ops
;
1316 /* clk_ops for 36xx and 2650 are similar */
1319 pll
->enable_offs
= PLL36XX_ENABLE_SHIFT
;
1320 pll
->lock_offs
= PLL36XX_LOCK_STAT_SHIFT
;
1321 if (!pll
->rate_table
)
1322 init
.ops
= &samsung_pll36xx_clk_min_ops
;
1324 init
.ops
= &samsung_pll36xx_clk_ops
;
1327 case pll_6552_s3c2416
:
1328 init
.ops
= &samsung_pll6552_clk_ops
;
1331 init
.ops
= &samsung_pll6553_clk_ops
;
1337 if (!pll
->rate_table
)
1338 init
.ops
= &samsung_pll46xx_clk_min_ops
;
1340 init
.ops
= &samsung_pll46xx_clk_ops
;
1342 case pll_s3c2410_mpll
:
1343 if (!pll
->rate_table
)
1344 init
.ops
= &samsung_s3c2410_mpll_clk_min_ops
;
1346 init
.ops
= &samsung_s3c2410_mpll_clk_ops
;
1348 case pll_s3c2410_upll
:
1349 if (!pll
->rate_table
)
1350 init
.ops
= &samsung_s3c2410_upll_clk_min_ops
;
1352 init
.ops
= &samsung_s3c2410_upll_clk_ops
;
1354 case pll_s3c2440_mpll
:
1355 if (!pll
->rate_table
)
1356 init
.ops
= &samsung_s3c2440_mpll_clk_min_ops
;
1358 init
.ops
= &samsung_s3c2440_mpll_clk_ops
;
1361 init
.ops
= &samsung_pll2550x_clk_ops
;
1364 if (!pll
->rate_table
)
1365 init
.ops
= &samsung_pll2550xx_clk_min_ops
;
1367 init
.ops
= &samsung_pll2550xx_clk_ops
;
1370 if (!pll
->rate_table
)
1371 init
.ops
= &samsung_pll2650x_clk_min_ops
;
1373 init
.ops
= &samsung_pll2650x_clk_ops
;
1376 if (!pll
->rate_table
)
1377 init
.ops
= &samsung_pll2650xx_clk_min_ops
;
1379 init
.ops
= &samsung_pll2650xx_clk_ops
;
1382 pr_warn("%s: Unknown pll type for pll clk %s\n",
1383 __func__
, pll_clk
->name
);
1386 pll
->hw
.init
= &init
;
1387 pll
->type
= pll_clk
->type
;
1388 pll
->lock_reg
= base
+ pll_clk
->lock_offset
;
1389 pll
->con_reg
= base
+ pll_clk
->con_offset
;
1391 ret
= clk_hw_register(ctx
->dev
, &pll
->hw
);
1393 pr_err("%s: failed to register pll clock %s : %d\n",
1394 __func__
, pll_clk
->name
, ret
);
1399 samsung_clk_add_lookup(ctx
, &pll
->hw
, pll_clk
->id
);
1402 void __init
samsung_clk_register_pll(struct samsung_clk_provider
*ctx
,
1403 const struct samsung_pll_clock
*pll_list
,
1404 unsigned int nr_pll
, void __iomem
*base
)
1408 for (cnt
= 0; cnt
< nr_pll
; cnt
++)
1409 _samsung_clk_register_pll(ctx
, &pll_list
[cnt
], base
);