Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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 <linux/hrtimer.h>
14 #include <linux/delay.h>
15 #include "clk.h"
16 #include "clk-pll.h"
17
18 #define PLL_TIMEOUT_MS          10
19
20 struct samsung_clk_pll {
21         struct clk_hw           hw;
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;
27 };
28
29 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
30
31 static const struct samsung_pll_rate_table *samsung_get_pll_settings(
32                                 struct samsung_clk_pll *pll, unsigned long rate)
33 {
34         const struct samsung_pll_rate_table  *rate_table = pll->rate_table;
35         int i;
36
37         for (i = 0; i < pll->rate_count; i++) {
38                 if (rate == rate_table[i].rate)
39                         return &rate_table[i];
40         }
41
42         return NULL;
43 }
44
45 static long samsung_pll_round_rate(struct clk_hw *hw,
46                         unsigned long drate, unsigned long *prate)
47 {
48         struct samsung_clk_pll *pll = to_clk_pll(hw);
49         const struct samsung_pll_rate_table *rate_table = pll->rate_table;
50         int i;
51
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;
56         }
57
58         /* return minimum supported value */
59         return rate_table[i - 1].rate;
60 }
61
62 /*
63  * PLL2126 Clock Type
64  */
65
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)
72
73 static unsigned long samsung_pll2126_recalc_rate(struct clk_hw *hw,
74                                 unsigned long parent_rate)
75 {
76         struct samsung_clk_pll *pll = to_clk_pll(hw);
77         u32 pll_con, mdiv, pdiv, sdiv;
78         u64 fvco = parent_rate;
79
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;
84
85         fvco *= (mdiv + 8);
86         do_div(fvco, (pdiv + 2) << sdiv);
87
88         return (unsigned long)fvco;
89 }
90
91 static const struct clk_ops samsung_pll2126_clk_ops = {
92         .recalc_rate = samsung_pll2126_recalc_rate,
93 };
94
95 /*
96  * PLL3000 Clock Type
97  */
98
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)
105
106 static unsigned long samsung_pll3000_recalc_rate(struct clk_hw *hw,
107                                 unsigned long parent_rate)
108 {
109         struct samsung_clk_pll *pll = to_clk_pll(hw);
110         u32 pll_con, mdiv, pdiv, sdiv;
111         u64 fvco = parent_rate;
112
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;
117
118         fvco *= (2 * (mdiv + 8));
119         do_div(fvco, pdiv << sdiv);
120
121         return (unsigned long)fvco;
122 }
123
124 static const struct clk_ops samsung_pll3000_clk_ops = {
125         .recalc_rate = samsung_pll3000_recalc_rate,
126 };
127
128 /*
129  * PLL35xx Clock Type
130  */
131 /* Maximum lock time can be 270 * PDIV cycles */
132 #define PLL35XX_LOCK_FACTOR     (270)
133
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)
142
143 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
144                                 unsigned long parent_rate)
145 {
146         struct samsung_clk_pll *pll = to_clk_pll(hw);
147         u32 mdiv, pdiv, sdiv, pll_con;
148         u64 fvco = parent_rate;
149
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;
154
155         fvco *= mdiv;
156         do_div(fvco, (pdiv << sdiv));
157
158         return (unsigned long)fvco;
159 }
160
161 static inline bool samsung_pll35xx_mp_change(
162                 const struct samsung_pll_rate_table *rate, u32 pll_con)
163 {
164         u32 old_mdiv, old_pdiv;
165
166         old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
167         old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
168
169         return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
170 }
171
172 static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
173                                         unsigned long prate)
174 {
175         struct samsung_clk_pll *pll = to_clk_pll(hw);
176         const struct samsung_pll_rate_table *rate;
177         u32 tmp;
178
179         /* Get required rate settings from table */
180         rate = samsung_get_pll_settings(pll, drate);
181         if (!rate) {
182                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
183                         drate, __clk_get_name(hw->clk));
184                 return -EINVAL;
185         }
186
187         tmp = __raw_readl(pll->con_reg);
188
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);
194
195                 return 0;
196         }
197
198         /* Set PLL lock time. */
199         __raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
200                         pll->lock_reg);
201
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);
210
211         /* wait_lock_time */
212         do {
213                 cpu_relax();
214                 tmp = __raw_readl(pll->con_reg);
215         } while (!(tmp & (PLL35XX_LOCK_STAT_MASK
216                                 << PLL35XX_LOCK_STAT_SHIFT)));
217         return 0;
218 }
219
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,
224 };
225
226 static const struct clk_ops samsung_pll35xx_clk_min_ops = {
227         .recalc_rate = samsung_pll35xx_recalc_rate,
228 };
229
230 /*
231  * PLL36xx Clock Type
232  */
233 /* Maximum lock time can be 3000 * PDIV cycles */
234 #define PLL36XX_LOCK_FACTOR    (3000)
235
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)
245
246 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
247                                 unsigned long parent_rate)
248 {
249         struct samsung_clk_pll *pll = to_clk_pll(hw);
250         u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
251         s16 kdiv;
252         u64 fvco = parent_rate;
253
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);
260
261         fvco *= (mdiv << 16) + kdiv;
262         do_div(fvco, (pdiv << sdiv));
263         fvco >>= 16;
264
265         return (unsigned long)fvco;
266 }
267
268 static inline bool samsung_pll36xx_mpk_change(
269         const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
270 {
271         u32 old_mdiv, old_pdiv, old_kdiv;
272
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;
276
277         return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
278                 rate->kdiv != old_kdiv);
279 }
280
281 static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
282                                         unsigned long parent_rate)
283 {
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;
287
288         rate = samsung_get_pll_settings(pll, drate);
289         if (!rate) {
290                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
291                         drate, __clk_get_name(hw->clk));
292                 return -EINVAL;
293         }
294
295         pll_con0 = __raw_readl(pll->con_reg);
296         pll_con1 = __raw_readl(pll->con_reg + 4);
297
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);
303
304                 return 0;
305         }
306
307         /* Set PLL lock time. */
308         __raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
309
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);
318
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);
322
323         /* wait_lock_time */
324         do {
325                 cpu_relax();
326                 tmp = __raw_readl(pll->con_reg);
327         } while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
328
329         return 0;
330 }
331
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,
336 };
337
338 static const struct clk_ops samsung_pll36xx_clk_min_ops = {
339         .recalc_rate = samsung_pll36xx_recalc_rate,
340 };
341
342 /*
343  * PLL45xx Clock Type
344  */
345 #define PLL4502_LOCK_FACTOR     400
346 #define PLL4508_LOCK_FACTOR     240
347
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)
356
357 #define PLL45XX_ENABLE          BIT(31)
358 #define PLL45XX_LOCKED          BIT(29)
359
360 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
361                                 unsigned long parent_rate)
362 {
363         struct samsung_clk_pll *pll = to_clk_pll(hw);
364         u32 mdiv, pdiv, sdiv, pll_con;
365         u64 fvco = parent_rate;
366
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;
371
372         if (pll->type == pll_4508)
373                 sdiv = sdiv - 1;
374
375         fvco *= mdiv;
376         do_div(fvco, (pdiv << sdiv));
377
378         return (unsigned long)fvco;
379 }
380
381 static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
382                                 const struct samsung_pll_rate_table *rate)
383 {
384         u32 old_mdiv, old_pdiv, old_afc;
385
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;
389
390         return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
391                 || old_afc != rate->afc);
392 }
393
394 static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
395                                         unsigned long prate)
396 {
397         struct samsung_clk_pll *pll = to_clk_pll(hw);
398         const struct samsung_pll_rate_table *rate;
399         u32 con0, con1;
400         ktime_t start;
401
402         /* Get required rate settings from table */
403         rate = samsung_get_pll_settings(pll, drate);
404         if (!rate) {
405                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
406                         drate, __clk_get_name(hw->clk));
407                 return -EINVAL;
408         }
409
410         con0 = __raw_readl(pll->con_reg);
411         con1 = __raw_readl(pll->con_reg + 0x4);
412
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);
418
419                 return 0;
420         }
421
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);
429
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);
434
435         /* Set PLL lock time. */
436         switch (pll->type) {
437         case pll_4502:
438                 __raw_writel(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
439                 break;
440         case pll_4508:
441                 __raw_writel(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
442                 break;
443         default:
444                 break;
445         }
446
447         /* Set new configuration. */
448         __raw_writel(con1, pll->con_reg + 0x4);
449         __raw_writel(con0, pll->con_reg);
450
451         /* Wait for locking. */
452         start = ktime_get();
453         while (!(__raw_readl(pll->con_reg) & PLL45XX_LOCKED)) {
454                 ktime_t delta = ktime_sub(ktime_get(), start);
455
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));
459                         return -EFAULT;
460                 }
461
462                 cpu_relax();
463         }
464
465         return 0;
466 }
467
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,
472 };
473
474 static const struct clk_ops samsung_pll45xx_clk_min_ops = {
475         .recalc_rate = samsung_pll45xx_recalc_rate,
476 };
477
478 /*
479  * PLL46xx Clock Type
480  */
481 #define PLL46XX_LOCK_FACTOR     3000
482
483 #define PLL46XX_VSEL_MASK       (1)
484 #define PLL46XX_MDIV_MASK       (0x1FF)
485 #define PLL1460X_MDIV_MASK      (0x3FF)
486
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)
493
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)
502
503 #define PLL46XX_ENABLE          BIT(31)
504 #define PLL46XX_LOCKED          BIT(29)
505 #define PLL46XX_VSEL            BIT(27)
506
507 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
508                                 unsigned long parent_rate)
509 {
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;
513
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;
522
523         shift = ((pll->type == pll_4600) || (pll->type == pll_1460x)) ? 16 : 10;
524
525         fvco *= (mdiv << shift) + kdiv;
526         do_div(fvco, (pdiv << sdiv));
527         fvco >>= shift;
528
529         return (unsigned long)fvco;
530 }
531
532 static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
533                                 const struct samsung_pll_rate_table *rate)
534 {
535         u32 old_mdiv, old_pdiv, old_kdiv;
536
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;
540
541         return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
542                 || old_kdiv != rate->kdiv);
543 }
544
545 static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
546                                         unsigned long prate)
547 {
548         struct samsung_clk_pll *pll = to_clk_pll(hw);
549         const struct samsung_pll_rate_table *rate;
550         u32 con0, con1, lock;
551         ktime_t start;
552
553         /* Get required rate settings from table */
554         rate = samsung_get_pll_settings(pll, drate);
555         if (!rate) {
556                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
557                         drate, __clk_get_name(hw->clk));
558                 return -EINVAL;
559         }
560
561         con0 = __raw_readl(pll->con_reg);
562         con1 = __raw_readl(pll->con_reg + 0x4);
563
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);
569
570                 return 0;
571         }
572
573         /* Set PLL lock time. */
574         lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
575         if (lock > 0xffff)
576                 /* Maximum lock time bitfield is 16-bit. */
577                 lock = 0xffff;
578
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));
584         } else {
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;
590         }
591
592         con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
593                         (rate->pdiv << PLL46XX_PDIV_SHIFT) |
594                         (rate->sdiv << PLL46XX_SDIV_SHIFT);
595
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);
604
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);
609
610         /* Wait for locking. */
611         start = ktime_get();
612         while (!(__raw_readl(pll->con_reg) & PLL46XX_LOCKED)) {
613                 ktime_t delta = ktime_sub(ktime_get(), start);
614
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));
618                         return -EFAULT;
619                 }
620
621                 cpu_relax();
622         }
623
624         return 0;
625 }
626
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,
631 };
632
633 static const struct clk_ops samsung_pll46xx_clk_min_ops = {
634         .recalc_rate = samsung_pll46xx_recalc_rate,
635 };
636
637 /*
638  * PLL6552 Clock Type
639  */
640
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
649
650 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
651                                                 unsigned long parent_rate)
652 {
653         struct samsung_clk_pll *pll = to_clk_pll(hw);
654         u32 mdiv, pdiv, sdiv, pll_con;
655         u64 fvco = parent_rate;
656
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;
661         } else {
662                 mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
663                 pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
664         }
665         sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
666
667         fvco *= mdiv;
668         do_div(fvco, (pdiv << sdiv));
669
670         return (unsigned long)fvco;
671 }
672
673 static const struct clk_ops samsung_pll6552_clk_ops = {
674         .recalc_rate = samsung_pll6552_recalc_rate,
675 };
676
677 /*
678  * PLL6553 Clock Type
679  */
680
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
689
690 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
691                                                 unsigned long parent_rate)
692 {
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;
696
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;
703
704         fvco *= (mdiv << 16) + kdiv;
705         do_div(fvco, (pdiv << sdiv));
706         fvco >>= 16;
707
708         return (unsigned long)fvco;
709 }
710
711 static const struct clk_ops samsung_pll6553_clk_ops = {
712         .recalc_rate = samsung_pll6553_recalc_rate,
713 };
714
715 /*
716  * PLL Clock Type of S3C24XX before S3C2443
717  */
718
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)
725
726 #define PLLS3C2410_ENABLE_REG_OFFSET    0x10
727
728 static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw *hw,
729                                         unsigned long parent_rate)
730 {
731         struct samsung_clk_pll *pll = to_clk_pll(hw);
732         u32 pll_con, mdiv, pdiv, sdiv;
733         u64 fvco = parent_rate;
734
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;
739
740         fvco *= (mdiv + 8);
741         do_div(fvco, (pdiv + 2) << sdiv);
742
743         return (unsigned int)fvco;
744 }
745
746 static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw *hw,
747                                         unsigned long parent_rate)
748 {
749         struct samsung_clk_pll *pll = to_clk_pll(hw);
750         u32 pll_con, mdiv, pdiv, sdiv;
751         u64 fvco = parent_rate;
752
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;
757
758         fvco *= (2 * (mdiv + 8));
759         do_div(fvco, (pdiv + 2) << sdiv);
760
761         return (unsigned int)fvco;
762 }
763
764 static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
765                                         unsigned long prate)
766 {
767         struct samsung_clk_pll *pll = to_clk_pll(hw);
768         const struct samsung_pll_rate_table *rate;
769         u32 tmp;
770
771         /* Get required rate settings from table */
772         rate = samsung_get_pll_settings(pll, drate);
773         if (!rate) {
774                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
775                         drate, __clk_get_name(hw->clk));
776                 return -EINVAL;
777         }
778
779         tmp = __raw_readl(pll->con_reg);
780
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);
789
790         /* Time to settle according to the manual */
791         udelay(300);
792
793         return 0;
794 }
795
796 static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable)
797 {
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;
801
802         if (enable)
803                 pll_en &= ~BIT(bit);
804         else
805                 pll_en |= BIT(bit);
806
807         __raw_writel(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
808
809         /* if we started the UPLL, then allow to settle */
810         if (enable && (pll_en_orig & BIT(bit)))
811                 udelay(300);
812
813         return 0;
814 }
815
816 static int samsung_s3c2410_mpll_enable(struct clk_hw *hw)
817 {
818         return samsung_s3c2410_pll_enable(hw, 5, true);
819 }
820
821 static void samsung_s3c2410_mpll_disable(struct clk_hw *hw)
822 {
823         samsung_s3c2410_pll_enable(hw, 5, false);
824 }
825
826 static int samsung_s3c2410_upll_enable(struct clk_hw *hw)
827 {
828         return samsung_s3c2410_pll_enable(hw, 7, true);
829 }
830
831 static void samsung_s3c2410_upll_disable(struct clk_hw *hw)
832 {
833         samsung_s3c2410_pll_enable(hw, 7, false);
834 }
835
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,
840 };
841
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,
846 };
847
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,
852 };
853
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,
860 };
861
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,
868 };
869
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,
876 };
877
878 /*
879  * PLL2550x Clock Type
880  */
881
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)
890
891 struct samsung_clk_pll2550x {
892         struct clk_hw           hw;
893         const void __iomem      *reg_base;
894         unsigned long           offset;
895 };
896
897 #define to_clk_pll2550x(_hw) container_of(_hw, struct samsung_clk_pll2550x, hw)
898
899 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
900                                 unsigned long parent_rate)
901 {
902         struct samsung_clk_pll2550x *pll = to_clk_pll2550x(hw);
903         u32 r, p, m, s, pll_stat;
904         u64 fvco = parent_rate;
905
906         pll_stat = __raw_readl(pll->reg_base + pll->offset * 3);
907         r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
908         if (!r)
909                 return 0;
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;
913
914         fvco *= m;
915         do_div(fvco, (p << s));
916
917         return (unsigned long)fvco;
918 }
919
920 static const struct clk_ops samsung_pll2550x_clk_ops = {
921         .recalc_rate = samsung_pll2550x_recalc_rate,
922 };
923
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)
927 {
928         struct samsung_clk_pll2550x *pll;
929         struct clk *clk;
930         struct clk_init_data init;
931
932         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
933         if (!pll) {
934                 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
935                 return NULL;
936         }
937
938         init.name = 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;
943
944         pll->hw.init = &init;
945         pll->reg_base = reg_base;
946         pll->offset = offset;
947
948         clk = clk_register(NULL, &pll->hw);
949         if (IS_ERR(clk)) {
950                 pr_err("%s: failed to register pll clock %s\n", __func__,
951                                 name);
952                 kfree(pll);
953         }
954
955         if (clk_register_clkdev(clk, name, NULL))
956                 pr_err("%s: failed to register lookup for %s", __func__, name);
957
958         return clk;
959 }
960
961 /*
962  * PLL2550xx Clock Type
963  */
964
965 /* Maximum lock time can be 270 * PDIV cycles */
966 #define PLL2550XX_LOCK_FACTOR 270
967
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
976
977 static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw *hw,
978                                 unsigned long parent_rate)
979 {
980         struct samsung_clk_pll *pll = to_clk_pll(hw);
981         u32 mdiv, pdiv, sdiv, pll_con;
982         u64 fvco = parent_rate;
983
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;
988
989         fvco *= mdiv;
990         do_div(fvco, (pdiv << sdiv));
991
992         return (unsigned long)fvco;
993 }
994
995 static inline bool samsung_pll2550xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con)
996 {
997         u32 old_mdiv, old_pdiv;
998
999         old_mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
1000         old_pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
1001
1002         return mdiv != old_mdiv || pdiv != old_pdiv;
1003 }
1004
1005 static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
1006                                         unsigned long prate)
1007 {
1008         struct samsung_clk_pll *pll = to_clk_pll(hw);
1009         const struct samsung_pll_rate_table *rate;
1010         u32 tmp;
1011
1012         /* Get required rate settings from table */
1013         rate = samsung_get_pll_settings(pll, drate);
1014         if (!rate) {
1015                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1016                         drate, __clk_get_name(hw->clk));
1017                 return -EINVAL;
1018         }
1019
1020         tmp = __raw_readl(pll->con_reg);
1021
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);
1027
1028                 return 0;
1029         }
1030
1031         /* Set PLL lock time. */
1032         __raw_writel(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg);
1033
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);
1042
1043         /* wait_lock_time */
1044         do {
1045                 cpu_relax();
1046                 tmp = __raw_readl(pll->con_reg);
1047         } while (!(tmp & (PLL2550XX_LOCK_STAT_MASK
1048                         << PLL2550XX_LOCK_STAT_SHIFT)));
1049
1050         return 0;
1051 }
1052
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,
1057 };
1058
1059 static const struct clk_ops samsung_pll2550xx_clk_min_ops = {
1060         .recalc_rate = samsung_pll2550xx_recalc_rate,
1061 };
1062
1063 /*
1064  * PLL2650XX Clock Type
1065  */
1066
1067 /* Maximum lock time can be 3000 * PDIV cycles */
1068 #define PLL2650XX_LOCK_FACTOR 3000
1069
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
1081
1082 static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw,
1083                                 unsigned long parent_rate)
1084 {
1085         struct samsung_clk_pll *pll = to_clk_pll(hw);
1086         u32 mdiv, pdiv, sdiv, pll_con0, pll_con2;
1087         s16 kdiv;
1088         u64 fvco = parent_rate;
1089
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);
1096
1097         fvco *= (mdiv << 16) + kdiv;
1098         do_div(fvco, (pdiv << sdiv));
1099         fvco >>= 16;
1100
1101         return (unsigned long)fvco;
1102 }
1103
1104 static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
1105                                         unsigned long parent_rate)
1106 {
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;
1110
1111         rate = samsung_get_pll_settings(pll, drate);
1112         if (!rate) {
1113                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1114                         drate, __clk_get_name(hw->clk));
1115                 return -EINVAL;
1116         }
1117
1118         pll_con0 = __raw_readl(pll->con_reg);
1119         pll_con2 = __raw_readl(pll->con_reg + 8);
1120
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;
1130
1131         pll_con2 &= ~(PLL2650XX_KDIV_MASK << PLL2650XX_KDIV_SHIFT);
1132         pll_con2 |= ((~(rate->kdiv) + 1) & PLL2650XX_KDIV_MASK)
1133                         << PLL2650XX_KDIV_SHIFT;
1134
1135         /* Set PLL lock time. */
1136         __raw_writel(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg);
1137
1138         __raw_writel(pll_con0, pll->con_reg);
1139         __raw_writel(pll_con2, pll->con_reg + 8);
1140
1141         do {
1142                 tmp = __raw_readl(pll->con_reg);
1143         } while (!(tmp & (0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT)));
1144
1145         return 0;
1146 }
1147
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,
1152 };
1153
1154 static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
1155         .recalc_rate = samsung_pll2650xx_recalc_rate,
1156 };
1157
1158 static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1159                                 struct samsung_pll_clock *pll_clk,
1160                                 void __iomem *base)
1161 {
1162         struct samsung_clk_pll *pll;
1163         struct clk *clk;
1164         struct clk_init_data init;
1165         int ret, len;
1166
1167         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
1168         if (!pll) {
1169                 pr_err("%s: could not allocate pll clk %s\n",
1170                         __func__, pll_clk->name);
1171                 return;
1172         }
1173
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;
1178
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; )
1182                         len++;
1183
1184                 pll->rate_count = len;
1185                 pll->rate_table = kmemdup(pll_clk->rate_table,
1186                                         pll->rate_count *
1187                                         sizeof(struct samsung_pll_rate_table),
1188                                         GFP_KERNEL);
1189                 WARN(!pll->rate_table,
1190                         "%s: could not allocate rate table for %s\n",
1191                         __func__, pll_clk->name);
1192         }
1193
1194         switch (pll_clk->type) {
1195         case pll_2126:
1196                 init.ops = &samsung_pll2126_clk_ops;
1197                 break;
1198         case pll_3000:
1199                 init.ops = &samsung_pll3000_clk_ops;
1200                 break;
1201         /* clk_ops for 35xx and 2550 are similar */
1202         case pll_35xx:
1203         case pll_2550:
1204         case pll_1450x:
1205         case pll_1451x:
1206         case pll_1452x:
1207                 if (!pll->rate_table)
1208                         init.ops = &samsung_pll35xx_clk_min_ops;
1209                 else
1210                         init.ops = &samsung_pll35xx_clk_ops;
1211                 break;
1212         case pll_4500:
1213                 init.ops = &samsung_pll45xx_clk_min_ops;
1214                 break;
1215         case pll_4502:
1216         case pll_4508:
1217                 if (!pll->rate_table)
1218                         init.ops = &samsung_pll45xx_clk_min_ops;
1219                 else
1220                         init.ops = &samsung_pll45xx_clk_ops;
1221                 break;
1222         /* clk_ops for 36xx and 2650 are similar */
1223         case pll_36xx:
1224         case pll_2650:
1225                 if (!pll->rate_table)
1226                         init.ops = &samsung_pll36xx_clk_min_ops;
1227                 else
1228                         init.ops = &samsung_pll36xx_clk_ops;
1229                 break;
1230         case pll_6552:
1231         case pll_6552_s3c2416:
1232                 init.ops = &samsung_pll6552_clk_ops;
1233                 break;
1234         case pll_6553:
1235                 init.ops = &samsung_pll6553_clk_ops;
1236                 break;
1237         case pll_4600:
1238         case pll_4650:
1239         case pll_4650c:
1240         case pll_1460x:
1241                 if (!pll->rate_table)
1242                         init.ops = &samsung_pll46xx_clk_min_ops;
1243                 else
1244                         init.ops = &samsung_pll46xx_clk_ops;
1245                 break;
1246         case pll_s3c2410_mpll:
1247                 if (!pll->rate_table)
1248                         init.ops = &samsung_s3c2410_mpll_clk_min_ops;
1249                 else
1250                         init.ops = &samsung_s3c2410_mpll_clk_ops;
1251                 break;
1252         case pll_s3c2410_upll:
1253                 if (!pll->rate_table)
1254                         init.ops = &samsung_s3c2410_upll_clk_min_ops;
1255                 else
1256                         init.ops = &samsung_s3c2410_upll_clk_ops;
1257                 break;
1258         case pll_s3c2440_mpll:
1259                 if (!pll->rate_table)
1260                         init.ops = &samsung_s3c2440_mpll_clk_min_ops;
1261                 else
1262                         init.ops = &samsung_s3c2440_mpll_clk_ops;
1263                 break;
1264         case pll_2550xx:
1265                 if (!pll->rate_table)
1266                         init.ops = &samsung_pll2550xx_clk_min_ops;
1267                 else
1268                         init.ops = &samsung_pll2550xx_clk_ops;
1269                 break;
1270         case pll_2650xx:
1271                 if (!pll->rate_table)
1272                         init.ops = &samsung_pll2650xx_clk_min_ops;
1273                 else
1274                         init.ops = &samsung_pll2650xx_clk_ops;
1275                 break;
1276         default:
1277                 pr_warn("%s: Unknown pll type for pll clk %s\n",
1278                         __func__, pll_clk->name);
1279         }
1280
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;
1285
1286         clk = clk_register(NULL, &pll->hw);
1287         if (IS_ERR(clk)) {
1288                 pr_err("%s: failed to register pll clock %s : %ld\n",
1289                         __func__, pll_clk->name, PTR_ERR(clk));
1290                 kfree(pll);
1291                 return;
1292         }
1293
1294         samsung_clk_add_lookup(ctx, clk, pll_clk->id);
1295
1296         if (!pll_clk->alias)
1297                 return;
1298
1299         ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
1300         if (ret)
1301                 pr_err("%s: failed to register lookup for %s : %d",
1302                         __func__, pll_clk->name, ret);
1303 }
1304
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)
1308 {
1309         int cnt;
1310
1311         for (cnt = 0; cnt < nr_pll; cnt++)
1312                 _samsung_clk_register_pll(ctx, &pll_list[cnt], base);
1313 }