Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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/iopoll.h>
12#include <linux/delay.h>
13#include <linux/slab.h>
14#include <linux/clk-provider.h>
15#include <linux/io.h>
16#include "clk.h"
17#include "clk-pll.h"
18
19#define PLL_TIMEOUT_LOOPS 20000U
20
21struct samsung_clk_pll {
22 struct clk_hw hw;
23 void __iomem *lock_reg;
24 void __iomem *con_reg;
25 /* PLL enable control bit offset in @con_reg register */
26 unsigned short enable_offs;
27 /* PLL lock status bit offset in @con_reg register */
28 unsigned short lock_offs;
29 enum samsung_pll_type type;
30 unsigned int rate_count;
31 const struct samsung_pll_rate_table *rate_table;
32};
33
34#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
35
36static const struct samsung_pll_rate_table *samsung_get_pll_settings(
37 struct samsung_clk_pll *pll, unsigned long rate)
38{
39 const struct samsung_pll_rate_table *rate_table = pll->rate_table;
40 int i;
41
42 for (i = 0; i < pll->rate_count; i++) {
43 if (rate == rate_table[i].rate)
44 return &rate_table[i];
45 }
46
47 return NULL;
48}
49
50static int samsung_pll_determine_rate(struct clk_hw *hw,
51 struct clk_rate_request *req)
52{
53 struct samsung_clk_pll *pll = to_clk_pll(hw);
54 const struct samsung_pll_rate_table *rate_table = pll->rate_table;
55 int i;
56
57 /* Assuming rate_table is in descending order */
58 for (i = 0; i < pll->rate_count; i++) {
59 if (req->rate >= rate_table[i].rate) {
60 req->rate = rate_table[i].rate;
61
62 return 0;
63 }
64 }
65
66 /* return minimum supported value */
67 req->rate = rate_table[i - 1].rate;
68
69 return 0;
70}
71
72/* Wait until the PLL is locked */
73static int samsung_pll_lock_wait(struct samsung_clk_pll *pll,
74 unsigned int reg_mask)
75{
76 int ret;
77 u32 val;
78
79 /*
80 * This function might be called when the timekeeping API can't be used
81 * to detect timeouts. One situation is when the clocksource is not yet
82 * initialized, another when the timekeeping is suspended. udelay() also
83 * cannot be used when the clocksource is not running on arm64, since
84 * the current timer is used as cycle counter. So a simple busy loop
85 * is used here.
86 * The limit of iterations has been derived from experimental
87 * measurements of various PLLs on multiple Exynos SoC variants. Single
88 * register read time was usually in range 0.4...1.5 us, never less than
89 * 0.4 us.
90 */
91 ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val,
92 val & reg_mask, 0,
93 PLL_TIMEOUT_LOOPS);
94 if (ret < 0)
95 pr_err("Could not lock PLL %s\n", clk_hw_get_name(&pll->hw));
96
97 return ret;
98}
99
100static int samsung_pll3xxx_enable(struct clk_hw *hw)
101{
102 struct samsung_clk_pll *pll = to_clk_pll(hw);
103 u32 tmp;
104
105 tmp = readl_relaxed(pll->con_reg);
106 tmp |= BIT(pll->enable_offs);
107 writel_relaxed(tmp, pll->con_reg);
108
109 return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
110}
111
112static void samsung_pll3xxx_disable(struct clk_hw *hw)
113{
114 struct samsung_clk_pll *pll = to_clk_pll(hw);
115 u32 tmp;
116
117 tmp = readl_relaxed(pll->con_reg);
118 tmp &= ~BIT(pll->enable_offs);
119 writel_relaxed(tmp, pll->con_reg);
120}
121
122/*
123 * PLL2126 Clock Type
124 */
125
126#define PLL2126_MDIV_MASK (0xff)
127#define PLL2126_PDIV_MASK (0x3f)
128#define PLL2126_SDIV_MASK (0x3)
129#define PLL2126_MDIV_SHIFT (16)
130#define PLL2126_PDIV_SHIFT (8)
131#define PLL2126_SDIV_SHIFT (0)
132
133static unsigned long samsung_pll2126_recalc_rate(struct clk_hw *hw,
134 unsigned long parent_rate)
135{
136 struct samsung_clk_pll *pll = to_clk_pll(hw);
137 u32 pll_con, mdiv, pdiv, sdiv;
138 u64 fvco = parent_rate;
139
140 pll_con = readl_relaxed(pll->con_reg);
141 mdiv = (pll_con >> PLL2126_MDIV_SHIFT) & PLL2126_MDIV_MASK;
142 pdiv = (pll_con >> PLL2126_PDIV_SHIFT) & PLL2126_PDIV_MASK;
143 sdiv = (pll_con >> PLL2126_SDIV_SHIFT) & PLL2126_SDIV_MASK;
144
145 fvco *= (mdiv + 8);
146 do_div(fvco, (pdiv + 2) << sdiv);
147
148 return (unsigned long)fvco;
149}
150
151static const struct clk_ops samsung_pll2126_clk_ops = {
152 .recalc_rate = samsung_pll2126_recalc_rate,
153};
154
155/*
156 * PLL3000 Clock Type
157 */
158
159#define PLL3000_MDIV_MASK (0xff)
160#define PLL3000_PDIV_MASK (0x3)
161#define PLL3000_SDIV_MASK (0x3)
162#define PLL3000_MDIV_SHIFT (16)
163#define PLL3000_PDIV_SHIFT (8)
164#define PLL3000_SDIV_SHIFT (0)
165
166static unsigned long samsung_pll3000_recalc_rate(struct clk_hw *hw,
167 unsigned long parent_rate)
168{
169 struct samsung_clk_pll *pll = to_clk_pll(hw);
170 u32 pll_con, mdiv, pdiv, sdiv;
171 u64 fvco = parent_rate;
172
173 pll_con = readl_relaxed(pll->con_reg);
174 mdiv = (pll_con >> PLL3000_MDIV_SHIFT) & PLL3000_MDIV_MASK;
175 pdiv = (pll_con >> PLL3000_PDIV_SHIFT) & PLL3000_PDIV_MASK;
176 sdiv = (pll_con >> PLL3000_SDIV_SHIFT) & PLL3000_SDIV_MASK;
177
178 fvco *= (2 * (mdiv + 8));
179 do_div(fvco, pdiv << sdiv);
180
181 return (unsigned long)fvco;
182}
183
184static const struct clk_ops samsung_pll3000_clk_ops = {
185 .recalc_rate = samsung_pll3000_recalc_rate,
186};
187
188/*
189 * PLL35xx Clock Type
190 */
191/* Maximum lock time can be 270 * PDIV cycles */
192#define PLL35XX_LOCK_FACTOR (270)
193#define PLL142XX_LOCK_FACTOR (150)
194
195#define PLL35XX_MDIV_MASK (0x3FF)
196#define PLL35XX_PDIV_MASK (0x3F)
197#define PLL35XX_SDIV_MASK (0x7)
198#define PLL35XX_MDIV_SHIFT (16)
199#define PLL35XX_PDIV_SHIFT (8)
200#define PLL35XX_SDIV_SHIFT (0)
201#define PLL35XX_LOCK_STAT_SHIFT (29)
202#define PLL35XX_ENABLE_SHIFT (31)
203
204/* A9FRACM is similar to PLL35xx, except that MDIV is bit different */
205#define PLLA9FRACM_MDIV_SHIFT (14)
206
207static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
208 unsigned long parent_rate)
209{
210 struct samsung_clk_pll *pll = to_clk_pll(hw);
211 u32 mdiv, pdiv, sdiv, pll_con;
212 u64 fvco = parent_rate;
213
214 pll_con = readl_relaxed(pll->con_reg);
215
216 if (pll->type == pll_a9fracm)
217 mdiv = (pll_con >> PLLA9FRACM_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
218 else
219 mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
220
221 pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
222 sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
223
224 fvco *= mdiv;
225 do_div(fvco, (pdiv << sdiv));
226
227 return (unsigned long)fvco;
228}
229
230static inline bool samsung_pll35xx_mp_change(u32 pll_type,
231 const struct samsung_pll_rate_table *rate, u32 pll_con)
232{
233 u32 old_mdiv, old_pdiv;
234
235 if (pll_type == pll_a9fracm)
236 old_mdiv = (pll_con >> PLLA9FRACM_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
237 else
238 old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
239 old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
240
241 return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
242}
243
244static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
245 unsigned long prate)
246{
247 struct samsung_clk_pll *pll = to_clk_pll(hw);
248 const struct samsung_pll_rate_table *rate;
249 u32 tmp;
250 u32 mdiv_shift;
251
252 if (pll->type == pll_a9fracm)
253 mdiv_shift = PLLA9FRACM_MDIV_SHIFT;
254 else
255 mdiv_shift = PLL35XX_MDIV_SHIFT;
256
257 /* Get required rate settings from table */
258 rate = samsung_get_pll_settings(pll, drate);
259 if (!rate) {
260 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
261 drate, clk_hw_get_name(hw));
262 return -EINVAL;
263 }
264
265 tmp = readl_relaxed(pll->con_reg);
266
267 if (!(samsung_pll35xx_mp_change(pll->type, rate, tmp))) {
268 /* If only s change, change just s value only*/
269 tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
270 tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
271 writel_relaxed(tmp, pll->con_reg);
272
273 return 0;
274 }
275
276 /* Set PLL lock time. */
277 if (pll->type == pll_142xx || pll->type == pll_1017x || pll->type == pll_a9fracm)
278 writel_relaxed(rate->pdiv * PLL142XX_LOCK_FACTOR,
279 pll->lock_reg);
280 else
281 writel_relaxed(rate->pdiv * PLL35XX_LOCK_FACTOR,
282 pll->lock_reg);
283
284 /* Change PLL PMS values */
285 tmp &= ~((PLL35XX_MDIV_MASK << mdiv_shift) |
286 (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
287 (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
288 tmp |= (rate->mdiv << mdiv_shift) |
289 (rate->pdiv << PLL35XX_PDIV_SHIFT) |
290 (rate->sdiv << PLL35XX_SDIV_SHIFT);
291 writel_relaxed(tmp, pll->con_reg);
292
293 /* Wait for PLL lock if the PLL is enabled */
294 if (tmp & BIT(pll->enable_offs))
295 return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
296
297 return 0;
298}
299
300static const struct clk_ops samsung_pll35xx_clk_ops = {
301 .recalc_rate = samsung_pll35xx_recalc_rate,
302 .determine_rate = samsung_pll_determine_rate,
303 .set_rate = samsung_pll35xx_set_rate,
304 .enable = samsung_pll3xxx_enable,
305 .disable = samsung_pll3xxx_disable,
306};
307
308static const struct clk_ops samsung_pll35xx_clk_min_ops = {
309 .recalc_rate = samsung_pll35xx_recalc_rate,
310};
311
312/*
313 * PLL36xx Clock Type
314 */
315/* Maximum lock time can be 3000 * PDIV cycles */
316#define PLL36XX_LOCK_FACTOR (3000)
317
318#define PLL36XX_KDIV_MASK (0xFFFF)
319#define PLL36XX_MDIV_MASK (0x1FF)
320#define PLL36XX_PDIV_MASK (0x3F)
321#define PLL36XX_SDIV_MASK (0x7)
322#define PLL36XX_MDIV_SHIFT (16)
323#define PLL36XX_PDIV_SHIFT (8)
324#define PLL36XX_SDIV_SHIFT (0)
325#define PLL36XX_KDIV_SHIFT (0)
326#define PLL36XX_LOCK_STAT_SHIFT (29)
327#define PLL36XX_ENABLE_SHIFT (31)
328
329static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
330 unsigned long parent_rate)
331{
332 struct samsung_clk_pll *pll = to_clk_pll(hw);
333 u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
334 s16 kdiv;
335 u64 fvco = parent_rate;
336
337 pll_con0 = readl_relaxed(pll->con_reg);
338 pll_con1 = readl_relaxed(pll->con_reg + 4);
339 mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
340 pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
341 sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
342 kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK);
343
344 fvco *= (mdiv << 16) + kdiv;
345 do_div(fvco, (pdiv << sdiv));
346 fvco >>= 16;
347
348 return (unsigned long)fvco;
349}
350
351static inline bool samsung_pll36xx_mpk_change(
352 const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
353{
354 u32 old_mdiv, old_pdiv, old_kdiv;
355
356 old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
357 old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
358 old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
359
360 return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
361 rate->kdiv != old_kdiv);
362}
363
364static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
365 unsigned long parent_rate)
366{
367 struct samsung_clk_pll *pll = to_clk_pll(hw);
368 u32 pll_con0, pll_con1;
369 const struct samsung_pll_rate_table *rate;
370
371 rate = samsung_get_pll_settings(pll, drate);
372 if (!rate) {
373 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
374 drate, clk_hw_get_name(hw));
375 return -EINVAL;
376 }
377
378 pll_con0 = readl_relaxed(pll->con_reg);
379 pll_con1 = readl_relaxed(pll->con_reg + 4);
380
381 if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
382 /* If only s change, change just s value only*/
383 pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
384 pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
385 writel_relaxed(pll_con0, pll->con_reg);
386
387 return 0;
388 }
389
390 /* Set PLL lock time. */
391 writel_relaxed(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
392
393 /* Change PLL PMS values */
394 pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
395 (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
396 (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
397 pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
398 (rate->pdiv << PLL36XX_PDIV_SHIFT) |
399 (rate->sdiv << PLL36XX_SDIV_SHIFT);
400 writel_relaxed(pll_con0, pll->con_reg);
401
402 pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
403 pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
404 writel_relaxed(pll_con1, pll->con_reg + 4);
405
406 if (pll_con0 & BIT(pll->enable_offs))
407 return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
408
409 return 0;
410}
411
412static const struct clk_ops samsung_pll36xx_clk_ops = {
413 .recalc_rate = samsung_pll36xx_recalc_rate,
414 .set_rate = samsung_pll36xx_set_rate,
415 .determine_rate = samsung_pll_determine_rate,
416 .enable = samsung_pll3xxx_enable,
417 .disable = samsung_pll3xxx_disable,
418};
419
420static const struct clk_ops samsung_pll36xx_clk_min_ops = {
421 .recalc_rate = samsung_pll36xx_recalc_rate,
422};
423
424/*
425 * PLL0822x Clock Type
426 */
427/* Maximum lock time can be 150 * PDIV cycles */
428#define PLL0822X_LOCK_FACTOR (150)
429
430#define PLL0822X_MDIV_MASK (0x3FF)
431#define PLL0822X_PDIV_MASK (0x3F)
432#define PLL0822X_SDIV_MASK (0x7)
433#define PLL0822X_MDIV_SHIFT (16)
434#define PLL0822X_PDIV_SHIFT (8)
435#define PLL0822X_SDIV_SHIFT (0)
436#define PLL0822X_LOCK_STAT_SHIFT (29)
437#define PLL0822X_ENABLE_SHIFT (31)
438
439/*
440 * PLL1418x, PLL0717x and PLL0718x are similar
441 * to PLL0822x, except that MDIV is one bit smaller
442 */
443#define PLL1418X_MDIV_MASK (0x1FF)
444
445static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
446 unsigned long parent_rate)
447{
448 struct samsung_clk_pll *pll = to_clk_pll(hw);
449 u32 mdiv, pdiv, sdiv, pll_con3;
450 u64 fvco = parent_rate;
451
452 pll_con3 = readl_relaxed(pll->con_reg);
453
454 if (pll->type != pll_1418x &&
455 pll->type != pll_0717x &&
456 pll->type != pll_0718x)
457 mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK;
458 else
459 mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL1418X_MDIV_MASK;
460
461 pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK;
462 sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK;
463
464 fvco *= mdiv;
465 if (pll->type == pll_0516x)
466 fvco *= 2;
467
468 do_div(fvco, (pdiv << sdiv));
469
470 return (unsigned long)fvco;
471}
472
473static int samsung_pll0822x_set_rate(struct clk_hw *hw, unsigned long drate,
474 unsigned long prate)
475{
476 const struct samsung_pll_rate_table *rate;
477 struct samsung_clk_pll *pll = to_clk_pll(hw);
478 u32 mdiv_mask, pll_con3;
479
480 if (pll->type != pll_1418x)
481 mdiv_mask = PLL0822X_MDIV_MASK;
482 else
483 mdiv_mask = PLL1418X_MDIV_MASK;
484
485 /* Get required rate settings from table */
486 rate = samsung_get_pll_settings(pll, drate);
487 if (!rate) {
488 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
489 drate, clk_hw_get_name(hw));
490 return -EINVAL;
491 }
492
493 /* Change PLL PMS values */
494 pll_con3 = readl_relaxed(pll->con_reg);
495 pll_con3 &= ~((mdiv_mask << PLL0822X_MDIV_SHIFT) |
496 (PLL0822X_PDIV_MASK << PLL0822X_PDIV_SHIFT) |
497 (PLL0822X_SDIV_MASK << PLL0822X_SDIV_SHIFT));
498 pll_con3 |= (rate->mdiv << PLL0822X_MDIV_SHIFT) |
499 (rate->pdiv << PLL0822X_PDIV_SHIFT) |
500 (rate->sdiv << PLL0822X_SDIV_SHIFT);
501
502 /* Set PLL lock time */
503 writel_relaxed(rate->pdiv * PLL0822X_LOCK_FACTOR,
504 pll->lock_reg);
505
506 /* Write PMS values */
507 writel_relaxed(pll_con3, pll->con_reg);
508
509 /* Wait for PLL lock if the PLL is enabled */
510 if (pll_con3 & BIT(pll->enable_offs))
511 return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
512
513 return 0;
514}
515
516static const struct clk_ops samsung_pll0822x_clk_ops = {
517 .recalc_rate = samsung_pll0822x_recalc_rate,
518 .determine_rate = samsung_pll_determine_rate,
519 .set_rate = samsung_pll0822x_set_rate,
520 .enable = samsung_pll3xxx_enable,
521 .disable = samsung_pll3xxx_disable,
522};
523
524static const struct clk_ops samsung_pll0822x_clk_min_ops = {
525 .recalc_rate = samsung_pll0822x_recalc_rate,
526};
527
528/*
529 * PLL0831x Clock Type
530 */
531/* Maximum lock time can be 500 * PDIV cycles */
532#define PLL0831X_LOCK_FACTOR (500)
533
534#define PLL0831X_KDIV_MASK (0xFFFF)
535#define PLL0831X_MDIV_MASK (0x1FF)
536#define PLL0831X_PDIV_MASK (0x3F)
537#define PLL0831X_SDIV_MASK (0x7)
538#define PLL0831X_MDIV_SHIFT (16)
539#define PLL0831X_PDIV_SHIFT (8)
540#define PLL0831X_SDIV_SHIFT (0)
541#define PLL0831X_KDIV_SHIFT (0)
542#define PLL0831X_LOCK_STAT_SHIFT (29)
543#define PLL0831X_ENABLE_SHIFT (31)
544
545static unsigned long samsung_pll0831x_recalc_rate(struct clk_hw *hw,
546 unsigned long parent_rate)
547{
548 struct samsung_clk_pll *pll = to_clk_pll(hw);
549 u32 mdiv, pdiv, sdiv, pll_con3, pll_con5;
550 s16 kdiv;
551 u64 fvco = parent_rate;
552
553 pll_con3 = readl_relaxed(pll->con_reg);
554 pll_con5 = readl_relaxed(pll->con_reg + 8);
555 mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK;
556 pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK;
557 sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK;
558 kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) & PLL0831X_KDIV_MASK);
559
560 fvco *= (mdiv << 16) + kdiv;
561 do_div(fvco, (pdiv << sdiv));
562 fvco >>= 16;
563
564 return (unsigned long)fvco;
565}
566
567static int samsung_pll0831x_set_rate(struct clk_hw *hw, unsigned long drate,
568 unsigned long parent_rate)
569{
570 const struct samsung_pll_rate_table *rate;
571 struct samsung_clk_pll *pll = to_clk_pll(hw);
572 u32 pll_con3, pll_con5;
573
574 /* Get required rate settings from table */
575 rate = samsung_get_pll_settings(pll, drate);
576 if (!rate) {
577 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
578 drate, clk_hw_get_name(hw));
579 return -EINVAL;
580 }
581
582 pll_con3 = readl_relaxed(pll->con_reg);
583 pll_con5 = readl_relaxed(pll->con_reg + 8);
584
585 /* Change PLL PMSK values */
586 pll_con3 &= ~((PLL0831X_MDIV_MASK << PLL0831X_MDIV_SHIFT) |
587 (PLL0831X_PDIV_MASK << PLL0831X_PDIV_SHIFT) |
588 (PLL0831X_SDIV_MASK << PLL0831X_SDIV_SHIFT));
589 pll_con3 |= (rate->mdiv << PLL0831X_MDIV_SHIFT) |
590 (rate->pdiv << PLL0831X_PDIV_SHIFT) |
591 (rate->sdiv << PLL0831X_SDIV_SHIFT);
592 pll_con5 &= ~(PLL0831X_KDIV_MASK << PLL0831X_KDIV_SHIFT);
593 /*
594 * kdiv is 16-bit 2's complement (s16), but stored as unsigned int.
595 * Cast it to u16 to avoid leading 0xffff's in case of negative value.
596 */
597 pll_con5 |= ((u16)rate->kdiv << PLL0831X_KDIV_SHIFT);
598
599 /* Set PLL lock time */
600 writel_relaxed(rate->pdiv * PLL0831X_LOCK_FACTOR, pll->lock_reg);
601
602 /* Write PMSK values */
603 writel_relaxed(pll_con3, pll->con_reg);
604 writel_relaxed(pll_con5, pll->con_reg + 8);
605
606 /* Wait for PLL lock if the PLL is enabled */
607 if (pll_con3 & BIT(pll->enable_offs))
608 return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
609
610 return 0;
611}
612
613static const struct clk_ops samsung_pll0831x_clk_ops = {
614 .recalc_rate = samsung_pll0831x_recalc_rate,
615 .set_rate = samsung_pll0831x_set_rate,
616 .determine_rate = samsung_pll_determine_rate,
617 .enable = samsung_pll3xxx_enable,
618 .disable = samsung_pll3xxx_disable,
619};
620
621static const struct clk_ops samsung_pll0831x_clk_min_ops = {
622 .recalc_rate = samsung_pll0831x_recalc_rate,
623};
624
625/*
626 * PLL45xx Clock Type
627 */
628#define PLL4502_LOCK_FACTOR 400
629#define PLL4508_LOCK_FACTOR 240
630
631#define PLL45XX_MDIV_MASK (0x3FF)
632#define PLL45XX_PDIV_MASK (0x3F)
633#define PLL45XX_SDIV_MASK (0x7)
634#define PLL45XX_AFC_MASK (0x1F)
635#define PLL45XX_MDIV_SHIFT (16)
636#define PLL45XX_PDIV_SHIFT (8)
637#define PLL45XX_SDIV_SHIFT (0)
638#define PLL45XX_AFC_SHIFT (0)
639
640#define PLL45XX_ENABLE BIT(31)
641#define PLL45XX_LOCKED BIT(29)
642
643static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
644 unsigned long parent_rate)
645{
646 struct samsung_clk_pll *pll = to_clk_pll(hw);
647 u32 mdiv, pdiv, sdiv, pll_con;
648 u64 fvco = parent_rate;
649
650 pll_con = readl_relaxed(pll->con_reg);
651 mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
652 pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
653 sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
654
655 if (pll->type == pll_4508)
656 sdiv = sdiv - 1;
657
658 fvco *= mdiv;
659 do_div(fvco, (pdiv << sdiv));
660
661 return (unsigned long)fvco;
662}
663
664static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
665 const struct samsung_pll_rate_table *rate)
666{
667 u32 old_mdiv, old_pdiv, old_afc;
668
669 old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
670 old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
671 old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK;
672
673 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
674 || old_afc != rate->afc);
675}
676
677static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
678 unsigned long prate)
679{
680 struct samsung_clk_pll *pll = to_clk_pll(hw);
681 const struct samsung_pll_rate_table *rate;
682 u32 con0, con1;
683
684 /* Get required rate settings from table */
685 rate = samsung_get_pll_settings(pll, drate);
686 if (!rate) {
687 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
688 drate, clk_hw_get_name(hw));
689 return -EINVAL;
690 }
691
692 con0 = readl_relaxed(pll->con_reg);
693 con1 = readl_relaxed(pll->con_reg + 0x4);
694
695 if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
696 /* If only s change, change just s value only*/
697 con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
698 con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
699 writel_relaxed(con0, pll->con_reg);
700
701 return 0;
702 }
703
704 /* Set PLL PMS values. */
705 con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
706 (PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
707 (PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
708 con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) |
709 (rate->pdiv << PLL45XX_PDIV_SHIFT) |
710 (rate->sdiv << PLL45XX_SDIV_SHIFT);
711
712 /* Set PLL AFC value. */
713 con1 = readl_relaxed(pll->con_reg + 0x4);
714 con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
715 con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
716
717 /* Set PLL lock time. */
718 switch (pll->type) {
719 case pll_4502:
720 writel_relaxed(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
721 break;
722 case pll_4508:
723 writel_relaxed(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
724 break;
725 default:
726 break;
727 }
728
729 /* Set new configuration. */
730 writel_relaxed(con1, pll->con_reg + 0x4);
731 writel_relaxed(con0, pll->con_reg);
732
733 /* Wait for PLL lock */
734 return samsung_pll_lock_wait(pll, PLL45XX_LOCKED);
735}
736
737static const struct clk_ops samsung_pll45xx_clk_ops = {
738 .recalc_rate = samsung_pll45xx_recalc_rate,
739 .determine_rate = samsung_pll_determine_rate,
740 .set_rate = samsung_pll45xx_set_rate,
741};
742
743static const struct clk_ops samsung_pll45xx_clk_min_ops = {
744 .recalc_rate = samsung_pll45xx_recalc_rate,
745};
746
747/*
748 * PLL46xx Clock Type
749 */
750#define PLL46XX_LOCK_FACTOR 3000
751
752#define PLL46XX_VSEL_MASK (1)
753#define PLL46XX_MDIV_MASK (0x1FF)
754#define PLL1460X_MDIV_MASK (0x3FF)
755
756#define PLL46XX_PDIV_MASK (0x3F)
757#define PLL46XX_SDIV_MASK (0x7)
758#define PLL46XX_VSEL_SHIFT (27)
759#define PLL46XX_MDIV_SHIFT (16)
760#define PLL46XX_PDIV_SHIFT (8)
761#define PLL46XX_SDIV_SHIFT (0)
762
763#define PLL46XX_KDIV_MASK (0xFFFF)
764#define PLL4650C_KDIV_MASK (0xFFF)
765#define PLL46XX_KDIV_SHIFT (0)
766#define PLL46XX_MFR_MASK (0x3F)
767#define PLL46XX_MRR_MASK (0x1F)
768#define PLL46XX_KDIV_SHIFT (0)
769#define PLL46XX_MFR_SHIFT (16)
770#define PLL46XX_MRR_SHIFT (24)
771
772#define PLL46XX_ENABLE BIT(31)
773#define PLL46XX_LOCKED BIT(29)
774#define PLL46XX_VSEL BIT(27)
775
776static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
777 unsigned long parent_rate)
778{
779 struct samsung_clk_pll *pll = to_clk_pll(hw);
780 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
781 u64 fvco = parent_rate;
782
783 pll_con0 = readl_relaxed(pll->con_reg);
784 pll_con1 = readl_relaxed(pll->con_reg + 4);
785 mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & ((pll->type == pll_1460x) ?
786 PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK);
787 pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
788 sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
789 kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
790 pll_con1 & PLL46XX_KDIV_MASK;
791
792 shift = ((pll->type == pll_4600) || (pll->type == pll_1460x)) ? 16 : 10;
793
794 fvco *= (mdiv << shift) + kdiv;
795 do_div(fvco, (pdiv << sdiv));
796 fvco >>= shift;
797
798 return (unsigned long)fvco;
799}
800
801static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
802 const struct samsung_pll_rate_table *rate)
803{
804 u32 old_mdiv, old_pdiv, old_kdiv;
805
806 old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
807 old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
808 old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
809
810 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
811 || old_kdiv != rate->kdiv);
812}
813
814static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
815 unsigned long prate)
816{
817 struct samsung_clk_pll *pll = to_clk_pll(hw);
818 const struct samsung_pll_rate_table *rate;
819 u32 con0, con1, lock;
820
821 /* Get required rate settings from table */
822 rate = samsung_get_pll_settings(pll, drate);
823 if (!rate) {
824 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
825 drate, clk_hw_get_name(hw));
826 return -EINVAL;
827 }
828
829 con0 = readl_relaxed(pll->con_reg);
830 con1 = readl_relaxed(pll->con_reg + 0x4);
831
832 if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
833 /* If only s change, change just s value only*/
834 con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
835 con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
836 writel_relaxed(con0, pll->con_reg);
837
838 return 0;
839 }
840
841 /* Set PLL lock time. */
842 lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
843 if (lock > 0xffff)
844 /* Maximum lock time bitfield is 16-bit. */
845 lock = 0xffff;
846
847 /* Set PLL PMS and VSEL values. */
848 if (pll->type == pll_1460x) {
849 con0 &= ~((PLL1460X_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
850 (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
851 (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT));
852 } else {
853 con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
854 (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
855 (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
856 (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
857 con0 |= rate->vsel << PLL46XX_VSEL_SHIFT;
858 }
859
860 con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
861 (rate->pdiv << PLL46XX_PDIV_SHIFT) |
862 (rate->sdiv << PLL46XX_SDIV_SHIFT);
863
864 /* Set PLL K, MFR and MRR values. */
865 con1 = readl_relaxed(pll->con_reg + 0x4);
866 con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
867 (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
868 (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
869 con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) |
870 (rate->mfr << PLL46XX_MFR_SHIFT) |
871 (rate->mrr << PLL46XX_MRR_SHIFT);
872
873 /* Write configuration to PLL */
874 writel_relaxed(lock, pll->lock_reg);
875 writel_relaxed(con0, pll->con_reg);
876 writel_relaxed(con1, pll->con_reg + 0x4);
877
878 /* Wait for PLL lock */
879 return samsung_pll_lock_wait(pll, PLL46XX_LOCKED);
880}
881
882static const struct clk_ops samsung_pll46xx_clk_ops = {
883 .recalc_rate = samsung_pll46xx_recalc_rate,
884 .determine_rate = samsung_pll_determine_rate,
885 .set_rate = samsung_pll46xx_set_rate,
886};
887
888static const struct clk_ops samsung_pll46xx_clk_min_ops = {
889 .recalc_rate = samsung_pll46xx_recalc_rate,
890};
891
892/*
893 * PLL6552 Clock Type
894 */
895
896#define PLL6552_MDIV_MASK 0x3ff
897#define PLL6552_PDIV_MASK 0x3f
898#define PLL6552_SDIV_MASK 0x7
899#define PLL6552_MDIV_SHIFT 16
900#define PLL6552_MDIV_SHIFT_2416 14
901#define PLL6552_PDIV_SHIFT 8
902#define PLL6552_PDIV_SHIFT_2416 5
903#define PLL6552_SDIV_SHIFT 0
904
905static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
906 unsigned long parent_rate)
907{
908 struct samsung_clk_pll *pll = to_clk_pll(hw);
909 u32 mdiv, pdiv, sdiv, pll_con;
910 u64 fvco = parent_rate;
911
912 pll_con = readl_relaxed(pll->con_reg);
913 if (pll->type == pll_6552_s3c2416) {
914 mdiv = (pll_con >> PLL6552_MDIV_SHIFT_2416) & PLL6552_MDIV_MASK;
915 pdiv = (pll_con >> PLL6552_PDIV_SHIFT_2416) & PLL6552_PDIV_MASK;
916 } else {
917 mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
918 pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
919 }
920 sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
921
922 fvco *= mdiv;
923 do_div(fvco, (pdiv << sdiv));
924
925 return (unsigned long)fvco;
926}
927
928static const struct clk_ops samsung_pll6552_clk_ops = {
929 .recalc_rate = samsung_pll6552_recalc_rate,
930};
931
932/*
933 * PLL6553 Clock Type
934 */
935
936#define PLL6553_MDIV_MASK 0xff
937#define PLL6553_PDIV_MASK 0x3f
938#define PLL6553_SDIV_MASK 0x7
939#define PLL6553_KDIV_MASK 0xffff
940#define PLL6553_MDIV_SHIFT 16
941#define PLL6553_PDIV_SHIFT 8
942#define PLL6553_SDIV_SHIFT 0
943#define PLL6553_KDIV_SHIFT 0
944
945static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
946 unsigned long parent_rate)
947{
948 struct samsung_clk_pll *pll = to_clk_pll(hw);
949 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
950 u64 fvco = parent_rate;
951
952 pll_con0 = readl_relaxed(pll->con_reg);
953 pll_con1 = readl_relaxed(pll->con_reg + 0x4);
954 mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
955 pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
956 sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
957 kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
958
959 fvco *= (mdiv << 16) + kdiv;
960 do_div(fvco, (pdiv << sdiv));
961 fvco >>= 16;
962
963 return (unsigned long)fvco;
964}
965
966static const struct clk_ops samsung_pll6553_clk_ops = {
967 .recalc_rate = samsung_pll6553_recalc_rate,
968};
969
970/*
971 * PLL2550x Clock Type
972 */
973
974#define PLL2550X_R_MASK (0x1)
975#define PLL2550X_P_MASK (0x3F)
976#define PLL2550X_M_MASK (0x3FF)
977#define PLL2550X_S_MASK (0x7)
978#define PLL2550X_R_SHIFT (20)
979#define PLL2550X_P_SHIFT (14)
980#define PLL2550X_M_SHIFT (4)
981#define PLL2550X_S_SHIFT (0)
982
983static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
984 unsigned long parent_rate)
985{
986 struct samsung_clk_pll *pll = to_clk_pll(hw);
987 u32 r, p, m, s, pll_stat;
988 u64 fvco = parent_rate;
989
990 pll_stat = readl_relaxed(pll->con_reg);
991 r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
992 if (!r)
993 return 0;
994 p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK;
995 m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK;
996 s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK;
997
998 fvco *= m;
999 do_div(fvco, (p << s));
1000
1001 return (unsigned long)fvco;
1002}
1003
1004static const struct clk_ops samsung_pll2550x_clk_ops = {
1005 .recalc_rate = samsung_pll2550x_recalc_rate,
1006};
1007
1008/*
1009 * PLL2550xx Clock Type
1010 */
1011
1012/* Maximum lock time can be 270 * PDIV cycles */
1013#define PLL2550XX_LOCK_FACTOR 270
1014
1015#define PLL2550XX_M_MASK 0x3FF
1016#define PLL2550XX_P_MASK 0x3F
1017#define PLL2550XX_S_MASK 0x7
1018#define PLL2550XX_LOCK_STAT_MASK 0x1
1019#define PLL2550XX_M_SHIFT 9
1020#define PLL2550XX_P_SHIFT 3
1021#define PLL2550XX_S_SHIFT 0
1022#define PLL2550XX_LOCK_STAT_SHIFT 21
1023
1024static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw *hw,
1025 unsigned long parent_rate)
1026{
1027 struct samsung_clk_pll *pll = to_clk_pll(hw);
1028 u32 mdiv, pdiv, sdiv, pll_con;
1029 u64 fvco = parent_rate;
1030
1031 pll_con = readl_relaxed(pll->con_reg);
1032 mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
1033 pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
1034 sdiv = (pll_con >> PLL2550XX_S_SHIFT) & PLL2550XX_S_MASK;
1035
1036 fvco *= mdiv;
1037 do_div(fvco, (pdiv << sdiv));
1038
1039 return (unsigned long)fvco;
1040}
1041
1042static inline bool samsung_pll2550xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con)
1043{
1044 u32 old_mdiv, old_pdiv;
1045
1046 old_mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
1047 old_pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
1048
1049 return mdiv != old_mdiv || pdiv != old_pdiv;
1050}
1051
1052static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
1053 unsigned long prate)
1054{
1055 struct samsung_clk_pll *pll = to_clk_pll(hw);
1056 const struct samsung_pll_rate_table *rate;
1057 u32 tmp;
1058
1059 /* Get required rate settings from table */
1060 rate = samsung_get_pll_settings(pll, drate);
1061 if (!rate) {
1062 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1063 drate, clk_hw_get_name(hw));
1064 return -EINVAL;
1065 }
1066
1067 tmp = readl_relaxed(pll->con_reg);
1068
1069 if (!(samsung_pll2550xx_mp_change(rate->mdiv, rate->pdiv, tmp))) {
1070 /* If only s change, change just s value only*/
1071 tmp &= ~(PLL2550XX_S_MASK << PLL2550XX_S_SHIFT);
1072 tmp |= rate->sdiv << PLL2550XX_S_SHIFT;
1073 writel_relaxed(tmp, pll->con_reg);
1074
1075 return 0;
1076 }
1077
1078 /* Set PLL lock time. */
1079 writel_relaxed(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg);
1080
1081 /* Change PLL PMS values */
1082 tmp &= ~((PLL2550XX_M_MASK << PLL2550XX_M_SHIFT) |
1083 (PLL2550XX_P_MASK << PLL2550XX_P_SHIFT) |
1084 (PLL2550XX_S_MASK << PLL2550XX_S_SHIFT));
1085 tmp |= (rate->mdiv << PLL2550XX_M_SHIFT) |
1086 (rate->pdiv << PLL2550XX_P_SHIFT) |
1087 (rate->sdiv << PLL2550XX_S_SHIFT);
1088 writel_relaxed(tmp, pll->con_reg);
1089
1090 /* Wait for PLL lock */
1091 return samsung_pll_lock_wait(pll,
1092 PLL2550XX_LOCK_STAT_MASK << PLL2550XX_LOCK_STAT_SHIFT);
1093}
1094
1095static const struct clk_ops samsung_pll2550xx_clk_ops = {
1096 .recalc_rate = samsung_pll2550xx_recalc_rate,
1097 .determine_rate = samsung_pll_determine_rate,
1098 .set_rate = samsung_pll2550xx_set_rate,
1099};
1100
1101static const struct clk_ops samsung_pll2550xx_clk_min_ops = {
1102 .recalc_rate = samsung_pll2550xx_recalc_rate,
1103};
1104
1105/*
1106 * PLL2650x Clock Type
1107 */
1108
1109/* Maximum lock time can be 3000 * PDIV cycles */
1110#define PLL2650X_LOCK_FACTOR 3000
1111
1112#define PLL2650X_M_MASK 0x1ff
1113#define PLL2650X_P_MASK 0x3f
1114#define PLL2650X_S_MASK 0x7
1115#define PLL2650X_K_MASK 0xffff
1116#define PLL2650X_LOCK_STAT_MASK 0x1
1117#define PLL2650X_M_SHIFT 16
1118#define PLL2650X_P_SHIFT 8
1119#define PLL2650X_S_SHIFT 0
1120#define PLL2650X_K_SHIFT 0
1121#define PLL2650X_LOCK_STAT_SHIFT 29
1122#define PLL2650X_PLL_ENABLE_SHIFT 31
1123
1124static unsigned long samsung_pll2650x_recalc_rate(struct clk_hw *hw,
1125 unsigned long parent_rate)
1126{
1127 struct samsung_clk_pll *pll = to_clk_pll(hw);
1128 u64 fout = parent_rate;
1129 u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
1130 s16 kdiv;
1131
1132 pll_con0 = readl_relaxed(pll->con_reg);
1133 mdiv = (pll_con0 >> PLL2650X_M_SHIFT) & PLL2650X_M_MASK;
1134 pdiv = (pll_con0 >> PLL2650X_P_SHIFT) & PLL2650X_P_MASK;
1135 sdiv = (pll_con0 >> PLL2650X_S_SHIFT) & PLL2650X_S_MASK;
1136
1137 pll_con1 = readl_relaxed(pll->con_reg + 4);
1138 kdiv = (s16)((pll_con1 >> PLL2650X_K_SHIFT) & PLL2650X_K_MASK);
1139
1140 fout *= (mdiv << 16) + kdiv;
1141 do_div(fout, (pdiv << sdiv));
1142 fout >>= 16;
1143
1144 return (unsigned long)fout;
1145}
1146
1147static int samsung_pll2650x_set_rate(struct clk_hw *hw, unsigned long drate,
1148 unsigned long prate)
1149{
1150 struct samsung_clk_pll *pll = to_clk_pll(hw);
1151 const struct samsung_pll_rate_table *rate;
1152 u32 con0, con1;
1153
1154 /* Get required rate settings from table */
1155 rate = samsung_get_pll_settings(pll, drate);
1156 if (!rate) {
1157 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1158 drate, clk_hw_get_name(hw));
1159 return -EINVAL;
1160 }
1161
1162 con0 = readl_relaxed(pll->con_reg);
1163 con1 = readl_relaxed(pll->con_reg + 4);
1164
1165 /* Set PLL lock time. */
1166 writel_relaxed(rate->pdiv * PLL2650X_LOCK_FACTOR, pll->lock_reg);
1167
1168 /* Change PLL PMS values */
1169 con0 &= ~((PLL2650X_M_MASK << PLL2650X_M_SHIFT) |
1170 (PLL2650X_P_MASK << PLL2650X_P_SHIFT) |
1171 (PLL2650X_S_MASK << PLL2650X_S_SHIFT));
1172 con0 |= (rate->mdiv << PLL2650X_M_SHIFT) |
1173 (rate->pdiv << PLL2650X_P_SHIFT) |
1174 (rate->sdiv << PLL2650X_S_SHIFT);
1175 con0 |= (1 << PLL2650X_PLL_ENABLE_SHIFT);
1176 writel_relaxed(con0, pll->con_reg);
1177
1178 con1 &= ~(PLL2650X_K_MASK << PLL2650X_K_SHIFT);
1179 con1 |= ((rate->kdiv & PLL2650X_K_MASK) << PLL2650X_K_SHIFT);
1180 writel_relaxed(con1, pll->con_reg + 4);
1181
1182 /* Wait for PLL lock */
1183 return samsung_pll_lock_wait(pll,
1184 PLL2650X_LOCK_STAT_MASK << PLL2650X_LOCK_STAT_SHIFT);
1185}
1186
1187static const struct clk_ops samsung_pll2650x_clk_ops = {
1188 .recalc_rate = samsung_pll2650x_recalc_rate,
1189 .determine_rate = samsung_pll_determine_rate,
1190 .set_rate = samsung_pll2650x_set_rate,
1191};
1192
1193static const struct clk_ops samsung_pll2650x_clk_min_ops = {
1194 .recalc_rate = samsung_pll2650x_recalc_rate,
1195};
1196
1197/*
1198 * PLL2650XX Clock Type
1199 */
1200
1201/* Maximum lock time can be 3000 * PDIV cycles */
1202#define PLL2650XX_LOCK_FACTOR 3000
1203
1204#define PLL2650XX_MDIV_SHIFT 9
1205#define PLL2650XX_PDIV_SHIFT 3
1206#define PLL2650XX_SDIV_SHIFT 0
1207#define PLL2650XX_KDIV_SHIFT 0
1208#define PLL2650XX_MDIV_MASK 0x1ff
1209#define PLL2650XX_PDIV_MASK 0x3f
1210#define PLL2650XX_SDIV_MASK 0x7
1211#define PLL2650XX_KDIV_MASK 0xffff
1212#define PLL2650XX_PLL_ENABLE_SHIFT 23
1213#define PLL2650XX_PLL_LOCKTIME_SHIFT 21
1214#define PLL2650XX_PLL_FOUTMASK_SHIFT 31
1215
1216static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw,
1217 unsigned long parent_rate)
1218{
1219 struct samsung_clk_pll *pll = to_clk_pll(hw);
1220 u32 mdiv, pdiv, sdiv, pll_con0, pll_con2;
1221 s16 kdiv;
1222 u64 fvco = parent_rate;
1223
1224 pll_con0 = readl_relaxed(pll->con_reg);
1225 pll_con2 = readl_relaxed(pll->con_reg + 8);
1226 mdiv = (pll_con0 >> PLL2650XX_MDIV_SHIFT) & PLL2650XX_MDIV_MASK;
1227 pdiv = (pll_con0 >> PLL2650XX_PDIV_SHIFT) & PLL2650XX_PDIV_MASK;
1228 sdiv = (pll_con0 >> PLL2650XX_SDIV_SHIFT) & PLL2650XX_SDIV_MASK;
1229 kdiv = (s16)(pll_con2 & PLL2650XX_KDIV_MASK);
1230
1231 fvco *= (mdiv << 16) + kdiv;
1232 do_div(fvco, (pdiv << sdiv));
1233 fvco >>= 16;
1234
1235 return (unsigned long)fvco;
1236}
1237
1238static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
1239 unsigned long parent_rate)
1240{
1241 struct samsung_clk_pll *pll = to_clk_pll(hw);
1242 u32 pll_con0, pll_con2;
1243 const struct samsung_pll_rate_table *rate;
1244
1245 rate = samsung_get_pll_settings(pll, drate);
1246 if (!rate) {
1247 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1248 drate, clk_hw_get_name(hw));
1249 return -EINVAL;
1250 }
1251
1252 pll_con0 = readl_relaxed(pll->con_reg);
1253 pll_con2 = readl_relaxed(pll->con_reg + 8);
1254
1255 /* Change PLL PMS values */
1256 pll_con0 &= ~(PLL2650XX_MDIV_MASK << PLL2650XX_MDIV_SHIFT |
1257 PLL2650XX_PDIV_MASK << PLL2650XX_PDIV_SHIFT |
1258 PLL2650XX_SDIV_MASK << PLL2650XX_SDIV_SHIFT);
1259 pll_con0 |= rate->mdiv << PLL2650XX_MDIV_SHIFT;
1260 pll_con0 |= rate->pdiv << PLL2650XX_PDIV_SHIFT;
1261 pll_con0 |= rate->sdiv << PLL2650XX_SDIV_SHIFT;
1262 pll_con0 |= 1 << PLL2650XX_PLL_ENABLE_SHIFT;
1263 pll_con0 |= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT;
1264
1265 pll_con2 &= ~(PLL2650XX_KDIV_MASK << PLL2650XX_KDIV_SHIFT);
1266 pll_con2 |= ((~(rate->kdiv) + 1) & PLL2650XX_KDIV_MASK)
1267 << PLL2650XX_KDIV_SHIFT;
1268
1269 /* Set PLL lock time. */
1270 writel_relaxed(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg);
1271
1272 writel_relaxed(pll_con0, pll->con_reg);
1273 writel_relaxed(pll_con2, pll->con_reg + 8);
1274
1275 return samsung_pll_lock_wait(pll, 0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT);
1276}
1277
1278static const struct clk_ops samsung_pll2650xx_clk_ops = {
1279 .recalc_rate = samsung_pll2650xx_recalc_rate,
1280 .set_rate = samsung_pll2650xx_set_rate,
1281 .determine_rate = samsung_pll_determine_rate,
1282};
1283
1284static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
1285 .recalc_rate = samsung_pll2650xx_recalc_rate,
1286};
1287
1288/*
1289 * PLL531X Clock Type
1290 */
1291/* Maximum lock time can be 500 * PDIV cycles */
1292#define PLL531X_LOCK_FACTOR (500)
1293#define PLL531X_MDIV_MASK (0x3FF)
1294#define PLL531X_PDIV_MASK (0x3F)
1295#define PLL531X_SDIV_MASK (0x7)
1296#define PLL531X_FDIV_MASK (0xFFFFFFFF)
1297#define PLL531X_MDIV_SHIFT (16)
1298#define PLL531X_PDIV_SHIFT (8)
1299#define PLL531X_SDIV_SHIFT (0)
1300
1301static unsigned long samsung_pll531x_recalc_rate(struct clk_hw *hw,
1302 unsigned long parent_rate)
1303{
1304 struct samsung_clk_pll *pll = to_clk_pll(hw);
1305 u32 pdiv, sdiv, fdiv, pll_con0, pll_con8;
1306 u64 mdiv, fout = parent_rate;
1307
1308 pll_con0 = readl_relaxed(pll->con_reg);
1309 pll_con8 = readl_relaxed(pll->con_reg + 20);
1310 mdiv = (pll_con0 >> PLL531X_MDIV_SHIFT) & PLL531X_MDIV_MASK;
1311 pdiv = (pll_con0 >> PLL531X_PDIV_SHIFT) & PLL531X_PDIV_MASK;
1312 sdiv = (pll_con0 >> PLL531X_SDIV_SHIFT) & PLL531X_SDIV_MASK;
1313 fdiv = (pll_con8 & PLL531X_FDIV_MASK);
1314
1315 if (fdiv >> 31)
1316 mdiv--;
1317
1318 fout *= (mdiv << 24) + (fdiv >> 8);
1319 do_div(fout, (pdiv << sdiv));
1320 fout >>= 24;
1321
1322 return (unsigned long)fout;
1323}
1324
1325static const struct clk_ops samsung_pll531x_clk_ops = {
1326 .recalc_rate = samsung_pll531x_recalc_rate,
1327};
1328
1329/*
1330 * PLL1031x Clock Type
1331 */
1332#define PLL1031X_LOCK_FACTOR (500)
1333
1334#define PLL1031X_MDIV_MASK (0x3ff)
1335#define PLL1031X_PDIV_MASK (0x3f)
1336#define PLL1031X_SDIV_MASK (0x7)
1337#define PLL1031X_MDIV_SHIFT (16)
1338#define PLL1031X_PDIV_SHIFT (8)
1339#define PLL1031X_SDIV_SHIFT (0)
1340
1341#define PLL1031X_KDIV_MASK (0xffff)
1342#define PLL1031X_KDIV_SHIFT (0)
1343#define PLL1031X_MFR_MASK (0x3f)
1344#define PLL1031X_MRR_MASK (0x1f)
1345#define PLL1031X_MFR_SHIFT (16)
1346#define PLL1031X_MRR_SHIFT (24)
1347
1348static unsigned long samsung_pll1031x_recalc_rate(struct clk_hw *hw,
1349 unsigned long parent_rate)
1350{
1351 struct samsung_clk_pll *pll = to_clk_pll(hw);
1352 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con3;
1353 u64 fvco = parent_rate;
1354
1355 pll_con0 = readl_relaxed(pll->con_reg);
1356 pll_con3 = readl_relaxed(pll->con_reg + 0xc);
1357 mdiv = (pll_con0 >> PLL1031X_MDIV_SHIFT) & PLL1031X_MDIV_MASK;
1358 pdiv = (pll_con0 >> PLL1031X_PDIV_SHIFT) & PLL1031X_PDIV_MASK;
1359 sdiv = (pll_con0 >> PLL1031X_SDIV_SHIFT) & PLL1031X_SDIV_MASK;
1360 kdiv = (pll_con3 & PLL1031X_KDIV_MASK);
1361
1362 fvco *= (mdiv << PLL1031X_MDIV_SHIFT) + kdiv;
1363 do_div(fvco, (pdiv << sdiv));
1364 fvco >>= PLL1031X_MDIV_SHIFT;
1365
1366 return (unsigned long)fvco;
1367}
1368
1369static bool samsung_pll1031x_mpk_change(u32 pll_con0, u32 pll_con3,
1370 const struct samsung_pll_rate_table *rate)
1371{
1372 u32 old_mdiv, old_pdiv, old_kdiv;
1373
1374 old_mdiv = (pll_con0 >> PLL1031X_MDIV_SHIFT) & PLL1031X_MDIV_MASK;
1375 old_pdiv = (pll_con0 >> PLL1031X_PDIV_SHIFT) & PLL1031X_PDIV_MASK;
1376 old_kdiv = (pll_con3 >> PLL1031X_KDIV_SHIFT) & PLL1031X_KDIV_MASK;
1377
1378 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv ||
1379 old_kdiv != rate->kdiv);
1380}
1381
1382static int samsung_pll1031x_set_rate(struct clk_hw *hw, unsigned long drate,
1383 unsigned long prate)
1384{
1385 struct samsung_clk_pll *pll = to_clk_pll(hw);
1386 const struct samsung_pll_rate_table *rate;
1387 u32 con0, con3;
1388
1389 /* Get required rate settings from table */
1390 rate = samsung_get_pll_settings(pll, drate);
1391 if (!rate) {
1392 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1393 drate, clk_hw_get_name(hw));
1394 return -EINVAL;
1395 }
1396
1397 con0 = readl_relaxed(pll->con_reg);
1398 con3 = readl_relaxed(pll->con_reg + 0xc);
1399
1400 if (!(samsung_pll1031x_mpk_change(con0, con3, rate))) {
1401 /* If only s change, change just s value only */
1402 con0 &= ~(PLL1031X_SDIV_MASK << PLL1031X_SDIV_SHIFT);
1403 con0 |= rate->sdiv << PLL1031X_SDIV_SHIFT;
1404 writel_relaxed(con0, pll->con_reg);
1405
1406 return 0;
1407 }
1408
1409 /* Set PLL lock time. */
1410 writel_relaxed(rate->pdiv * PLL1031X_LOCK_FACTOR, pll->lock_reg);
1411
1412 /* Set PLL M, P, and S values. */
1413 con0 &= ~((PLL1031X_MDIV_MASK << PLL1031X_MDIV_SHIFT) |
1414 (PLL1031X_PDIV_MASK << PLL1031X_PDIV_SHIFT) |
1415 (PLL1031X_SDIV_MASK << PLL1031X_SDIV_SHIFT));
1416
1417 con0 |= (rate->mdiv << PLL1031X_MDIV_SHIFT) |
1418 (rate->pdiv << PLL1031X_PDIV_SHIFT) |
1419 (rate->sdiv << PLL1031X_SDIV_SHIFT);
1420
1421 /* Set PLL K, MFR and MRR values. */
1422 con3 = readl_relaxed(pll->con_reg + 0xc);
1423 con3 &= ~((PLL1031X_KDIV_MASK << PLL1031X_KDIV_SHIFT) |
1424 (PLL1031X_MFR_MASK << PLL1031X_MFR_SHIFT) |
1425 (PLL1031X_MRR_MASK << PLL1031X_MRR_SHIFT));
1426 con3 |= (rate->kdiv << PLL1031X_KDIV_SHIFT) |
1427 (rate->mfr << PLL1031X_MFR_SHIFT) |
1428 (rate->mrr << PLL1031X_MRR_SHIFT);
1429
1430 /* Write configuration to PLL */
1431 writel_relaxed(con0, pll->con_reg);
1432 writel_relaxed(con3, pll->con_reg + 0xc);
1433
1434 /* Wait for PLL lock if the PLL is enabled */
1435 return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
1436}
1437
1438static const struct clk_ops samsung_pll1031x_clk_ops = {
1439 .recalc_rate = samsung_pll1031x_recalc_rate,
1440 .determine_rate = samsung_pll_determine_rate,
1441 .set_rate = samsung_pll1031x_set_rate,
1442};
1443
1444static const struct clk_ops samsung_pll1031x_clk_min_ops = {
1445 .recalc_rate = samsung_pll1031x_recalc_rate,
1446};
1447
1448/*
1449 * PLLA9FRACO Clock Type
1450 */
1451#define PLLA9FRACO_LOCK_FACTOR (500)
1452
1453#define PLLA9FRACO_MDIV_MASK (0x3ff)
1454#define PLLA9FRACO_PDIV_MASK (0x3f)
1455#define PLLA9FRACO_SDIV_MASK (0x7)
1456#define PLLA9FRACO_MDIV_SHIFT (14)
1457#define PLLA9FRACO_PDIV_SHIFT (8)
1458#define PLLA9FRACO_SDIV_SHIFT (0)
1459
1460#define PLLA9FRACO_PLL_CON5_DIV_FRAC (0x14)
1461#define PLLA9FRACO_KDIV_MASK (0xffffff)
1462#define PLLA9FRACO_KDIV_SHIFT (0)
1463#define PLLA9FRACO_DAC_MODE BIT(30)
1464#define PLLA9FRACO_DSM_EN BIT(31)
1465#define PLLA9FRACO_FOUTPOSTDIVEN BIT(3)
1466#define PLLA9FRACO_MUX_SEL BIT(4)
1467#define PLLA9FRACO_ENABLE_SHIFT (31)
1468#define PLLA9FRACO_LOCK_STAT_SHIFT (29)
1469
1470static unsigned long samsung_a9fraco_recalc_rate(struct clk_hw *hw,
1471 unsigned long parent_rate)
1472{
1473 struct samsung_clk_pll *pll = to_clk_pll(hw);
1474 u32 pll_con0, pll_con5;
1475 u64 mdiv, pdiv, sdiv, kdiv;
1476 u64 fvco = parent_rate;
1477
1478 pll_con0 = readl_relaxed(pll->con_reg);
1479 pll_con5 = readl_relaxed(pll->con_reg + PLLA9FRACO_PLL_CON5_DIV_FRAC);
1480 mdiv = (pll_con0 >> PLLA9FRACO_MDIV_SHIFT) & PLLA9FRACO_MDIV_MASK;
1481 pdiv = (pll_con0 >> PLLA9FRACO_PDIV_SHIFT) & PLLA9FRACO_PDIV_MASK;
1482 sdiv = (pll_con0 >> PLLA9FRACO_SDIV_SHIFT) & PLLA9FRACO_SDIV_MASK;
1483 kdiv = (pll_con5 & PLLA9FRACO_KDIV_MASK);
1484
1485 /* fvco = fref * (M + K/2^24) / p * (S+1) */
1486 fvco *= mdiv;
1487 fvco = (fvco << 24) + kdiv;
1488 fvco = div64_u64(fvco, ((pdiv * (sdiv + 1)) << 24));
1489
1490 return (unsigned long)fvco;
1491}
1492
1493static bool samsung_a9fraco_mpk_change(u32 pll_con0, u32 pll_con5,
1494 const struct samsung_pll_rate_table *rate)
1495{
1496 u32 old_mdiv, old_pdiv, old_kdiv;
1497
1498 old_mdiv = (pll_con0 >> PLLA9FRACO_MDIV_SHIFT) & PLLA9FRACO_MDIV_MASK;
1499 old_pdiv = (pll_con0 >> PLLA9FRACO_PDIV_SHIFT) & PLLA9FRACO_PDIV_MASK;
1500 old_kdiv = (pll_con5 >> PLLA9FRACO_KDIV_SHIFT) & PLLA9FRACO_KDIV_MASK;
1501
1502 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv || old_kdiv != rate->kdiv);
1503}
1504
1505static int samsung_a9fraco_set_rate(struct clk_hw *hw, unsigned long drate, unsigned long prate)
1506{
1507 struct samsung_clk_pll *pll = to_clk_pll(hw);
1508 const struct samsung_pll_rate_table *rate;
1509 u32 con0, con5;
1510 int ret;
1511
1512 /* Get required rate settings from table */
1513 rate = samsung_get_pll_settings(pll, drate);
1514 if (!rate) {
1515 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1516 drate, clk_hw_get_name(hw));
1517 return -EINVAL;
1518 }
1519
1520 con0 = readl_relaxed(pll->con_reg);
1521 con5 = readl_relaxed(pll->con_reg + PLLA9FRACO_PLL_CON5_DIV_FRAC);
1522
1523 if (!(samsung_a9fraco_mpk_change(con0, con5, rate))) {
1524 /* If only s change, change just s value only */
1525 con0 &= ~(PLLA9FRACO_SDIV_MASK << PLLA9FRACO_SDIV_SHIFT);
1526 con0 |= rate->sdiv << PLLA9FRACO_SDIV_SHIFT;
1527 writel_relaxed(con0, pll->con_reg);
1528
1529 return 0;
1530 }
1531
1532 /* Select OSCCLK (0) */
1533 con0 = readl_relaxed(pll->con_reg);
1534 con0 &= ~(PLLA9FRACO_MUX_SEL);
1535 writel_relaxed(con0, pll->con_reg);
1536
1537 /* Disable PLL */
1538 con0 &= ~BIT(PLLA9FRACO_ENABLE_SHIFT);
1539 writel_relaxed(con0, pll->con_reg);
1540
1541 /* Set PLL lock time. */
1542 writel_relaxed(rate->pdiv * PLLA9FRACO_LOCK_FACTOR, pll->lock_reg);
1543
1544 /* Set PLL M, P, and S values. */
1545 con0 &= ~((PLLA9FRACO_MDIV_MASK << PLLA9FRACO_MDIV_SHIFT) |
1546 (PLLA9FRACO_PDIV_MASK << PLLA9FRACO_PDIV_SHIFT) |
1547 (PLLA9FRACO_SDIV_MASK << PLLA9FRACO_SDIV_SHIFT));
1548
1549 /* The field FOUTPOSTDIVEN should always be 1, else FOUT might be 0 Hz. */
1550 con0 |= (rate->mdiv << PLLA9FRACO_MDIV_SHIFT) |
1551 (rate->pdiv << PLLA9FRACO_PDIV_SHIFT) |
1552 (rate->sdiv << PLLA9FRACO_SDIV_SHIFT) | (PLLA9FRACO_FOUTPOSTDIVEN);
1553
1554 /* Set PLL K, DSM_EN and DAC_MODE values. */
1555 con5 = readl_relaxed(pll->con_reg + PLLA9FRACO_PLL_CON5_DIV_FRAC);
1556 con5 &= ~((PLLA9FRACO_KDIV_MASK << PLLA9FRACO_KDIV_SHIFT) |
1557 PLLA9FRACO_DSM_EN | PLLA9FRACO_DAC_MODE);
1558 con5 |= (rate->kdiv << PLLA9FRACO_KDIV_SHIFT) | PLLA9FRACO_DSM_EN | PLLA9FRACO_DAC_MODE;
1559
1560 /* Write configuration to PLL */
1561 writel_relaxed(con0, pll->con_reg);
1562 writel_relaxed(con5, pll->con_reg + PLLA9FRACO_PLL_CON5_DIV_FRAC);
1563
1564 /* Enable PLL */
1565 con0 = readl_relaxed(pll->con_reg);
1566 con0 |= BIT(PLLA9FRACO_ENABLE_SHIFT);
1567 writel_relaxed(con0, pll->con_reg);
1568
1569 /* Wait for PLL lock if the PLL is enabled */
1570 ret = samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
1571 if (ret < 0)
1572 return ret;
1573
1574 /* Select FOUT (1) */
1575 con0 |= (PLLA9FRACO_MUX_SEL);
1576 writel_relaxed(con0, pll->con_reg);
1577
1578 return 0;
1579}
1580
1581static const struct clk_ops samsung_a9fraco_clk_ops = {
1582 .recalc_rate = samsung_a9fraco_recalc_rate,
1583 .determine_rate = samsung_pll_determine_rate,
1584 .set_rate = samsung_a9fraco_set_rate,
1585};
1586
1587static const struct clk_ops samsung_a9fraco_clk_min_ops = {
1588 .recalc_rate = samsung_a9fraco_recalc_rate,
1589};
1590
1591static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1592 const struct samsung_pll_clock *pll_clk)
1593{
1594 struct samsung_clk_pll *pll;
1595 struct clk_init_data init;
1596 int ret, len;
1597
1598 pll = kzalloc_obj(*pll);
1599 if (!pll) {
1600 pr_err("%s: could not allocate pll clk %s\n",
1601 __func__, pll_clk->name);
1602 return;
1603 }
1604
1605 init.name = pll_clk->name;
1606 init.flags = pll_clk->flags;
1607 init.parent_names = &pll_clk->parent_name;
1608 init.num_parents = 1;
1609
1610 if (pll_clk->rate_table) {
1611 /* find count of rates in rate_table */
1612 for (len = 0; pll_clk->rate_table[len].rate != 0; )
1613 len++;
1614
1615 pll->rate_count = len;
1616 pll->rate_table = kmemdup_array(pll_clk->rate_table,
1617 pll->rate_count,
1618 sizeof(*pll->rate_table),
1619 GFP_KERNEL);
1620 WARN(!pll->rate_table,
1621 "%s: could not allocate rate table for %s\n",
1622 __func__, pll_clk->name);
1623 }
1624
1625 switch (pll_clk->type) {
1626 case pll_2126:
1627 init.ops = &samsung_pll2126_clk_ops;
1628 break;
1629 case pll_3000:
1630 init.ops = &samsung_pll3000_clk_ops;
1631 break;
1632 /* clk_ops for 35xx and 2550 are similar */
1633 case pll_35xx:
1634 case pll_2550:
1635 case pll_1450x:
1636 case pll_1451x:
1637 case pll_1452x:
1638 case pll_142xx:
1639 case pll_1017x:
1640 case pll_a9fracm:
1641 pll->enable_offs = PLL35XX_ENABLE_SHIFT;
1642 pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
1643 if (!pll->rate_table)
1644 init.ops = &samsung_pll35xx_clk_min_ops;
1645 else
1646 init.ops = &samsung_pll35xx_clk_ops;
1647 break;
1648 case pll_1417x:
1649 case pll_1418x:
1650 case pll_1051x:
1651 case pll_1052x:
1652 case pll_0818x:
1653 case pll_0822x:
1654 case pll_0516x:
1655 case pll_0517x:
1656 case pll_0518x:
1657 case pll_0717x:
1658 case pll_0718x:
1659 case pll_0732x:
1660 pll->enable_offs = PLL0822X_ENABLE_SHIFT;
1661 pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
1662 if (!pll->rate_table)
1663 init.ops = &samsung_pll0822x_clk_min_ops;
1664 else
1665 init.ops = &samsung_pll0822x_clk_ops;
1666 break;
1667 case pll_4500:
1668 init.ops = &samsung_pll45xx_clk_min_ops;
1669 break;
1670 case pll_4502:
1671 case pll_4508:
1672 if (!pll->rate_table)
1673 init.ops = &samsung_pll45xx_clk_min_ops;
1674 else
1675 init.ops = &samsung_pll45xx_clk_ops;
1676 break;
1677 /* clk_ops for 36xx and 2650 are similar */
1678 case pll_36xx:
1679 case pll_2650:
1680 pll->enable_offs = PLL36XX_ENABLE_SHIFT;
1681 pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT;
1682 if (!pll->rate_table)
1683 init.ops = &samsung_pll36xx_clk_min_ops;
1684 else
1685 init.ops = &samsung_pll36xx_clk_ops;
1686 break;
1687 case pll_0831x:
1688 pll->enable_offs = PLL0831X_ENABLE_SHIFT;
1689 pll->lock_offs = PLL0831X_LOCK_STAT_SHIFT;
1690 if (!pll->rate_table)
1691 init.ops = &samsung_pll0831x_clk_min_ops;
1692 else
1693 init.ops = &samsung_pll0831x_clk_ops;
1694 break;
1695 case pll_6552:
1696 case pll_6552_s3c2416:
1697 init.ops = &samsung_pll6552_clk_ops;
1698 break;
1699 case pll_6553:
1700 init.ops = &samsung_pll6553_clk_ops;
1701 break;
1702 case pll_4600:
1703 case pll_4650:
1704 case pll_4650c:
1705 case pll_1460x:
1706 if (!pll->rate_table)
1707 init.ops = &samsung_pll46xx_clk_min_ops;
1708 else
1709 init.ops = &samsung_pll46xx_clk_ops;
1710 break;
1711 case pll_2550x:
1712 init.ops = &samsung_pll2550x_clk_ops;
1713 break;
1714 case pll_2550xx:
1715 if (!pll->rate_table)
1716 init.ops = &samsung_pll2550xx_clk_min_ops;
1717 else
1718 init.ops = &samsung_pll2550xx_clk_ops;
1719 break;
1720 case pll_2650x:
1721 if (!pll->rate_table)
1722 init.ops = &samsung_pll2650x_clk_min_ops;
1723 else
1724 init.ops = &samsung_pll2650x_clk_ops;
1725 break;
1726 case pll_2650xx:
1727 if (!pll->rate_table)
1728 init.ops = &samsung_pll2650xx_clk_min_ops;
1729 else
1730 init.ops = &samsung_pll2650xx_clk_ops;
1731 break;
1732 case pll_531x:
1733 case pll_4311:
1734 init.ops = &samsung_pll531x_clk_ops;
1735 break;
1736 case pll_1031x:
1737 if (!pll->rate_table)
1738 init.ops = &samsung_pll1031x_clk_min_ops;
1739 else
1740 init.ops = &samsung_pll1031x_clk_ops;
1741 break;
1742 case pll_a9fraco:
1743 pll->enable_offs = PLLA9FRACO_ENABLE_SHIFT;
1744 pll->lock_offs = PLLA9FRACO_LOCK_STAT_SHIFT;
1745 if (!pll->rate_table)
1746 init.ops = &samsung_a9fraco_clk_min_ops;
1747 else
1748 init.ops = &samsung_a9fraco_clk_ops;
1749 break;
1750 default:
1751 pr_warn("%s: Unknown pll type for pll clk %s\n",
1752 __func__, pll_clk->name);
1753 }
1754
1755 pll->hw.init = &init;
1756 pll->type = pll_clk->type;
1757 pll->lock_reg = ctx->reg_base + pll_clk->lock_offset;
1758 pll->con_reg = ctx->reg_base + pll_clk->con_offset;
1759
1760 ret = clk_hw_register(ctx->dev, &pll->hw);
1761 if (ret) {
1762 pr_err("%s: failed to register pll clock %s : %d\n",
1763 __func__, pll_clk->name, ret);
1764 kfree(pll->rate_table);
1765 kfree(pll);
1766 return;
1767 }
1768
1769 samsung_clk_add_lookup(ctx, &pll->hw, pll_clk->id);
1770}
1771
1772void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1773 const struct samsung_pll_clock *pll_list,
1774 unsigned int nr_pll)
1775{
1776 int cnt;
1777
1778 for (cnt = 0; cnt < nr_pll; cnt++)
1779 _samsung_clk_register_pll(ctx, &pll_list[cnt]);
1780}