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