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>
17 #define PLL_TIMEOUT_MS 10
19 struct samsung_clk_pll {
21 void __iomem *lock_reg;
22 void __iomem *con_reg;
23 enum samsung_pll_type type;
24 unsigned int rate_count;
25 const struct samsung_pll_rate_table *rate_table;
28 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
30 static const struct samsung_pll_rate_table *samsung_get_pll_settings(
31 struct samsung_clk_pll *pll, unsigned long rate)
33 const struct samsung_pll_rate_table *rate_table = pll->rate_table;
36 for (i = 0; i < pll->rate_count; i++) {
37 if (rate == rate_table[i].rate)
38 return &rate_table[i];
44 static long samsung_pll_round_rate(struct clk_hw *hw,
45 unsigned long drate, unsigned long *prate)
47 struct samsung_clk_pll *pll = to_clk_pll(hw);
48 const struct samsung_pll_rate_table *rate_table = pll->rate_table;
51 /* Assumming rate_table is in descending order */
52 for (i = 0; i < pll->rate_count; i++) {
53 if (drate >= rate_table[i].rate)
54 return rate_table[i].rate;
57 /* return minimum supported value */
58 return rate_table[i - 1].rate;
65 #define PLL2126_MDIV_MASK (0xff)
66 #define PLL2126_PDIV_MASK (0x3f)
67 #define PLL2126_SDIV_MASK (0x3)
68 #define PLL2126_MDIV_SHIFT (16)
69 #define PLL2126_PDIV_SHIFT (8)
70 #define PLL2126_SDIV_SHIFT (0)
72 static unsigned long samsung_pll2126_recalc_rate(struct clk_hw *hw,
73 unsigned long parent_rate)
75 struct samsung_clk_pll *pll = to_clk_pll(hw);
76 u32 pll_con, mdiv, pdiv, sdiv;
77 u64 fvco = parent_rate;
79 pll_con = __raw_readl(pll->con_reg);
80 mdiv = (pll_con >> PLL2126_MDIV_SHIFT) & PLL2126_MDIV_MASK;
81 pdiv = (pll_con >> PLL2126_PDIV_SHIFT) & PLL2126_PDIV_MASK;
82 sdiv = (pll_con >> PLL2126_SDIV_SHIFT) & PLL2126_SDIV_MASK;
85 do_div(fvco, (pdiv + 2) << sdiv);
87 return (unsigned long)fvco;
90 static const struct clk_ops samsung_pll2126_clk_ops = {
91 .recalc_rate = samsung_pll2126_recalc_rate,
98 #define PLL3000_MDIV_MASK (0xff)
99 #define PLL3000_PDIV_MASK (0x3)
100 #define PLL3000_SDIV_MASK (0x3)
101 #define PLL3000_MDIV_SHIFT (16)
102 #define PLL3000_PDIV_SHIFT (8)
103 #define PLL3000_SDIV_SHIFT (0)
105 static unsigned long samsung_pll3000_recalc_rate(struct clk_hw *hw,
106 unsigned long parent_rate)
108 struct samsung_clk_pll *pll = to_clk_pll(hw);
109 u32 pll_con, mdiv, pdiv, sdiv;
110 u64 fvco = parent_rate;
112 pll_con = __raw_readl(pll->con_reg);
113 mdiv = (pll_con >> PLL3000_MDIV_SHIFT) & PLL3000_MDIV_MASK;
114 pdiv = (pll_con >> PLL3000_PDIV_SHIFT) & PLL3000_PDIV_MASK;
115 sdiv = (pll_con >> PLL3000_SDIV_SHIFT) & PLL3000_SDIV_MASK;
117 fvco *= (2 * (mdiv + 8));
118 do_div(fvco, pdiv << sdiv);
120 return (unsigned long)fvco;
123 static const struct clk_ops samsung_pll3000_clk_ops = {
124 .recalc_rate = samsung_pll3000_recalc_rate,
130 /* Maximum lock time can be 270 * PDIV cycles */
131 #define PLL35XX_LOCK_FACTOR (270)
133 #define PLL35XX_MDIV_MASK (0x3FF)
134 #define PLL35XX_PDIV_MASK (0x3F)
135 #define PLL35XX_SDIV_MASK (0x7)
136 #define PLL35XX_LOCK_STAT_MASK (0x1)
137 #define PLL35XX_MDIV_SHIFT (16)
138 #define PLL35XX_PDIV_SHIFT (8)
139 #define PLL35XX_SDIV_SHIFT (0)
140 #define PLL35XX_LOCK_STAT_SHIFT (29)
142 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
143 unsigned long parent_rate)
145 struct samsung_clk_pll *pll = to_clk_pll(hw);
146 u32 mdiv, pdiv, sdiv, pll_con;
147 u64 fvco = parent_rate;
149 pll_con = __raw_readl(pll->con_reg);
150 mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
151 pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
152 sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
155 do_div(fvco, (pdiv << sdiv));
157 return (unsigned long)fvco;
160 static inline bool samsung_pll35xx_mp_change(
161 const struct samsung_pll_rate_table *rate, u32 pll_con)
163 u32 old_mdiv, old_pdiv;
165 old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
166 old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
168 return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
171 static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
174 struct samsung_clk_pll *pll = to_clk_pll(hw);
175 const struct samsung_pll_rate_table *rate;
178 /* Get required rate settings from table */
179 rate = samsung_get_pll_settings(pll, drate);
181 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
182 drate, __clk_get_name(hw->clk));
186 tmp = __raw_readl(pll->con_reg);
188 if (!(samsung_pll35xx_mp_change(rate, tmp))) {
189 /* If only s change, change just s value only*/
190 tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
191 tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
192 __raw_writel(tmp, pll->con_reg);
197 /* Set PLL lock time. */
198 __raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
201 /* Change PLL PMS values */
202 tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
203 (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
204 (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
205 tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
206 (rate->pdiv << PLL35XX_PDIV_SHIFT) |
207 (rate->sdiv << PLL35XX_SDIV_SHIFT);
208 __raw_writel(tmp, pll->con_reg);
213 tmp = __raw_readl(pll->con_reg);
214 } while (!(tmp & (PLL35XX_LOCK_STAT_MASK
215 << PLL35XX_LOCK_STAT_SHIFT)));
219 static const struct clk_ops samsung_pll35xx_clk_ops = {
220 .recalc_rate = samsung_pll35xx_recalc_rate,
221 .round_rate = samsung_pll_round_rate,
222 .set_rate = samsung_pll35xx_set_rate,
225 static const struct clk_ops samsung_pll35xx_clk_min_ops = {
226 .recalc_rate = samsung_pll35xx_recalc_rate,
232 /* Maximum lock time can be 3000 * PDIV cycles */
233 #define PLL36XX_LOCK_FACTOR (3000)
235 #define PLL36XX_KDIV_MASK (0xFFFF)
236 #define PLL36XX_MDIV_MASK (0x1FF)
237 #define PLL36XX_PDIV_MASK (0x3F)
238 #define PLL36XX_SDIV_MASK (0x7)
239 #define PLL36XX_MDIV_SHIFT (16)
240 #define PLL36XX_PDIV_SHIFT (8)
241 #define PLL36XX_SDIV_SHIFT (0)
242 #define PLL36XX_KDIV_SHIFT (0)
243 #define PLL36XX_LOCK_STAT_SHIFT (29)
245 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
246 unsigned long parent_rate)
248 struct samsung_clk_pll *pll = to_clk_pll(hw);
249 u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
251 u64 fvco = parent_rate;
253 pll_con0 = __raw_readl(pll->con_reg);
254 pll_con1 = __raw_readl(pll->con_reg + 4);
255 mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
256 pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
257 sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
258 kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK);
260 fvco *= (mdiv << 16) + kdiv;
261 do_div(fvco, (pdiv << sdiv));
264 return (unsigned long)fvco;
267 static inline bool samsung_pll36xx_mpk_change(
268 const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
270 u32 old_mdiv, old_pdiv, old_kdiv;
272 old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
273 old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
274 old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
276 return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
277 rate->kdiv != old_kdiv);
280 static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
281 unsigned long parent_rate)
283 struct samsung_clk_pll *pll = to_clk_pll(hw);
284 u32 tmp, pll_con0, pll_con1;
285 const struct samsung_pll_rate_table *rate;
287 rate = samsung_get_pll_settings(pll, drate);
289 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
290 drate, __clk_get_name(hw->clk));
294 pll_con0 = __raw_readl(pll->con_reg);
295 pll_con1 = __raw_readl(pll->con_reg + 4);
297 if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
298 /* If only s change, change just s value only*/
299 pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
300 pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
301 __raw_writel(pll_con0, pll->con_reg);
306 /* Set PLL lock time. */
307 __raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
309 /* Change PLL PMS values */
310 pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
311 (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
312 (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
313 pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
314 (rate->pdiv << PLL36XX_PDIV_SHIFT) |
315 (rate->sdiv << PLL36XX_SDIV_SHIFT);
316 __raw_writel(pll_con0, pll->con_reg);
318 pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
319 pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
320 __raw_writel(pll_con1, pll->con_reg + 4);
325 tmp = __raw_readl(pll->con_reg);
326 } while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
331 static const struct clk_ops samsung_pll36xx_clk_ops = {
332 .recalc_rate = samsung_pll36xx_recalc_rate,
333 .set_rate = samsung_pll36xx_set_rate,
334 .round_rate = samsung_pll_round_rate,
337 static const struct clk_ops samsung_pll36xx_clk_min_ops = {
338 .recalc_rate = samsung_pll36xx_recalc_rate,
344 #define PLL4502_LOCK_FACTOR 400
345 #define PLL4508_LOCK_FACTOR 240
347 #define PLL45XX_MDIV_MASK (0x3FF)
348 #define PLL45XX_PDIV_MASK (0x3F)
349 #define PLL45XX_SDIV_MASK (0x7)
350 #define PLL45XX_AFC_MASK (0x1F)
351 #define PLL45XX_MDIV_SHIFT (16)
352 #define PLL45XX_PDIV_SHIFT (8)
353 #define PLL45XX_SDIV_SHIFT (0)
354 #define PLL45XX_AFC_SHIFT (0)
356 #define PLL45XX_ENABLE BIT(31)
357 #define PLL45XX_LOCKED BIT(29)
359 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
360 unsigned long parent_rate)
362 struct samsung_clk_pll *pll = to_clk_pll(hw);
363 u32 mdiv, pdiv, sdiv, pll_con;
364 u64 fvco = parent_rate;
366 pll_con = __raw_readl(pll->con_reg);
367 mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
368 pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
369 sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
371 if (pll->type == pll_4508)
375 do_div(fvco, (pdiv << sdiv));
377 return (unsigned long)fvco;
380 static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
381 const struct samsung_pll_rate_table *rate)
383 u32 old_mdiv, old_pdiv, old_afc;
385 old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
386 old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
387 old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK;
389 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
390 || old_afc != rate->afc);
393 static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
396 struct samsung_clk_pll *pll = to_clk_pll(hw);
397 const struct samsung_pll_rate_table *rate;
401 /* Get required rate settings from table */
402 rate = samsung_get_pll_settings(pll, drate);
404 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
405 drate, __clk_get_name(hw->clk));
409 con0 = __raw_readl(pll->con_reg);
410 con1 = __raw_readl(pll->con_reg + 0x4);
412 if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
413 /* If only s change, change just s value only*/
414 con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
415 con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
416 __raw_writel(con0, pll->con_reg);
421 /* Set PLL PMS values. */
422 con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
423 (PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
424 (PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
425 con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) |
426 (rate->pdiv << PLL45XX_PDIV_SHIFT) |
427 (rate->sdiv << PLL45XX_SDIV_SHIFT);
429 /* Set PLL AFC value. */
430 con1 = __raw_readl(pll->con_reg + 0x4);
431 con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
432 con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
434 /* Set PLL lock time. */
437 __raw_writel(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
440 __raw_writel(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
446 /* Set new configuration. */
447 __raw_writel(con1, pll->con_reg + 0x4);
448 __raw_writel(con0, pll->con_reg);
450 /* Wait for locking. */
452 while (!(__raw_readl(pll->con_reg) & PLL45XX_LOCKED)) {
453 ktime_t delta = ktime_sub(ktime_get(), start);
455 if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
456 pr_err("%s: could not lock PLL %s\n",
457 __func__, __clk_get_name(hw->clk));
467 static const struct clk_ops samsung_pll45xx_clk_ops = {
468 .recalc_rate = samsung_pll45xx_recalc_rate,
469 .round_rate = samsung_pll_round_rate,
470 .set_rate = samsung_pll45xx_set_rate,
473 static const struct clk_ops samsung_pll45xx_clk_min_ops = {
474 .recalc_rate = samsung_pll45xx_recalc_rate,
480 #define PLL46XX_LOCK_FACTOR 3000
482 #define PLL46XX_VSEL_MASK (1)
483 #define PLL46XX_MDIV_MASK (0x1FF)
484 #define PLL46XX_PDIV_MASK (0x3F)
485 #define PLL46XX_SDIV_MASK (0x7)
486 #define PLL46XX_VSEL_SHIFT (27)
487 #define PLL46XX_MDIV_SHIFT (16)
488 #define PLL46XX_PDIV_SHIFT (8)
489 #define PLL46XX_SDIV_SHIFT (0)
491 #define PLL46XX_KDIV_MASK (0xFFFF)
492 #define PLL4650C_KDIV_MASK (0xFFF)
493 #define PLL46XX_KDIV_SHIFT (0)
494 #define PLL46XX_MFR_MASK (0x3F)
495 #define PLL46XX_MRR_MASK (0x1F)
496 #define PLL46XX_KDIV_SHIFT (0)
497 #define PLL46XX_MFR_SHIFT (16)
498 #define PLL46XX_MRR_SHIFT (24)
500 #define PLL46XX_ENABLE BIT(31)
501 #define PLL46XX_LOCKED BIT(29)
502 #define PLL46XX_VSEL BIT(27)
504 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
505 unsigned long parent_rate)
507 struct samsung_clk_pll *pll = to_clk_pll(hw);
508 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
509 u64 fvco = parent_rate;
511 pll_con0 = __raw_readl(pll->con_reg);
512 pll_con1 = __raw_readl(pll->con_reg + 4);
513 mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
514 pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
515 sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
516 kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
517 pll_con1 & PLL46XX_KDIV_MASK;
519 shift = pll->type == pll_4600 ? 16 : 10;
520 fvco *= (mdiv << shift) + kdiv;
521 do_div(fvco, (pdiv << sdiv));
524 return (unsigned long)fvco;
527 static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
528 const struct samsung_pll_rate_table *rate)
530 u32 old_mdiv, old_pdiv, old_kdiv;
532 old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
533 old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
534 old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
536 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
537 || old_kdiv != rate->kdiv);
540 static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
543 struct samsung_clk_pll *pll = to_clk_pll(hw);
544 const struct samsung_pll_rate_table *rate;
545 u32 con0, con1, lock;
548 /* Get required rate settings from table */
549 rate = samsung_get_pll_settings(pll, drate);
551 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
552 drate, __clk_get_name(hw->clk));
556 con0 = __raw_readl(pll->con_reg);
557 con1 = __raw_readl(pll->con_reg + 0x4);
559 if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
560 /* If only s change, change just s value only*/
561 con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
562 con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
563 __raw_writel(con0, pll->con_reg);
568 /* Set PLL lock time. */
569 lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
571 /* Maximum lock time bitfield is 16-bit. */
574 /* Set PLL PMS and VSEL values. */
575 con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
576 (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
577 (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
578 (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
579 con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
580 (rate->pdiv << PLL46XX_PDIV_SHIFT) |
581 (rate->sdiv << PLL46XX_SDIV_SHIFT) |
582 (rate->vsel << PLL46XX_VSEL_SHIFT);
584 /* Set PLL K, MFR and MRR values. */
585 con1 = __raw_readl(pll->con_reg + 0x4);
586 con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
587 (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
588 (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
589 con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) |
590 (rate->mfr << PLL46XX_MFR_SHIFT) |
591 (rate->mrr << PLL46XX_MRR_SHIFT);
593 /* Write configuration to PLL */
594 __raw_writel(lock, pll->lock_reg);
595 __raw_writel(con0, pll->con_reg);
596 __raw_writel(con1, pll->con_reg + 0x4);
598 /* Wait for locking. */
600 while (!(__raw_readl(pll->con_reg) & PLL46XX_LOCKED)) {
601 ktime_t delta = ktime_sub(ktime_get(), start);
603 if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
604 pr_err("%s: could not lock PLL %s\n",
605 __func__, __clk_get_name(hw->clk));
615 static const struct clk_ops samsung_pll46xx_clk_ops = {
616 .recalc_rate = samsung_pll46xx_recalc_rate,
617 .round_rate = samsung_pll_round_rate,
618 .set_rate = samsung_pll46xx_set_rate,
621 static const struct clk_ops samsung_pll46xx_clk_min_ops = {
622 .recalc_rate = samsung_pll46xx_recalc_rate,
629 #define PLL6552_MDIV_MASK 0x3ff
630 #define PLL6552_PDIV_MASK 0x3f
631 #define PLL6552_SDIV_MASK 0x7
632 #define PLL6552_MDIV_SHIFT 16
633 #define PLL6552_MDIV_SHIFT_2416 14
634 #define PLL6552_PDIV_SHIFT 8
635 #define PLL6552_PDIV_SHIFT_2416 5
636 #define PLL6552_SDIV_SHIFT 0
638 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
639 unsigned long parent_rate)
641 struct samsung_clk_pll *pll = to_clk_pll(hw);
642 u32 mdiv, pdiv, sdiv, pll_con;
643 u64 fvco = parent_rate;
645 pll_con = __raw_readl(pll->con_reg);
646 if (pll->type == pll_6552_s3c2416) {
647 mdiv = (pll_con >> PLL6552_MDIV_SHIFT_2416) & PLL6552_MDIV_MASK;
648 pdiv = (pll_con >> PLL6552_PDIV_SHIFT_2416) & PLL6552_PDIV_MASK;
650 mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
651 pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
653 sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
656 do_div(fvco, (pdiv << sdiv));
658 return (unsigned long)fvco;
661 static const struct clk_ops samsung_pll6552_clk_ops = {
662 .recalc_rate = samsung_pll6552_recalc_rate,
669 #define PLL6553_MDIV_MASK 0xff
670 #define PLL6553_PDIV_MASK 0x3f
671 #define PLL6553_SDIV_MASK 0x7
672 #define PLL6553_KDIV_MASK 0xffff
673 #define PLL6553_MDIV_SHIFT 16
674 #define PLL6553_PDIV_SHIFT 8
675 #define PLL6553_SDIV_SHIFT 0
676 #define PLL6553_KDIV_SHIFT 0
678 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
679 unsigned long parent_rate)
681 struct samsung_clk_pll *pll = to_clk_pll(hw);
682 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
683 u64 fvco = parent_rate;
685 pll_con0 = __raw_readl(pll->con_reg);
686 pll_con1 = __raw_readl(pll->con_reg + 0x4);
687 mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
688 pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
689 sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
690 kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
692 fvco *= (mdiv << 16) + kdiv;
693 do_div(fvco, (pdiv << sdiv));
696 return (unsigned long)fvco;
699 static const struct clk_ops samsung_pll6553_clk_ops = {
700 .recalc_rate = samsung_pll6553_recalc_rate,
704 * PLL2550x Clock Type
707 #define PLL2550X_R_MASK (0x1)
708 #define PLL2550X_P_MASK (0x3F)
709 #define PLL2550X_M_MASK (0x3FF)
710 #define PLL2550X_S_MASK (0x7)
711 #define PLL2550X_R_SHIFT (20)
712 #define PLL2550X_P_SHIFT (14)
713 #define PLL2550X_M_SHIFT (4)
714 #define PLL2550X_S_SHIFT (0)
716 struct samsung_clk_pll2550x {
718 const void __iomem *reg_base;
719 unsigned long offset;
722 #define to_clk_pll2550x(_hw) container_of(_hw, struct samsung_clk_pll2550x, hw)
724 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
725 unsigned long parent_rate)
727 struct samsung_clk_pll2550x *pll = to_clk_pll2550x(hw);
728 u32 r, p, m, s, pll_stat;
729 u64 fvco = parent_rate;
731 pll_stat = __raw_readl(pll->reg_base + pll->offset * 3);
732 r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
735 p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK;
736 m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK;
737 s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK;
740 do_div(fvco, (p << s));
742 return (unsigned long)fvco;
745 static const struct clk_ops samsung_pll2550x_clk_ops = {
746 .recalc_rate = samsung_pll2550x_recalc_rate,
749 struct clk * __init samsung_clk_register_pll2550x(const char *name,
750 const char *pname, const void __iomem *reg_base,
751 const unsigned long offset)
753 struct samsung_clk_pll2550x *pll;
755 struct clk_init_data init;
757 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
759 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
764 init.ops = &samsung_pll2550x_clk_ops;
765 init.flags = CLK_GET_RATE_NOCACHE;
766 init.parent_names = &pname;
767 init.num_parents = 1;
769 pll->hw.init = &init;
770 pll->reg_base = reg_base;
771 pll->offset = offset;
773 clk = clk_register(NULL, &pll->hw);
775 pr_err("%s: failed to register pll clock %s\n", __func__,
780 if (clk_register_clkdev(clk, name, NULL))
781 pr_err("%s: failed to register lookup for %s", __func__, name);
786 static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
789 struct samsung_clk_pll *pll;
791 struct clk_init_data init;
794 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
796 pr_err("%s: could not allocate pll clk %s\n",
797 __func__, pll_clk->name);
801 init.name = pll_clk->name;
802 init.flags = pll_clk->flags;
803 init.parent_names = &pll_clk->parent_name;
804 init.num_parents = 1;
806 if (pll_clk->rate_table) {
807 /* find count of rates in rate_table */
808 for (len = 0; pll_clk->rate_table[len].rate != 0; )
811 pll->rate_count = len;
812 pll->rate_table = kmemdup(pll_clk->rate_table,
814 sizeof(struct samsung_pll_rate_table),
816 WARN(!pll->rate_table,
817 "%s: could not allocate rate table for %s\n",
818 __func__, pll_clk->name);
821 switch (pll_clk->type) {
823 init.ops = &samsung_pll2126_clk_ops;
826 init.ops = &samsung_pll3000_clk_ops;
828 /* clk_ops for 35xx and 2550 are similar */
831 if (!pll->rate_table)
832 init.ops = &samsung_pll35xx_clk_min_ops;
834 init.ops = &samsung_pll35xx_clk_ops;
837 init.ops = &samsung_pll45xx_clk_min_ops;
841 if (!pll->rate_table)
842 init.ops = &samsung_pll45xx_clk_min_ops;
844 init.ops = &samsung_pll45xx_clk_ops;
846 /* clk_ops for 36xx and 2650 are similar */
849 if (!pll->rate_table)
850 init.ops = &samsung_pll36xx_clk_min_ops;
852 init.ops = &samsung_pll36xx_clk_ops;
855 case pll_6552_s3c2416:
856 init.ops = &samsung_pll6552_clk_ops;
859 init.ops = &samsung_pll6553_clk_ops;
864 if (!pll->rate_table)
865 init.ops = &samsung_pll46xx_clk_min_ops;
867 init.ops = &samsung_pll46xx_clk_ops;
870 pr_warn("%s: Unknown pll type for pll clk %s\n",
871 __func__, pll_clk->name);
874 pll->hw.init = &init;
875 pll->type = pll_clk->type;
876 pll->lock_reg = base + pll_clk->lock_offset;
877 pll->con_reg = base + pll_clk->con_offset;
879 clk = clk_register(NULL, &pll->hw);
881 pr_err("%s: failed to register pll clock %s : %ld\n",
882 __func__, pll_clk->name, PTR_ERR(clk));
887 samsung_clk_add_lookup(clk, pll_clk->id);
892 ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
894 pr_err("%s: failed to register lookup for %s : %d",
895 __func__, pll_clk->name, ret);
898 void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
899 unsigned int nr_pll, void __iomem *base)
903 for (cnt = 0; cnt < nr_pll; cnt++)
904 _samsung_clk_register_pll(&pll_list[cnt], base);