GNU Linux-libre 5.10.215-gnu1
[releases.git] / drivers / clk / samsung / clk-pll.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
4  * Copyright (c) 2013 Linaro Ltd.
5  *
6  * This file contains the utility functions to register the pll clocks.
7 */
8
9 #include <linux/errno.h>
10 #include <linux/hrtimer.h>
11 #include <linux/delay.h>
12 #include <linux/slab.h>
13 #include <linux/clk-provider.h>
14 #include <linux/io.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         /* PLL enable control bit offset in @con_reg register */
25         unsigned short          enable_offs;
26         /* PLL lock status bit offset in @con_reg register */
27         unsigned short          lock_offs;
28         enum samsung_pll_type   type;
29         unsigned int            rate_count;
30         const struct samsung_pll_rate_table *rate_table;
31 };
32
33 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
34
35 static const struct samsung_pll_rate_table *samsung_get_pll_settings(
36                                 struct samsung_clk_pll *pll, unsigned long rate)
37 {
38         const struct samsung_pll_rate_table  *rate_table = pll->rate_table;
39         int i;
40
41         for (i = 0; i < pll->rate_count; i++) {
42                 if (rate == rate_table[i].rate)
43                         return &rate_table[i];
44         }
45
46         return NULL;
47 }
48
49 static long samsung_pll_round_rate(struct clk_hw *hw,
50                         unsigned long drate, unsigned long *prate)
51 {
52         struct samsung_clk_pll *pll = to_clk_pll(hw);
53         const struct samsung_pll_rate_table *rate_table = pll->rate_table;
54         int i;
55
56         /* Assumming rate_table is in descending order */
57         for (i = 0; i < pll->rate_count; i++) {
58                 if (drate >= rate_table[i].rate)
59                         return rate_table[i].rate;
60         }
61
62         /* return minimum supported value */
63         return rate_table[i - 1].rate;
64 }
65
66 static int samsung_pll3xxx_enable(struct clk_hw *hw)
67 {
68         struct samsung_clk_pll *pll = to_clk_pll(hw);
69         u32 tmp;
70
71         tmp = readl_relaxed(pll->con_reg);
72         tmp |= BIT(pll->enable_offs);
73         writel_relaxed(tmp, pll->con_reg);
74
75         /* wait lock time */
76         do {
77                 cpu_relax();
78                 tmp = readl_relaxed(pll->con_reg);
79         } while (!(tmp & BIT(pll->lock_offs)));
80
81         return 0;
82 }
83
84 static void samsung_pll3xxx_disable(struct clk_hw *hw)
85 {
86         struct samsung_clk_pll *pll = to_clk_pll(hw);
87         u32 tmp;
88
89         tmp = readl_relaxed(pll->con_reg);
90         tmp &= ~BIT(pll->enable_offs);
91         writel_relaxed(tmp, pll->con_reg);
92 }
93
94 /*
95  * PLL2126 Clock Type
96  */
97
98 #define PLL2126_MDIV_MASK       (0xff)
99 #define PLL2126_PDIV_MASK       (0x3f)
100 #define PLL2126_SDIV_MASK       (0x3)
101 #define PLL2126_MDIV_SHIFT      (16)
102 #define PLL2126_PDIV_SHIFT      (8)
103 #define PLL2126_SDIV_SHIFT      (0)
104
105 static unsigned long samsung_pll2126_recalc_rate(struct clk_hw *hw,
106                                 unsigned long parent_rate)
107 {
108         struct samsung_clk_pll *pll = to_clk_pll(hw);
109         u32 pll_con, mdiv, pdiv, sdiv;
110         u64 fvco = parent_rate;
111
112         pll_con = readl_relaxed(pll->con_reg);
113         mdiv = (pll_con >> PLL2126_MDIV_SHIFT) & PLL2126_MDIV_MASK;
114         pdiv = (pll_con >> PLL2126_PDIV_SHIFT) & PLL2126_PDIV_MASK;
115         sdiv = (pll_con >> PLL2126_SDIV_SHIFT) & PLL2126_SDIV_MASK;
116
117         fvco *= (mdiv + 8);
118         do_div(fvco, (pdiv + 2) << sdiv);
119
120         return (unsigned long)fvco;
121 }
122
123 static const struct clk_ops samsung_pll2126_clk_ops = {
124         .recalc_rate = samsung_pll2126_recalc_rate,
125 };
126
127 /*
128  * PLL3000 Clock Type
129  */
130
131 #define PLL3000_MDIV_MASK       (0xff)
132 #define PLL3000_PDIV_MASK       (0x3)
133 #define PLL3000_SDIV_MASK       (0x3)
134 #define PLL3000_MDIV_SHIFT      (16)
135 #define PLL3000_PDIV_SHIFT      (8)
136 #define PLL3000_SDIV_SHIFT      (0)
137
138 static unsigned long samsung_pll3000_recalc_rate(struct clk_hw *hw,
139                                 unsigned long parent_rate)
140 {
141         struct samsung_clk_pll *pll = to_clk_pll(hw);
142         u32 pll_con, mdiv, pdiv, sdiv;
143         u64 fvco = parent_rate;
144
145         pll_con = readl_relaxed(pll->con_reg);
146         mdiv = (pll_con >> PLL3000_MDIV_SHIFT) & PLL3000_MDIV_MASK;
147         pdiv = (pll_con >> PLL3000_PDIV_SHIFT) & PLL3000_PDIV_MASK;
148         sdiv = (pll_con >> PLL3000_SDIV_SHIFT) & PLL3000_SDIV_MASK;
149
150         fvco *= (2 * (mdiv + 8));
151         do_div(fvco, pdiv << sdiv);
152
153         return (unsigned long)fvco;
154 }
155
156 static const struct clk_ops samsung_pll3000_clk_ops = {
157         .recalc_rate = samsung_pll3000_recalc_rate,
158 };
159
160 /*
161  * PLL35xx Clock Type
162  */
163 /* Maximum lock time can be 270 * PDIV cycles */
164 #define PLL35XX_LOCK_FACTOR     (270)
165
166 #define PLL35XX_MDIV_MASK       (0x3FF)
167 #define PLL35XX_PDIV_MASK       (0x3F)
168 #define PLL35XX_SDIV_MASK       (0x7)
169 #define PLL35XX_MDIV_SHIFT      (16)
170 #define PLL35XX_PDIV_SHIFT      (8)
171 #define PLL35XX_SDIV_SHIFT      (0)
172 #define PLL35XX_LOCK_STAT_SHIFT (29)
173 #define PLL35XX_ENABLE_SHIFT    (31)
174
175 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
176                                 unsigned long parent_rate)
177 {
178         struct samsung_clk_pll *pll = to_clk_pll(hw);
179         u32 mdiv, pdiv, sdiv, pll_con;
180         u64 fvco = parent_rate;
181
182         pll_con = readl_relaxed(pll->con_reg);
183         mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
184         pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
185         sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
186
187         fvco *= mdiv;
188         do_div(fvco, (pdiv << sdiv));
189
190         return (unsigned long)fvco;
191 }
192
193 static inline bool samsung_pll35xx_mp_change(
194                 const struct samsung_pll_rate_table *rate, u32 pll_con)
195 {
196         u32 old_mdiv, old_pdiv;
197
198         old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
199         old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
200
201         return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
202 }
203
204 static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
205                                         unsigned long prate)
206 {
207         struct samsung_clk_pll *pll = to_clk_pll(hw);
208         const struct samsung_pll_rate_table *rate;
209         u32 tmp;
210
211         /* Get required rate settings from table */
212         rate = samsung_get_pll_settings(pll, drate);
213         if (!rate) {
214                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
215                         drate, clk_hw_get_name(hw));
216                 return -EINVAL;
217         }
218
219         tmp = readl_relaxed(pll->con_reg);
220
221         if (!(samsung_pll35xx_mp_change(rate, tmp))) {
222                 /* If only s change, change just s value only*/
223                 tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
224                 tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
225                 writel_relaxed(tmp, pll->con_reg);
226
227                 return 0;
228         }
229
230         /* Set PLL lock time. */
231         writel_relaxed(rate->pdiv * PLL35XX_LOCK_FACTOR,
232                         pll->lock_reg);
233
234         /* Change PLL PMS values */
235         tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
236                         (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
237                         (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
238         tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
239                         (rate->pdiv << PLL35XX_PDIV_SHIFT) |
240                         (rate->sdiv << PLL35XX_SDIV_SHIFT);
241         writel_relaxed(tmp, pll->con_reg);
242
243         /* Wait until the PLL is locked if it is enabled. */
244         if (tmp & BIT(pll->enable_offs)) {
245                 do {
246                         cpu_relax();
247                         tmp = readl_relaxed(pll->con_reg);
248                 } while (!(tmp & BIT(pll->lock_offs)));
249         }
250         return 0;
251 }
252
253 static const struct clk_ops samsung_pll35xx_clk_ops = {
254         .recalc_rate = samsung_pll35xx_recalc_rate,
255         .round_rate = samsung_pll_round_rate,
256         .set_rate = samsung_pll35xx_set_rate,
257         .enable = samsung_pll3xxx_enable,
258         .disable = samsung_pll3xxx_disable,
259 };
260
261 static const struct clk_ops samsung_pll35xx_clk_min_ops = {
262         .recalc_rate = samsung_pll35xx_recalc_rate,
263 };
264
265 /*
266  * PLL36xx Clock Type
267  */
268 /* Maximum lock time can be 3000 * PDIV cycles */
269 #define PLL36XX_LOCK_FACTOR    (3000)
270
271 #define PLL36XX_KDIV_MASK       (0xFFFF)
272 #define PLL36XX_MDIV_MASK       (0x1FF)
273 #define PLL36XX_PDIV_MASK       (0x3F)
274 #define PLL36XX_SDIV_MASK       (0x7)
275 #define PLL36XX_MDIV_SHIFT      (16)
276 #define PLL36XX_PDIV_SHIFT      (8)
277 #define PLL36XX_SDIV_SHIFT      (0)
278 #define PLL36XX_KDIV_SHIFT      (0)
279 #define PLL36XX_LOCK_STAT_SHIFT (29)
280 #define PLL36XX_ENABLE_SHIFT    (31)
281
282 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
283                                 unsigned long parent_rate)
284 {
285         struct samsung_clk_pll *pll = to_clk_pll(hw);
286         u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
287         s16 kdiv;
288         u64 fvco = parent_rate;
289
290         pll_con0 = readl_relaxed(pll->con_reg);
291         pll_con1 = readl_relaxed(pll->con_reg + 4);
292         mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
293         pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
294         sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
295         kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK);
296
297         fvco *= (mdiv << 16) + kdiv;
298         do_div(fvco, (pdiv << sdiv));
299         fvco >>= 16;
300
301         return (unsigned long)fvco;
302 }
303
304 static inline bool samsung_pll36xx_mpk_change(
305         const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
306 {
307         u32 old_mdiv, old_pdiv, old_kdiv;
308
309         old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
310         old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
311         old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
312
313         return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
314                 rate->kdiv != old_kdiv);
315 }
316
317 static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
318                                         unsigned long parent_rate)
319 {
320         struct samsung_clk_pll *pll = to_clk_pll(hw);
321         u32 tmp, pll_con0, pll_con1;
322         const struct samsung_pll_rate_table *rate;
323
324         rate = samsung_get_pll_settings(pll, drate);
325         if (!rate) {
326                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
327                         drate, clk_hw_get_name(hw));
328                 return -EINVAL;
329         }
330
331         pll_con0 = readl_relaxed(pll->con_reg);
332         pll_con1 = readl_relaxed(pll->con_reg + 4);
333
334         if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
335                 /* If only s change, change just s value only*/
336                 pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
337                 pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
338                 writel_relaxed(pll_con0, pll->con_reg);
339
340                 return 0;
341         }
342
343         /* Set PLL lock time. */
344         writel_relaxed(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
345
346          /* Change PLL PMS values */
347         pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
348                         (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
349                         (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
350         pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
351                         (rate->pdiv << PLL36XX_PDIV_SHIFT) |
352                         (rate->sdiv << PLL36XX_SDIV_SHIFT);
353         writel_relaxed(pll_con0, pll->con_reg);
354
355         pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
356         pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
357         writel_relaxed(pll_con1, pll->con_reg + 4);
358
359         /* wait_lock_time */
360         if (pll_con0 & BIT(pll->enable_offs)) {
361                 do {
362                         cpu_relax();
363                         tmp = readl_relaxed(pll->con_reg);
364                 } while (!(tmp & BIT(pll->lock_offs)));
365         }
366
367         return 0;
368 }
369
370 static const struct clk_ops samsung_pll36xx_clk_ops = {
371         .recalc_rate = samsung_pll36xx_recalc_rate,
372         .set_rate = samsung_pll36xx_set_rate,
373         .round_rate = samsung_pll_round_rate,
374         .enable = samsung_pll3xxx_enable,
375         .disable = samsung_pll3xxx_disable,
376 };
377
378 static const struct clk_ops samsung_pll36xx_clk_min_ops = {
379         .recalc_rate = samsung_pll36xx_recalc_rate,
380 };
381
382 /*
383  * PLL45xx Clock Type
384  */
385 #define PLL4502_LOCK_FACTOR     400
386 #define PLL4508_LOCK_FACTOR     240
387
388 #define PLL45XX_MDIV_MASK       (0x3FF)
389 #define PLL45XX_PDIV_MASK       (0x3F)
390 #define PLL45XX_SDIV_MASK       (0x7)
391 #define PLL45XX_AFC_MASK        (0x1F)
392 #define PLL45XX_MDIV_SHIFT      (16)
393 #define PLL45XX_PDIV_SHIFT      (8)
394 #define PLL45XX_SDIV_SHIFT      (0)
395 #define PLL45XX_AFC_SHIFT       (0)
396
397 #define PLL45XX_ENABLE          BIT(31)
398 #define PLL45XX_LOCKED          BIT(29)
399
400 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
401                                 unsigned long parent_rate)
402 {
403         struct samsung_clk_pll *pll = to_clk_pll(hw);
404         u32 mdiv, pdiv, sdiv, pll_con;
405         u64 fvco = parent_rate;
406
407         pll_con = readl_relaxed(pll->con_reg);
408         mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
409         pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
410         sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
411
412         if (pll->type == pll_4508)
413                 sdiv = sdiv - 1;
414
415         fvco *= mdiv;
416         do_div(fvco, (pdiv << sdiv));
417
418         return (unsigned long)fvco;
419 }
420
421 static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
422                                 const struct samsung_pll_rate_table *rate)
423 {
424         u32 old_mdiv, old_pdiv, old_afc;
425
426         old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
427         old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
428         old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK;
429
430         return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
431                 || old_afc != rate->afc);
432 }
433
434 static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
435                                         unsigned long prate)
436 {
437         struct samsung_clk_pll *pll = to_clk_pll(hw);
438         const struct samsung_pll_rate_table *rate;
439         u32 con0, con1;
440         ktime_t start;
441
442         /* Get required rate settings from table */
443         rate = samsung_get_pll_settings(pll, drate);
444         if (!rate) {
445                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
446                         drate, clk_hw_get_name(hw));
447                 return -EINVAL;
448         }
449
450         con0 = readl_relaxed(pll->con_reg);
451         con1 = readl_relaxed(pll->con_reg + 0x4);
452
453         if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
454                 /* If only s change, change just s value only*/
455                 con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
456                 con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
457                 writel_relaxed(con0, pll->con_reg);
458
459                 return 0;
460         }
461
462         /* Set PLL PMS values. */
463         con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
464                         (PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
465                         (PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
466         con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) |
467                         (rate->pdiv << PLL45XX_PDIV_SHIFT) |
468                         (rate->sdiv << PLL45XX_SDIV_SHIFT);
469
470         /* Set PLL AFC value. */
471         con1 = readl_relaxed(pll->con_reg + 0x4);
472         con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
473         con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
474
475         /* Set PLL lock time. */
476         switch (pll->type) {
477         case pll_4502:
478                 writel_relaxed(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
479                 break;
480         case pll_4508:
481                 writel_relaxed(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
482                 break;
483         default:
484                 break;
485         }
486
487         /* Set new configuration. */
488         writel_relaxed(con1, pll->con_reg + 0x4);
489         writel_relaxed(con0, pll->con_reg);
490
491         /* Wait for locking. */
492         start = ktime_get();
493         while (!(readl_relaxed(pll->con_reg) & PLL45XX_LOCKED)) {
494                 ktime_t delta = ktime_sub(ktime_get(), start);
495
496                 if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
497                         pr_err("%s: could not lock PLL %s\n",
498                                         __func__, clk_hw_get_name(hw));
499                         return -EFAULT;
500                 }
501
502                 cpu_relax();
503         }
504
505         return 0;
506 }
507
508 static const struct clk_ops samsung_pll45xx_clk_ops = {
509         .recalc_rate = samsung_pll45xx_recalc_rate,
510         .round_rate = samsung_pll_round_rate,
511         .set_rate = samsung_pll45xx_set_rate,
512 };
513
514 static const struct clk_ops samsung_pll45xx_clk_min_ops = {
515         .recalc_rate = samsung_pll45xx_recalc_rate,
516 };
517
518 /*
519  * PLL46xx Clock Type
520  */
521 #define PLL46XX_LOCK_FACTOR     3000
522
523 #define PLL46XX_VSEL_MASK       (1)
524 #define PLL46XX_MDIV_MASK       (0x1FF)
525 #define PLL1460X_MDIV_MASK      (0x3FF)
526
527 #define PLL46XX_PDIV_MASK       (0x3F)
528 #define PLL46XX_SDIV_MASK       (0x7)
529 #define PLL46XX_VSEL_SHIFT      (27)
530 #define PLL46XX_MDIV_SHIFT      (16)
531 #define PLL46XX_PDIV_SHIFT      (8)
532 #define PLL46XX_SDIV_SHIFT      (0)
533
534 #define PLL46XX_KDIV_MASK       (0xFFFF)
535 #define PLL4650C_KDIV_MASK      (0xFFF)
536 #define PLL46XX_KDIV_SHIFT      (0)
537 #define PLL46XX_MFR_MASK        (0x3F)
538 #define PLL46XX_MRR_MASK        (0x1F)
539 #define PLL46XX_KDIV_SHIFT      (0)
540 #define PLL46XX_MFR_SHIFT       (16)
541 #define PLL46XX_MRR_SHIFT       (24)
542
543 #define PLL46XX_ENABLE          BIT(31)
544 #define PLL46XX_LOCKED          BIT(29)
545 #define PLL46XX_VSEL            BIT(27)
546
547 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
548                                 unsigned long parent_rate)
549 {
550         struct samsung_clk_pll *pll = to_clk_pll(hw);
551         u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
552         u64 fvco = parent_rate;
553
554         pll_con0 = readl_relaxed(pll->con_reg);
555         pll_con1 = readl_relaxed(pll->con_reg + 4);
556         mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & ((pll->type == pll_1460x) ?
557                                 PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK);
558         pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
559         sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
560         kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
561                                         pll_con1 & PLL46XX_KDIV_MASK;
562
563         shift = ((pll->type == pll_4600) || (pll->type == pll_1460x)) ? 16 : 10;
564
565         fvco *= (mdiv << shift) + kdiv;
566         do_div(fvco, (pdiv << sdiv));
567         fvco >>= shift;
568
569         return (unsigned long)fvco;
570 }
571
572 static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
573                                 const struct samsung_pll_rate_table *rate)
574 {
575         u32 old_mdiv, old_pdiv, old_kdiv;
576
577         old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
578         old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
579         old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
580
581         return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
582                 || old_kdiv != rate->kdiv);
583 }
584
585 static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
586                                         unsigned long prate)
587 {
588         struct samsung_clk_pll *pll = to_clk_pll(hw);
589         const struct samsung_pll_rate_table *rate;
590         u32 con0, con1, lock;
591         ktime_t start;
592
593         /* Get required rate settings from table */
594         rate = samsung_get_pll_settings(pll, drate);
595         if (!rate) {
596                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
597                         drate, clk_hw_get_name(hw));
598                 return -EINVAL;
599         }
600
601         con0 = readl_relaxed(pll->con_reg);
602         con1 = readl_relaxed(pll->con_reg + 0x4);
603
604         if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
605                 /* If only s change, change just s value only*/
606                 con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
607                 con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
608                 writel_relaxed(con0, pll->con_reg);
609
610                 return 0;
611         }
612
613         /* Set PLL lock time. */
614         lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
615         if (lock > 0xffff)
616                 /* Maximum lock time bitfield is 16-bit. */
617                 lock = 0xffff;
618
619         /* Set PLL PMS and VSEL values. */
620         if (pll->type == pll_1460x) {
621                 con0 &= ~((PLL1460X_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
622                         (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
623                         (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT));
624         } else {
625                 con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
626                         (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
627                         (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
628                         (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
629                 con0 |= rate->vsel << PLL46XX_VSEL_SHIFT;
630         }
631
632         con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
633                         (rate->pdiv << PLL46XX_PDIV_SHIFT) |
634                         (rate->sdiv << PLL46XX_SDIV_SHIFT);
635
636         /* Set PLL K, MFR and MRR values. */
637         con1 = readl_relaxed(pll->con_reg + 0x4);
638         con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
639                         (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
640                         (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
641         con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) |
642                         (rate->mfr << PLL46XX_MFR_SHIFT) |
643                         (rate->mrr << PLL46XX_MRR_SHIFT);
644
645         /* Write configuration to PLL */
646         writel_relaxed(lock, pll->lock_reg);
647         writel_relaxed(con0, pll->con_reg);
648         writel_relaxed(con1, pll->con_reg + 0x4);
649
650         /* Wait for locking. */
651         start = ktime_get();
652         while (!(readl_relaxed(pll->con_reg) & PLL46XX_LOCKED)) {
653                 ktime_t delta = ktime_sub(ktime_get(), start);
654
655                 if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
656                         pr_err("%s: could not lock PLL %s\n",
657                                         __func__, clk_hw_get_name(hw));
658                         return -EFAULT;
659                 }
660
661                 cpu_relax();
662         }
663
664         return 0;
665 }
666
667 static const struct clk_ops samsung_pll46xx_clk_ops = {
668         .recalc_rate = samsung_pll46xx_recalc_rate,
669         .round_rate = samsung_pll_round_rate,
670         .set_rate = samsung_pll46xx_set_rate,
671 };
672
673 static const struct clk_ops samsung_pll46xx_clk_min_ops = {
674         .recalc_rate = samsung_pll46xx_recalc_rate,
675 };
676
677 /*
678  * PLL6552 Clock Type
679  */
680
681 #define PLL6552_MDIV_MASK       0x3ff
682 #define PLL6552_PDIV_MASK       0x3f
683 #define PLL6552_SDIV_MASK       0x7
684 #define PLL6552_MDIV_SHIFT      16
685 #define PLL6552_MDIV_SHIFT_2416 14
686 #define PLL6552_PDIV_SHIFT      8
687 #define PLL6552_PDIV_SHIFT_2416 5
688 #define PLL6552_SDIV_SHIFT      0
689
690 static unsigned long samsung_pll6552_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, pll_con;
695         u64 fvco = parent_rate;
696
697         pll_con = readl_relaxed(pll->con_reg);
698         if (pll->type == pll_6552_s3c2416) {
699                 mdiv = (pll_con >> PLL6552_MDIV_SHIFT_2416) & PLL6552_MDIV_MASK;
700                 pdiv = (pll_con >> PLL6552_PDIV_SHIFT_2416) & PLL6552_PDIV_MASK;
701         } else {
702                 mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
703                 pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
704         }
705         sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
706
707         fvco *= mdiv;
708         do_div(fvco, (pdiv << sdiv));
709
710         return (unsigned long)fvco;
711 }
712
713 static const struct clk_ops samsung_pll6552_clk_ops = {
714         .recalc_rate = samsung_pll6552_recalc_rate,
715 };
716
717 /*
718  * PLL6553 Clock Type
719  */
720
721 #define PLL6553_MDIV_MASK       0xff
722 #define PLL6553_PDIV_MASK       0x3f
723 #define PLL6553_SDIV_MASK       0x7
724 #define PLL6553_KDIV_MASK       0xffff
725 #define PLL6553_MDIV_SHIFT      16
726 #define PLL6553_PDIV_SHIFT      8
727 #define PLL6553_SDIV_SHIFT      0
728 #define PLL6553_KDIV_SHIFT      0
729
730 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
731                                                 unsigned long parent_rate)
732 {
733         struct samsung_clk_pll *pll = to_clk_pll(hw);
734         u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
735         u64 fvco = parent_rate;
736
737         pll_con0 = readl_relaxed(pll->con_reg);
738         pll_con1 = readl_relaxed(pll->con_reg + 0x4);
739         mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
740         pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
741         sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
742         kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
743
744         fvco *= (mdiv << 16) + kdiv;
745         do_div(fvco, (pdiv << sdiv));
746         fvco >>= 16;
747
748         return (unsigned long)fvco;
749 }
750
751 static const struct clk_ops samsung_pll6553_clk_ops = {
752         .recalc_rate = samsung_pll6553_recalc_rate,
753 };
754
755 /*
756  * PLL Clock Type of S3C24XX before S3C2443
757  */
758
759 #define PLLS3C2410_MDIV_MASK            (0xff)
760 #define PLLS3C2410_PDIV_MASK            (0x1f)
761 #define PLLS3C2410_SDIV_MASK            (0x3)
762 #define PLLS3C2410_MDIV_SHIFT           (12)
763 #define PLLS3C2410_PDIV_SHIFT           (4)
764 #define PLLS3C2410_SDIV_SHIFT           (0)
765
766 #define PLLS3C2410_ENABLE_REG_OFFSET    0x10
767
768 static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw *hw,
769                                         unsigned long parent_rate)
770 {
771         struct samsung_clk_pll *pll = to_clk_pll(hw);
772         u32 pll_con, mdiv, pdiv, sdiv;
773         u64 fvco = parent_rate;
774
775         pll_con = readl_relaxed(pll->con_reg);
776         mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
777         pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
778         sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
779
780         fvco *= (mdiv + 8);
781         do_div(fvco, (pdiv + 2) << sdiv);
782
783         return (unsigned int)fvco;
784 }
785
786 static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw *hw,
787                                         unsigned long parent_rate)
788 {
789         struct samsung_clk_pll *pll = to_clk_pll(hw);
790         u32 pll_con, mdiv, pdiv, sdiv;
791         u64 fvco = parent_rate;
792
793         pll_con = readl_relaxed(pll->con_reg);
794         mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
795         pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
796         sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
797
798         fvco *= (2 * (mdiv + 8));
799         do_div(fvco, (pdiv + 2) << sdiv);
800
801         return (unsigned int)fvco;
802 }
803
804 static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
805                                         unsigned long prate)
806 {
807         struct samsung_clk_pll *pll = to_clk_pll(hw);
808         const struct samsung_pll_rate_table *rate;
809         u32 tmp;
810
811         /* Get required rate settings from table */
812         rate = samsung_get_pll_settings(pll, drate);
813         if (!rate) {
814                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
815                         drate, clk_hw_get_name(hw));
816                 return -EINVAL;
817         }
818
819         tmp = readl_relaxed(pll->con_reg);
820
821         /* Change PLL PMS values */
822         tmp &= ~((PLLS3C2410_MDIV_MASK << PLLS3C2410_MDIV_SHIFT) |
823                         (PLLS3C2410_PDIV_MASK << PLLS3C2410_PDIV_SHIFT) |
824                         (PLLS3C2410_SDIV_MASK << PLLS3C2410_SDIV_SHIFT));
825         tmp |= (rate->mdiv << PLLS3C2410_MDIV_SHIFT) |
826                         (rate->pdiv << PLLS3C2410_PDIV_SHIFT) |
827                         (rate->sdiv << PLLS3C2410_SDIV_SHIFT);
828         writel_relaxed(tmp, pll->con_reg);
829
830         /* Time to settle according to the manual */
831         udelay(300);
832
833         return 0;
834 }
835
836 static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable)
837 {
838         struct samsung_clk_pll *pll = to_clk_pll(hw);
839         u32 pll_en = readl_relaxed(pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
840         u32 pll_en_orig = pll_en;
841
842         if (enable)
843                 pll_en &= ~BIT(bit);
844         else
845                 pll_en |= BIT(bit);
846
847         writel_relaxed(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
848
849         /* if we started the UPLL, then allow to settle */
850         if (enable && (pll_en_orig & BIT(bit)))
851                 udelay(300);
852
853         return 0;
854 }
855
856 static int samsung_s3c2410_mpll_enable(struct clk_hw *hw)
857 {
858         return samsung_s3c2410_pll_enable(hw, 5, true);
859 }
860
861 static void samsung_s3c2410_mpll_disable(struct clk_hw *hw)
862 {
863         samsung_s3c2410_pll_enable(hw, 5, false);
864 }
865
866 static int samsung_s3c2410_upll_enable(struct clk_hw *hw)
867 {
868         return samsung_s3c2410_pll_enable(hw, 7, true);
869 }
870
871 static void samsung_s3c2410_upll_disable(struct clk_hw *hw)
872 {
873         samsung_s3c2410_pll_enable(hw, 7, false);
874 }
875
876 static const struct clk_ops samsung_s3c2410_mpll_clk_min_ops = {
877         .recalc_rate = samsung_s3c2410_pll_recalc_rate,
878         .enable = samsung_s3c2410_mpll_enable,
879         .disable = samsung_s3c2410_mpll_disable,
880 };
881
882 static const struct clk_ops samsung_s3c2410_upll_clk_min_ops = {
883         .recalc_rate = samsung_s3c2410_pll_recalc_rate,
884         .enable = samsung_s3c2410_upll_enable,
885         .disable = samsung_s3c2410_upll_disable,
886 };
887
888 static const struct clk_ops samsung_s3c2440_mpll_clk_min_ops = {
889         .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
890         .enable = samsung_s3c2410_mpll_enable,
891         .disable = samsung_s3c2410_mpll_disable,
892 };
893
894 static const struct clk_ops samsung_s3c2410_mpll_clk_ops = {
895         .recalc_rate = samsung_s3c2410_pll_recalc_rate,
896         .enable = samsung_s3c2410_mpll_enable,
897         .disable = samsung_s3c2410_mpll_disable,
898         .round_rate = samsung_pll_round_rate,
899         .set_rate = samsung_s3c2410_pll_set_rate,
900 };
901
902 static const struct clk_ops samsung_s3c2410_upll_clk_ops = {
903         .recalc_rate = samsung_s3c2410_pll_recalc_rate,
904         .enable = samsung_s3c2410_upll_enable,
905         .disable = samsung_s3c2410_upll_disable,
906         .round_rate = samsung_pll_round_rate,
907         .set_rate = samsung_s3c2410_pll_set_rate,
908 };
909
910 static const struct clk_ops samsung_s3c2440_mpll_clk_ops = {
911         .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
912         .enable = samsung_s3c2410_mpll_enable,
913         .disable = samsung_s3c2410_mpll_disable,
914         .round_rate = samsung_pll_round_rate,
915         .set_rate = samsung_s3c2410_pll_set_rate,
916 };
917
918 /*
919  * PLL2550x Clock Type
920  */
921
922 #define PLL2550X_R_MASK       (0x1)
923 #define PLL2550X_P_MASK       (0x3F)
924 #define PLL2550X_M_MASK       (0x3FF)
925 #define PLL2550X_S_MASK       (0x7)
926 #define PLL2550X_R_SHIFT      (20)
927 #define PLL2550X_P_SHIFT      (14)
928 #define PLL2550X_M_SHIFT      (4)
929 #define PLL2550X_S_SHIFT      (0)
930
931 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
932                                 unsigned long parent_rate)
933 {
934         struct samsung_clk_pll *pll = to_clk_pll(hw);
935         u32 r, p, m, s, pll_stat;
936         u64 fvco = parent_rate;
937
938         pll_stat = readl_relaxed(pll->con_reg);
939         r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
940         if (!r)
941                 return 0;
942         p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK;
943         m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK;
944         s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK;
945
946         fvco *= m;
947         do_div(fvco, (p << s));
948
949         return (unsigned long)fvco;
950 }
951
952 static const struct clk_ops samsung_pll2550x_clk_ops = {
953         .recalc_rate = samsung_pll2550x_recalc_rate,
954 };
955
956 /*
957  * PLL2550xx Clock Type
958  */
959
960 /* Maximum lock time can be 270 * PDIV cycles */
961 #define PLL2550XX_LOCK_FACTOR 270
962
963 #define PLL2550XX_M_MASK                0x3FF
964 #define PLL2550XX_P_MASK                0x3F
965 #define PLL2550XX_S_MASK                0x7
966 #define PLL2550XX_LOCK_STAT_MASK        0x1
967 #define PLL2550XX_M_SHIFT               9
968 #define PLL2550XX_P_SHIFT               3
969 #define PLL2550XX_S_SHIFT               0
970 #define PLL2550XX_LOCK_STAT_SHIFT       21
971
972 static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw *hw,
973                                 unsigned long parent_rate)
974 {
975         struct samsung_clk_pll *pll = to_clk_pll(hw);
976         u32 mdiv, pdiv, sdiv, pll_con;
977         u64 fvco = parent_rate;
978
979         pll_con = readl_relaxed(pll->con_reg);
980         mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
981         pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
982         sdiv = (pll_con >> PLL2550XX_S_SHIFT) & PLL2550XX_S_MASK;
983
984         fvco *= mdiv;
985         do_div(fvco, (pdiv << sdiv));
986
987         return (unsigned long)fvco;
988 }
989
990 static inline bool samsung_pll2550xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con)
991 {
992         u32 old_mdiv, old_pdiv;
993
994         old_mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
995         old_pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
996
997         return mdiv != old_mdiv || pdiv != old_pdiv;
998 }
999
1000 static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
1001                                         unsigned long prate)
1002 {
1003         struct samsung_clk_pll *pll = to_clk_pll(hw);
1004         const struct samsung_pll_rate_table *rate;
1005         u32 tmp;
1006
1007         /* Get required rate settings from table */
1008         rate = samsung_get_pll_settings(pll, drate);
1009         if (!rate) {
1010                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1011                         drate, clk_hw_get_name(hw));
1012                 return -EINVAL;
1013         }
1014
1015         tmp = readl_relaxed(pll->con_reg);
1016
1017         if (!(samsung_pll2550xx_mp_change(rate->mdiv, rate->pdiv, tmp))) {
1018                 /* If only s change, change just s value only*/
1019                 tmp &= ~(PLL2550XX_S_MASK << PLL2550XX_S_SHIFT);
1020                 tmp |= rate->sdiv << PLL2550XX_S_SHIFT;
1021                 writel_relaxed(tmp, pll->con_reg);
1022
1023                 return 0;
1024         }
1025
1026         /* Set PLL lock time. */
1027         writel_relaxed(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg);
1028
1029         /* Change PLL PMS values */
1030         tmp &= ~((PLL2550XX_M_MASK << PLL2550XX_M_SHIFT) |
1031                         (PLL2550XX_P_MASK << PLL2550XX_P_SHIFT) |
1032                         (PLL2550XX_S_MASK << PLL2550XX_S_SHIFT));
1033         tmp |= (rate->mdiv << PLL2550XX_M_SHIFT) |
1034                         (rate->pdiv << PLL2550XX_P_SHIFT) |
1035                         (rate->sdiv << PLL2550XX_S_SHIFT);
1036         writel_relaxed(tmp, pll->con_reg);
1037
1038         /* wait_lock_time */
1039         do {
1040                 cpu_relax();
1041                 tmp = readl_relaxed(pll->con_reg);
1042         } while (!(tmp & (PLL2550XX_LOCK_STAT_MASK
1043                         << PLL2550XX_LOCK_STAT_SHIFT)));
1044
1045         return 0;
1046 }
1047
1048 static const struct clk_ops samsung_pll2550xx_clk_ops = {
1049         .recalc_rate = samsung_pll2550xx_recalc_rate,
1050         .round_rate = samsung_pll_round_rate,
1051         .set_rate = samsung_pll2550xx_set_rate,
1052 };
1053
1054 static const struct clk_ops samsung_pll2550xx_clk_min_ops = {
1055         .recalc_rate = samsung_pll2550xx_recalc_rate,
1056 };
1057
1058 /*
1059  * PLL2650x Clock Type
1060  */
1061
1062 /* Maximum lock time can be 3000 * PDIV cycles */
1063 #define PLL2650X_LOCK_FACTOR            3000
1064
1065 #define PLL2650X_M_MASK                 0x1ff
1066 #define PLL2650X_P_MASK                 0x3f
1067 #define PLL2650X_S_MASK                 0x7
1068 #define PLL2650X_K_MASK                 0xffff
1069 #define PLL2650X_LOCK_STAT_MASK         0x1
1070 #define PLL2650X_M_SHIFT                16
1071 #define PLL2650X_P_SHIFT                8
1072 #define PLL2650X_S_SHIFT                0
1073 #define PLL2650X_K_SHIFT                0
1074 #define PLL2650X_LOCK_STAT_SHIFT        29
1075 #define PLL2650X_PLL_ENABLE_SHIFT       31
1076
1077 static unsigned long samsung_pll2650x_recalc_rate(struct clk_hw *hw,
1078                                 unsigned long parent_rate)
1079 {
1080         struct samsung_clk_pll *pll = to_clk_pll(hw);
1081         u64 fout = parent_rate;
1082         u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
1083         s16 kdiv;
1084
1085         pll_con0 = readl_relaxed(pll->con_reg);
1086         mdiv = (pll_con0 >> PLL2650X_M_SHIFT) & PLL2650X_M_MASK;
1087         pdiv = (pll_con0 >> PLL2650X_P_SHIFT) & PLL2650X_P_MASK;
1088         sdiv = (pll_con0 >> PLL2650X_S_SHIFT) & PLL2650X_S_MASK;
1089
1090         pll_con1 = readl_relaxed(pll->con_reg + 4);
1091         kdiv = (s16)((pll_con1 >> PLL2650X_K_SHIFT) & PLL2650X_K_MASK);
1092
1093         fout *= (mdiv << 16) + kdiv;
1094         do_div(fout, (pdiv << sdiv));
1095         fout >>= 16;
1096
1097         return (unsigned long)fout;
1098 }
1099
1100 static int samsung_pll2650x_set_rate(struct clk_hw *hw, unsigned long drate,
1101                                         unsigned long prate)
1102 {
1103         struct samsung_clk_pll *pll = to_clk_pll(hw);
1104         const struct samsung_pll_rate_table *rate;
1105         u32 con0, con1;
1106
1107         /* Get required rate settings from table */
1108         rate = samsung_get_pll_settings(pll, drate);
1109         if (!rate) {
1110                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1111                         drate, clk_hw_get_name(hw));
1112                 return -EINVAL;
1113         }
1114
1115         con0 = readl_relaxed(pll->con_reg);
1116         con1 = readl_relaxed(pll->con_reg + 4);
1117
1118         /* Set PLL lock time. */
1119         writel_relaxed(rate->pdiv * PLL2650X_LOCK_FACTOR, pll->lock_reg);
1120
1121         /* Change PLL PMS values */
1122         con0 &= ~((PLL2650X_M_MASK << PLL2650X_M_SHIFT) |
1123                         (PLL2650X_P_MASK << PLL2650X_P_SHIFT) |
1124                         (PLL2650X_S_MASK << PLL2650X_S_SHIFT));
1125         con0 |= (rate->mdiv << PLL2650X_M_SHIFT) |
1126                         (rate->pdiv << PLL2650X_P_SHIFT) |
1127                         (rate->sdiv << PLL2650X_S_SHIFT);
1128         con0 |= (1 << PLL2650X_PLL_ENABLE_SHIFT);
1129         writel_relaxed(con0, pll->con_reg);
1130
1131         con1 &= ~(PLL2650X_K_MASK << PLL2650X_K_SHIFT);
1132         con1 |= ((rate->kdiv & PLL2650X_K_MASK) << PLL2650X_K_SHIFT);
1133         writel_relaxed(con1, pll->con_reg + 4);
1134
1135         do {
1136                 cpu_relax();
1137                 con0 = readl_relaxed(pll->con_reg);
1138         } while (!(con0 & (PLL2650X_LOCK_STAT_MASK
1139                         << PLL2650X_LOCK_STAT_SHIFT)));
1140
1141         return 0;
1142 }
1143
1144 static const struct clk_ops samsung_pll2650x_clk_ops = {
1145         .recalc_rate = samsung_pll2650x_recalc_rate,
1146         .round_rate = samsung_pll_round_rate,
1147         .set_rate = samsung_pll2650x_set_rate,
1148 };
1149
1150 static const struct clk_ops samsung_pll2650x_clk_min_ops = {
1151         .recalc_rate = samsung_pll2650x_recalc_rate,
1152 };
1153
1154 /*
1155  * PLL2650XX Clock Type
1156  */
1157
1158 /* Maximum lock time can be 3000 * PDIV cycles */
1159 #define PLL2650XX_LOCK_FACTOR 3000
1160
1161 #define PLL2650XX_MDIV_SHIFT            9
1162 #define PLL2650XX_PDIV_SHIFT            3
1163 #define PLL2650XX_SDIV_SHIFT            0
1164 #define PLL2650XX_KDIV_SHIFT            0
1165 #define PLL2650XX_MDIV_MASK             0x1ff
1166 #define PLL2650XX_PDIV_MASK             0x3f
1167 #define PLL2650XX_SDIV_MASK             0x7
1168 #define PLL2650XX_KDIV_MASK             0xffff
1169 #define PLL2650XX_PLL_ENABLE_SHIFT      23
1170 #define PLL2650XX_PLL_LOCKTIME_SHIFT    21
1171 #define PLL2650XX_PLL_FOUTMASK_SHIFT    31
1172
1173 static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw,
1174                                 unsigned long parent_rate)
1175 {
1176         struct samsung_clk_pll *pll = to_clk_pll(hw);
1177         u32 mdiv, pdiv, sdiv, pll_con0, pll_con2;
1178         s16 kdiv;
1179         u64 fvco = parent_rate;
1180
1181         pll_con0 = readl_relaxed(pll->con_reg);
1182         pll_con2 = readl_relaxed(pll->con_reg + 8);
1183         mdiv = (pll_con0 >> PLL2650XX_MDIV_SHIFT) & PLL2650XX_MDIV_MASK;
1184         pdiv = (pll_con0 >> PLL2650XX_PDIV_SHIFT) & PLL2650XX_PDIV_MASK;
1185         sdiv = (pll_con0 >> PLL2650XX_SDIV_SHIFT) & PLL2650XX_SDIV_MASK;
1186         kdiv = (s16)(pll_con2 & PLL2650XX_KDIV_MASK);
1187
1188         fvco *= (mdiv << 16) + kdiv;
1189         do_div(fvco, (pdiv << sdiv));
1190         fvco >>= 16;
1191
1192         return (unsigned long)fvco;
1193 }
1194
1195 static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
1196                                         unsigned long parent_rate)
1197 {
1198         struct samsung_clk_pll *pll = to_clk_pll(hw);
1199         u32 tmp, pll_con0, pll_con2;
1200         const struct samsung_pll_rate_table *rate;
1201
1202         rate = samsung_get_pll_settings(pll, drate);
1203         if (!rate) {
1204                 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1205                         drate, clk_hw_get_name(hw));
1206                 return -EINVAL;
1207         }
1208
1209         pll_con0 = readl_relaxed(pll->con_reg);
1210         pll_con2 = readl_relaxed(pll->con_reg + 8);
1211
1212          /* Change PLL PMS values */
1213         pll_con0 &= ~(PLL2650XX_MDIV_MASK << PLL2650XX_MDIV_SHIFT |
1214                         PLL2650XX_PDIV_MASK << PLL2650XX_PDIV_SHIFT |
1215                         PLL2650XX_SDIV_MASK << PLL2650XX_SDIV_SHIFT);
1216         pll_con0 |= rate->mdiv << PLL2650XX_MDIV_SHIFT;
1217         pll_con0 |= rate->pdiv << PLL2650XX_PDIV_SHIFT;
1218         pll_con0 |= rate->sdiv << PLL2650XX_SDIV_SHIFT;
1219         pll_con0 |= 1 << PLL2650XX_PLL_ENABLE_SHIFT;
1220         pll_con0 |= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT;
1221
1222         pll_con2 &= ~(PLL2650XX_KDIV_MASK << PLL2650XX_KDIV_SHIFT);
1223         pll_con2 |= ((~(rate->kdiv) + 1) & PLL2650XX_KDIV_MASK)
1224                         << PLL2650XX_KDIV_SHIFT;
1225
1226         /* Set PLL lock time. */
1227         writel_relaxed(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg);
1228
1229         writel_relaxed(pll_con0, pll->con_reg);
1230         writel_relaxed(pll_con2, pll->con_reg + 8);
1231
1232         do {
1233                 tmp = readl_relaxed(pll->con_reg);
1234         } while (!(tmp & (0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT)));
1235
1236         return 0;
1237 }
1238
1239 static const struct clk_ops samsung_pll2650xx_clk_ops = {
1240         .recalc_rate = samsung_pll2650xx_recalc_rate,
1241         .set_rate = samsung_pll2650xx_set_rate,
1242         .round_rate = samsung_pll_round_rate,
1243 };
1244
1245 static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
1246         .recalc_rate = samsung_pll2650xx_recalc_rate,
1247 };
1248
1249 static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1250                                 const struct samsung_pll_clock *pll_clk,
1251                                 void __iomem *base)
1252 {
1253         struct samsung_clk_pll *pll;
1254         struct clk_init_data init;
1255         int ret, len;
1256
1257         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
1258         if (!pll) {
1259                 pr_err("%s: could not allocate pll clk %s\n",
1260                         __func__, pll_clk->name);
1261                 return;
1262         }
1263
1264         init.name = pll_clk->name;
1265         init.flags = pll_clk->flags;
1266         init.parent_names = &pll_clk->parent_name;
1267         init.num_parents = 1;
1268
1269         if (pll_clk->rate_table) {
1270                 /* find count of rates in rate_table */
1271                 for (len = 0; pll_clk->rate_table[len].rate != 0; )
1272                         len++;
1273
1274                 pll->rate_count = len;
1275                 pll->rate_table = kmemdup(pll_clk->rate_table,
1276                                         pll->rate_count *
1277                                         sizeof(struct samsung_pll_rate_table),
1278                                         GFP_KERNEL);
1279                 WARN(!pll->rate_table,
1280                         "%s: could not allocate rate table for %s\n",
1281                         __func__, pll_clk->name);
1282         }
1283
1284         switch (pll_clk->type) {
1285         case pll_2126:
1286                 init.ops = &samsung_pll2126_clk_ops;
1287                 break;
1288         case pll_3000:
1289                 init.ops = &samsung_pll3000_clk_ops;
1290                 break;
1291         /* clk_ops for 35xx and 2550 are similar */
1292         case pll_35xx:
1293         case pll_2550:
1294         case pll_1450x:
1295         case pll_1451x:
1296         case pll_1452x:
1297                 pll->enable_offs = PLL35XX_ENABLE_SHIFT;
1298                 pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
1299                 if (!pll->rate_table)
1300                         init.ops = &samsung_pll35xx_clk_min_ops;
1301                 else
1302                         init.ops = &samsung_pll35xx_clk_ops;
1303                 break;
1304         case pll_4500:
1305                 init.ops = &samsung_pll45xx_clk_min_ops;
1306                 break;
1307         case pll_4502:
1308         case pll_4508:
1309                 if (!pll->rate_table)
1310                         init.ops = &samsung_pll45xx_clk_min_ops;
1311                 else
1312                         init.ops = &samsung_pll45xx_clk_ops;
1313                 break;
1314         /* clk_ops for 36xx and 2650 are similar */
1315         case pll_36xx:
1316         case pll_2650:
1317                 pll->enable_offs = PLL36XX_ENABLE_SHIFT;
1318                 pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT;
1319                 if (!pll->rate_table)
1320                         init.ops = &samsung_pll36xx_clk_min_ops;
1321                 else
1322                         init.ops = &samsung_pll36xx_clk_ops;
1323                 break;
1324         case pll_6552:
1325         case pll_6552_s3c2416:
1326                 init.ops = &samsung_pll6552_clk_ops;
1327                 break;
1328         case pll_6553:
1329                 init.ops = &samsung_pll6553_clk_ops;
1330                 break;
1331         case pll_4600:
1332         case pll_4650:
1333         case pll_4650c:
1334         case pll_1460x:
1335                 if (!pll->rate_table)
1336                         init.ops = &samsung_pll46xx_clk_min_ops;
1337                 else
1338                         init.ops = &samsung_pll46xx_clk_ops;
1339                 break;
1340         case pll_s3c2410_mpll:
1341                 if (!pll->rate_table)
1342                         init.ops = &samsung_s3c2410_mpll_clk_min_ops;
1343                 else
1344                         init.ops = &samsung_s3c2410_mpll_clk_ops;
1345                 break;
1346         case pll_s3c2410_upll:
1347                 if (!pll->rate_table)
1348                         init.ops = &samsung_s3c2410_upll_clk_min_ops;
1349                 else
1350                         init.ops = &samsung_s3c2410_upll_clk_ops;
1351                 break;
1352         case pll_s3c2440_mpll:
1353                 if (!pll->rate_table)
1354                         init.ops = &samsung_s3c2440_mpll_clk_min_ops;
1355                 else
1356                         init.ops = &samsung_s3c2440_mpll_clk_ops;
1357                 break;
1358         case pll_2550x:
1359                 init.ops = &samsung_pll2550x_clk_ops;
1360                 break;
1361         case pll_2550xx:
1362                 if (!pll->rate_table)
1363                         init.ops = &samsung_pll2550xx_clk_min_ops;
1364                 else
1365                         init.ops = &samsung_pll2550xx_clk_ops;
1366                 break;
1367         case pll_2650x:
1368                 if (!pll->rate_table)
1369                         init.ops = &samsung_pll2650x_clk_min_ops;
1370                 else
1371                         init.ops = &samsung_pll2650x_clk_ops;
1372                 break;
1373         case pll_2650xx:
1374                 if (!pll->rate_table)
1375                         init.ops = &samsung_pll2650xx_clk_min_ops;
1376                 else
1377                         init.ops = &samsung_pll2650xx_clk_ops;
1378                 break;
1379         default:
1380                 pr_warn("%s: Unknown pll type for pll clk %s\n",
1381                         __func__, pll_clk->name);
1382         }
1383
1384         pll->hw.init = &init;
1385         pll->type = pll_clk->type;
1386         pll->lock_reg = base + pll_clk->lock_offset;
1387         pll->con_reg = base + pll_clk->con_offset;
1388
1389         ret = clk_hw_register(ctx->dev, &pll->hw);
1390         if (ret) {
1391                 pr_err("%s: failed to register pll clock %s : %d\n",
1392                         __func__, pll_clk->name, ret);
1393                 kfree(pll->rate_table);
1394                 kfree(pll);
1395                 return;
1396         }
1397
1398         samsung_clk_add_lookup(ctx, &pll->hw, pll_clk->id);
1399 }
1400
1401 void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1402                         const struct samsung_pll_clock *pll_list,
1403                         unsigned int nr_pll, void __iomem *base)
1404 {
1405         int cnt;
1406
1407         for (cnt = 0; cnt < nr_pll; cnt++)
1408                 _samsung_clk_register_pll(ctx, &pll_list[cnt], base);
1409 }