xref: /openbmc/linux/drivers/clk/samsung/clk-pll.c (revision e23feb16)
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 "clk.h"
15 #include "clk-pll.h"
16 
17 #define PLL_TIMEOUT_MS		10
18 
19 struct samsung_clk_pll {
20 	struct clk_hw		hw;
21 	void __iomem		*lock_reg;
22 	void __iomem		*con_reg;
23 	enum samsung_pll_type	type;
24 	unsigned int		rate_count;
25 	const struct samsung_pll_rate_table *rate_table;
26 };
27 
28 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
29 
30 static const struct samsung_pll_rate_table *samsung_get_pll_settings(
31 				struct samsung_clk_pll *pll, unsigned long rate)
32 {
33 	const struct samsung_pll_rate_table  *rate_table = pll->rate_table;
34 	int i;
35 
36 	for (i = 0; i < pll->rate_count; i++) {
37 		if (rate == rate_table[i].rate)
38 			return &rate_table[i];
39 	}
40 
41 	return NULL;
42 }
43 
44 static long samsung_pll_round_rate(struct clk_hw *hw,
45 			unsigned long drate, unsigned long *prate)
46 {
47 	struct samsung_clk_pll *pll = to_clk_pll(hw);
48 	const struct samsung_pll_rate_table *rate_table = pll->rate_table;
49 	int i;
50 
51 	/* Assumming rate_table is in descending order */
52 	for (i = 0; i < pll->rate_count; i++) {
53 		if (drate >= rate_table[i].rate)
54 			return rate_table[i].rate;
55 	}
56 
57 	/* return minimum supported value */
58 	return rate_table[i - 1].rate;
59 }
60 
61 /*
62  * PLL35xx Clock Type
63  */
64 /* Maximum lock time can be 270 * PDIV cycles */
65 #define PLL35XX_LOCK_FACTOR	(270)
66 
67 #define PLL35XX_MDIV_MASK       (0x3FF)
68 #define PLL35XX_PDIV_MASK       (0x3F)
69 #define PLL35XX_SDIV_MASK       (0x7)
70 #define PLL35XX_LOCK_STAT_MASK	(0x1)
71 #define PLL35XX_MDIV_SHIFT      (16)
72 #define PLL35XX_PDIV_SHIFT      (8)
73 #define PLL35XX_SDIV_SHIFT      (0)
74 #define PLL35XX_LOCK_STAT_SHIFT	(29)
75 
76 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
77 				unsigned long parent_rate)
78 {
79 	struct samsung_clk_pll *pll = to_clk_pll(hw);
80 	u32 mdiv, pdiv, sdiv, pll_con;
81 	u64 fvco = parent_rate;
82 
83 	pll_con = __raw_readl(pll->con_reg);
84 	mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
85 	pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
86 	sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
87 
88 	fvco *= mdiv;
89 	do_div(fvco, (pdiv << sdiv));
90 
91 	return (unsigned long)fvco;
92 }
93 
94 static inline bool samsung_pll35xx_mp_change(
95 		const struct samsung_pll_rate_table *rate, u32 pll_con)
96 {
97 	u32 old_mdiv, old_pdiv;
98 
99 	old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
100 	old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
101 
102 	return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
103 }
104 
105 static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
106 					unsigned long prate)
107 {
108 	struct samsung_clk_pll *pll = to_clk_pll(hw);
109 	const struct samsung_pll_rate_table *rate;
110 	u32 tmp;
111 
112 	/* Get required rate settings from table */
113 	rate = samsung_get_pll_settings(pll, drate);
114 	if (!rate) {
115 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
116 			drate, __clk_get_name(hw->clk));
117 		return -EINVAL;
118 	}
119 
120 	tmp = __raw_readl(pll->con_reg);
121 
122 	if (!(samsung_pll35xx_mp_change(rate, tmp))) {
123 		/* If only s change, change just s value only*/
124 		tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
125 		tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
126 		__raw_writel(tmp, pll->con_reg);
127 
128 		return 0;
129 	}
130 
131 	/* Set PLL lock time. */
132 	__raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
133 			pll->lock_reg);
134 
135 	/* Change PLL PMS values */
136 	tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
137 			(PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
138 			(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
139 	tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
140 			(rate->pdiv << PLL35XX_PDIV_SHIFT) |
141 			(rate->sdiv << PLL35XX_SDIV_SHIFT);
142 	__raw_writel(tmp, pll->con_reg);
143 
144 	/* wait_lock_time */
145 	do {
146 		cpu_relax();
147 		tmp = __raw_readl(pll->con_reg);
148 	} while (!(tmp & (PLL35XX_LOCK_STAT_MASK
149 				<< PLL35XX_LOCK_STAT_SHIFT)));
150 	return 0;
151 }
152 
153 static const struct clk_ops samsung_pll35xx_clk_ops = {
154 	.recalc_rate = samsung_pll35xx_recalc_rate,
155 	.round_rate = samsung_pll_round_rate,
156 	.set_rate = samsung_pll35xx_set_rate,
157 };
158 
159 static const struct clk_ops samsung_pll35xx_clk_min_ops = {
160 	.recalc_rate = samsung_pll35xx_recalc_rate,
161 };
162 
163 /*
164  * PLL36xx Clock Type
165  */
166 /* Maximum lock time can be 3000 * PDIV cycles */
167 #define PLL36XX_LOCK_FACTOR    (3000)
168 
169 #define PLL36XX_KDIV_MASK	(0xFFFF)
170 #define PLL36XX_MDIV_MASK	(0x1FF)
171 #define PLL36XX_PDIV_MASK	(0x3F)
172 #define PLL36XX_SDIV_MASK	(0x7)
173 #define PLL36XX_MDIV_SHIFT	(16)
174 #define PLL36XX_PDIV_SHIFT	(8)
175 #define PLL36XX_SDIV_SHIFT	(0)
176 #define PLL36XX_KDIV_SHIFT	(0)
177 #define PLL36XX_LOCK_STAT_SHIFT	(29)
178 
179 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
180 				unsigned long parent_rate)
181 {
182 	struct samsung_clk_pll *pll = to_clk_pll(hw);
183 	u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
184 	s16 kdiv;
185 	u64 fvco = parent_rate;
186 
187 	pll_con0 = __raw_readl(pll->con_reg);
188 	pll_con1 = __raw_readl(pll->con_reg + 4);
189 	mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
190 	pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
191 	sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
192 	kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK);
193 
194 	fvco *= (mdiv << 16) + kdiv;
195 	do_div(fvco, (pdiv << sdiv));
196 	fvco >>= 16;
197 
198 	return (unsigned long)fvco;
199 }
200 
201 static inline bool samsung_pll36xx_mpk_change(
202 	const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
203 {
204 	u32 old_mdiv, old_pdiv, old_kdiv;
205 
206 	old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
207 	old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
208 	old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
209 
210 	return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
211 		rate->kdiv != old_kdiv);
212 }
213 
214 static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
215 					unsigned long parent_rate)
216 {
217 	struct samsung_clk_pll *pll = to_clk_pll(hw);
218 	u32 tmp, pll_con0, pll_con1;
219 	const struct samsung_pll_rate_table *rate;
220 
221 	rate = samsung_get_pll_settings(pll, drate);
222 	if (!rate) {
223 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
224 			drate, __clk_get_name(hw->clk));
225 		return -EINVAL;
226 	}
227 
228 	pll_con0 = __raw_readl(pll->con_reg);
229 	pll_con1 = __raw_readl(pll->con_reg + 4);
230 
231 	if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
232 		/* If only s change, change just s value only*/
233 		pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
234 		pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
235 		__raw_writel(pll_con0, pll->con_reg);
236 
237 		return 0;
238 	}
239 
240 	/* Set PLL lock time. */
241 	__raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
242 
243 	 /* Change PLL PMS values */
244 	pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
245 			(PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
246 			(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
247 	pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
248 			(rate->pdiv << PLL36XX_PDIV_SHIFT) |
249 			(rate->sdiv << PLL36XX_SDIV_SHIFT);
250 	__raw_writel(pll_con0, pll->con_reg);
251 
252 	pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
253 	pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
254 	__raw_writel(pll_con1, pll->con_reg + 4);
255 
256 	/* wait_lock_time */
257 	do {
258 		cpu_relax();
259 		tmp = __raw_readl(pll->con_reg);
260 	} while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
261 
262 	return 0;
263 }
264 
265 static const struct clk_ops samsung_pll36xx_clk_ops = {
266 	.recalc_rate = samsung_pll36xx_recalc_rate,
267 	.set_rate = samsung_pll36xx_set_rate,
268 	.round_rate = samsung_pll_round_rate,
269 };
270 
271 static const struct clk_ops samsung_pll36xx_clk_min_ops = {
272 	.recalc_rate = samsung_pll36xx_recalc_rate,
273 };
274 
275 /*
276  * PLL45xx Clock Type
277  */
278 #define PLL4502_LOCK_FACTOR	400
279 #define PLL4508_LOCK_FACTOR	240
280 
281 #define PLL45XX_MDIV_MASK	(0x3FF)
282 #define PLL45XX_PDIV_MASK	(0x3F)
283 #define PLL45XX_SDIV_MASK	(0x7)
284 #define PLL45XX_AFC_MASK	(0x1F)
285 #define PLL45XX_MDIV_SHIFT	(16)
286 #define PLL45XX_PDIV_SHIFT	(8)
287 #define PLL45XX_SDIV_SHIFT	(0)
288 #define PLL45XX_AFC_SHIFT	(0)
289 
290 #define PLL45XX_ENABLE		BIT(31)
291 #define PLL45XX_LOCKED		BIT(29)
292 
293 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
294 				unsigned long parent_rate)
295 {
296 	struct samsung_clk_pll *pll = to_clk_pll(hw);
297 	u32 mdiv, pdiv, sdiv, pll_con;
298 	u64 fvco = parent_rate;
299 
300 	pll_con = __raw_readl(pll->con_reg);
301 	mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
302 	pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
303 	sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
304 
305 	if (pll->type == pll_4508)
306 		sdiv = sdiv - 1;
307 
308 	fvco *= mdiv;
309 	do_div(fvco, (pdiv << sdiv));
310 
311 	return (unsigned long)fvco;
312 }
313 
314 static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
315 				const struct samsung_pll_rate_table *rate)
316 {
317 	u32 old_mdiv, old_pdiv, old_afc;
318 
319 	old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
320 	old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
321 	old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK;
322 
323 	return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
324 		|| old_afc != rate->afc);
325 }
326 
327 static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
328 					unsigned long prate)
329 {
330 	struct samsung_clk_pll *pll = to_clk_pll(hw);
331 	const struct samsung_pll_rate_table *rate;
332 	u32 con0, con1;
333 	ktime_t start;
334 
335 	/* Get required rate settings from table */
336 	rate = samsung_get_pll_settings(pll, drate);
337 	if (!rate) {
338 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
339 			drate, __clk_get_name(hw->clk));
340 		return -EINVAL;
341 	}
342 
343 	con0 = __raw_readl(pll->con_reg);
344 	con1 = __raw_readl(pll->con_reg + 0x4);
345 
346 	if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
347 		/* If only s change, change just s value only*/
348 		con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
349 		con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
350 		__raw_writel(con0, pll->con_reg);
351 
352 		return 0;
353 	}
354 
355 	/* Set PLL PMS values. */
356 	con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
357 			(PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
358 			(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
359 	con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) |
360 			(rate->pdiv << PLL45XX_PDIV_SHIFT) |
361 			(rate->sdiv << PLL45XX_SDIV_SHIFT);
362 
363 	/* Set PLL AFC value. */
364 	con1 = __raw_readl(pll->con_reg + 0x4);
365 	con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
366 	con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
367 
368 	/* Set PLL lock time. */
369 	switch (pll->type) {
370 	case pll_4502:
371 		__raw_writel(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
372 		break;
373 	case pll_4508:
374 		__raw_writel(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
375 		break;
376 	default:
377 		break;
378 	};
379 
380 	/* Set new configuration. */
381 	__raw_writel(con1, pll->con_reg + 0x4);
382 	__raw_writel(con0, pll->con_reg);
383 
384 	/* Wait for locking. */
385 	start = ktime_get();
386 	while (!(__raw_readl(pll->con_reg) & PLL45XX_LOCKED)) {
387 		ktime_t delta = ktime_sub(ktime_get(), start);
388 
389 		if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
390 			pr_err("%s: could not lock PLL %s\n",
391 					__func__, __clk_get_name(hw->clk));
392 			return -EFAULT;
393 		}
394 
395 		cpu_relax();
396 	}
397 
398 	return 0;
399 }
400 
401 static const struct clk_ops samsung_pll45xx_clk_ops = {
402 	.recalc_rate = samsung_pll45xx_recalc_rate,
403 	.round_rate = samsung_pll_round_rate,
404 	.set_rate = samsung_pll45xx_set_rate,
405 };
406 
407 static const struct clk_ops samsung_pll45xx_clk_min_ops = {
408 	.recalc_rate = samsung_pll45xx_recalc_rate,
409 };
410 
411 /*
412  * PLL46xx Clock Type
413  */
414 #define PLL46XX_LOCK_FACTOR	3000
415 
416 #define PLL46XX_VSEL_MASK	(1)
417 #define PLL46XX_MDIV_MASK	(0x1FF)
418 #define PLL46XX_PDIV_MASK	(0x3F)
419 #define PLL46XX_SDIV_MASK	(0x7)
420 #define PLL46XX_VSEL_SHIFT	(27)
421 #define PLL46XX_MDIV_SHIFT	(16)
422 #define PLL46XX_PDIV_SHIFT	(8)
423 #define PLL46XX_SDIV_SHIFT	(0)
424 
425 #define PLL46XX_KDIV_MASK	(0xFFFF)
426 #define PLL4650C_KDIV_MASK	(0xFFF)
427 #define PLL46XX_KDIV_SHIFT	(0)
428 #define PLL46XX_MFR_MASK	(0x3F)
429 #define PLL46XX_MRR_MASK	(0x1F)
430 #define PLL46XX_KDIV_SHIFT	(0)
431 #define PLL46XX_MFR_SHIFT	(16)
432 #define PLL46XX_MRR_SHIFT	(24)
433 
434 #define PLL46XX_ENABLE		BIT(31)
435 #define PLL46XX_LOCKED		BIT(29)
436 #define PLL46XX_VSEL		BIT(27)
437 
438 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
439 				unsigned long parent_rate)
440 {
441 	struct samsung_clk_pll *pll = to_clk_pll(hw);
442 	u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
443 	u64 fvco = parent_rate;
444 
445 	pll_con0 = __raw_readl(pll->con_reg);
446 	pll_con1 = __raw_readl(pll->con_reg + 4);
447 	mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
448 	pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
449 	sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
450 	kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
451 					pll_con1 & PLL46XX_KDIV_MASK;
452 
453 	shift = pll->type == pll_4600 ? 16 : 10;
454 	fvco *= (mdiv << shift) + kdiv;
455 	do_div(fvco, (pdiv << sdiv));
456 	fvco >>= shift;
457 
458 	return (unsigned long)fvco;
459 }
460 
461 static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
462 				const struct samsung_pll_rate_table *rate)
463 {
464 	u32 old_mdiv, old_pdiv, old_kdiv;
465 
466 	old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
467 	old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
468 	old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
469 
470 	return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
471 		|| old_kdiv != rate->kdiv);
472 }
473 
474 static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
475 					unsigned long prate)
476 {
477 	struct samsung_clk_pll *pll = to_clk_pll(hw);
478 	const struct samsung_pll_rate_table *rate;
479 	u32 con0, con1, lock;
480 	ktime_t start;
481 
482 	/* Get required rate settings from table */
483 	rate = samsung_get_pll_settings(pll, drate);
484 	if (!rate) {
485 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
486 			drate, __clk_get_name(hw->clk));
487 		return -EINVAL;
488 	}
489 
490 	con0 = __raw_readl(pll->con_reg);
491 	con1 = __raw_readl(pll->con_reg + 0x4);
492 
493 	if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
494 		/* If only s change, change just s value only*/
495 		con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
496 		con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
497 		__raw_writel(con0, pll->con_reg);
498 
499 		return 0;
500 	}
501 
502 	/* Set PLL lock time. */
503 	lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
504 	if (lock > 0xffff)
505 		/* Maximum lock time bitfield is 16-bit. */
506 		lock = 0xffff;
507 
508 	/* Set PLL PMS and VSEL values. */
509 	con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
510 			(PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
511 			(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
512 			(PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
513 	con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
514 			(rate->pdiv << PLL46XX_PDIV_SHIFT) |
515 			(rate->sdiv << PLL46XX_SDIV_SHIFT) |
516 			(rate->vsel << PLL46XX_VSEL_SHIFT);
517 
518 	/* Set PLL K, MFR and MRR values. */
519 	con1 = __raw_readl(pll->con_reg + 0x4);
520 	con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
521 			(PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
522 			(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
523 	con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) |
524 			(rate->mfr << PLL46XX_MFR_SHIFT) |
525 			(rate->mrr << PLL46XX_MRR_SHIFT);
526 
527 	/* Write configuration to PLL */
528 	__raw_writel(lock, pll->lock_reg);
529 	__raw_writel(con0, pll->con_reg);
530 	__raw_writel(con1, pll->con_reg + 0x4);
531 
532 	/* Wait for locking. */
533 	start = ktime_get();
534 	while (!(__raw_readl(pll->con_reg) & PLL46XX_LOCKED)) {
535 		ktime_t delta = ktime_sub(ktime_get(), start);
536 
537 		if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
538 			pr_err("%s: could not lock PLL %s\n",
539 					__func__, __clk_get_name(hw->clk));
540 			return -EFAULT;
541 		}
542 
543 		cpu_relax();
544 	}
545 
546 	return 0;
547 }
548 
549 static const struct clk_ops samsung_pll46xx_clk_ops = {
550 	.recalc_rate = samsung_pll46xx_recalc_rate,
551 	.round_rate = samsung_pll_round_rate,
552 	.set_rate = samsung_pll46xx_set_rate,
553 };
554 
555 static const struct clk_ops samsung_pll46xx_clk_min_ops = {
556 	.recalc_rate = samsung_pll46xx_recalc_rate,
557 };
558 
559 /*
560  * PLL6552 Clock Type
561  */
562 
563 #define PLL6552_MDIV_MASK	0x3ff
564 #define PLL6552_PDIV_MASK	0x3f
565 #define PLL6552_SDIV_MASK	0x7
566 #define PLL6552_MDIV_SHIFT	16
567 #define PLL6552_PDIV_SHIFT	8
568 #define PLL6552_SDIV_SHIFT	0
569 
570 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
571 						unsigned long parent_rate)
572 {
573 	struct samsung_clk_pll *pll = to_clk_pll(hw);
574 	u32 mdiv, pdiv, sdiv, pll_con;
575 	u64 fvco = parent_rate;
576 
577 	pll_con = __raw_readl(pll->con_reg);
578 	mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
579 	pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
580 	sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
581 
582 	fvco *= mdiv;
583 	do_div(fvco, (pdiv << sdiv));
584 
585 	return (unsigned long)fvco;
586 }
587 
588 static const struct clk_ops samsung_pll6552_clk_ops = {
589 	.recalc_rate = samsung_pll6552_recalc_rate,
590 };
591 
592 /*
593  * PLL6553 Clock Type
594  */
595 
596 #define PLL6553_MDIV_MASK	0xff
597 #define PLL6553_PDIV_MASK	0x3f
598 #define PLL6553_SDIV_MASK	0x7
599 #define PLL6553_KDIV_MASK	0xffff
600 #define PLL6553_MDIV_SHIFT	16
601 #define PLL6553_PDIV_SHIFT	8
602 #define PLL6553_SDIV_SHIFT	0
603 #define PLL6553_KDIV_SHIFT	0
604 
605 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
606 						unsigned long parent_rate)
607 {
608 	struct samsung_clk_pll *pll = to_clk_pll(hw);
609 	u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
610 	u64 fvco = parent_rate;
611 
612 	pll_con0 = __raw_readl(pll->con_reg);
613 	pll_con1 = __raw_readl(pll->con_reg + 0x4);
614 	mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
615 	pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
616 	sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
617 	kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
618 
619 	fvco *= (mdiv << 16) + kdiv;
620 	do_div(fvco, (pdiv << sdiv));
621 	fvco >>= 16;
622 
623 	return (unsigned long)fvco;
624 }
625 
626 static const struct clk_ops samsung_pll6553_clk_ops = {
627 	.recalc_rate = samsung_pll6553_recalc_rate,
628 };
629 
630 /*
631  * PLL2550x Clock Type
632  */
633 
634 #define PLL2550X_R_MASK       (0x1)
635 #define PLL2550X_P_MASK       (0x3F)
636 #define PLL2550X_M_MASK       (0x3FF)
637 #define PLL2550X_S_MASK       (0x7)
638 #define PLL2550X_R_SHIFT      (20)
639 #define PLL2550X_P_SHIFT      (14)
640 #define PLL2550X_M_SHIFT      (4)
641 #define PLL2550X_S_SHIFT      (0)
642 
643 struct samsung_clk_pll2550x {
644 	struct clk_hw		hw;
645 	const void __iomem	*reg_base;
646 	unsigned long		offset;
647 };
648 
649 #define to_clk_pll2550x(_hw) container_of(_hw, struct samsung_clk_pll2550x, hw)
650 
651 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
652 				unsigned long parent_rate)
653 {
654 	struct samsung_clk_pll2550x *pll = to_clk_pll2550x(hw);
655 	u32 r, p, m, s, pll_stat;
656 	u64 fvco = parent_rate;
657 
658 	pll_stat = __raw_readl(pll->reg_base + pll->offset * 3);
659 	r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
660 	if (!r)
661 		return 0;
662 	p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK;
663 	m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK;
664 	s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK;
665 
666 	fvco *= m;
667 	do_div(fvco, (p << s));
668 
669 	return (unsigned long)fvco;
670 }
671 
672 static const struct clk_ops samsung_pll2550x_clk_ops = {
673 	.recalc_rate = samsung_pll2550x_recalc_rate,
674 };
675 
676 struct clk * __init samsung_clk_register_pll2550x(const char *name,
677 			const char *pname, const void __iomem *reg_base,
678 			const unsigned long offset)
679 {
680 	struct samsung_clk_pll2550x *pll;
681 	struct clk *clk;
682 	struct clk_init_data init;
683 
684 	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
685 	if (!pll) {
686 		pr_err("%s: could not allocate pll clk %s\n", __func__, name);
687 		return NULL;
688 	}
689 
690 	init.name = name;
691 	init.ops = &samsung_pll2550x_clk_ops;
692 	init.flags = CLK_GET_RATE_NOCACHE;
693 	init.parent_names = &pname;
694 	init.num_parents = 1;
695 
696 	pll->hw.init = &init;
697 	pll->reg_base = reg_base;
698 	pll->offset = offset;
699 
700 	clk = clk_register(NULL, &pll->hw);
701 	if (IS_ERR(clk)) {
702 		pr_err("%s: failed to register pll clock %s\n", __func__,
703 				name);
704 		kfree(pll);
705 	}
706 
707 	if (clk_register_clkdev(clk, name, NULL))
708 		pr_err("%s: failed to register lookup for %s", __func__, name);
709 
710 	return clk;
711 }
712 
713 static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
714 						void __iomem *base)
715 {
716 	struct samsung_clk_pll *pll;
717 	struct clk *clk;
718 	struct clk_init_data init;
719 	int ret, len;
720 
721 	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
722 	if (!pll) {
723 		pr_err("%s: could not allocate pll clk %s\n",
724 			__func__, pll_clk->name);
725 		return;
726 	}
727 
728 	init.name = pll_clk->name;
729 	init.flags = pll_clk->flags;
730 	init.parent_names = &pll_clk->parent_name;
731 	init.num_parents = 1;
732 
733 	if (pll_clk->rate_table) {
734 		/* find count of rates in rate_table */
735 		for (len = 0; pll_clk->rate_table[len].rate != 0; )
736 			len++;
737 
738 		pll->rate_count = len;
739 		pll->rate_table = kmemdup(pll_clk->rate_table,
740 					pll->rate_count *
741 					sizeof(struct samsung_pll_rate_table),
742 					GFP_KERNEL);
743 		WARN(!pll->rate_table,
744 			"%s: could not allocate rate table for %s\n",
745 			__func__, pll_clk->name);
746 	}
747 
748 	switch (pll_clk->type) {
749 	/* clk_ops for 35xx and 2550 are similar */
750 	case pll_35xx:
751 	case pll_2550:
752 		if (!pll->rate_table)
753 			init.ops = &samsung_pll35xx_clk_min_ops;
754 		else
755 			init.ops = &samsung_pll35xx_clk_ops;
756 		break;
757 	case pll_4500:
758 		init.ops = &samsung_pll45xx_clk_min_ops;
759 		break;
760 	case pll_4502:
761 	case pll_4508:
762 		if (!pll->rate_table)
763 			init.ops = &samsung_pll45xx_clk_min_ops;
764 		else
765 			init.ops = &samsung_pll45xx_clk_ops;
766 		break;
767 	/* clk_ops for 36xx and 2650 are similar */
768 	case pll_36xx:
769 	case pll_2650:
770 		if (!pll->rate_table)
771 			init.ops = &samsung_pll36xx_clk_min_ops;
772 		else
773 			init.ops = &samsung_pll36xx_clk_ops;
774 		break;
775 	case pll_6552:
776 		init.ops = &samsung_pll6552_clk_ops;
777 		break;
778 	case pll_6553:
779 		init.ops = &samsung_pll6553_clk_ops;
780 		break;
781 	case pll_4600:
782 	case pll_4650:
783 	case pll_4650c:
784 		if (!pll->rate_table)
785 			init.ops = &samsung_pll46xx_clk_min_ops;
786 		else
787 			init.ops = &samsung_pll46xx_clk_ops;
788 		break;
789 	default:
790 		pr_warn("%s: Unknown pll type for pll clk %s\n",
791 			__func__, pll_clk->name);
792 	}
793 
794 	pll->hw.init = &init;
795 	pll->type = pll_clk->type;
796 	pll->lock_reg = base + pll_clk->lock_offset;
797 	pll->con_reg = base + pll_clk->con_offset;
798 
799 	clk = clk_register(NULL, &pll->hw);
800 	if (IS_ERR(clk)) {
801 		pr_err("%s: failed to register pll clock %s : %ld\n",
802 			__func__, pll_clk->name, PTR_ERR(clk));
803 		kfree(pll);
804 		return;
805 	}
806 
807 	samsung_clk_add_lookup(clk, pll_clk->id);
808 
809 	if (!pll_clk->alias)
810 		return;
811 
812 	ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
813 	if (ret)
814 		pr_err("%s: failed to register lookup for %s : %d",
815 			__func__, pll_clk->name, ret);
816 }
817 
818 void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
819 				unsigned int nr_pll, void __iomem *base)
820 {
821 	int cnt;
822 
823 	for (cnt = 0; cnt < nr_pll; cnt++)
824 		_samsung_clk_register_pll(&pll_list[cnt], base);
825 }
826