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>
18 #define PLL_TIMEOUT_MS 10
20 struct samsung_clk_pll
{
22 void __iomem
*lock_reg
;
23 void __iomem
*con_reg
;
24 enum samsung_pll_type type
;
25 unsigned int rate_count
;
26 const struct samsung_pll_rate_table
*rate_table
;
29 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
31 static const struct samsung_pll_rate_table
*samsung_get_pll_settings(
32 struct samsung_clk_pll
*pll
, unsigned long rate
)
34 const struct samsung_pll_rate_table
*rate_table
= pll
->rate_table
;
37 for (i
= 0; i
< pll
->rate_count
; i
++) {
38 if (rate
== rate_table
[i
].rate
)
39 return &rate_table
[i
];
45 static long samsung_pll_round_rate(struct clk_hw
*hw
,
46 unsigned long drate
, unsigned long *prate
)
48 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
49 const struct samsung_pll_rate_table
*rate_table
= pll
->rate_table
;
52 /* Assumming rate_table is in descending order */
53 for (i
= 0; i
< pll
->rate_count
; i
++) {
54 if (drate
>= rate_table
[i
].rate
)
55 return rate_table
[i
].rate
;
58 /* return minimum supported value */
59 return rate_table
[i
- 1].rate
;
66 #define PLL2126_MDIV_MASK (0xff)
67 #define PLL2126_PDIV_MASK (0x3f)
68 #define PLL2126_SDIV_MASK (0x3)
69 #define PLL2126_MDIV_SHIFT (16)
70 #define PLL2126_PDIV_SHIFT (8)
71 #define PLL2126_SDIV_SHIFT (0)
73 static unsigned long samsung_pll2126_recalc_rate(struct clk_hw
*hw
,
74 unsigned long parent_rate
)
76 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
77 u32 pll_con
, mdiv
, pdiv
, sdiv
;
78 u64 fvco
= parent_rate
;
80 pll_con
= __raw_readl(pll
->con_reg
);
81 mdiv
= (pll_con
>> PLL2126_MDIV_SHIFT
) & PLL2126_MDIV_MASK
;
82 pdiv
= (pll_con
>> PLL2126_PDIV_SHIFT
) & PLL2126_PDIV_MASK
;
83 sdiv
= (pll_con
>> PLL2126_SDIV_SHIFT
) & PLL2126_SDIV_MASK
;
86 do_div(fvco
, (pdiv
+ 2) << sdiv
);
88 return (unsigned long)fvco
;
91 static const struct clk_ops samsung_pll2126_clk_ops
= {
92 .recalc_rate
= samsung_pll2126_recalc_rate
,
99 #define PLL3000_MDIV_MASK (0xff)
100 #define PLL3000_PDIV_MASK (0x3)
101 #define PLL3000_SDIV_MASK (0x3)
102 #define PLL3000_MDIV_SHIFT (16)
103 #define PLL3000_PDIV_SHIFT (8)
104 #define PLL3000_SDIV_SHIFT (0)
106 static unsigned long samsung_pll3000_recalc_rate(struct clk_hw
*hw
,
107 unsigned long parent_rate
)
109 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
110 u32 pll_con
, mdiv
, pdiv
, sdiv
;
111 u64 fvco
= parent_rate
;
113 pll_con
= __raw_readl(pll
->con_reg
);
114 mdiv
= (pll_con
>> PLL3000_MDIV_SHIFT
) & PLL3000_MDIV_MASK
;
115 pdiv
= (pll_con
>> PLL3000_PDIV_SHIFT
) & PLL3000_PDIV_MASK
;
116 sdiv
= (pll_con
>> PLL3000_SDIV_SHIFT
) & PLL3000_SDIV_MASK
;
118 fvco
*= (2 * (mdiv
+ 8));
119 do_div(fvco
, pdiv
<< sdiv
);
121 return (unsigned long)fvco
;
124 static const struct clk_ops samsung_pll3000_clk_ops
= {
125 .recalc_rate
= samsung_pll3000_recalc_rate
,
131 /* Maximum lock time can be 270 * PDIV cycles */
132 #define PLL35XX_LOCK_FACTOR (270)
134 #define PLL35XX_MDIV_MASK (0x3FF)
135 #define PLL35XX_PDIV_MASK (0x3F)
136 #define PLL35XX_SDIV_MASK (0x7)
137 #define PLL35XX_LOCK_STAT_MASK (0x1)
138 #define PLL35XX_MDIV_SHIFT (16)
139 #define PLL35XX_PDIV_SHIFT (8)
140 #define PLL35XX_SDIV_SHIFT (0)
141 #define PLL35XX_LOCK_STAT_SHIFT (29)
143 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw
*hw
,
144 unsigned long parent_rate
)
146 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
147 u32 mdiv
, pdiv
, sdiv
, pll_con
;
148 u64 fvco
= parent_rate
;
150 pll_con
= __raw_readl(pll
->con_reg
);
151 mdiv
= (pll_con
>> PLL35XX_MDIV_SHIFT
) & PLL35XX_MDIV_MASK
;
152 pdiv
= (pll_con
>> PLL35XX_PDIV_SHIFT
) & PLL35XX_PDIV_MASK
;
153 sdiv
= (pll_con
>> PLL35XX_SDIV_SHIFT
) & PLL35XX_SDIV_MASK
;
156 do_div(fvco
, (pdiv
<< sdiv
));
158 return (unsigned long)fvco
;
161 static inline bool samsung_pll35xx_mp_change(
162 const struct samsung_pll_rate_table
*rate
, u32 pll_con
)
164 u32 old_mdiv
, old_pdiv
;
166 old_mdiv
= (pll_con
>> PLL35XX_MDIV_SHIFT
) & PLL35XX_MDIV_MASK
;
167 old_pdiv
= (pll_con
>> PLL35XX_PDIV_SHIFT
) & PLL35XX_PDIV_MASK
;
169 return (rate
->mdiv
!= old_mdiv
|| rate
->pdiv
!= old_pdiv
);
172 static int samsung_pll35xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
175 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
176 const struct samsung_pll_rate_table
*rate
;
179 /* Get required rate settings from table */
180 rate
= samsung_get_pll_settings(pll
, drate
);
182 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
183 drate
, __clk_get_name(hw
->clk
));
187 tmp
= __raw_readl(pll
->con_reg
);
189 if (!(samsung_pll35xx_mp_change(rate
, tmp
))) {
190 /* If only s change, change just s value only*/
191 tmp
&= ~(PLL35XX_SDIV_MASK
<< PLL35XX_SDIV_SHIFT
);
192 tmp
|= rate
->sdiv
<< PLL35XX_SDIV_SHIFT
;
193 __raw_writel(tmp
, pll
->con_reg
);
198 /* Set PLL lock time. */
199 __raw_writel(rate
->pdiv
* PLL35XX_LOCK_FACTOR
,
202 /* Change PLL PMS values */
203 tmp
&= ~((PLL35XX_MDIV_MASK
<< PLL35XX_MDIV_SHIFT
) |
204 (PLL35XX_PDIV_MASK
<< PLL35XX_PDIV_SHIFT
) |
205 (PLL35XX_SDIV_MASK
<< PLL35XX_SDIV_SHIFT
));
206 tmp
|= (rate
->mdiv
<< PLL35XX_MDIV_SHIFT
) |
207 (rate
->pdiv
<< PLL35XX_PDIV_SHIFT
) |
208 (rate
->sdiv
<< PLL35XX_SDIV_SHIFT
);
209 __raw_writel(tmp
, pll
->con_reg
);
214 tmp
= __raw_readl(pll
->con_reg
);
215 } while (!(tmp
& (PLL35XX_LOCK_STAT_MASK
216 << PLL35XX_LOCK_STAT_SHIFT
)));
220 static const struct clk_ops samsung_pll35xx_clk_ops
= {
221 .recalc_rate
= samsung_pll35xx_recalc_rate
,
222 .round_rate
= samsung_pll_round_rate
,
223 .set_rate
= samsung_pll35xx_set_rate
,
226 static const struct clk_ops samsung_pll35xx_clk_min_ops
= {
227 .recalc_rate
= samsung_pll35xx_recalc_rate
,
233 /* Maximum lock time can be 3000 * PDIV cycles */
234 #define PLL36XX_LOCK_FACTOR (3000)
236 #define PLL36XX_KDIV_MASK (0xFFFF)
237 #define PLL36XX_MDIV_MASK (0x1FF)
238 #define PLL36XX_PDIV_MASK (0x3F)
239 #define PLL36XX_SDIV_MASK (0x7)
240 #define PLL36XX_MDIV_SHIFT (16)
241 #define PLL36XX_PDIV_SHIFT (8)
242 #define PLL36XX_SDIV_SHIFT (0)
243 #define PLL36XX_KDIV_SHIFT (0)
244 #define PLL36XX_LOCK_STAT_SHIFT (29)
246 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw
*hw
,
247 unsigned long parent_rate
)
249 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
250 u32 mdiv
, pdiv
, sdiv
, pll_con0
, pll_con1
;
252 u64 fvco
= parent_rate
;
254 pll_con0
= __raw_readl(pll
->con_reg
);
255 pll_con1
= __raw_readl(pll
->con_reg
+ 4);
256 mdiv
= (pll_con0
>> PLL36XX_MDIV_SHIFT
) & PLL36XX_MDIV_MASK
;
257 pdiv
= (pll_con0
>> PLL36XX_PDIV_SHIFT
) & PLL36XX_PDIV_MASK
;
258 sdiv
= (pll_con0
>> PLL36XX_SDIV_SHIFT
) & PLL36XX_SDIV_MASK
;
259 kdiv
= (s16
)(pll_con1
& PLL36XX_KDIV_MASK
);
261 fvco
*= (mdiv
<< 16) + kdiv
;
262 do_div(fvco
, (pdiv
<< sdiv
));
265 return (unsigned long)fvco
;
268 static inline bool samsung_pll36xx_mpk_change(
269 const struct samsung_pll_rate_table
*rate
, u32 pll_con0
, u32 pll_con1
)
271 u32 old_mdiv
, old_pdiv
, old_kdiv
;
273 old_mdiv
= (pll_con0
>> PLL36XX_MDIV_SHIFT
) & PLL36XX_MDIV_MASK
;
274 old_pdiv
= (pll_con0
>> PLL36XX_PDIV_SHIFT
) & PLL36XX_PDIV_MASK
;
275 old_kdiv
= (pll_con1
>> PLL36XX_KDIV_SHIFT
) & PLL36XX_KDIV_MASK
;
277 return (rate
->mdiv
!= old_mdiv
|| rate
->pdiv
!= old_pdiv
||
278 rate
->kdiv
!= old_kdiv
);
281 static int samsung_pll36xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
282 unsigned long parent_rate
)
284 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
285 u32 tmp
, pll_con0
, pll_con1
;
286 const struct samsung_pll_rate_table
*rate
;
288 rate
= samsung_get_pll_settings(pll
, drate
);
290 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
291 drate
, __clk_get_name(hw
->clk
));
295 pll_con0
= __raw_readl(pll
->con_reg
);
296 pll_con1
= __raw_readl(pll
->con_reg
+ 4);
298 if (!(samsung_pll36xx_mpk_change(rate
, pll_con0
, pll_con1
))) {
299 /* If only s change, change just s value only*/
300 pll_con0
&= ~(PLL36XX_SDIV_MASK
<< PLL36XX_SDIV_SHIFT
);
301 pll_con0
|= (rate
->sdiv
<< PLL36XX_SDIV_SHIFT
);
302 __raw_writel(pll_con0
, pll
->con_reg
);
307 /* Set PLL lock time. */
308 __raw_writel(rate
->pdiv
* PLL36XX_LOCK_FACTOR
, pll
->lock_reg
);
310 /* Change PLL PMS values */
311 pll_con0
&= ~((PLL36XX_MDIV_MASK
<< PLL36XX_MDIV_SHIFT
) |
312 (PLL36XX_PDIV_MASK
<< PLL36XX_PDIV_SHIFT
) |
313 (PLL36XX_SDIV_MASK
<< PLL36XX_SDIV_SHIFT
));
314 pll_con0
|= (rate
->mdiv
<< PLL36XX_MDIV_SHIFT
) |
315 (rate
->pdiv
<< PLL36XX_PDIV_SHIFT
) |
316 (rate
->sdiv
<< PLL36XX_SDIV_SHIFT
);
317 __raw_writel(pll_con0
, pll
->con_reg
);
319 pll_con1
&= ~(PLL36XX_KDIV_MASK
<< PLL36XX_KDIV_SHIFT
);
320 pll_con1
|= rate
->kdiv
<< PLL36XX_KDIV_SHIFT
;
321 __raw_writel(pll_con1
, pll
->con_reg
+ 4);
326 tmp
= __raw_readl(pll
->con_reg
);
327 } while (!(tmp
& (1 << PLL36XX_LOCK_STAT_SHIFT
)));
332 static const struct clk_ops samsung_pll36xx_clk_ops
= {
333 .recalc_rate
= samsung_pll36xx_recalc_rate
,
334 .set_rate
= samsung_pll36xx_set_rate
,
335 .round_rate
= samsung_pll_round_rate
,
338 static const struct clk_ops samsung_pll36xx_clk_min_ops
= {
339 .recalc_rate
= samsung_pll36xx_recalc_rate
,
345 #define PLL4502_LOCK_FACTOR 400
346 #define PLL4508_LOCK_FACTOR 240
348 #define PLL45XX_MDIV_MASK (0x3FF)
349 #define PLL45XX_PDIV_MASK (0x3F)
350 #define PLL45XX_SDIV_MASK (0x7)
351 #define PLL45XX_AFC_MASK (0x1F)
352 #define PLL45XX_MDIV_SHIFT (16)
353 #define PLL45XX_PDIV_SHIFT (8)
354 #define PLL45XX_SDIV_SHIFT (0)
355 #define PLL45XX_AFC_SHIFT (0)
357 #define PLL45XX_ENABLE BIT(31)
358 #define PLL45XX_LOCKED BIT(29)
360 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw
*hw
,
361 unsigned long parent_rate
)
363 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
364 u32 mdiv
, pdiv
, sdiv
, pll_con
;
365 u64 fvco
= parent_rate
;
367 pll_con
= __raw_readl(pll
->con_reg
);
368 mdiv
= (pll_con
>> PLL45XX_MDIV_SHIFT
) & PLL45XX_MDIV_MASK
;
369 pdiv
= (pll_con
>> PLL45XX_PDIV_SHIFT
) & PLL45XX_PDIV_MASK
;
370 sdiv
= (pll_con
>> PLL45XX_SDIV_SHIFT
) & PLL45XX_SDIV_MASK
;
372 if (pll
->type
== pll_4508
)
376 do_div(fvco
, (pdiv
<< sdiv
));
378 return (unsigned long)fvco
;
381 static bool samsung_pll45xx_mp_change(u32 pll_con0
, u32 pll_con1
,
382 const struct samsung_pll_rate_table
*rate
)
384 u32 old_mdiv
, old_pdiv
, old_afc
;
386 old_mdiv
= (pll_con0
>> PLL45XX_MDIV_SHIFT
) & PLL45XX_MDIV_MASK
;
387 old_pdiv
= (pll_con0
>> PLL45XX_PDIV_SHIFT
) & PLL45XX_PDIV_MASK
;
388 old_afc
= (pll_con1
>> PLL45XX_AFC_SHIFT
) & PLL45XX_AFC_MASK
;
390 return (old_mdiv
!= rate
->mdiv
|| old_pdiv
!= rate
->pdiv
391 || old_afc
!= rate
->afc
);
394 static int samsung_pll45xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
397 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
398 const struct samsung_pll_rate_table
*rate
;
402 /* Get required rate settings from table */
403 rate
= samsung_get_pll_settings(pll
, drate
);
405 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
406 drate
, __clk_get_name(hw
->clk
));
410 con0
= __raw_readl(pll
->con_reg
);
411 con1
= __raw_readl(pll
->con_reg
+ 0x4);
413 if (!(samsung_pll45xx_mp_change(con0
, con1
, rate
))) {
414 /* If only s change, change just s value only*/
415 con0
&= ~(PLL45XX_SDIV_MASK
<< PLL45XX_SDIV_SHIFT
);
416 con0
|= rate
->sdiv
<< PLL45XX_SDIV_SHIFT
;
417 __raw_writel(con0
, pll
->con_reg
);
422 /* Set PLL PMS values. */
423 con0
&= ~((PLL45XX_MDIV_MASK
<< PLL45XX_MDIV_SHIFT
) |
424 (PLL45XX_PDIV_MASK
<< PLL45XX_PDIV_SHIFT
) |
425 (PLL45XX_SDIV_MASK
<< PLL45XX_SDIV_SHIFT
));
426 con0
|= (rate
->mdiv
<< PLL45XX_MDIV_SHIFT
) |
427 (rate
->pdiv
<< PLL45XX_PDIV_SHIFT
) |
428 (rate
->sdiv
<< PLL45XX_SDIV_SHIFT
);
430 /* Set PLL AFC value. */
431 con1
= __raw_readl(pll
->con_reg
+ 0x4);
432 con1
&= ~(PLL45XX_AFC_MASK
<< PLL45XX_AFC_SHIFT
);
433 con1
|= (rate
->afc
<< PLL45XX_AFC_SHIFT
);
435 /* Set PLL lock time. */
438 __raw_writel(rate
->pdiv
* PLL4502_LOCK_FACTOR
, pll
->lock_reg
);
441 __raw_writel(rate
->pdiv
* PLL4508_LOCK_FACTOR
, pll
->lock_reg
);
447 /* Set new configuration. */
448 __raw_writel(con1
, pll
->con_reg
+ 0x4);
449 __raw_writel(con0
, pll
->con_reg
);
451 /* Wait for locking. */
453 while (!(__raw_readl(pll
->con_reg
) & PLL45XX_LOCKED
)) {
454 ktime_t delta
= ktime_sub(ktime_get(), start
);
456 if (ktime_to_ms(delta
) > PLL_TIMEOUT_MS
) {
457 pr_err("%s: could not lock PLL %s\n",
458 __func__
, __clk_get_name(hw
->clk
));
468 static const struct clk_ops samsung_pll45xx_clk_ops
= {
469 .recalc_rate
= samsung_pll45xx_recalc_rate
,
470 .round_rate
= samsung_pll_round_rate
,
471 .set_rate
= samsung_pll45xx_set_rate
,
474 static const struct clk_ops samsung_pll45xx_clk_min_ops
= {
475 .recalc_rate
= samsung_pll45xx_recalc_rate
,
481 #define PLL46XX_LOCK_FACTOR 3000
483 #define PLL46XX_VSEL_MASK (1)
484 #define PLL46XX_MDIV_MASK (0x1FF)
485 #define PLL1460X_MDIV_MASK (0x3FF)
487 #define PLL46XX_PDIV_MASK (0x3F)
488 #define PLL46XX_SDIV_MASK (0x7)
489 #define PLL46XX_VSEL_SHIFT (27)
490 #define PLL46XX_MDIV_SHIFT (16)
491 #define PLL46XX_PDIV_SHIFT (8)
492 #define PLL46XX_SDIV_SHIFT (0)
494 #define PLL46XX_KDIV_MASK (0xFFFF)
495 #define PLL4650C_KDIV_MASK (0xFFF)
496 #define PLL46XX_KDIV_SHIFT (0)
497 #define PLL46XX_MFR_MASK (0x3F)
498 #define PLL46XX_MRR_MASK (0x1F)
499 #define PLL46XX_KDIV_SHIFT (0)
500 #define PLL46XX_MFR_SHIFT (16)
501 #define PLL46XX_MRR_SHIFT (24)
503 #define PLL46XX_ENABLE BIT(31)
504 #define PLL46XX_LOCKED BIT(29)
505 #define PLL46XX_VSEL BIT(27)
507 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw
*hw
,
508 unsigned long parent_rate
)
510 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
511 u32 mdiv
, pdiv
, sdiv
, kdiv
, pll_con0
, pll_con1
, shift
;
512 u64 fvco
= parent_rate
;
514 pll_con0
= __raw_readl(pll
->con_reg
);
515 pll_con1
= __raw_readl(pll
->con_reg
+ 4);
516 mdiv
= (pll_con0
>> PLL46XX_MDIV_SHIFT
) & ((pll
->type
== pll_1460x
) ?
517 PLL1460X_MDIV_MASK
: PLL46XX_MDIV_MASK
);
518 pdiv
= (pll_con0
>> PLL46XX_PDIV_SHIFT
) & PLL46XX_PDIV_MASK
;
519 sdiv
= (pll_con0
>> PLL46XX_SDIV_SHIFT
) & PLL46XX_SDIV_MASK
;
520 kdiv
= pll
->type
== pll_4650c
? pll_con1
& PLL4650C_KDIV_MASK
:
521 pll_con1
& PLL46XX_KDIV_MASK
;
523 shift
= ((pll
->type
== pll_4600
) || (pll
->type
== pll_1460x
)) ? 16 : 10;
525 fvco
*= (mdiv
<< shift
) + kdiv
;
526 do_div(fvco
, (pdiv
<< sdiv
));
529 return (unsigned long)fvco
;
532 static bool samsung_pll46xx_mpk_change(u32 pll_con0
, u32 pll_con1
,
533 const struct samsung_pll_rate_table
*rate
)
535 u32 old_mdiv
, old_pdiv
, old_kdiv
;
537 old_mdiv
= (pll_con0
>> PLL46XX_MDIV_SHIFT
) & PLL46XX_MDIV_MASK
;
538 old_pdiv
= (pll_con0
>> PLL46XX_PDIV_SHIFT
) & PLL46XX_PDIV_MASK
;
539 old_kdiv
= (pll_con1
>> PLL46XX_KDIV_SHIFT
) & PLL46XX_KDIV_MASK
;
541 return (old_mdiv
!= rate
->mdiv
|| old_pdiv
!= rate
->pdiv
542 || old_kdiv
!= rate
->kdiv
);
545 static int samsung_pll46xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
548 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
549 const struct samsung_pll_rate_table
*rate
;
550 u32 con0
, con1
, lock
;
553 /* Get required rate settings from table */
554 rate
= samsung_get_pll_settings(pll
, drate
);
556 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
557 drate
, __clk_get_name(hw
->clk
));
561 con0
= __raw_readl(pll
->con_reg
);
562 con1
= __raw_readl(pll
->con_reg
+ 0x4);
564 if (!(samsung_pll46xx_mpk_change(con0
, con1
, rate
))) {
565 /* If only s change, change just s value only*/
566 con0
&= ~(PLL46XX_SDIV_MASK
<< PLL46XX_SDIV_SHIFT
);
567 con0
|= rate
->sdiv
<< PLL46XX_SDIV_SHIFT
;
568 __raw_writel(con0
, pll
->con_reg
);
573 /* Set PLL lock time. */
574 lock
= rate
->pdiv
* PLL46XX_LOCK_FACTOR
;
576 /* Maximum lock time bitfield is 16-bit. */
579 /* Set PLL PMS and VSEL values. */
580 if (pll
->type
== pll_1460x
) {
581 con0
&= ~((PLL1460X_MDIV_MASK
<< PLL46XX_MDIV_SHIFT
) |
582 (PLL46XX_PDIV_MASK
<< PLL46XX_PDIV_SHIFT
) |
583 (PLL46XX_SDIV_MASK
<< PLL46XX_SDIV_SHIFT
));
585 con0
&= ~((PLL46XX_MDIV_MASK
<< PLL46XX_MDIV_SHIFT
) |
586 (PLL46XX_PDIV_MASK
<< PLL46XX_PDIV_SHIFT
) |
587 (PLL46XX_SDIV_MASK
<< PLL46XX_SDIV_SHIFT
) |
588 (PLL46XX_VSEL_MASK
<< PLL46XX_VSEL_SHIFT
));
589 con0
|= rate
->vsel
<< PLL46XX_VSEL_SHIFT
;
592 con0
|= (rate
->mdiv
<< PLL46XX_MDIV_SHIFT
) |
593 (rate
->pdiv
<< PLL46XX_PDIV_SHIFT
) |
594 (rate
->sdiv
<< PLL46XX_SDIV_SHIFT
);
596 /* Set PLL K, MFR and MRR values. */
597 con1
= __raw_readl(pll
->con_reg
+ 0x4);
598 con1
&= ~((PLL46XX_KDIV_MASK
<< PLL46XX_KDIV_SHIFT
) |
599 (PLL46XX_MFR_MASK
<< PLL46XX_MFR_SHIFT
) |
600 (PLL46XX_MRR_MASK
<< PLL46XX_MRR_SHIFT
));
601 con1
|= (rate
->kdiv
<< PLL46XX_KDIV_SHIFT
) |
602 (rate
->mfr
<< PLL46XX_MFR_SHIFT
) |
603 (rate
->mrr
<< PLL46XX_MRR_SHIFT
);
605 /* Write configuration to PLL */
606 __raw_writel(lock
, pll
->lock_reg
);
607 __raw_writel(con0
, pll
->con_reg
);
608 __raw_writel(con1
, pll
->con_reg
+ 0x4);
610 /* Wait for locking. */
612 while (!(__raw_readl(pll
->con_reg
) & PLL46XX_LOCKED
)) {
613 ktime_t delta
= ktime_sub(ktime_get(), start
);
615 if (ktime_to_ms(delta
) > PLL_TIMEOUT_MS
) {
616 pr_err("%s: could not lock PLL %s\n",
617 __func__
, __clk_get_name(hw
->clk
));
627 static const struct clk_ops samsung_pll46xx_clk_ops
= {
628 .recalc_rate
= samsung_pll46xx_recalc_rate
,
629 .round_rate
= samsung_pll_round_rate
,
630 .set_rate
= samsung_pll46xx_set_rate
,
633 static const struct clk_ops samsung_pll46xx_clk_min_ops
= {
634 .recalc_rate
= samsung_pll46xx_recalc_rate
,
641 #define PLL6552_MDIV_MASK 0x3ff
642 #define PLL6552_PDIV_MASK 0x3f
643 #define PLL6552_SDIV_MASK 0x7
644 #define PLL6552_MDIV_SHIFT 16
645 #define PLL6552_MDIV_SHIFT_2416 14
646 #define PLL6552_PDIV_SHIFT 8
647 #define PLL6552_PDIV_SHIFT_2416 5
648 #define PLL6552_SDIV_SHIFT 0
650 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw
*hw
,
651 unsigned long parent_rate
)
653 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
654 u32 mdiv
, pdiv
, sdiv
, pll_con
;
655 u64 fvco
= parent_rate
;
657 pll_con
= __raw_readl(pll
->con_reg
);
658 if (pll
->type
== pll_6552_s3c2416
) {
659 mdiv
= (pll_con
>> PLL6552_MDIV_SHIFT_2416
) & PLL6552_MDIV_MASK
;
660 pdiv
= (pll_con
>> PLL6552_PDIV_SHIFT_2416
) & PLL6552_PDIV_MASK
;
662 mdiv
= (pll_con
>> PLL6552_MDIV_SHIFT
) & PLL6552_MDIV_MASK
;
663 pdiv
= (pll_con
>> PLL6552_PDIV_SHIFT
) & PLL6552_PDIV_MASK
;
665 sdiv
= (pll_con
>> PLL6552_SDIV_SHIFT
) & PLL6552_SDIV_MASK
;
668 do_div(fvco
, (pdiv
<< sdiv
));
670 return (unsigned long)fvco
;
673 static const struct clk_ops samsung_pll6552_clk_ops
= {
674 .recalc_rate
= samsung_pll6552_recalc_rate
,
681 #define PLL6553_MDIV_MASK 0xff
682 #define PLL6553_PDIV_MASK 0x3f
683 #define PLL6553_SDIV_MASK 0x7
684 #define PLL6553_KDIV_MASK 0xffff
685 #define PLL6553_MDIV_SHIFT 16
686 #define PLL6553_PDIV_SHIFT 8
687 #define PLL6553_SDIV_SHIFT 0
688 #define PLL6553_KDIV_SHIFT 0
690 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw
*hw
,
691 unsigned long parent_rate
)
693 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
694 u32 mdiv
, pdiv
, sdiv
, kdiv
, pll_con0
, pll_con1
;
695 u64 fvco
= parent_rate
;
697 pll_con0
= __raw_readl(pll
->con_reg
);
698 pll_con1
= __raw_readl(pll
->con_reg
+ 0x4);
699 mdiv
= (pll_con0
>> PLL6553_MDIV_SHIFT
) & PLL6553_MDIV_MASK
;
700 pdiv
= (pll_con0
>> PLL6553_PDIV_SHIFT
) & PLL6553_PDIV_MASK
;
701 sdiv
= (pll_con0
>> PLL6553_SDIV_SHIFT
) & PLL6553_SDIV_MASK
;
702 kdiv
= (pll_con1
>> PLL6553_KDIV_SHIFT
) & PLL6553_KDIV_MASK
;
704 fvco
*= (mdiv
<< 16) + kdiv
;
705 do_div(fvco
, (pdiv
<< sdiv
));
708 return (unsigned long)fvco
;
711 static const struct clk_ops samsung_pll6553_clk_ops
= {
712 .recalc_rate
= samsung_pll6553_recalc_rate
,
716 * PLL Clock Type of S3C24XX before S3C2443
719 #define PLLS3C2410_MDIV_MASK (0xff)
720 #define PLLS3C2410_PDIV_MASK (0x1f)
721 #define PLLS3C2410_SDIV_MASK (0x3)
722 #define PLLS3C2410_MDIV_SHIFT (12)
723 #define PLLS3C2410_PDIV_SHIFT (4)
724 #define PLLS3C2410_SDIV_SHIFT (0)
726 #define PLLS3C2410_ENABLE_REG_OFFSET 0x10
728 static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw
*hw
,
729 unsigned long parent_rate
)
731 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
732 u32 pll_con
, mdiv
, pdiv
, sdiv
;
733 u64 fvco
= parent_rate
;
735 pll_con
= __raw_readl(pll
->con_reg
);
736 mdiv
= (pll_con
>> PLLS3C2410_MDIV_SHIFT
) & PLLS3C2410_MDIV_MASK
;
737 pdiv
= (pll_con
>> PLLS3C2410_PDIV_SHIFT
) & PLLS3C2410_PDIV_MASK
;
738 sdiv
= (pll_con
>> PLLS3C2410_SDIV_SHIFT
) & PLLS3C2410_SDIV_MASK
;
741 do_div(fvco
, (pdiv
+ 2) << sdiv
);
743 return (unsigned int)fvco
;
746 static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw
*hw
,
747 unsigned long parent_rate
)
749 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
750 u32 pll_con
, mdiv
, pdiv
, sdiv
;
751 u64 fvco
= parent_rate
;
753 pll_con
= __raw_readl(pll
->con_reg
);
754 mdiv
= (pll_con
>> PLLS3C2410_MDIV_SHIFT
) & PLLS3C2410_MDIV_MASK
;
755 pdiv
= (pll_con
>> PLLS3C2410_PDIV_SHIFT
) & PLLS3C2410_PDIV_MASK
;
756 sdiv
= (pll_con
>> PLLS3C2410_SDIV_SHIFT
) & PLLS3C2410_SDIV_MASK
;
758 fvco
*= (2 * (mdiv
+ 8));
759 do_div(fvco
, (pdiv
+ 2) << sdiv
);
761 return (unsigned int)fvco
;
764 static int samsung_s3c2410_pll_set_rate(struct clk_hw
*hw
, unsigned long drate
,
767 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
768 const struct samsung_pll_rate_table
*rate
;
771 /* Get required rate settings from table */
772 rate
= samsung_get_pll_settings(pll
, drate
);
774 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
775 drate
, __clk_get_name(hw
->clk
));
779 tmp
= __raw_readl(pll
->con_reg
);
781 /* Change PLL PMS values */
782 tmp
&= ~((PLLS3C2410_MDIV_MASK
<< PLLS3C2410_MDIV_SHIFT
) |
783 (PLLS3C2410_PDIV_MASK
<< PLLS3C2410_PDIV_SHIFT
) |
784 (PLLS3C2410_SDIV_MASK
<< PLLS3C2410_SDIV_SHIFT
));
785 tmp
|= (rate
->mdiv
<< PLLS3C2410_MDIV_SHIFT
) |
786 (rate
->pdiv
<< PLLS3C2410_PDIV_SHIFT
) |
787 (rate
->sdiv
<< PLLS3C2410_SDIV_SHIFT
);
788 __raw_writel(tmp
, pll
->con_reg
);
790 /* Time to settle according to the manual */
796 static int samsung_s3c2410_pll_enable(struct clk_hw
*hw
, int bit
, bool enable
)
798 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
799 u32 pll_en
= __raw_readl(pll
->lock_reg
+ PLLS3C2410_ENABLE_REG_OFFSET
);
800 u32 pll_en_orig
= pll_en
;
807 __raw_writel(pll_en
, pll
->lock_reg
+ PLLS3C2410_ENABLE_REG_OFFSET
);
809 /* if we started the UPLL, then allow to settle */
810 if (enable
&& (pll_en_orig
& BIT(bit
)))
816 static int samsung_s3c2410_mpll_enable(struct clk_hw
*hw
)
818 return samsung_s3c2410_pll_enable(hw
, 5, true);
821 static void samsung_s3c2410_mpll_disable(struct clk_hw
*hw
)
823 samsung_s3c2410_pll_enable(hw
, 5, false);
826 static int samsung_s3c2410_upll_enable(struct clk_hw
*hw
)
828 return samsung_s3c2410_pll_enable(hw
, 7, true);
831 static void samsung_s3c2410_upll_disable(struct clk_hw
*hw
)
833 samsung_s3c2410_pll_enable(hw
, 7, false);
836 static const struct clk_ops samsung_s3c2410_mpll_clk_min_ops
= {
837 .recalc_rate
= samsung_s3c2410_pll_recalc_rate
,
838 .enable
= samsung_s3c2410_mpll_enable
,
839 .disable
= samsung_s3c2410_mpll_disable
,
842 static const struct clk_ops samsung_s3c2410_upll_clk_min_ops
= {
843 .recalc_rate
= samsung_s3c2410_pll_recalc_rate
,
844 .enable
= samsung_s3c2410_upll_enable
,
845 .disable
= samsung_s3c2410_upll_disable
,
848 static const struct clk_ops samsung_s3c2440_mpll_clk_min_ops
= {
849 .recalc_rate
= samsung_s3c2440_mpll_recalc_rate
,
850 .enable
= samsung_s3c2410_mpll_enable
,
851 .disable
= samsung_s3c2410_mpll_disable
,
854 static const struct clk_ops samsung_s3c2410_mpll_clk_ops
= {
855 .recalc_rate
= samsung_s3c2410_pll_recalc_rate
,
856 .enable
= samsung_s3c2410_mpll_enable
,
857 .disable
= samsung_s3c2410_mpll_disable
,
858 .round_rate
= samsung_pll_round_rate
,
859 .set_rate
= samsung_s3c2410_pll_set_rate
,
862 static const struct clk_ops samsung_s3c2410_upll_clk_ops
= {
863 .recalc_rate
= samsung_s3c2410_pll_recalc_rate
,
864 .enable
= samsung_s3c2410_upll_enable
,
865 .disable
= samsung_s3c2410_upll_disable
,
866 .round_rate
= samsung_pll_round_rate
,
867 .set_rate
= samsung_s3c2410_pll_set_rate
,
870 static const struct clk_ops samsung_s3c2440_mpll_clk_ops
= {
871 .recalc_rate
= samsung_s3c2440_mpll_recalc_rate
,
872 .enable
= samsung_s3c2410_mpll_enable
,
873 .disable
= samsung_s3c2410_mpll_disable
,
874 .round_rate
= samsung_pll_round_rate
,
875 .set_rate
= samsung_s3c2410_pll_set_rate
,
879 * PLL2550x Clock Type
882 #define PLL2550X_R_MASK (0x1)
883 #define PLL2550X_P_MASK (0x3F)
884 #define PLL2550X_M_MASK (0x3FF)
885 #define PLL2550X_S_MASK (0x7)
886 #define PLL2550X_R_SHIFT (20)
887 #define PLL2550X_P_SHIFT (14)
888 #define PLL2550X_M_SHIFT (4)
889 #define PLL2550X_S_SHIFT (0)
891 struct samsung_clk_pll2550x
{
893 const void __iomem
*reg_base
;
894 unsigned long offset
;
897 #define to_clk_pll2550x(_hw) container_of(_hw, struct samsung_clk_pll2550x, hw)
899 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw
*hw
,
900 unsigned long parent_rate
)
902 struct samsung_clk_pll2550x
*pll
= to_clk_pll2550x(hw
);
903 u32 r
, p
, m
, s
, pll_stat
;
904 u64 fvco
= parent_rate
;
906 pll_stat
= __raw_readl(pll
->reg_base
+ pll
->offset
* 3);
907 r
= (pll_stat
>> PLL2550X_R_SHIFT
) & PLL2550X_R_MASK
;
910 p
= (pll_stat
>> PLL2550X_P_SHIFT
) & PLL2550X_P_MASK
;
911 m
= (pll_stat
>> PLL2550X_M_SHIFT
) & PLL2550X_M_MASK
;
912 s
= (pll_stat
>> PLL2550X_S_SHIFT
) & PLL2550X_S_MASK
;
915 do_div(fvco
, (p
<< s
));
917 return (unsigned long)fvco
;
920 static const struct clk_ops samsung_pll2550x_clk_ops
= {
921 .recalc_rate
= samsung_pll2550x_recalc_rate
,
924 struct clk
* __init
samsung_clk_register_pll2550x(const char *name
,
925 const char *pname
, const void __iomem
*reg_base
,
926 const unsigned long offset
)
928 struct samsung_clk_pll2550x
*pll
;
930 struct clk_init_data init
;
932 pll
= kzalloc(sizeof(*pll
), GFP_KERNEL
);
934 pr_err("%s: could not allocate pll clk %s\n", __func__
, name
);
939 init
.ops
= &samsung_pll2550x_clk_ops
;
940 init
.flags
= CLK_GET_RATE_NOCACHE
;
941 init
.parent_names
= &pname
;
942 init
.num_parents
= 1;
944 pll
->hw
.init
= &init
;
945 pll
->reg_base
= reg_base
;
946 pll
->offset
= offset
;
948 clk
= clk_register(NULL
, &pll
->hw
);
950 pr_err("%s: failed to register pll clock %s\n", __func__
,
955 if (clk_register_clkdev(clk
, name
, NULL
))
956 pr_err("%s: failed to register lookup for %s", __func__
, name
);
962 * PLL2550xx Clock Type
965 /* Maximum lock time can be 270 * PDIV cycles */
966 #define PLL2550XX_LOCK_FACTOR 270
968 #define PLL2550XX_M_MASK 0x3FF
969 #define PLL2550XX_P_MASK 0x3F
970 #define PLL2550XX_S_MASK 0x7
971 #define PLL2550XX_LOCK_STAT_MASK 0x1
972 #define PLL2550XX_M_SHIFT 9
973 #define PLL2550XX_P_SHIFT 3
974 #define PLL2550XX_S_SHIFT 0
975 #define PLL2550XX_LOCK_STAT_SHIFT 21
977 static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw
*hw
,
978 unsigned long parent_rate
)
980 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
981 u32 mdiv
, pdiv
, sdiv
, pll_con
;
982 u64 fvco
= parent_rate
;
984 pll_con
= __raw_readl(pll
->con_reg
);
985 mdiv
= (pll_con
>> PLL2550XX_M_SHIFT
) & PLL2550XX_M_MASK
;
986 pdiv
= (pll_con
>> PLL2550XX_P_SHIFT
) & PLL2550XX_P_MASK
;
987 sdiv
= (pll_con
>> PLL2550XX_S_SHIFT
) & PLL2550XX_S_MASK
;
990 do_div(fvco
, (pdiv
<< sdiv
));
992 return (unsigned long)fvco
;
995 static inline bool samsung_pll2550xx_mp_change(u32 mdiv
, u32 pdiv
, u32 pll_con
)
997 u32 old_mdiv
, old_pdiv
;
999 old_mdiv
= (pll_con
>> PLL2550XX_M_SHIFT
) & PLL2550XX_M_MASK
;
1000 old_pdiv
= (pll_con
>> PLL2550XX_P_SHIFT
) & PLL2550XX_P_MASK
;
1002 return mdiv
!= old_mdiv
|| pdiv
!= old_pdiv
;
1005 static int samsung_pll2550xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
1006 unsigned long prate
)
1008 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1009 const struct samsung_pll_rate_table
*rate
;
1012 /* Get required rate settings from table */
1013 rate
= samsung_get_pll_settings(pll
, drate
);
1015 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
1016 drate
, __clk_get_name(hw
->clk
));
1020 tmp
= __raw_readl(pll
->con_reg
);
1022 if (!(samsung_pll2550xx_mp_change(rate
->mdiv
, rate
->pdiv
, tmp
))) {
1023 /* If only s change, change just s value only*/
1024 tmp
&= ~(PLL2550XX_S_MASK
<< PLL2550XX_S_SHIFT
);
1025 tmp
|= rate
->sdiv
<< PLL2550XX_S_SHIFT
;
1026 __raw_writel(tmp
, pll
->con_reg
);
1031 /* Set PLL lock time. */
1032 __raw_writel(rate
->pdiv
* PLL2550XX_LOCK_FACTOR
, pll
->lock_reg
);
1034 /* Change PLL PMS values */
1035 tmp
&= ~((PLL2550XX_M_MASK
<< PLL2550XX_M_SHIFT
) |
1036 (PLL2550XX_P_MASK
<< PLL2550XX_P_SHIFT
) |
1037 (PLL2550XX_S_MASK
<< PLL2550XX_S_SHIFT
));
1038 tmp
|= (rate
->mdiv
<< PLL2550XX_M_SHIFT
) |
1039 (rate
->pdiv
<< PLL2550XX_P_SHIFT
) |
1040 (rate
->sdiv
<< PLL2550XX_S_SHIFT
);
1041 __raw_writel(tmp
, pll
->con_reg
);
1043 /* wait_lock_time */
1046 tmp
= __raw_readl(pll
->con_reg
);
1047 } while (!(tmp
& (PLL2550XX_LOCK_STAT_MASK
1048 << PLL2550XX_LOCK_STAT_SHIFT
)));
1053 static const struct clk_ops samsung_pll2550xx_clk_ops
= {
1054 .recalc_rate
= samsung_pll2550xx_recalc_rate
,
1055 .round_rate
= samsung_pll_round_rate
,
1056 .set_rate
= samsung_pll2550xx_set_rate
,
1059 static const struct clk_ops samsung_pll2550xx_clk_min_ops
= {
1060 .recalc_rate
= samsung_pll2550xx_recalc_rate
,
1064 * PLL2650XX Clock Type
1067 /* Maximum lock time can be 3000 * PDIV cycles */
1068 #define PLL2650XX_LOCK_FACTOR 3000
1070 #define PLL2650XX_MDIV_SHIFT 9
1071 #define PLL2650XX_PDIV_SHIFT 3
1072 #define PLL2650XX_SDIV_SHIFT 0
1073 #define PLL2650XX_KDIV_SHIFT 0
1074 #define PLL2650XX_MDIV_MASK 0x1ff
1075 #define PLL2650XX_PDIV_MASK 0x3f
1076 #define PLL2650XX_SDIV_MASK 0x7
1077 #define PLL2650XX_KDIV_MASK 0xffff
1078 #define PLL2650XX_PLL_ENABLE_SHIFT 23
1079 #define PLL2650XX_PLL_LOCKTIME_SHIFT 21
1080 #define PLL2650XX_PLL_FOUTMASK_SHIFT 31
1082 static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw
*hw
,
1083 unsigned long parent_rate
)
1085 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1086 u32 mdiv
, pdiv
, sdiv
, pll_con0
, pll_con2
;
1088 u64 fvco
= parent_rate
;
1090 pll_con0
= __raw_readl(pll
->con_reg
);
1091 pll_con2
= __raw_readl(pll
->con_reg
+ 8);
1092 mdiv
= (pll_con0
>> PLL2650XX_MDIV_SHIFT
) & PLL2650XX_MDIV_MASK
;
1093 pdiv
= (pll_con0
>> PLL2650XX_PDIV_SHIFT
) & PLL2650XX_PDIV_MASK
;
1094 sdiv
= (pll_con0
>> PLL2650XX_SDIV_SHIFT
) & PLL2650XX_SDIV_MASK
;
1095 kdiv
= (s16
)(pll_con2
& PLL2650XX_KDIV_MASK
);
1097 fvco
*= (mdiv
<< 16) + kdiv
;
1098 do_div(fvco
, (pdiv
<< sdiv
));
1101 return (unsigned long)fvco
;
1104 static int samsung_pll2650xx_set_rate(struct clk_hw
*hw
, unsigned long drate
,
1105 unsigned long parent_rate
)
1107 struct samsung_clk_pll
*pll
= to_clk_pll(hw
);
1108 u32 tmp
, pll_con0
, pll_con2
;
1109 const struct samsung_pll_rate_table
*rate
;
1111 rate
= samsung_get_pll_settings(pll
, drate
);
1113 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__
,
1114 drate
, __clk_get_name(hw
->clk
));
1118 pll_con0
= __raw_readl(pll
->con_reg
);
1119 pll_con2
= __raw_readl(pll
->con_reg
+ 8);
1121 /* Change PLL PMS values */
1122 pll_con0
&= ~(PLL2650XX_MDIV_MASK
<< PLL2650XX_MDIV_SHIFT
|
1123 PLL2650XX_PDIV_MASK
<< PLL2650XX_PDIV_SHIFT
|
1124 PLL2650XX_SDIV_MASK
<< PLL2650XX_SDIV_SHIFT
);
1125 pll_con0
|= rate
->mdiv
<< PLL2650XX_MDIV_SHIFT
;
1126 pll_con0
|= rate
->pdiv
<< PLL2650XX_PDIV_SHIFT
;
1127 pll_con0
|= rate
->sdiv
<< PLL2650XX_SDIV_SHIFT
;
1128 pll_con0
|= 1 << PLL2650XX_PLL_ENABLE_SHIFT
;
1129 pll_con0
|= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT
;
1131 pll_con2
&= ~(PLL2650XX_KDIV_MASK
<< PLL2650XX_KDIV_SHIFT
);
1132 pll_con2
|= ((~(rate
->kdiv
) + 1) & PLL2650XX_KDIV_MASK
)
1133 << PLL2650XX_KDIV_SHIFT
;
1135 /* Set PLL lock time. */
1136 __raw_writel(PLL2650XX_LOCK_FACTOR
* rate
->pdiv
, pll
->lock_reg
);
1138 __raw_writel(pll_con0
, pll
->con_reg
);
1139 __raw_writel(pll_con2
, pll
->con_reg
+ 8);
1142 tmp
= __raw_readl(pll
->con_reg
);
1143 } while (!(tmp
& (0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT
)));
1148 static const struct clk_ops samsung_pll2650xx_clk_ops
= {
1149 .recalc_rate
= samsung_pll2650xx_recalc_rate
,
1150 .set_rate
= samsung_pll2650xx_set_rate
,
1151 .round_rate
= samsung_pll_round_rate
,
1154 static const struct clk_ops samsung_pll2650xx_clk_min_ops
= {
1155 .recalc_rate
= samsung_pll2650xx_recalc_rate
,
1158 static void __init
_samsung_clk_register_pll(struct samsung_clk_provider
*ctx
,
1159 struct samsung_pll_clock
*pll_clk
,
1162 struct samsung_clk_pll
*pll
;
1164 struct clk_init_data init
;
1167 pll
= kzalloc(sizeof(*pll
), GFP_KERNEL
);
1169 pr_err("%s: could not allocate pll clk %s\n",
1170 __func__
, pll_clk
->name
);
1174 init
.name
= pll_clk
->name
;
1175 init
.flags
= pll_clk
->flags
;
1176 init
.parent_names
= &pll_clk
->parent_name
;
1177 init
.num_parents
= 1;
1179 if (pll_clk
->rate_table
) {
1180 /* find count of rates in rate_table */
1181 for (len
= 0; pll_clk
->rate_table
[len
].rate
!= 0; )
1184 pll
->rate_count
= len
;
1185 pll
->rate_table
= kmemdup(pll_clk
->rate_table
,
1187 sizeof(struct samsung_pll_rate_table
),
1189 WARN(!pll
->rate_table
,
1190 "%s: could not allocate rate table for %s\n",
1191 __func__
, pll_clk
->name
);
1194 switch (pll_clk
->type
) {
1196 init
.ops
= &samsung_pll2126_clk_ops
;
1199 init
.ops
= &samsung_pll3000_clk_ops
;
1201 /* clk_ops for 35xx and 2550 are similar */
1207 if (!pll
->rate_table
)
1208 init
.ops
= &samsung_pll35xx_clk_min_ops
;
1210 init
.ops
= &samsung_pll35xx_clk_ops
;
1213 init
.ops
= &samsung_pll45xx_clk_min_ops
;
1217 if (!pll
->rate_table
)
1218 init
.ops
= &samsung_pll45xx_clk_min_ops
;
1220 init
.ops
= &samsung_pll45xx_clk_ops
;
1222 /* clk_ops for 36xx and 2650 are similar */
1225 if (!pll
->rate_table
)
1226 init
.ops
= &samsung_pll36xx_clk_min_ops
;
1228 init
.ops
= &samsung_pll36xx_clk_ops
;
1231 case pll_6552_s3c2416
:
1232 init
.ops
= &samsung_pll6552_clk_ops
;
1235 init
.ops
= &samsung_pll6553_clk_ops
;
1241 if (!pll
->rate_table
)
1242 init
.ops
= &samsung_pll46xx_clk_min_ops
;
1244 init
.ops
= &samsung_pll46xx_clk_ops
;
1246 case pll_s3c2410_mpll
:
1247 if (!pll
->rate_table
)
1248 init
.ops
= &samsung_s3c2410_mpll_clk_min_ops
;
1250 init
.ops
= &samsung_s3c2410_mpll_clk_ops
;
1252 case pll_s3c2410_upll
:
1253 if (!pll
->rate_table
)
1254 init
.ops
= &samsung_s3c2410_upll_clk_min_ops
;
1256 init
.ops
= &samsung_s3c2410_upll_clk_ops
;
1258 case pll_s3c2440_mpll
:
1259 if (!pll
->rate_table
)
1260 init
.ops
= &samsung_s3c2440_mpll_clk_min_ops
;
1262 init
.ops
= &samsung_s3c2440_mpll_clk_ops
;
1265 if (!pll
->rate_table
)
1266 init
.ops
= &samsung_pll2550xx_clk_min_ops
;
1268 init
.ops
= &samsung_pll2550xx_clk_ops
;
1271 if (!pll
->rate_table
)
1272 init
.ops
= &samsung_pll2650xx_clk_min_ops
;
1274 init
.ops
= &samsung_pll2650xx_clk_ops
;
1277 pr_warn("%s: Unknown pll type for pll clk %s\n",
1278 __func__
, pll_clk
->name
);
1281 pll
->hw
.init
= &init
;
1282 pll
->type
= pll_clk
->type
;
1283 pll
->lock_reg
= base
+ pll_clk
->lock_offset
;
1284 pll
->con_reg
= base
+ pll_clk
->con_offset
;
1286 clk
= clk_register(NULL
, &pll
->hw
);
1288 pr_err("%s: failed to register pll clock %s : %ld\n",
1289 __func__
, pll_clk
->name
, PTR_ERR(clk
));
1294 samsung_clk_add_lookup(ctx
, clk
, pll_clk
->id
);
1296 if (!pll_clk
->alias
)
1299 ret
= clk_register_clkdev(clk
, pll_clk
->alias
, pll_clk
->dev_name
);
1301 pr_err("%s: failed to register lookup for %s : %d",
1302 __func__
, pll_clk
->name
, ret
);
1305 void __init
samsung_clk_register_pll(struct samsung_clk_provider
*ctx
,
1306 struct samsung_pll_clock
*pll_list
,
1307 unsigned int nr_pll
, void __iomem
*base
)
1311 for (cnt
= 0; cnt
< nr_pll
; cnt
++)
1312 _samsung_clk_register_pll(ctx
, &pll_list
[cnt
], base
);