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>
16 struct samsung_clk_pll {
18 void __iomem *lock_reg;
19 void __iomem *con_reg;
20 enum samsung_pll_type type;
21 unsigned int rate_count;
22 const struct samsung_pll_rate_table *rate_table;
25 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
27 static const struct samsung_pll_rate_table *samsung_get_pll_settings(
28 struct samsung_clk_pll *pll, unsigned long rate)
30 const struct samsung_pll_rate_table *rate_table = pll->rate_table;
33 for (i = 0; i < pll->rate_count; i++) {
34 if (rate == rate_table[i].rate)
35 return &rate_table[i];
41 static long samsung_pll_round_rate(struct clk_hw *hw,
42 unsigned long drate, unsigned long *prate)
44 struct samsung_clk_pll *pll = to_clk_pll(hw);
45 const struct samsung_pll_rate_table *rate_table = pll->rate_table;
48 /* Assumming rate_table is in descending order */
49 for (i = 0; i < pll->rate_count; i++) {
50 if (drate >= rate_table[i].rate)
51 return rate_table[i].rate;
54 /* return minimum supported value */
55 return rate_table[i - 1].rate;
61 /* Maximum lock time can be 270 * PDIV cycles */
62 #define PLL35XX_LOCK_FACTOR (270)
64 #define PLL35XX_MDIV_MASK (0x3FF)
65 #define PLL35XX_PDIV_MASK (0x3F)
66 #define PLL35XX_SDIV_MASK (0x7)
67 #define PLL35XX_LOCK_STAT_MASK (0x1)
68 #define PLL35XX_MDIV_SHIFT (16)
69 #define PLL35XX_PDIV_SHIFT (8)
70 #define PLL35XX_SDIV_SHIFT (0)
71 #define PLL35XX_LOCK_STAT_SHIFT (29)
73 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
74 unsigned long parent_rate)
76 struct samsung_clk_pll *pll = to_clk_pll(hw);
77 u32 mdiv, pdiv, sdiv, pll_con;
78 u64 fvco = parent_rate;
80 pll_con = __raw_readl(pll->con_reg);
81 mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
82 pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
83 sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
86 do_div(fvco, (pdiv << sdiv));
88 return (unsigned long)fvco;
91 static inline bool samsung_pll35xx_mp_change(
92 const struct samsung_pll_rate_table *rate, u32 pll_con)
94 u32 old_mdiv, old_pdiv;
96 old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
97 old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
99 return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
102 static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
105 struct samsung_clk_pll *pll = to_clk_pll(hw);
106 const struct samsung_pll_rate_table *rate;
109 /* Get required rate settings from table */
110 rate = samsung_get_pll_settings(pll, drate);
112 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
113 drate, __clk_get_name(hw->clk));
117 tmp = __raw_readl(pll->con_reg);
119 if (!(samsung_pll35xx_mp_change(rate, tmp))) {
120 /* If only s change, change just s value only*/
121 tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
122 tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
123 __raw_writel(tmp, pll->con_reg);
128 /* Set PLL lock time. */
129 __raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
132 /* Change PLL PMS values */
133 tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
134 (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
135 (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
136 tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
137 (rate->pdiv << PLL35XX_PDIV_SHIFT) |
138 (rate->sdiv << PLL35XX_SDIV_SHIFT);
139 __raw_writel(tmp, pll->con_reg);
144 tmp = __raw_readl(pll->con_reg);
145 } while (!(tmp & (PLL35XX_LOCK_STAT_MASK
146 << PLL35XX_LOCK_STAT_SHIFT)));
150 static const struct clk_ops samsung_pll35xx_clk_ops = {
151 .recalc_rate = samsung_pll35xx_recalc_rate,
152 .round_rate = samsung_pll_round_rate,
153 .set_rate = samsung_pll35xx_set_rate,
156 static const struct clk_ops samsung_pll35xx_clk_min_ops = {
157 .recalc_rate = samsung_pll35xx_recalc_rate,
163 /* Maximum lock time can be 3000 * PDIV cycles */
164 #define PLL36XX_LOCK_FACTOR (3000)
166 #define PLL36XX_KDIV_MASK (0xFFFF)
167 #define PLL36XX_MDIV_MASK (0x1FF)
168 #define PLL36XX_PDIV_MASK (0x3F)
169 #define PLL36XX_SDIV_MASK (0x7)
170 #define PLL36XX_MDIV_SHIFT (16)
171 #define PLL36XX_PDIV_SHIFT (8)
172 #define PLL36XX_SDIV_SHIFT (0)
173 #define PLL36XX_KDIV_SHIFT (0)
174 #define PLL36XX_LOCK_STAT_SHIFT (29)
176 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
177 unsigned long parent_rate)
179 struct samsung_clk_pll *pll = to_clk_pll(hw);
180 u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
182 u64 fvco = parent_rate;
184 pll_con0 = __raw_readl(pll->con_reg);
185 pll_con1 = __raw_readl(pll->con_reg + 4);
186 mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
187 pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
188 sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
189 kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK);
191 fvco *= (mdiv << 16) + kdiv;
192 do_div(fvco, (pdiv << sdiv));
195 return (unsigned long)fvco;
198 static inline bool samsung_pll36xx_mpk_change(
199 const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
201 u32 old_mdiv, old_pdiv, old_kdiv;
203 old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
204 old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
205 old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
207 return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
208 rate->kdiv != old_kdiv);
211 static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
212 unsigned long parent_rate)
214 struct samsung_clk_pll *pll = to_clk_pll(hw);
215 u32 tmp, pll_con0, pll_con1;
216 const struct samsung_pll_rate_table *rate;
218 rate = samsung_get_pll_settings(pll, drate);
220 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
221 drate, __clk_get_name(hw->clk));
225 pll_con0 = __raw_readl(pll->con_reg);
226 pll_con1 = __raw_readl(pll->con_reg + 4);
228 if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
229 /* If only s change, change just s value only*/
230 pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
231 pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
232 __raw_writel(pll_con0, pll->con_reg);
237 /* Set PLL lock time. */
238 __raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
240 /* Change PLL PMS values */
241 pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
242 (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
243 (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
244 pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
245 (rate->pdiv << PLL36XX_PDIV_SHIFT) |
246 (rate->sdiv << PLL36XX_SDIV_SHIFT);
247 __raw_writel(pll_con0, pll->con_reg);
249 pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
250 pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
251 __raw_writel(pll_con1, pll->con_reg + 4);
256 tmp = __raw_readl(pll->con_reg);
257 } while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
262 static const struct clk_ops samsung_pll36xx_clk_ops = {
263 .recalc_rate = samsung_pll36xx_recalc_rate,
264 .set_rate = samsung_pll36xx_set_rate,
265 .round_rate = samsung_pll_round_rate,
268 static const struct clk_ops samsung_pll36xx_clk_min_ops = {
269 .recalc_rate = samsung_pll36xx_recalc_rate,
276 #define PLL45XX_MDIV_MASK (0x3FF)
277 #define PLL45XX_PDIV_MASK (0x3F)
278 #define PLL45XX_SDIV_MASK (0x7)
279 #define PLL45XX_MDIV_SHIFT (16)
280 #define PLL45XX_PDIV_SHIFT (8)
281 #define PLL45XX_SDIV_SHIFT (0)
283 struct samsung_clk_pll45xx {
285 enum pll45xx_type type;
286 const void __iomem *con_reg;
289 #define to_clk_pll45xx(_hw) container_of(_hw, struct samsung_clk_pll45xx, hw)
291 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
292 unsigned long parent_rate)
294 struct samsung_clk_pll45xx *pll = to_clk_pll45xx(hw);
295 u32 mdiv, pdiv, sdiv, pll_con;
296 u64 fvco = parent_rate;
298 pll_con = __raw_readl(pll->con_reg);
299 mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
300 pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
301 sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
303 if (pll->type == pll_4508)
307 do_div(fvco, (pdiv << sdiv));
309 return (unsigned long)fvco;
312 static const struct clk_ops samsung_pll45xx_clk_ops = {
313 .recalc_rate = samsung_pll45xx_recalc_rate,
316 struct clk * __init samsung_clk_register_pll45xx(const char *name,
317 const char *pname, const void __iomem *con_reg,
318 enum pll45xx_type type)
320 struct samsung_clk_pll45xx *pll;
322 struct clk_init_data init;
324 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
326 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
331 init.ops = &samsung_pll45xx_clk_ops;
332 init.flags = CLK_GET_RATE_NOCACHE;
333 init.parent_names = &pname;
334 init.num_parents = 1;
336 pll->hw.init = &init;
337 pll->con_reg = con_reg;
340 clk = clk_register(NULL, &pll->hw);
342 pr_err("%s: failed to register pll clock %s\n", __func__,
347 if (clk_register_clkdev(clk, name, NULL))
348 pr_err("%s: failed to register lookup for %s", __func__, name);
357 #define PLL46XX_MDIV_MASK (0x1FF)
358 #define PLL46XX_PDIV_MASK (0x3F)
359 #define PLL46XX_SDIV_MASK (0x7)
360 #define PLL46XX_MDIV_SHIFT (16)
361 #define PLL46XX_PDIV_SHIFT (8)
362 #define PLL46XX_SDIV_SHIFT (0)
364 #define PLL46XX_KDIV_MASK (0xFFFF)
365 #define PLL4650C_KDIV_MASK (0xFFF)
366 #define PLL46XX_KDIV_SHIFT (0)
368 struct samsung_clk_pll46xx {
370 enum pll46xx_type type;
371 const void __iomem *con_reg;
374 #define to_clk_pll46xx(_hw) container_of(_hw, struct samsung_clk_pll46xx, hw)
376 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
377 unsigned long parent_rate)
379 struct samsung_clk_pll46xx *pll = to_clk_pll46xx(hw);
380 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
381 u64 fvco = parent_rate;
383 pll_con0 = __raw_readl(pll->con_reg);
384 pll_con1 = __raw_readl(pll->con_reg + 4);
385 mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
386 pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
387 sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
388 kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
389 pll_con1 & PLL46XX_KDIV_MASK;
391 shift = pll->type == pll_4600 ? 16 : 10;
392 fvco *= (mdiv << shift) + kdiv;
393 do_div(fvco, (pdiv << sdiv));
396 return (unsigned long)fvco;
399 static const struct clk_ops samsung_pll46xx_clk_ops = {
400 .recalc_rate = samsung_pll46xx_recalc_rate,
403 struct clk * __init samsung_clk_register_pll46xx(const char *name,
404 const char *pname, const void __iomem *con_reg,
405 enum pll46xx_type type)
407 struct samsung_clk_pll46xx *pll;
409 struct clk_init_data init;
411 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
413 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
418 init.ops = &samsung_pll46xx_clk_ops;
419 init.flags = CLK_GET_RATE_NOCACHE;
420 init.parent_names = &pname;
421 init.num_parents = 1;
423 pll->hw.init = &init;
424 pll->con_reg = con_reg;
427 clk = clk_register(NULL, &pll->hw);
429 pr_err("%s: failed to register pll clock %s\n", __func__,
434 if (clk_register_clkdev(clk, name, NULL))
435 pr_err("%s: failed to register lookup for %s", __func__, name);
444 #define PLL6552_LOCK_REG 0x00
445 #define PLL6552_CON_REG 0x0c
447 #define PLL6552_MDIV_MASK 0x3ff
448 #define PLL6552_PDIV_MASK 0x3f
449 #define PLL6552_SDIV_MASK 0x7
450 #define PLL6552_MDIV_SHIFT 16
451 #define PLL6552_PDIV_SHIFT 8
452 #define PLL6552_SDIV_SHIFT 0
454 struct samsung_clk_pll6552 {
456 void __iomem *reg_base;
459 #define to_clk_pll6552(_hw) container_of(_hw, struct samsung_clk_pll6552, hw)
461 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
462 unsigned long parent_rate)
464 struct samsung_clk_pll6552 *pll = to_clk_pll6552(hw);
465 u32 mdiv, pdiv, sdiv, pll_con;
466 u64 fvco = parent_rate;
468 pll_con = __raw_readl(pll->reg_base + PLL6552_CON_REG);
469 mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
470 pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
471 sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
474 do_div(fvco, (pdiv << sdiv));
476 return (unsigned long)fvco;
479 static const struct clk_ops samsung_pll6552_clk_ops = {
480 .recalc_rate = samsung_pll6552_recalc_rate,
483 struct clk * __init samsung_clk_register_pll6552(const char *name,
484 const char *pname, void __iomem *base)
486 struct samsung_clk_pll6552 *pll;
488 struct clk_init_data init;
490 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
492 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
497 init.ops = &samsung_pll6552_clk_ops;
498 init.parent_names = &pname;
499 init.num_parents = 1;
501 pll->hw.init = &init;
502 pll->reg_base = base;
504 clk = clk_register(NULL, &pll->hw);
506 pr_err("%s: failed to register pll clock %s\n", __func__,
511 if (clk_register_clkdev(clk, name, NULL))
512 pr_err("%s: failed to register lookup for %s", __func__, name);
521 #define PLL6553_LOCK_REG 0x00
522 #define PLL6553_CON0_REG 0x0c
523 #define PLL6553_CON1_REG 0x10
525 #define PLL6553_MDIV_MASK 0xff
526 #define PLL6553_PDIV_MASK 0x3f
527 #define PLL6553_SDIV_MASK 0x7
528 #define PLL6553_KDIV_MASK 0xffff
529 #define PLL6553_MDIV_SHIFT 16
530 #define PLL6553_PDIV_SHIFT 8
531 #define PLL6553_SDIV_SHIFT 0
532 #define PLL6553_KDIV_SHIFT 0
534 struct samsung_clk_pll6553 {
536 void __iomem *reg_base;
539 #define to_clk_pll6553(_hw) container_of(_hw, struct samsung_clk_pll6553, hw)
541 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
542 unsigned long parent_rate)
544 struct samsung_clk_pll6553 *pll = to_clk_pll6553(hw);
545 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
546 u64 fvco = parent_rate;
548 pll_con0 = __raw_readl(pll->reg_base + PLL6553_CON0_REG);
549 pll_con1 = __raw_readl(pll->reg_base + PLL6553_CON1_REG);
550 mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
551 pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
552 sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
553 kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
555 fvco *= (mdiv << 16) + kdiv;
556 do_div(fvco, (pdiv << sdiv));
559 return (unsigned long)fvco;
562 static const struct clk_ops samsung_pll6553_clk_ops = {
563 .recalc_rate = samsung_pll6553_recalc_rate,
566 struct clk * __init samsung_clk_register_pll6553(const char *name,
567 const char *pname, void __iomem *base)
569 struct samsung_clk_pll6553 *pll;
571 struct clk_init_data init;
573 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
575 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
580 init.ops = &samsung_pll6553_clk_ops;
581 init.parent_names = &pname;
582 init.num_parents = 1;
584 pll->hw.init = &init;
585 pll->reg_base = base;
587 clk = clk_register(NULL, &pll->hw);
589 pr_err("%s: failed to register pll clock %s\n", __func__,
594 if (clk_register_clkdev(clk, name, NULL))
595 pr_err("%s: failed to register lookup for %s", __func__, name);
601 * PLL2550x Clock Type
604 #define PLL2550X_R_MASK (0x1)
605 #define PLL2550X_P_MASK (0x3F)
606 #define PLL2550X_M_MASK (0x3FF)
607 #define PLL2550X_S_MASK (0x7)
608 #define PLL2550X_R_SHIFT (20)
609 #define PLL2550X_P_SHIFT (14)
610 #define PLL2550X_M_SHIFT (4)
611 #define PLL2550X_S_SHIFT (0)
613 struct samsung_clk_pll2550x {
615 const void __iomem *reg_base;
616 unsigned long offset;
619 #define to_clk_pll2550x(_hw) container_of(_hw, struct samsung_clk_pll2550x, hw)
621 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
622 unsigned long parent_rate)
624 struct samsung_clk_pll2550x *pll = to_clk_pll2550x(hw);
625 u32 r, p, m, s, pll_stat;
626 u64 fvco = parent_rate;
628 pll_stat = __raw_readl(pll->reg_base + pll->offset * 3);
629 r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
632 p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK;
633 m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK;
634 s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK;
637 do_div(fvco, (p << s));
639 return (unsigned long)fvco;
642 static const struct clk_ops samsung_pll2550x_clk_ops = {
643 .recalc_rate = samsung_pll2550x_recalc_rate,
646 struct clk * __init samsung_clk_register_pll2550x(const char *name,
647 const char *pname, const void __iomem *reg_base,
648 const unsigned long offset)
650 struct samsung_clk_pll2550x *pll;
652 struct clk_init_data init;
654 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
656 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
661 init.ops = &samsung_pll2550x_clk_ops;
662 init.flags = CLK_GET_RATE_NOCACHE;
663 init.parent_names = &pname;
664 init.num_parents = 1;
666 pll->hw.init = &init;
667 pll->reg_base = reg_base;
668 pll->offset = offset;
670 clk = clk_register(NULL, &pll->hw);
672 pr_err("%s: failed to register pll clock %s\n", __func__,
677 if (clk_register_clkdev(clk, name, NULL))
678 pr_err("%s: failed to register lookup for %s", __func__, name);
683 static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
686 struct samsung_clk_pll *pll;
688 struct clk_init_data init;
691 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
693 pr_err("%s: could not allocate pll clk %s\n",
694 __func__, pll_clk->name);
698 init.name = pll_clk->name;
699 init.flags = pll_clk->flags;
700 init.parent_names = &pll_clk->parent_name;
701 init.num_parents = 1;
703 if (pll_clk->rate_table) {
704 /* find count of rates in rate_table */
705 for (len = 0; pll_clk->rate_table[len].rate != 0; )
708 pll->rate_count = len;
709 pll->rate_table = kmemdup(pll_clk->rate_table,
711 sizeof(struct samsung_pll_rate_table),
713 WARN(!pll->rate_table,
714 "%s: could not allocate rate table for %s\n",
715 __func__, pll_clk->name);
718 switch (pll_clk->type) {
719 /* clk_ops for 35xx and 2550 are similar */
722 if (!pll->rate_table)
723 init.ops = &samsung_pll35xx_clk_min_ops;
725 init.ops = &samsung_pll35xx_clk_ops;
727 /* clk_ops for 36xx and 2650 are similar */
730 if (!pll->rate_table)
731 init.ops = &samsung_pll36xx_clk_min_ops;
733 init.ops = &samsung_pll36xx_clk_ops;
736 pr_warn("%s: Unknown pll type for pll clk %s\n",
737 __func__, pll_clk->name);
740 pll->hw.init = &init;
741 pll->type = pll_clk->type;
742 pll->lock_reg = base + pll_clk->lock_offset;
743 pll->con_reg = base + pll_clk->con_offset;
745 clk = clk_register(NULL, &pll->hw);
747 pr_err("%s: failed to register pll clock %s : %ld\n",
748 __func__, pll_clk->name, PTR_ERR(clk));
753 samsung_clk_add_lookup(clk, pll_clk->id);
758 ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
760 pr_err("%s: failed to register lookup for %s : %d",
761 __func__, pll_clk->name, ret);
764 void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
765 unsigned int nr_pll, void __iomem *base)
769 for (cnt = 0; cnt < nr_pll; cnt++)
770 _samsung_clk_register_pll(&pll_list[cnt], base);