Merge branch 'clk-next-s3c64xx' into clk-next
[firefly-linux-kernel-4.4.55.git] / drivers / clk / samsung / clk-pll.c
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
3  * Copyright (c) 2013 Linaro Ltd.
4  *
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.
8  *
9  * This file contains the utility functions to register the pll clocks.
10 */
11
12 #include <linux/errno.h>
13 #include "clk.h"
14 #include "clk-pll.h"
15
16 struct samsung_clk_pll {
17         struct clk_hw           hw;
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;
23 };
24
25 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
26
27 static const struct samsung_pll_rate_table *samsung_get_pll_settings(
28                                 struct samsung_clk_pll *pll, unsigned long rate)
29 {
30         const struct samsung_pll_rate_table  *rate_table = pll->rate_table;
31         int i;
32
33         for (i = 0; i < pll->rate_count; i++) {
34                 if (rate == rate_table[i].rate)
35                         return &rate_table[i];
36         }
37
38         return NULL;
39 }
40
41 static long samsung_pll_round_rate(struct clk_hw *hw,
42                         unsigned long drate, unsigned long *prate)
43 {
44         struct samsung_clk_pll *pll = to_clk_pll(hw);
45         const struct samsung_pll_rate_table *rate_table = pll->rate_table;
46         int i;
47
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;
52         }
53
54         /* return minimum supported value */
55         return rate_table[i - 1].rate;
56 }
57
58 /*
59  * PLL35xx Clock Type
60  */
61 /* Maximum lock time can be 270 * PDIV cycles */
62 #define PLL35XX_LOCK_FACTOR     (270)
63
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)
72
73 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
74                                 unsigned long parent_rate)
75 {
76         struct samsung_clk_pll *pll = to_clk_pll(hw);
77         u32 mdiv, pdiv, sdiv, pll_con;
78         u64 fvco = parent_rate;
79
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;
84
85         fvco *= mdiv;
86         do_div(fvco, (pdiv << sdiv));
87
88         return (unsigned long)fvco;
89 }
90
91 static inline bool samsung_pll35xx_mp_change(
92                 const struct samsung_pll_rate_table *rate, u32 pll_con)
93 {
94         u32 old_mdiv, old_pdiv;
95
96         old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
97         old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
98
99         return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
100 }
101
102 static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
103                                         unsigned long prate)
104 {
105         struct samsung_clk_pll *pll = to_clk_pll(hw);
106         const struct samsung_pll_rate_table *rate;
107         u32 tmp;
108
109         /* Get required rate settings from table */
110         rate = samsung_get_pll_settings(pll, drate);
111         if (!rate) {
112                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
113                         drate, __clk_get_name(hw->clk));
114                 return -EINVAL;
115         }
116
117         tmp = __raw_readl(pll->con_reg);
118
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);
124
125                 return 0;
126         }
127
128         /* Set PLL lock time. */
129         __raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
130                         pll->lock_reg);
131
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);
140
141         /* wait_lock_time */
142         do {
143                 cpu_relax();
144                 tmp = __raw_readl(pll->con_reg);
145         } while (!(tmp & (PLL35XX_LOCK_STAT_MASK
146                                 << PLL35XX_LOCK_STAT_SHIFT)));
147         return 0;
148 }
149
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,
154 };
155
156 static const struct clk_ops samsung_pll35xx_clk_min_ops = {
157         .recalc_rate = samsung_pll35xx_recalc_rate,
158 };
159
160 /*
161  * PLL36xx Clock Type
162  */
163 /* Maximum lock time can be 3000 * PDIV cycles */
164 #define PLL36XX_LOCK_FACTOR    (3000)
165
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)
175
176 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
177                                 unsigned long parent_rate)
178 {
179         struct samsung_clk_pll *pll = to_clk_pll(hw);
180         u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
181         s16 kdiv;
182         u64 fvco = parent_rate;
183
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);
190
191         fvco *= (mdiv << 16) + kdiv;
192         do_div(fvco, (pdiv << sdiv));
193         fvco >>= 16;
194
195         return (unsigned long)fvco;
196 }
197
198 static inline bool samsung_pll36xx_mpk_change(
199         const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
200 {
201         u32 old_mdiv, old_pdiv, old_kdiv;
202
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;
206
207         return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
208                 rate->kdiv != old_kdiv);
209 }
210
211 static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
212                                         unsigned long parent_rate)
213 {
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;
217
218         rate = samsung_get_pll_settings(pll, drate);
219         if (!rate) {
220                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
221                         drate, __clk_get_name(hw->clk));
222                 return -EINVAL;
223         }
224
225         pll_con0 = __raw_readl(pll->con_reg);
226         pll_con1 = __raw_readl(pll->con_reg + 4);
227
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);
233
234                 return 0;
235         }
236
237         /* Set PLL lock time. */
238         __raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
239
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);
248
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);
252
253         /* wait_lock_time */
254         do {
255                 cpu_relax();
256                 tmp = __raw_readl(pll->con_reg);
257         } while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
258
259         return 0;
260 }
261
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,
266 };
267
268 static const struct clk_ops samsung_pll36xx_clk_min_ops = {
269         .recalc_rate = samsung_pll36xx_recalc_rate,
270 };
271
272 /*
273  * PLL45xx Clock Type
274  */
275
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)
282
283 struct samsung_clk_pll45xx {
284         struct clk_hw           hw;
285         enum pll45xx_type       type;
286         const void __iomem      *con_reg;
287 };
288
289 #define to_clk_pll45xx(_hw) container_of(_hw, struct samsung_clk_pll45xx, hw)
290
291 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
292                                 unsigned long parent_rate)
293 {
294         struct samsung_clk_pll45xx *pll = to_clk_pll45xx(hw);
295         u32 mdiv, pdiv, sdiv, pll_con;
296         u64 fvco = parent_rate;
297
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;
302
303         if (pll->type == pll_4508)
304                 sdiv = sdiv - 1;
305
306         fvco *= mdiv;
307         do_div(fvco, (pdiv << sdiv));
308
309         return (unsigned long)fvco;
310 }
311
312 static const struct clk_ops samsung_pll45xx_clk_ops = {
313         .recalc_rate = samsung_pll45xx_recalc_rate,
314 };
315
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)
319 {
320         struct samsung_clk_pll45xx *pll;
321         struct clk *clk;
322         struct clk_init_data init;
323
324         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
325         if (!pll) {
326                 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
327                 return NULL;
328         }
329
330         init.name = 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;
335
336         pll->hw.init = &init;
337         pll->con_reg = con_reg;
338         pll->type = type;
339
340         clk = clk_register(NULL, &pll->hw);
341         if (IS_ERR(clk)) {
342                 pr_err("%s: failed to register pll clock %s\n", __func__,
343                                 name);
344                 kfree(pll);
345         }
346
347         if (clk_register_clkdev(clk, name, NULL))
348                 pr_err("%s: failed to register lookup for %s", __func__, name);
349
350         return clk;
351 }
352
353 /*
354  * PLL46xx Clock Type
355  */
356
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)
363
364 #define PLL46XX_KDIV_MASK       (0xFFFF)
365 #define PLL4650C_KDIV_MASK      (0xFFF)
366 #define PLL46XX_KDIV_SHIFT      (0)
367
368 struct samsung_clk_pll46xx {
369         struct clk_hw           hw;
370         enum pll46xx_type       type;
371         const void __iomem      *con_reg;
372 };
373
374 #define to_clk_pll46xx(_hw) container_of(_hw, struct samsung_clk_pll46xx, hw)
375
376 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
377                                 unsigned long parent_rate)
378 {
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;
382
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;
390
391         shift = pll->type == pll_4600 ? 16 : 10;
392         fvco *= (mdiv << shift) + kdiv;
393         do_div(fvco, (pdiv << sdiv));
394         fvco >>= shift;
395
396         return (unsigned long)fvco;
397 }
398
399 static const struct clk_ops samsung_pll46xx_clk_ops = {
400         .recalc_rate = samsung_pll46xx_recalc_rate,
401 };
402
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)
406 {
407         struct samsung_clk_pll46xx *pll;
408         struct clk *clk;
409         struct clk_init_data init;
410
411         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
412         if (!pll) {
413                 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
414                 return NULL;
415         }
416
417         init.name = 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;
422
423         pll->hw.init = &init;
424         pll->con_reg = con_reg;
425         pll->type = type;
426
427         clk = clk_register(NULL, &pll->hw);
428         if (IS_ERR(clk)) {
429                 pr_err("%s: failed to register pll clock %s\n", __func__,
430                                 name);
431                 kfree(pll);
432         }
433
434         if (clk_register_clkdev(clk, name, NULL))
435                 pr_err("%s: failed to register lookup for %s", __func__, name);
436
437         return clk;
438 }
439
440 /*
441  * PLL6552 Clock Type
442  */
443
444 #define PLL6552_LOCK_REG        0x00
445 #define PLL6552_CON_REG         0x0c
446
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
453
454 struct samsung_clk_pll6552 {
455         struct clk_hw hw;
456         void __iomem *reg_base;
457 };
458
459 #define to_clk_pll6552(_hw) container_of(_hw, struct samsung_clk_pll6552, hw)
460
461 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
462                                                 unsigned long parent_rate)
463 {
464         struct samsung_clk_pll6552 *pll = to_clk_pll6552(hw);
465         u32 mdiv, pdiv, sdiv, pll_con;
466         u64 fvco = parent_rate;
467
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;
472
473         fvco *= mdiv;
474         do_div(fvco, (pdiv << sdiv));
475
476         return (unsigned long)fvco;
477 }
478
479 static const struct clk_ops samsung_pll6552_clk_ops = {
480         .recalc_rate = samsung_pll6552_recalc_rate,
481 };
482
483 struct clk * __init samsung_clk_register_pll6552(const char *name,
484                                         const char *pname, void __iomem *base)
485 {
486         struct samsung_clk_pll6552 *pll;
487         struct clk *clk;
488         struct clk_init_data init;
489
490         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
491         if (!pll) {
492                 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
493                 return NULL;
494         }
495
496         init.name = name;
497         init.ops = &samsung_pll6552_clk_ops;
498         init.parent_names = &pname;
499         init.num_parents = 1;
500
501         pll->hw.init = &init;
502         pll->reg_base = base;
503
504         clk = clk_register(NULL, &pll->hw);
505         if (IS_ERR(clk)) {
506                 pr_err("%s: failed to register pll clock %s\n", __func__,
507                                 name);
508                 kfree(pll);
509         }
510
511         if (clk_register_clkdev(clk, name, NULL))
512                 pr_err("%s: failed to register lookup for %s", __func__, name);
513
514         return clk;
515 }
516
517 /*
518  * PLL6553 Clock Type
519  */
520
521 #define PLL6553_LOCK_REG        0x00
522 #define PLL6553_CON0_REG        0x0c
523 #define PLL6553_CON1_REG        0x10
524
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
533
534 struct samsung_clk_pll6553 {
535         struct clk_hw hw;
536         void __iomem *reg_base;
537 };
538
539 #define to_clk_pll6553(_hw) container_of(_hw, struct samsung_clk_pll6553, hw)
540
541 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
542                                                 unsigned long parent_rate)
543 {
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;
547
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;
554
555         fvco *= (mdiv << 16) + kdiv;
556         do_div(fvco, (pdiv << sdiv));
557         fvco >>= 16;
558
559         return (unsigned long)fvco;
560 }
561
562 static const struct clk_ops samsung_pll6553_clk_ops = {
563         .recalc_rate = samsung_pll6553_recalc_rate,
564 };
565
566 struct clk * __init samsung_clk_register_pll6553(const char *name,
567                                         const char *pname, void __iomem *base)
568 {
569         struct samsung_clk_pll6553 *pll;
570         struct clk *clk;
571         struct clk_init_data init;
572
573         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
574         if (!pll) {
575                 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
576                 return NULL;
577         }
578
579         init.name = name;
580         init.ops = &samsung_pll6553_clk_ops;
581         init.parent_names = &pname;
582         init.num_parents = 1;
583
584         pll->hw.init = &init;
585         pll->reg_base = base;
586
587         clk = clk_register(NULL, &pll->hw);
588         if (IS_ERR(clk)) {
589                 pr_err("%s: failed to register pll clock %s\n", __func__,
590                                 name);
591                 kfree(pll);
592         }
593
594         if (clk_register_clkdev(clk, name, NULL))
595                 pr_err("%s: failed to register lookup for %s", __func__, name);
596
597         return clk;
598 }
599
600 /*
601  * PLL2550x Clock Type
602  */
603
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)
612
613 struct samsung_clk_pll2550x {
614         struct clk_hw           hw;
615         const void __iomem      *reg_base;
616         unsigned long           offset;
617 };
618
619 #define to_clk_pll2550x(_hw) container_of(_hw, struct samsung_clk_pll2550x, hw)
620
621 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
622                                 unsigned long parent_rate)
623 {
624         struct samsung_clk_pll2550x *pll = to_clk_pll2550x(hw);
625         u32 r, p, m, s, pll_stat;
626         u64 fvco = parent_rate;
627
628         pll_stat = __raw_readl(pll->reg_base + pll->offset * 3);
629         r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
630         if (!r)
631                 return 0;
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;
635
636         fvco *= m;
637         do_div(fvco, (p << s));
638
639         return (unsigned long)fvco;
640 }
641
642 static const struct clk_ops samsung_pll2550x_clk_ops = {
643         .recalc_rate = samsung_pll2550x_recalc_rate,
644 };
645
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)
649 {
650         struct samsung_clk_pll2550x *pll;
651         struct clk *clk;
652         struct clk_init_data init;
653
654         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
655         if (!pll) {
656                 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
657                 return NULL;
658         }
659
660         init.name = 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;
665
666         pll->hw.init = &init;
667         pll->reg_base = reg_base;
668         pll->offset = offset;
669
670         clk = clk_register(NULL, &pll->hw);
671         if (IS_ERR(clk)) {
672                 pr_err("%s: failed to register pll clock %s\n", __func__,
673                                 name);
674                 kfree(pll);
675         }
676
677         if (clk_register_clkdev(clk, name, NULL))
678                 pr_err("%s: failed to register lookup for %s", __func__, name);
679
680         return clk;
681 }
682
683 static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
684                                                 void __iomem *base)
685 {
686         struct samsung_clk_pll *pll;
687         struct clk *clk;
688         struct clk_init_data init;
689         int ret, len;
690
691         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
692         if (!pll) {
693                 pr_err("%s: could not allocate pll clk %s\n",
694                         __func__, pll_clk->name);
695                 return;
696         }
697
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;
702
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; )
706                         len++;
707
708                 pll->rate_count = len;
709                 pll->rate_table = kmemdup(pll_clk->rate_table,
710                                         pll->rate_count *
711                                         sizeof(struct samsung_pll_rate_table),
712                                         GFP_KERNEL);
713                 WARN(!pll->rate_table,
714                         "%s: could not allocate rate table for %s\n",
715                         __func__, pll_clk->name);
716         }
717
718         switch (pll_clk->type) {
719         /* clk_ops for 35xx and 2550 are similar */
720         case pll_35xx:
721         case pll_2550:
722                 if (!pll->rate_table)
723                         init.ops = &samsung_pll35xx_clk_min_ops;
724                 else
725                         init.ops = &samsung_pll35xx_clk_ops;
726                 break;
727         /* clk_ops for 36xx and 2650 are similar */
728         case pll_36xx:
729         case pll_2650:
730                 if (!pll->rate_table)
731                         init.ops = &samsung_pll36xx_clk_min_ops;
732                 else
733                         init.ops = &samsung_pll36xx_clk_ops;
734                 break;
735         default:
736                 pr_warn("%s: Unknown pll type for pll clk %s\n",
737                         __func__, pll_clk->name);
738         }
739
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;
744
745         clk = clk_register(NULL, &pll->hw);
746         if (IS_ERR(clk)) {
747                 pr_err("%s: failed to register pll clock %s : %ld\n",
748                         __func__, pll_clk->name, PTR_ERR(clk));
749                 kfree(pll);
750                 return;
751         }
752
753         samsung_clk_add_lookup(clk, pll_clk->id);
754
755         if (!pll_clk->alias)
756                 return;
757
758         ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
759         if (ret)
760                 pr_err("%s: failed to register lookup for %s : %d",
761                         __func__, pll_clk->name, ret);
762 }
763
764 void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
765                                 unsigned int nr_pll, void __iomem *base)
766 {
767         int cnt;
768
769         for (cnt = 0; cnt < nr_pll; cnt++)
770                 _samsung_clk_register_pll(&pll_list[cnt], base);
771 }