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