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