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