xref: /linux/drivers/clk/samsung/clk-pll.c (revision fbf5df34a4dbcd09d433dd4f0916bf9b2ddb16de)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
4  * Copyright (c) 2013 Linaro Ltd.
5  *
6  * This file contains the utility functions to register the pll clocks.
7 */
8 
9 #include <linux/errno.h>
10 #include <linux/hrtimer.h>
11 #include <linux/iopoll.h>
12 #include <linux/delay.h>
13 #include <linux/slab.h>
14 #include <linux/clk-provider.h>
15 #include <linux/io.h>
16 #include "clk.h"
17 #include "clk-pll.h"
18 
19 #define PLL_TIMEOUT_LOOPS	20000U
20 
21 struct samsung_clk_pll {
22 	struct clk_hw		hw;
23 	void __iomem		*lock_reg;
24 	void __iomem		*con_reg;
25 	/* PLL enable control bit offset in @con_reg register */
26 	unsigned short		enable_offs;
27 	/* PLL lock status bit offset in @con_reg register */
28 	unsigned short		lock_offs;
29 	enum samsung_pll_type	type;
30 	unsigned int		rate_count;
31 	const struct samsung_pll_rate_table *rate_table;
32 };
33 
34 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
35 
36 static const struct samsung_pll_rate_table *samsung_get_pll_settings(
37 				struct samsung_clk_pll *pll, unsigned long rate)
38 {
39 	const struct samsung_pll_rate_table  *rate_table = pll->rate_table;
40 	int i;
41 
42 	for (i = 0; i < pll->rate_count; i++) {
43 		if (rate == rate_table[i].rate)
44 			return &rate_table[i];
45 	}
46 
47 	return NULL;
48 }
49 
50 static int samsung_pll_determine_rate(struct clk_hw *hw,
51 				      struct clk_rate_request *req)
52 {
53 	struct samsung_clk_pll *pll = to_clk_pll(hw);
54 	const struct samsung_pll_rate_table *rate_table = pll->rate_table;
55 	int i;
56 
57 	/* Assuming rate_table is in descending order */
58 	for (i = 0; i < pll->rate_count; i++) {
59 		if (req->rate >= rate_table[i].rate) {
60 			req->rate = rate_table[i].rate;
61 
62 			return 0;
63 		}
64 	}
65 
66 	/* return minimum supported value */
67 	req->rate = rate_table[i - 1].rate;
68 
69 	return 0;
70 }
71 
72 /* Wait until the PLL is locked */
73 static int samsung_pll_lock_wait(struct samsung_clk_pll *pll,
74 				 unsigned int reg_mask)
75 {
76 	int ret;
77 	u32 val;
78 
79 	/*
80 	 * This function might be called when the timekeeping API can't be used
81 	 * to detect timeouts. One situation is when the clocksource is not yet
82 	 * initialized, another when the timekeeping is suspended. udelay() also
83 	 * cannot be used when the clocksource is not running on arm64, since
84 	 * the current timer is used as cycle counter. So a simple busy loop
85 	 * is used here.
86 	 * The limit of iterations has been derived from experimental
87 	 * measurements of various PLLs on multiple Exynos SoC variants. Single
88 	 * register read time was usually in range 0.4...1.5 us, never less than
89 	 * 0.4 us.
90 	 */
91 	ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val,
92 						val & reg_mask, 0,
93 						PLL_TIMEOUT_LOOPS);
94 	if (ret < 0)
95 		pr_err("Could not lock PLL %s\n", clk_hw_get_name(&pll->hw));
96 
97 	return ret;
98 }
99 
100 static int samsung_pll3xxx_enable(struct clk_hw *hw)
101 {
102 	struct samsung_clk_pll *pll = to_clk_pll(hw);
103 	u32 tmp;
104 
105 	tmp = readl_relaxed(pll->con_reg);
106 	tmp |= BIT(pll->enable_offs);
107 	writel_relaxed(tmp, pll->con_reg);
108 
109 	return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
110 }
111 
112 static void samsung_pll3xxx_disable(struct clk_hw *hw)
113 {
114 	struct samsung_clk_pll *pll = to_clk_pll(hw);
115 	u32 tmp;
116 
117 	tmp = readl_relaxed(pll->con_reg);
118 	tmp &= ~BIT(pll->enable_offs);
119 	writel_relaxed(tmp, pll->con_reg);
120 }
121 
122 /*
123  * PLL2126 Clock Type
124  */
125 
126 #define PLL2126_MDIV_MASK	(0xff)
127 #define PLL2126_PDIV_MASK	(0x3f)
128 #define PLL2126_SDIV_MASK	(0x3)
129 #define PLL2126_MDIV_SHIFT	(16)
130 #define PLL2126_PDIV_SHIFT	(8)
131 #define PLL2126_SDIV_SHIFT	(0)
132 
133 static unsigned long samsung_pll2126_recalc_rate(struct clk_hw *hw,
134 				unsigned long parent_rate)
135 {
136 	struct samsung_clk_pll *pll = to_clk_pll(hw);
137 	u32 pll_con, mdiv, pdiv, sdiv;
138 	u64 fvco = parent_rate;
139 
140 	pll_con = readl_relaxed(pll->con_reg);
141 	mdiv = (pll_con >> PLL2126_MDIV_SHIFT) & PLL2126_MDIV_MASK;
142 	pdiv = (pll_con >> PLL2126_PDIV_SHIFT) & PLL2126_PDIV_MASK;
143 	sdiv = (pll_con >> PLL2126_SDIV_SHIFT) & PLL2126_SDIV_MASK;
144 
145 	fvco *= (mdiv + 8);
146 	do_div(fvco, (pdiv + 2) << sdiv);
147 
148 	return (unsigned long)fvco;
149 }
150 
151 static const struct clk_ops samsung_pll2126_clk_ops = {
152 	.recalc_rate = samsung_pll2126_recalc_rate,
153 };
154 
155 /*
156  * PLL3000 Clock Type
157  */
158 
159 #define PLL3000_MDIV_MASK	(0xff)
160 #define PLL3000_PDIV_MASK	(0x3)
161 #define PLL3000_SDIV_MASK	(0x3)
162 #define PLL3000_MDIV_SHIFT	(16)
163 #define PLL3000_PDIV_SHIFT	(8)
164 #define PLL3000_SDIV_SHIFT	(0)
165 
166 static unsigned long samsung_pll3000_recalc_rate(struct clk_hw *hw,
167 				unsigned long parent_rate)
168 {
169 	struct samsung_clk_pll *pll = to_clk_pll(hw);
170 	u32 pll_con, mdiv, pdiv, sdiv;
171 	u64 fvco = parent_rate;
172 
173 	pll_con = readl_relaxed(pll->con_reg);
174 	mdiv = (pll_con >> PLL3000_MDIV_SHIFT) & PLL3000_MDIV_MASK;
175 	pdiv = (pll_con >> PLL3000_PDIV_SHIFT) & PLL3000_PDIV_MASK;
176 	sdiv = (pll_con >> PLL3000_SDIV_SHIFT) & PLL3000_SDIV_MASK;
177 
178 	fvco *= (2 * (mdiv + 8));
179 	do_div(fvco, pdiv << sdiv);
180 
181 	return (unsigned long)fvco;
182 }
183 
184 static const struct clk_ops samsung_pll3000_clk_ops = {
185 	.recalc_rate = samsung_pll3000_recalc_rate,
186 };
187 
188 /*
189  * PLL35xx Clock Type
190  */
191 /* Maximum lock time can be 270 * PDIV cycles */
192 #define PLL35XX_LOCK_FACTOR	(270)
193 #define PLL142XX_LOCK_FACTOR	(150)
194 
195 #define PLL35XX_MDIV_MASK       (0x3FF)
196 #define PLL35XX_PDIV_MASK       (0x3F)
197 #define PLL35XX_SDIV_MASK       (0x7)
198 #define PLL35XX_MDIV_SHIFT      (16)
199 #define PLL35XX_PDIV_SHIFT      (8)
200 #define PLL35XX_SDIV_SHIFT      (0)
201 #define PLL35XX_LOCK_STAT_SHIFT	(29)
202 #define PLL35XX_ENABLE_SHIFT	(31)
203 
204 /* A9FRACM is similar to PLL35xx, except that MDIV is bit different */
205 #define PLLA9FRACM_MDIV_SHIFT	(14)
206 
207 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
208 				unsigned long parent_rate)
209 {
210 	struct samsung_clk_pll *pll = to_clk_pll(hw);
211 	u32 mdiv, pdiv, sdiv, pll_con;
212 	u64 fvco = parent_rate;
213 
214 	pll_con = readl_relaxed(pll->con_reg);
215 
216 	if (pll->type == pll_a9fracm)
217 		mdiv = (pll_con >> PLLA9FRACM_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
218 	else
219 		mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
220 
221 	pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
222 	sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
223 
224 	fvco *= mdiv;
225 	do_div(fvco, (pdiv << sdiv));
226 
227 	return (unsigned long)fvco;
228 }
229 
230 static inline bool samsung_pll35xx_mp_change(u32 pll_type,
231 					     const struct samsung_pll_rate_table *rate, u32 pll_con)
232 {
233 	u32 old_mdiv, old_pdiv;
234 
235 	if (pll_type == pll_a9fracm)
236 		old_mdiv = (pll_con >> PLLA9FRACM_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
237 	else
238 		old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
239 	old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
240 
241 	return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
242 }
243 
244 static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
245 					unsigned long prate)
246 {
247 	struct samsung_clk_pll *pll = to_clk_pll(hw);
248 	const struct samsung_pll_rate_table *rate;
249 	u32 tmp;
250 	u32 mdiv_shift;
251 
252 	if (pll->type == pll_a9fracm)
253 		mdiv_shift = PLLA9FRACM_MDIV_SHIFT;
254 	else
255 		mdiv_shift = PLL35XX_MDIV_SHIFT;
256 
257 	/* Get required rate settings from table */
258 	rate = samsung_get_pll_settings(pll, drate);
259 	if (!rate) {
260 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
261 			drate, clk_hw_get_name(hw));
262 		return -EINVAL;
263 	}
264 
265 	tmp = readl_relaxed(pll->con_reg);
266 
267 	if (!(samsung_pll35xx_mp_change(pll->type, rate, tmp))) {
268 		/* If only s change, change just s value only*/
269 		tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
270 		tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
271 		writel_relaxed(tmp, pll->con_reg);
272 
273 		return 0;
274 	}
275 
276 	/* Set PLL lock time. */
277 	if (pll->type == pll_142xx || pll->type == pll_1017x || pll->type == pll_a9fracm)
278 		writel_relaxed(rate->pdiv * PLL142XX_LOCK_FACTOR,
279 			pll->lock_reg);
280 	else
281 		writel_relaxed(rate->pdiv * PLL35XX_LOCK_FACTOR,
282 			pll->lock_reg);
283 
284 	/* Change PLL PMS values */
285 	tmp &= ~((PLL35XX_MDIV_MASK << mdiv_shift) |
286 			(PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
287 			(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
288 	tmp |= (rate->mdiv << mdiv_shift) |
289 			(rate->pdiv << PLL35XX_PDIV_SHIFT) |
290 			(rate->sdiv << PLL35XX_SDIV_SHIFT);
291 	writel_relaxed(tmp, pll->con_reg);
292 
293 	/* Wait for PLL lock if the PLL is enabled */
294 	if (tmp & BIT(pll->enable_offs))
295 		return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
296 
297 	return 0;
298 }
299 
300 static const struct clk_ops samsung_pll35xx_clk_ops = {
301 	.recalc_rate = samsung_pll35xx_recalc_rate,
302 	.determine_rate = samsung_pll_determine_rate,
303 	.set_rate = samsung_pll35xx_set_rate,
304 	.enable = samsung_pll3xxx_enable,
305 	.disable = samsung_pll3xxx_disable,
306 };
307 
308 static const struct clk_ops samsung_pll35xx_clk_min_ops = {
309 	.recalc_rate = samsung_pll35xx_recalc_rate,
310 };
311 
312 /*
313  * PLL36xx Clock Type
314  */
315 /* Maximum lock time can be 3000 * PDIV cycles */
316 #define PLL36XX_LOCK_FACTOR    (3000)
317 
318 #define PLL36XX_KDIV_MASK	(0xFFFF)
319 #define PLL36XX_MDIV_MASK	(0x1FF)
320 #define PLL36XX_PDIV_MASK	(0x3F)
321 #define PLL36XX_SDIV_MASK	(0x7)
322 #define PLL36XX_MDIV_SHIFT	(16)
323 #define PLL36XX_PDIV_SHIFT	(8)
324 #define PLL36XX_SDIV_SHIFT	(0)
325 #define PLL36XX_KDIV_SHIFT	(0)
326 #define PLL36XX_LOCK_STAT_SHIFT	(29)
327 #define PLL36XX_ENABLE_SHIFT	(31)
328 
329 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
330 				unsigned long parent_rate)
331 {
332 	struct samsung_clk_pll *pll = to_clk_pll(hw);
333 	u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
334 	s16 kdiv;
335 	u64 fvco = parent_rate;
336 
337 	pll_con0 = readl_relaxed(pll->con_reg);
338 	pll_con1 = readl_relaxed(pll->con_reg + 4);
339 	mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
340 	pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
341 	sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
342 	kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK);
343 
344 	fvco *= (mdiv << 16) + kdiv;
345 	do_div(fvco, (pdiv << sdiv));
346 	fvco >>= 16;
347 
348 	return (unsigned long)fvco;
349 }
350 
351 static inline bool samsung_pll36xx_mpk_change(
352 	const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
353 {
354 	u32 old_mdiv, old_pdiv, old_kdiv;
355 
356 	old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
357 	old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
358 	old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
359 
360 	return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
361 		rate->kdiv != old_kdiv);
362 }
363 
364 static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
365 					unsigned long parent_rate)
366 {
367 	struct samsung_clk_pll *pll = to_clk_pll(hw);
368 	u32 pll_con0, pll_con1;
369 	const struct samsung_pll_rate_table *rate;
370 
371 	rate = samsung_get_pll_settings(pll, drate);
372 	if (!rate) {
373 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
374 			drate, clk_hw_get_name(hw));
375 		return -EINVAL;
376 	}
377 
378 	pll_con0 = readl_relaxed(pll->con_reg);
379 	pll_con1 = readl_relaxed(pll->con_reg + 4);
380 
381 	if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
382 		/* If only s change, change just s value only*/
383 		pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
384 		pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
385 		writel_relaxed(pll_con0, pll->con_reg);
386 
387 		return 0;
388 	}
389 
390 	/* Set PLL lock time. */
391 	writel_relaxed(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
392 
393 	 /* Change PLL PMS values */
394 	pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
395 			(PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
396 			(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
397 	pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
398 			(rate->pdiv << PLL36XX_PDIV_SHIFT) |
399 			(rate->sdiv << PLL36XX_SDIV_SHIFT);
400 	writel_relaxed(pll_con0, pll->con_reg);
401 
402 	pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
403 	pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
404 	writel_relaxed(pll_con1, pll->con_reg + 4);
405 
406 	if (pll_con0 & BIT(pll->enable_offs))
407 		return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
408 
409 	return 0;
410 }
411 
412 static const struct clk_ops samsung_pll36xx_clk_ops = {
413 	.recalc_rate = samsung_pll36xx_recalc_rate,
414 	.set_rate = samsung_pll36xx_set_rate,
415 	.determine_rate = samsung_pll_determine_rate,
416 	.enable = samsung_pll3xxx_enable,
417 	.disable = samsung_pll3xxx_disable,
418 };
419 
420 static const struct clk_ops samsung_pll36xx_clk_min_ops = {
421 	.recalc_rate = samsung_pll36xx_recalc_rate,
422 };
423 
424 /*
425  * PLL0822x Clock Type
426  */
427 /* Maximum lock time can be 150 * PDIV cycles */
428 #define PLL0822X_LOCK_FACTOR		(150)
429 
430 #define PLL0822X_MDIV_MASK		(0x3FF)
431 #define PLL0822X_PDIV_MASK		(0x3F)
432 #define PLL0822X_SDIV_MASK		(0x7)
433 #define PLL0822X_MDIV_SHIFT		(16)
434 #define PLL0822X_PDIV_SHIFT		(8)
435 #define PLL0822X_SDIV_SHIFT		(0)
436 #define PLL0822X_LOCK_STAT_SHIFT	(29)
437 #define PLL0822X_ENABLE_SHIFT		(31)
438 
439 /*
440  * PLL1418x, PLL0717x and PLL0718x are similar
441  * to PLL0822x, except that MDIV is one bit smaller
442  */
443 #define PLL1418X_MDIV_MASK		(0x1FF)
444 
445 static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
446 						  unsigned long parent_rate)
447 {
448 	struct samsung_clk_pll *pll = to_clk_pll(hw);
449 	u32 mdiv, pdiv, sdiv, pll_con3;
450 	u64 fvco = parent_rate;
451 
452 	pll_con3 = readl_relaxed(pll->con_reg);
453 
454 	if (pll->type != pll_1418x &&
455 	    pll->type != pll_0717x &&
456 	    pll->type != pll_0718x)
457 		mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK;
458 	else
459 		mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL1418X_MDIV_MASK;
460 
461 	pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK;
462 	sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK;
463 
464 	fvco *= mdiv;
465 	if (pll->type == pll_0516x)
466 		fvco *= 2;
467 
468 	do_div(fvco, (pdiv << sdiv));
469 
470 	return (unsigned long)fvco;
471 }
472 
473 static int samsung_pll0822x_set_rate(struct clk_hw *hw, unsigned long drate,
474 				     unsigned long prate)
475 {
476 	const struct samsung_pll_rate_table *rate;
477 	struct samsung_clk_pll *pll = to_clk_pll(hw);
478 	u32 mdiv_mask, pll_con3;
479 
480 	if (pll->type != pll_1418x)
481 		mdiv_mask = PLL0822X_MDIV_MASK;
482 	else
483 		mdiv_mask = PLL1418X_MDIV_MASK;
484 
485 	/* Get required rate settings from table */
486 	rate = samsung_get_pll_settings(pll, drate);
487 	if (!rate) {
488 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
489 			drate, clk_hw_get_name(hw));
490 		return -EINVAL;
491 	}
492 
493 	/* Change PLL PMS values */
494 	pll_con3 = readl_relaxed(pll->con_reg);
495 	pll_con3 &= ~((mdiv_mask << PLL0822X_MDIV_SHIFT) |
496 			(PLL0822X_PDIV_MASK << PLL0822X_PDIV_SHIFT) |
497 			(PLL0822X_SDIV_MASK << PLL0822X_SDIV_SHIFT));
498 	pll_con3 |= (rate->mdiv << PLL0822X_MDIV_SHIFT) |
499 			(rate->pdiv << PLL0822X_PDIV_SHIFT) |
500 			(rate->sdiv << PLL0822X_SDIV_SHIFT);
501 
502 	/* Set PLL lock time */
503 	writel_relaxed(rate->pdiv * PLL0822X_LOCK_FACTOR,
504 			pll->lock_reg);
505 
506 	/* Write PMS values */
507 	writel_relaxed(pll_con3, pll->con_reg);
508 
509 	/* Wait for PLL lock if the PLL is enabled */
510 	if (pll_con3 & BIT(pll->enable_offs))
511 		return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
512 
513 	return 0;
514 }
515 
516 static const struct clk_ops samsung_pll0822x_clk_ops = {
517 	.recalc_rate = samsung_pll0822x_recalc_rate,
518 	.determine_rate = samsung_pll_determine_rate,
519 	.set_rate = samsung_pll0822x_set_rate,
520 	.enable = samsung_pll3xxx_enable,
521 	.disable = samsung_pll3xxx_disable,
522 };
523 
524 static const struct clk_ops samsung_pll0822x_clk_min_ops = {
525 	.recalc_rate = samsung_pll0822x_recalc_rate,
526 };
527 
528 /*
529  * PLL0831x Clock Type
530  */
531 /* Maximum lock time can be 500 * PDIV cycles */
532 #define PLL0831X_LOCK_FACTOR		(500)
533 
534 #define PLL0831X_KDIV_MASK		(0xFFFF)
535 #define PLL0831X_MDIV_MASK		(0x1FF)
536 #define PLL0831X_PDIV_MASK		(0x3F)
537 #define PLL0831X_SDIV_MASK		(0x7)
538 #define PLL0831X_MDIV_SHIFT		(16)
539 #define PLL0831X_PDIV_SHIFT		(8)
540 #define PLL0831X_SDIV_SHIFT		(0)
541 #define PLL0831X_KDIV_SHIFT		(0)
542 #define PLL0831X_LOCK_STAT_SHIFT	(29)
543 #define PLL0831X_ENABLE_SHIFT		(31)
544 
545 static unsigned long samsung_pll0831x_recalc_rate(struct clk_hw *hw,
546 						  unsigned long parent_rate)
547 {
548 	struct samsung_clk_pll *pll = to_clk_pll(hw);
549 	u32 mdiv, pdiv, sdiv, pll_con3, pll_con5;
550 	s16 kdiv;
551 	u64 fvco = parent_rate;
552 
553 	pll_con3 = readl_relaxed(pll->con_reg);
554 	pll_con5 = readl_relaxed(pll->con_reg + 8);
555 	mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK;
556 	pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK;
557 	sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK;
558 	kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) & PLL0831X_KDIV_MASK);
559 
560 	fvco *= (mdiv << 16) + kdiv;
561 	do_div(fvco, (pdiv << sdiv));
562 	fvco >>= 16;
563 
564 	return (unsigned long)fvco;
565 }
566 
567 static int samsung_pll0831x_set_rate(struct clk_hw *hw, unsigned long drate,
568 				     unsigned long parent_rate)
569 {
570 	const struct samsung_pll_rate_table *rate;
571 	struct samsung_clk_pll *pll = to_clk_pll(hw);
572 	u32 pll_con3, pll_con5;
573 
574 	/* Get required rate settings from table */
575 	rate = samsung_get_pll_settings(pll, drate);
576 	if (!rate) {
577 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
578 			drate, clk_hw_get_name(hw));
579 		return -EINVAL;
580 	}
581 
582 	pll_con3 = readl_relaxed(pll->con_reg);
583 	pll_con5 = readl_relaxed(pll->con_reg + 8);
584 
585 	/* Change PLL PMSK values */
586 	pll_con3 &= ~((PLL0831X_MDIV_MASK << PLL0831X_MDIV_SHIFT) |
587 			(PLL0831X_PDIV_MASK << PLL0831X_PDIV_SHIFT) |
588 			(PLL0831X_SDIV_MASK << PLL0831X_SDIV_SHIFT));
589 	pll_con3 |= (rate->mdiv << PLL0831X_MDIV_SHIFT) |
590 			(rate->pdiv << PLL0831X_PDIV_SHIFT) |
591 			(rate->sdiv << PLL0831X_SDIV_SHIFT);
592 	pll_con5 &= ~(PLL0831X_KDIV_MASK << PLL0831X_KDIV_SHIFT);
593 	/*
594 	 * kdiv is 16-bit 2's complement (s16), but stored as unsigned int.
595 	 * Cast it to u16 to avoid leading 0xffff's in case of negative value.
596 	 */
597 	pll_con5 |= ((u16)rate->kdiv << PLL0831X_KDIV_SHIFT);
598 
599 	/* Set PLL lock time */
600 	writel_relaxed(rate->pdiv * PLL0831X_LOCK_FACTOR, pll->lock_reg);
601 
602 	/* Write PMSK values */
603 	writel_relaxed(pll_con3, pll->con_reg);
604 	writel_relaxed(pll_con5, pll->con_reg + 8);
605 
606 	/* Wait for PLL lock if the PLL is enabled */
607 	if (pll_con3 & BIT(pll->enable_offs))
608 		return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
609 
610 	return 0;
611 }
612 
613 static const struct clk_ops samsung_pll0831x_clk_ops = {
614 	.recalc_rate = samsung_pll0831x_recalc_rate,
615 	.set_rate = samsung_pll0831x_set_rate,
616 	.determine_rate = samsung_pll_determine_rate,
617 	.enable = samsung_pll3xxx_enable,
618 	.disable = samsung_pll3xxx_disable,
619 };
620 
621 static const struct clk_ops samsung_pll0831x_clk_min_ops = {
622 	.recalc_rate = samsung_pll0831x_recalc_rate,
623 };
624 
625 /*
626  * PLL45xx Clock Type
627  */
628 #define PLL4502_LOCK_FACTOR	400
629 #define PLL4508_LOCK_FACTOR	240
630 
631 #define PLL45XX_MDIV_MASK	(0x3FF)
632 #define PLL45XX_PDIV_MASK	(0x3F)
633 #define PLL45XX_SDIV_MASK	(0x7)
634 #define PLL45XX_AFC_MASK	(0x1F)
635 #define PLL45XX_MDIV_SHIFT	(16)
636 #define PLL45XX_PDIV_SHIFT	(8)
637 #define PLL45XX_SDIV_SHIFT	(0)
638 #define PLL45XX_AFC_SHIFT	(0)
639 
640 #define PLL45XX_ENABLE		BIT(31)
641 #define PLL45XX_LOCKED		BIT(29)
642 
643 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
644 				unsigned long parent_rate)
645 {
646 	struct samsung_clk_pll *pll = to_clk_pll(hw);
647 	u32 mdiv, pdiv, sdiv, pll_con;
648 	u64 fvco = parent_rate;
649 
650 	pll_con = readl_relaxed(pll->con_reg);
651 	mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
652 	pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
653 	sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
654 
655 	if (pll->type == pll_4508)
656 		sdiv = sdiv - 1;
657 
658 	fvco *= mdiv;
659 	do_div(fvco, (pdiv << sdiv));
660 
661 	return (unsigned long)fvco;
662 }
663 
664 static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
665 				const struct samsung_pll_rate_table *rate)
666 {
667 	u32 old_mdiv, old_pdiv, old_afc;
668 
669 	old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
670 	old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
671 	old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK;
672 
673 	return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
674 		|| old_afc != rate->afc);
675 }
676 
677 static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
678 					unsigned long prate)
679 {
680 	struct samsung_clk_pll *pll = to_clk_pll(hw);
681 	const struct samsung_pll_rate_table *rate;
682 	u32 con0, con1;
683 
684 	/* Get required rate settings from table */
685 	rate = samsung_get_pll_settings(pll, drate);
686 	if (!rate) {
687 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
688 			drate, clk_hw_get_name(hw));
689 		return -EINVAL;
690 	}
691 
692 	con0 = readl_relaxed(pll->con_reg);
693 	con1 = readl_relaxed(pll->con_reg + 0x4);
694 
695 	if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
696 		/* If only s change, change just s value only*/
697 		con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
698 		con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
699 		writel_relaxed(con0, pll->con_reg);
700 
701 		return 0;
702 	}
703 
704 	/* Set PLL PMS values. */
705 	con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
706 			(PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
707 			(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
708 	con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) |
709 			(rate->pdiv << PLL45XX_PDIV_SHIFT) |
710 			(rate->sdiv << PLL45XX_SDIV_SHIFT);
711 
712 	/* Set PLL AFC value. */
713 	con1 = readl_relaxed(pll->con_reg + 0x4);
714 	con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
715 	con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
716 
717 	/* Set PLL lock time. */
718 	switch (pll->type) {
719 	case pll_4502:
720 		writel_relaxed(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
721 		break;
722 	case pll_4508:
723 		writel_relaxed(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
724 		break;
725 	default:
726 		break;
727 	}
728 
729 	/* Set new configuration. */
730 	writel_relaxed(con1, pll->con_reg + 0x4);
731 	writel_relaxed(con0, pll->con_reg);
732 
733 	/* Wait for PLL lock */
734 	return samsung_pll_lock_wait(pll, PLL45XX_LOCKED);
735 }
736 
737 static const struct clk_ops samsung_pll45xx_clk_ops = {
738 	.recalc_rate = samsung_pll45xx_recalc_rate,
739 	.determine_rate = samsung_pll_determine_rate,
740 	.set_rate = samsung_pll45xx_set_rate,
741 };
742 
743 static const struct clk_ops samsung_pll45xx_clk_min_ops = {
744 	.recalc_rate = samsung_pll45xx_recalc_rate,
745 };
746 
747 /*
748  * PLL46xx Clock Type
749  */
750 #define PLL46XX_LOCK_FACTOR	3000
751 
752 #define PLL46XX_VSEL_MASK	(1)
753 #define PLL46XX_MDIV_MASK	(0x1FF)
754 #define PLL1460X_MDIV_MASK	(0x3FF)
755 
756 #define PLL46XX_PDIV_MASK	(0x3F)
757 #define PLL46XX_SDIV_MASK	(0x7)
758 #define PLL46XX_VSEL_SHIFT	(27)
759 #define PLL46XX_MDIV_SHIFT	(16)
760 #define PLL46XX_PDIV_SHIFT	(8)
761 #define PLL46XX_SDIV_SHIFT	(0)
762 
763 #define PLL46XX_KDIV_MASK	(0xFFFF)
764 #define PLL4650C_KDIV_MASK	(0xFFF)
765 #define PLL46XX_KDIV_SHIFT	(0)
766 #define PLL46XX_MFR_MASK	(0x3F)
767 #define PLL46XX_MRR_MASK	(0x1F)
768 #define PLL46XX_KDIV_SHIFT	(0)
769 #define PLL46XX_MFR_SHIFT	(16)
770 #define PLL46XX_MRR_SHIFT	(24)
771 
772 #define PLL46XX_ENABLE		BIT(31)
773 #define PLL46XX_LOCKED		BIT(29)
774 #define PLL46XX_VSEL		BIT(27)
775 
776 static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
777 				unsigned long parent_rate)
778 {
779 	struct samsung_clk_pll *pll = to_clk_pll(hw);
780 	u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
781 	u64 fvco = parent_rate;
782 
783 	pll_con0 = readl_relaxed(pll->con_reg);
784 	pll_con1 = readl_relaxed(pll->con_reg + 4);
785 	mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & ((pll->type == pll_1460x) ?
786 				PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK);
787 	pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
788 	sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
789 	kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
790 					pll_con1 & PLL46XX_KDIV_MASK;
791 
792 	shift = ((pll->type == pll_4600) || (pll->type == pll_1460x)) ? 16 : 10;
793 
794 	fvco *= (mdiv << shift) + kdiv;
795 	do_div(fvco, (pdiv << sdiv));
796 	fvco >>= shift;
797 
798 	return (unsigned long)fvco;
799 }
800 
801 static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
802 				const struct samsung_pll_rate_table *rate)
803 {
804 	u32 old_mdiv, old_pdiv, old_kdiv;
805 
806 	old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
807 	old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
808 	old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
809 
810 	return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
811 		|| old_kdiv != rate->kdiv);
812 }
813 
814 static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
815 					unsigned long prate)
816 {
817 	struct samsung_clk_pll *pll = to_clk_pll(hw);
818 	const struct samsung_pll_rate_table *rate;
819 	u32 con0, con1, lock;
820 
821 	/* Get required rate settings from table */
822 	rate = samsung_get_pll_settings(pll, drate);
823 	if (!rate) {
824 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
825 			drate, clk_hw_get_name(hw));
826 		return -EINVAL;
827 	}
828 
829 	con0 = readl_relaxed(pll->con_reg);
830 	con1 = readl_relaxed(pll->con_reg + 0x4);
831 
832 	if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
833 		/* If only s change, change just s value only*/
834 		con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
835 		con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
836 		writel_relaxed(con0, pll->con_reg);
837 
838 		return 0;
839 	}
840 
841 	/* Set PLL lock time. */
842 	lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
843 	if (lock > 0xffff)
844 		/* Maximum lock time bitfield is 16-bit. */
845 		lock = 0xffff;
846 
847 	/* Set PLL PMS and VSEL values. */
848 	if (pll->type == pll_1460x) {
849 		con0 &= ~((PLL1460X_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
850 			(PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
851 			(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT));
852 	} else {
853 		con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
854 			(PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
855 			(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
856 			(PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
857 		con0 |=	rate->vsel << PLL46XX_VSEL_SHIFT;
858 	}
859 
860 	con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
861 			(rate->pdiv << PLL46XX_PDIV_SHIFT) |
862 			(rate->sdiv << PLL46XX_SDIV_SHIFT);
863 
864 	/* Set PLL K, MFR and MRR values. */
865 	con1 = readl_relaxed(pll->con_reg + 0x4);
866 	con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
867 			(PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
868 			(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
869 	con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) |
870 			(rate->mfr << PLL46XX_MFR_SHIFT) |
871 			(rate->mrr << PLL46XX_MRR_SHIFT);
872 
873 	/* Write configuration to PLL */
874 	writel_relaxed(lock, pll->lock_reg);
875 	writel_relaxed(con0, pll->con_reg);
876 	writel_relaxed(con1, pll->con_reg + 0x4);
877 
878 	/* Wait for PLL lock */
879 	return samsung_pll_lock_wait(pll, PLL46XX_LOCKED);
880 }
881 
882 static const struct clk_ops samsung_pll46xx_clk_ops = {
883 	.recalc_rate = samsung_pll46xx_recalc_rate,
884 	.determine_rate = samsung_pll_determine_rate,
885 	.set_rate = samsung_pll46xx_set_rate,
886 };
887 
888 static const struct clk_ops samsung_pll46xx_clk_min_ops = {
889 	.recalc_rate = samsung_pll46xx_recalc_rate,
890 };
891 
892 /*
893  * PLL6552 Clock Type
894  */
895 
896 #define PLL6552_MDIV_MASK	0x3ff
897 #define PLL6552_PDIV_MASK	0x3f
898 #define PLL6552_SDIV_MASK	0x7
899 #define PLL6552_MDIV_SHIFT	16
900 #define PLL6552_MDIV_SHIFT_2416	14
901 #define PLL6552_PDIV_SHIFT	8
902 #define PLL6552_PDIV_SHIFT_2416	5
903 #define PLL6552_SDIV_SHIFT	0
904 
905 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
906 						unsigned long parent_rate)
907 {
908 	struct samsung_clk_pll *pll = to_clk_pll(hw);
909 	u32 mdiv, pdiv, sdiv, pll_con;
910 	u64 fvco = parent_rate;
911 
912 	pll_con = readl_relaxed(pll->con_reg);
913 	if (pll->type == pll_6552_s3c2416) {
914 		mdiv = (pll_con >> PLL6552_MDIV_SHIFT_2416) & PLL6552_MDIV_MASK;
915 		pdiv = (pll_con >> PLL6552_PDIV_SHIFT_2416) & PLL6552_PDIV_MASK;
916 	} else {
917 		mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
918 		pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
919 	}
920 	sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
921 
922 	fvco *= mdiv;
923 	do_div(fvco, (pdiv << sdiv));
924 
925 	return (unsigned long)fvco;
926 }
927 
928 static const struct clk_ops samsung_pll6552_clk_ops = {
929 	.recalc_rate = samsung_pll6552_recalc_rate,
930 };
931 
932 /*
933  * PLL6553 Clock Type
934  */
935 
936 #define PLL6553_MDIV_MASK	0xff
937 #define PLL6553_PDIV_MASK	0x3f
938 #define PLL6553_SDIV_MASK	0x7
939 #define PLL6553_KDIV_MASK	0xffff
940 #define PLL6553_MDIV_SHIFT	16
941 #define PLL6553_PDIV_SHIFT	8
942 #define PLL6553_SDIV_SHIFT	0
943 #define PLL6553_KDIV_SHIFT	0
944 
945 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
946 						unsigned long parent_rate)
947 {
948 	struct samsung_clk_pll *pll = to_clk_pll(hw);
949 	u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
950 	u64 fvco = parent_rate;
951 
952 	pll_con0 = readl_relaxed(pll->con_reg);
953 	pll_con1 = readl_relaxed(pll->con_reg + 0x4);
954 	mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
955 	pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
956 	sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
957 	kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
958 
959 	fvco *= (mdiv << 16) + kdiv;
960 	do_div(fvco, (pdiv << sdiv));
961 	fvco >>= 16;
962 
963 	return (unsigned long)fvco;
964 }
965 
966 static const struct clk_ops samsung_pll6553_clk_ops = {
967 	.recalc_rate = samsung_pll6553_recalc_rate,
968 };
969 
970 /*
971  * PLL2550x Clock Type
972  */
973 
974 #define PLL2550X_R_MASK       (0x1)
975 #define PLL2550X_P_MASK       (0x3F)
976 #define PLL2550X_M_MASK       (0x3FF)
977 #define PLL2550X_S_MASK       (0x7)
978 #define PLL2550X_R_SHIFT      (20)
979 #define PLL2550X_P_SHIFT      (14)
980 #define PLL2550X_M_SHIFT      (4)
981 #define PLL2550X_S_SHIFT      (0)
982 
983 static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
984 				unsigned long parent_rate)
985 {
986 	struct samsung_clk_pll *pll = to_clk_pll(hw);
987 	u32 r, p, m, s, pll_stat;
988 	u64 fvco = parent_rate;
989 
990 	pll_stat = readl_relaxed(pll->con_reg);
991 	r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
992 	if (!r)
993 		return 0;
994 	p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK;
995 	m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK;
996 	s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK;
997 
998 	fvco *= m;
999 	do_div(fvco, (p << s));
1000 
1001 	return (unsigned long)fvco;
1002 }
1003 
1004 static const struct clk_ops samsung_pll2550x_clk_ops = {
1005 	.recalc_rate = samsung_pll2550x_recalc_rate,
1006 };
1007 
1008 /*
1009  * PLL2550xx Clock Type
1010  */
1011 
1012 /* Maximum lock time can be 270 * PDIV cycles */
1013 #define PLL2550XX_LOCK_FACTOR 270
1014 
1015 #define PLL2550XX_M_MASK		0x3FF
1016 #define PLL2550XX_P_MASK		0x3F
1017 #define PLL2550XX_S_MASK		0x7
1018 #define PLL2550XX_LOCK_STAT_MASK	0x1
1019 #define PLL2550XX_M_SHIFT		9
1020 #define PLL2550XX_P_SHIFT		3
1021 #define PLL2550XX_S_SHIFT		0
1022 #define PLL2550XX_LOCK_STAT_SHIFT	21
1023 
1024 static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw *hw,
1025 				unsigned long parent_rate)
1026 {
1027 	struct samsung_clk_pll *pll = to_clk_pll(hw);
1028 	u32 mdiv, pdiv, sdiv, pll_con;
1029 	u64 fvco = parent_rate;
1030 
1031 	pll_con = readl_relaxed(pll->con_reg);
1032 	mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
1033 	pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
1034 	sdiv = (pll_con >> PLL2550XX_S_SHIFT) & PLL2550XX_S_MASK;
1035 
1036 	fvco *= mdiv;
1037 	do_div(fvco, (pdiv << sdiv));
1038 
1039 	return (unsigned long)fvco;
1040 }
1041 
1042 static inline bool samsung_pll2550xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con)
1043 {
1044 	u32 old_mdiv, old_pdiv;
1045 
1046 	old_mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
1047 	old_pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
1048 
1049 	return mdiv != old_mdiv || pdiv != old_pdiv;
1050 }
1051 
1052 static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
1053 					unsigned long prate)
1054 {
1055 	struct samsung_clk_pll *pll = to_clk_pll(hw);
1056 	const struct samsung_pll_rate_table *rate;
1057 	u32 tmp;
1058 
1059 	/* Get required rate settings from table */
1060 	rate = samsung_get_pll_settings(pll, drate);
1061 	if (!rate) {
1062 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1063 			drate, clk_hw_get_name(hw));
1064 		return -EINVAL;
1065 	}
1066 
1067 	tmp = readl_relaxed(pll->con_reg);
1068 
1069 	if (!(samsung_pll2550xx_mp_change(rate->mdiv, rate->pdiv, tmp))) {
1070 		/* If only s change, change just s value only*/
1071 		tmp &= ~(PLL2550XX_S_MASK << PLL2550XX_S_SHIFT);
1072 		tmp |= rate->sdiv << PLL2550XX_S_SHIFT;
1073 		writel_relaxed(tmp, pll->con_reg);
1074 
1075 		return 0;
1076 	}
1077 
1078 	/* Set PLL lock time. */
1079 	writel_relaxed(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg);
1080 
1081 	/* Change PLL PMS values */
1082 	tmp &= ~((PLL2550XX_M_MASK << PLL2550XX_M_SHIFT) |
1083 			(PLL2550XX_P_MASK << PLL2550XX_P_SHIFT) |
1084 			(PLL2550XX_S_MASK << PLL2550XX_S_SHIFT));
1085 	tmp |= (rate->mdiv << PLL2550XX_M_SHIFT) |
1086 			(rate->pdiv << PLL2550XX_P_SHIFT) |
1087 			(rate->sdiv << PLL2550XX_S_SHIFT);
1088 	writel_relaxed(tmp, pll->con_reg);
1089 
1090 	/* Wait for PLL lock */
1091 	return samsung_pll_lock_wait(pll,
1092 			PLL2550XX_LOCK_STAT_MASK << PLL2550XX_LOCK_STAT_SHIFT);
1093 }
1094 
1095 static const struct clk_ops samsung_pll2550xx_clk_ops = {
1096 	.recalc_rate = samsung_pll2550xx_recalc_rate,
1097 	.determine_rate = samsung_pll_determine_rate,
1098 	.set_rate = samsung_pll2550xx_set_rate,
1099 };
1100 
1101 static const struct clk_ops samsung_pll2550xx_clk_min_ops = {
1102 	.recalc_rate = samsung_pll2550xx_recalc_rate,
1103 };
1104 
1105 /*
1106  * PLL2650x Clock Type
1107  */
1108 
1109 /* Maximum lock time can be 3000 * PDIV cycles */
1110 #define PLL2650X_LOCK_FACTOR		3000
1111 
1112 #define PLL2650X_M_MASK			0x1ff
1113 #define PLL2650X_P_MASK			0x3f
1114 #define PLL2650X_S_MASK			0x7
1115 #define PLL2650X_K_MASK			0xffff
1116 #define PLL2650X_LOCK_STAT_MASK		0x1
1117 #define PLL2650X_M_SHIFT		16
1118 #define PLL2650X_P_SHIFT		8
1119 #define PLL2650X_S_SHIFT		0
1120 #define PLL2650X_K_SHIFT		0
1121 #define PLL2650X_LOCK_STAT_SHIFT	29
1122 #define PLL2650X_PLL_ENABLE_SHIFT	31
1123 
1124 static unsigned long samsung_pll2650x_recalc_rate(struct clk_hw *hw,
1125 				unsigned long parent_rate)
1126 {
1127 	struct samsung_clk_pll *pll = to_clk_pll(hw);
1128 	u64 fout = parent_rate;
1129 	u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
1130 	s16 kdiv;
1131 
1132 	pll_con0 = readl_relaxed(pll->con_reg);
1133 	mdiv = (pll_con0 >> PLL2650X_M_SHIFT) & PLL2650X_M_MASK;
1134 	pdiv = (pll_con0 >> PLL2650X_P_SHIFT) & PLL2650X_P_MASK;
1135 	sdiv = (pll_con0 >> PLL2650X_S_SHIFT) & PLL2650X_S_MASK;
1136 
1137 	pll_con1 = readl_relaxed(pll->con_reg + 4);
1138 	kdiv = (s16)((pll_con1 >> PLL2650X_K_SHIFT) & PLL2650X_K_MASK);
1139 
1140 	fout *= (mdiv << 16) + kdiv;
1141 	do_div(fout, (pdiv << sdiv));
1142 	fout >>= 16;
1143 
1144 	return (unsigned long)fout;
1145 }
1146 
1147 static int samsung_pll2650x_set_rate(struct clk_hw *hw, unsigned long drate,
1148 					unsigned long prate)
1149 {
1150 	struct samsung_clk_pll *pll = to_clk_pll(hw);
1151 	const struct samsung_pll_rate_table *rate;
1152 	u32 con0, con1;
1153 
1154 	/* Get required rate settings from table */
1155 	rate = samsung_get_pll_settings(pll, drate);
1156 	if (!rate) {
1157 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1158 			drate, clk_hw_get_name(hw));
1159 		return -EINVAL;
1160 	}
1161 
1162 	con0 = readl_relaxed(pll->con_reg);
1163 	con1 = readl_relaxed(pll->con_reg + 4);
1164 
1165 	/* Set PLL lock time. */
1166 	writel_relaxed(rate->pdiv * PLL2650X_LOCK_FACTOR, pll->lock_reg);
1167 
1168 	/* Change PLL PMS values */
1169 	con0 &= ~((PLL2650X_M_MASK << PLL2650X_M_SHIFT) |
1170 			(PLL2650X_P_MASK << PLL2650X_P_SHIFT) |
1171 			(PLL2650X_S_MASK << PLL2650X_S_SHIFT));
1172 	con0 |= (rate->mdiv << PLL2650X_M_SHIFT) |
1173 			(rate->pdiv << PLL2650X_P_SHIFT) |
1174 			(rate->sdiv << PLL2650X_S_SHIFT);
1175 	con0 |= (1 << PLL2650X_PLL_ENABLE_SHIFT);
1176 	writel_relaxed(con0, pll->con_reg);
1177 
1178 	con1 &= ~(PLL2650X_K_MASK << PLL2650X_K_SHIFT);
1179 	con1 |= ((rate->kdiv & PLL2650X_K_MASK) << PLL2650X_K_SHIFT);
1180 	writel_relaxed(con1, pll->con_reg + 4);
1181 
1182 	/* Wait for PLL lock */
1183 	return samsung_pll_lock_wait(pll,
1184 			PLL2650X_LOCK_STAT_MASK << PLL2650X_LOCK_STAT_SHIFT);
1185 }
1186 
1187 static const struct clk_ops samsung_pll2650x_clk_ops = {
1188 	.recalc_rate = samsung_pll2650x_recalc_rate,
1189 	.determine_rate = samsung_pll_determine_rate,
1190 	.set_rate = samsung_pll2650x_set_rate,
1191 };
1192 
1193 static const struct clk_ops samsung_pll2650x_clk_min_ops = {
1194 	.recalc_rate = samsung_pll2650x_recalc_rate,
1195 };
1196 
1197 /*
1198  * PLL2650XX Clock Type
1199  */
1200 
1201 /* Maximum lock time can be 3000 * PDIV cycles */
1202 #define PLL2650XX_LOCK_FACTOR 3000
1203 
1204 #define PLL2650XX_MDIV_SHIFT		9
1205 #define PLL2650XX_PDIV_SHIFT		3
1206 #define PLL2650XX_SDIV_SHIFT		0
1207 #define PLL2650XX_KDIV_SHIFT		0
1208 #define PLL2650XX_MDIV_MASK		0x1ff
1209 #define PLL2650XX_PDIV_MASK		0x3f
1210 #define PLL2650XX_SDIV_MASK		0x7
1211 #define PLL2650XX_KDIV_MASK		0xffff
1212 #define PLL2650XX_PLL_ENABLE_SHIFT	23
1213 #define PLL2650XX_PLL_LOCKTIME_SHIFT	21
1214 #define PLL2650XX_PLL_FOUTMASK_SHIFT	31
1215 
1216 static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw,
1217 				unsigned long parent_rate)
1218 {
1219 	struct samsung_clk_pll *pll = to_clk_pll(hw);
1220 	u32 mdiv, pdiv, sdiv, pll_con0, pll_con2;
1221 	s16 kdiv;
1222 	u64 fvco = parent_rate;
1223 
1224 	pll_con0 = readl_relaxed(pll->con_reg);
1225 	pll_con2 = readl_relaxed(pll->con_reg + 8);
1226 	mdiv = (pll_con0 >> PLL2650XX_MDIV_SHIFT) & PLL2650XX_MDIV_MASK;
1227 	pdiv = (pll_con0 >> PLL2650XX_PDIV_SHIFT) & PLL2650XX_PDIV_MASK;
1228 	sdiv = (pll_con0 >> PLL2650XX_SDIV_SHIFT) & PLL2650XX_SDIV_MASK;
1229 	kdiv = (s16)(pll_con2 & PLL2650XX_KDIV_MASK);
1230 
1231 	fvco *= (mdiv << 16) + kdiv;
1232 	do_div(fvco, (pdiv << sdiv));
1233 	fvco >>= 16;
1234 
1235 	return (unsigned long)fvco;
1236 }
1237 
1238 static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
1239 					unsigned long parent_rate)
1240 {
1241 	struct samsung_clk_pll *pll = to_clk_pll(hw);
1242 	u32 pll_con0, pll_con2;
1243 	const struct samsung_pll_rate_table *rate;
1244 
1245 	rate = samsung_get_pll_settings(pll, drate);
1246 	if (!rate) {
1247 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1248 			drate, clk_hw_get_name(hw));
1249 		return -EINVAL;
1250 	}
1251 
1252 	pll_con0 = readl_relaxed(pll->con_reg);
1253 	pll_con2 = readl_relaxed(pll->con_reg + 8);
1254 
1255 	 /* Change PLL PMS values */
1256 	pll_con0 &= ~(PLL2650XX_MDIV_MASK << PLL2650XX_MDIV_SHIFT |
1257 			PLL2650XX_PDIV_MASK << PLL2650XX_PDIV_SHIFT |
1258 			PLL2650XX_SDIV_MASK << PLL2650XX_SDIV_SHIFT);
1259 	pll_con0 |= rate->mdiv << PLL2650XX_MDIV_SHIFT;
1260 	pll_con0 |= rate->pdiv << PLL2650XX_PDIV_SHIFT;
1261 	pll_con0 |= rate->sdiv << PLL2650XX_SDIV_SHIFT;
1262 	pll_con0 |= 1 << PLL2650XX_PLL_ENABLE_SHIFT;
1263 	pll_con0 |= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT;
1264 
1265 	pll_con2 &= ~(PLL2650XX_KDIV_MASK << PLL2650XX_KDIV_SHIFT);
1266 	pll_con2 |= ((~(rate->kdiv) + 1) & PLL2650XX_KDIV_MASK)
1267 			<< PLL2650XX_KDIV_SHIFT;
1268 
1269 	/* Set PLL lock time. */
1270 	writel_relaxed(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg);
1271 
1272 	writel_relaxed(pll_con0, pll->con_reg);
1273 	writel_relaxed(pll_con2, pll->con_reg + 8);
1274 
1275 	return samsung_pll_lock_wait(pll, 0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT);
1276 }
1277 
1278 static const struct clk_ops samsung_pll2650xx_clk_ops = {
1279 	.recalc_rate = samsung_pll2650xx_recalc_rate,
1280 	.set_rate = samsung_pll2650xx_set_rate,
1281 	.determine_rate = samsung_pll_determine_rate,
1282 };
1283 
1284 static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
1285 	.recalc_rate = samsung_pll2650xx_recalc_rate,
1286 };
1287 
1288 /*
1289  * PLL531X Clock Type
1290  */
1291 /* Maximum lock time can be 500 * PDIV cycles */
1292 #define PLL531X_LOCK_FACTOR		(500)
1293 #define PLL531X_MDIV_MASK		(0x3FF)
1294 #define PLL531X_PDIV_MASK		(0x3F)
1295 #define PLL531X_SDIV_MASK		(0x7)
1296 #define PLL531X_FDIV_MASK		(0xFFFFFFFF)
1297 #define PLL531X_MDIV_SHIFT		(16)
1298 #define PLL531X_PDIV_SHIFT		(8)
1299 #define PLL531X_SDIV_SHIFT		(0)
1300 
1301 static unsigned long samsung_pll531x_recalc_rate(struct clk_hw *hw,
1302 						 unsigned long parent_rate)
1303 {
1304 	struct samsung_clk_pll *pll = to_clk_pll(hw);
1305 	u32 pdiv, sdiv, fdiv, pll_con0, pll_con8;
1306 	u64 mdiv, fout = parent_rate;
1307 
1308 	pll_con0 = readl_relaxed(pll->con_reg);
1309 	pll_con8 = readl_relaxed(pll->con_reg + 20);
1310 	mdiv = (pll_con0 >> PLL531X_MDIV_SHIFT) & PLL531X_MDIV_MASK;
1311 	pdiv = (pll_con0 >> PLL531X_PDIV_SHIFT) & PLL531X_PDIV_MASK;
1312 	sdiv = (pll_con0 >> PLL531X_SDIV_SHIFT) & PLL531X_SDIV_MASK;
1313 	fdiv = (pll_con8 & PLL531X_FDIV_MASK);
1314 
1315 	if (fdiv >> 31)
1316 		mdiv--;
1317 
1318 	fout *= (mdiv << 24) + (fdiv >> 8);
1319 	do_div(fout, (pdiv << sdiv));
1320 	fout >>= 24;
1321 
1322 	return (unsigned long)fout;
1323 }
1324 
1325 static const struct clk_ops samsung_pll531x_clk_ops = {
1326 	.recalc_rate = samsung_pll531x_recalc_rate,
1327 };
1328 
1329 /*
1330  * PLL1031x Clock Type
1331  */
1332 #define PLL1031X_LOCK_FACTOR	(500)
1333 
1334 #define PLL1031X_MDIV_MASK	(0x3ff)
1335 #define PLL1031X_PDIV_MASK	(0x3f)
1336 #define PLL1031X_SDIV_MASK	(0x7)
1337 #define PLL1031X_MDIV_SHIFT	(16)
1338 #define PLL1031X_PDIV_SHIFT	(8)
1339 #define PLL1031X_SDIV_SHIFT	(0)
1340 
1341 #define PLL1031X_KDIV_MASK	(0xffff)
1342 #define PLL1031X_KDIV_SHIFT	(0)
1343 #define PLL1031X_MFR_MASK	(0x3f)
1344 #define PLL1031X_MRR_MASK	(0x1f)
1345 #define PLL1031X_MFR_SHIFT	(16)
1346 #define PLL1031X_MRR_SHIFT	(24)
1347 
1348 static unsigned long samsung_pll1031x_recalc_rate(struct clk_hw *hw,
1349 						  unsigned long parent_rate)
1350 {
1351 	struct samsung_clk_pll *pll = to_clk_pll(hw);
1352 	u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con3;
1353 	u64 fvco = parent_rate;
1354 
1355 	pll_con0 = readl_relaxed(pll->con_reg);
1356 	pll_con3 = readl_relaxed(pll->con_reg + 0xc);
1357 	mdiv = (pll_con0 >> PLL1031X_MDIV_SHIFT) & PLL1031X_MDIV_MASK;
1358 	pdiv = (pll_con0 >> PLL1031X_PDIV_SHIFT) & PLL1031X_PDIV_MASK;
1359 	sdiv = (pll_con0 >> PLL1031X_SDIV_SHIFT) & PLL1031X_SDIV_MASK;
1360 	kdiv = (pll_con3 & PLL1031X_KDIV_MASK);
1361 
1362 	fvco *= (mdiv << PLL1031X_MDIV_SHIFT) + kdiv;
1363 	do_div(fvco, (pdiv << sdiv));
1364 	fvco >>= PLL1031X_MDIV_SHIFT;
1365 
1366 	return (unsigned long)fvco;
1367 }
1368 
1369 static bool samsung_pll1031x_mpk_change(u32 pll_con0, u32 pll_con3,
1370 					const struct samsung_pll_rate_table *rate)
1371 {
1372 	u32 old_mdiv, old_pdiv, old_kdiv;
1373 
1374 	old_mdiv = (pll_con0 >> PLL1031X_MDIV_SHIFT) & PLL1031X_MDIV_MASK;
1375 	old_pdiv = (pll_con0 >> PLL1031X_PDIV_SHIFT) & PLL1031X_PDIV_MASK;
1376 	old_kdiv = (pll_con3 >> PLL1031X_KDIV_SHIFT) & PLL1031X_KDIV_MASK;
1377 
1378 	return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv ||
1379 		old_kdiv != rate->kdiv);
1380 }
1381 
1382 static int samsung_pll1031x_set_rate(struct clk_hw *hw, unsigned long drate,
1383 				     unsigned long prate)
1384 {
1385 	struct samsung_clk_pll *pll = to_clk_pll(hw);
1386 	const struct samsung_pll_rate_table *rate;
1387 	u32 con0, con3;
1388 
1389 	/* Get required rate settings from table */
1390 	rate = samsung_get_pll_settings(pll, drate);
1391 	if (!rate) {
1392 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1393 		       drate, clk_hw_get_name(hw));
1394 		return -EINVAL;
1395 	}
1396 
1397 	con0 = readl_relaxed(pll->con_reg);
1398 	con3 = readl_relaxed(pll->con_reg + 0xc);
1399 
1400 	if (!(samsung_pll1031x_mpk_change(con0, con3, rate))) {
1401 		/* If only s change, change just s value only */
1402 		con0 &= ~(PLL1031X_SDIV_MASK << PLL1031X_SDIV_SHIFT);
1403 		con0 |= rate->sdiv << PLL1031X_SDIV_SHIFT;
1404 		writel_relaxed(con0, pll->con_reg);
1405 
1406 		return 0;
1407 	}
1408 
1409 	/* Set PLL lock time. */
1410 	writel_relaxed(rate->pdiv * PLL1031X_LOCK_FACTOR, pll->lock_reg);
1411 
1412 	/* Set PLL M, P, and S values. */
1413 	con0 &= ~((PLL1031X_MDIV_MASK << PLL1031X_MDIV_SHIFT) |
1414 		  (PLL1031X_PDIV_MASK << PLL1031X_PDIV_SHIFT) |
1415 		  (PLL1031X_SDIV_MASK << PLL1031X_SDIV_SHIFT));
1416 
1417 	con0 |= (rate->mdiv << PLL1031X_MDIV_SHIFT) |
1418 		(rate->pdiv << PLL1031X_PDIV_SHIFT) |
1419 		(rate->sdiv << PLL1031X_SDIV_SHIFT);
1420 
1421 	/* Set PLL K, MFR and MRR values. */
1422 	con3 = readl_relaxed(pll->con_reg + 0xc);
1423 	con3 &= ~((PLL1031X_KDIV_MASK << PLL1031X_KDIV_SHIFT) |
1424 		  (PLL1031X_MFR_MASK << PLL1031X_MFR_SHIFT) |
1425 		  (PLL1031X_MRR_MASK << PLL1031X_MRR_SHIFT));
1426 	con3 |= (rate->kdiv << PLL1031X_KDIV_SHIFT) |
1427 		(rate->mfr << PLL1031X_MFR_SHIFT) |
1428 		(rate->mrr << PLL1031X_MRR_SHIFT);
1429 
1430 	/* Write configuration to PLL */
1431 	writel_relaxed(con0, pll->con_reg);
1432 	writel_relaxed(con3, pll->con_reg + 0xc);
1433 
1434 	/* Wait for PLL lock if the PLL is enabled */
1435 	return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
1436 }
1437 
1438 static const struct clk_ops samsung_pll1031x_clk_ops = {
1439 	.recalc_rate = samsung_pll1031x_recalc_rate,
1440 	.determine_rate = samsung_pll_determine_rate,
1441 	.set_rate = samsung_pll1031x_set_rate,
1442 };
1443 
1444 static const struct clk_ops samsung_pll1031x_clk_min_ops = {
1445 	.recalc_rate = samsung_pll1031x_recalc_rate,
1446 };
1447 
1448 /*
1449  * PLLA9FRACO Clock Type
1450  */
1451 #define PLLA9FRACO_LOCK_FACTOR		(500)
1452 
1453 #define PLLA9FRACO_MDIV_MASK		(0x3ff)
1454 #define PLLA9FRACO_PDIV_MASK		(0x3f)
1455 #define PLLA9FRACO_SDIV_MASK		(0x7)
1456 #define PLLA9FRACO_MDIV_SHIFT		(14)
1457 #define PLLA9FRACO_PDIV_SHIFT		(8)
1458 #define PLLA9FRACO_SDIV_SHIFT		(0)
1459 
1460 #define PLLA9FRACO_PLL_CON5_DIV_FRAC	(0x14)
1461 #define PLLA9FRACO_KDIV_MASK		(0xffffff)
1462 #define PLLA9FRACO_KDIV_SHIFT		(0)
1463 #define PLLA9FRACO_DAC_MODE		BIT(30)
1464 #define PLLA9FRACO_DSM_EN		BIT(31)
1465 #define PLLA9FRACO_FOUTPOSTDIVEN	BIT(3)
1466 #define PLLA9FRACO_MUX_SEL		BIT(4)
1467 #define PLLA9FRACO_ENABLE_SHIFT		(31)
1468 #define PLLA9FRACO_LOCK_STAT_SHIFT	(29)
1469 
1470 static unsigned long samsung_a9fraco_recalc_rate(struct clk_hw *hw,
1471 						 unsigned long parent_rate)
1472 {
1473 	struct samsung_clk_pll *pll = to_clk_pll(hw);
1474 	u32 pll_con0, pll_con5;
1475 	u64 mdiv, pdiv, sdiv, kdiv;
1476 	u64 fvco = parent_rate;
1477 
1478 	pll_con0 = readl_relaxed(pll->con_reg);
1479 	pll_con5 = readl_relaxed(pll->con_reg + PLLA9FRACO_PLL_CON5_DIV_FRAC);
1480 	mdiv = (pll_con0 >> PLLA9FRACO_MDIV_SHIFT) & PLLA9FRACO_MDIV_MASK;
1481 	pdiv = (pll_con0 >> PLLA9FRACO_PDIV_SHIFT) & PLLA9FRACO_PDIV_MASK;
1482 	sdiv = (pll_con0 >> PLLA9FRACO_SDIV_SHIFT) & PLLA9FRACO_SDIV_MASK;
1483 	kdiv = (pll_con5 & PLLA9FRACO_KDIV_MASK);
1484 
1485 	/* fvco = fref * (M + K/2^24) / p * (S+1) */
1486 	fvco *= mdiv;
1487 	fvco = (fvco << 24) + kdiv;
1488 	fvco = div64_u64(fvco, ((pdiv * (sdiv + 1)) << 24));
1489 
1490 	return (unsigned long)fvco;
1491 }
1492 
1493 static bool samsung_a9fraco_mpk_change(u32 pll_con0, u32 pll_con5,
1494 				       const struct samsung_pll_rate_table *rate)
1495 {
1496 	u32 old_mdiv, old_pdiv, old_kdiv;
1497 
1498 	old_mdiv = (pll_con0 >> PLLA9FRACO_MDIV_SHIFT) & PLLA9FRACO_MDIV_MASK;
1499 	old_pdiv = (pll_con0 >> PLLA9FRACO_PDIV_SHIFT) & PLLA9FRACO_PDIV_MASK;
1500 	old_kdiv = (pll_con5 >> PLLA9FRACO_KDIV_SHIFT) & PLLA9FRACO_KDIV_MASK;
1501 
1502 	return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv || old_kdiv != rate->kdiv);
1503 }
1504 
1505 static int samsung_a9fraco_set_rate(struct clk_hw *hw, unsigned long drate, unsigned long prate)
1506 {
1507 	struct samsung_clk_pll *pll = to_clk_pll(hw);
1508 	const struct samsung_pll_rate_table *rate;
1509 	u32 con0, con5;
1510 	int ret;
1511 
1512 	/* Get required rate settings from table */
1513 	rate = samsung_get_pll_settings(pll, drate);
1514 	if (!rate) {
1515 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1516 		       drate, clk_hw_get_name(hw));
1517 		return -EINVAL;
1518 	}
1519 
1520 	con0 = readl_relaxed(pll->con_reg);
1521 	con5 = readl_relaxed(pll->con_reg + PLLA9FRACO_PLL_CON5_DIV_FRAC);
1522 
1523 	if (!(samsung_a9fraco_mpk_change(con0, con5, rate))) {
1524 		/* If only s change, change just s value only */
1525 		con0 &= ~(PLLA9FRACO_SDIV_MASK << PLLA9FRACO_SDIV_SHIFT);
1526 		con0 |= rate->sdiv << PLLA9FRACO_SDIV_SHIFT;
1527 		writel_relaxed(con0, pll->con_reg);
1528 
1529 		return 0;
1530 	}
1531 
1532 	/* Select OSCCLK (0) */
1533 	con0 = readl_relaxed(pll->con_reg);
1534 	con0 &= ~(PLLA9FRACO_MUX_SEL);
1535 	writel_relaxed(con0, pll->con_reg);
1536 
1537 	/* Disable PLL */
1538 	con0 &= ~BIT(PLLA9FRACO_ENABLE_SHIFT);
1539 	writel_relaxed(con0, pll->con_reg);
1540 
1541 	/* Set PLL lock time. */
1542 	writel_relaxed(rate->pdiv * PLLA9FRACO_LOCK_FACTOR, pll->lock_reg);
1543 
1544 	/* Set PLL M, P, and S values. */
1545 	con0 &= ~((PLLA9FRACO_MDIV_MASK << PLLA9FRACO_MDIV_SHIFT) |
1546 		  (PLLA9FRACO_PDIV_MASK << PLLA9FRACO_PDIV_SHIFT) |
1547 		  (PLLA9FRACO_SDIV_MASK << PLLA9FRACO_SDIV_SHIFT));
1548 
1549 	/* The field FOUTPOSTDIVEN should always be 1, else FOUT might be 0 Hz. */
1550 	con0 |= (rate->mdiv << PLLA9FRACO_MDIV_SHIFT) |
1551 		(rate->pdiv << PLLA9FRACO_PDIV_SHIFT) |
1552 		(rate->sdiv << PLLA9FRACO_SDIV_SHIFT) | (PLLA9FRACO_FOUTPOSTDIVEN);
1553 
1554 	/* Set PLL K, DSM_EN and DAC_MODE values. */
1555 	con5 = readl_relaxed(pll->con_reg + PLLA9FRACO_PLL_CON5_DIV_FRAC);
1556 	con5 &= ~((PLLA9FRACO_KDIV_MASK << PLLA9FRACO_KDIV_SHIFT) |
1557 		  PLLA9FRACO_DSM_EN | PLLA9FRACO_DAC_MODE);
1558 	con5 |= (rate->kdiv << PLLA9FRACO_KDIV_SHIFT) | PLLA9FRACO_DSM_EN | PLLA9FRACO_DAC_MODE;
1559 
1560 	/* Write configuration to PLL */
1561 	writel_relaxed(con0, pll->con_reg);
1562 	writel_relaxed(con5, pll->con_reg + PLLA9FRACO_PLL_CON5_DIV_FRAC);
1563 
1564 	/* Enable PLL */
1565 	con0 = readl_relaxed(pll->con_reg);
1566 	con0 |= BIT(PLLA9FRACO_ENABLE_SHIFT);
1567 	writel_relaxed(con0, pll->con_reg);
1568 
1569 	/* Wait for PLL lock if the PLL is enabled */
1570 	ret = samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
1571 	if (ret < 0)
1572 		return ret;
1573 
1574 	/* Select FOUT (1) */
1575 	con0 |= (PLLA9FRACO_MUX_SEL);
1576 	writel_relaxed(con0, pll->con_reg);
1577 
1578 	return 0;
1579 }
1580 
1581 static const struct clk_ops samsung_a9fraco_clk_ops = {
1582 	.recalc_rate = samsung_a9fraco_recalc_rate,
1583 	.determine_rate = samsung_pll_determine_rate,
1584 	.set_rate = samsung_a9fraco_set_rate,
1585 };
1586 
1587 static const struct clk_ops samsung_a9fraco_clk_min_ops = {
1588 	.recalc_rate = samsung_a9fraco_recalc_rate,
1589 };
1590 
1591 static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1592 				const struct samsung_pll_clock *pll_clk)
1593 {
1594 	struct samsung_clk_pll *pll;
1595 	struct clk_init_data init;
1596 	int ret, len;
1597 
1598 	pll = kzalloc_obj(*pll);
1599 	if (!pll) {
1600 		pr_err("%s: could not allocate pll clk %s\n",
1601 			__func__, pll_clk->name);
1602 		return;
1603 	}
1604 
1605 	init.name = pll_clk->name;
1606 	init.flags = pll_clk->flags;
1607 	init.parent_names = &pll_clk->parent_name;
1608 	init.num_parents = 1;
1609 
1610 	if (pll_clk->rate_table) {
1611 		/* find count of rates in rate_table */
1612 		for (len = 0; pll_clk->rate_table[len].rate != 0; )
1613 			len++;
1614 
1615 		pll->rate_count = len;
1616 		pll->rate_table = kmemdup_array(pll_clk->rate_table,
1617 						pll->rate_count,
1618 						sizeof(*pll->rate_table),
1619 						GFP_KERNEL);
1620 		WARN(!pll->rate_table,
1621 			"%s: could not allocate rate table for %s\n",
1622 			__func__, pll_clk->name);
1623 	}
1624 
1625 	switch (pll_clk->type) {
1626 	case pll_2126:
1627 		init.ops = &samsung_pll2126_clk_ops;
1628 		break;
1629 	case pll_3000:
1630 		init.ops = &samsung_pll3000_clk_ops;
1631 		break;
1632 	/* clk_ops for 35xx and 2550 are similar */
1633 	case pll_35xx:
1634 	case pll_2550:
1635 	case pll_1450x:
1636 	case pll_1451x:
1637 	case pll_1452x:
1638 	case pll_142xx:
1639 	case pll_1017x:
1640 	case pll_a9fracm:
1641 		pll->enable_offs = PLL35XX_ENABLE_SHIFT;
1642 		pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
1643 		if (!pll->rate_table)
1644 			init.ops = &samsung_pll35xx_clk_min_ops;
1645 		else
1646 			init.ops = &samsung_pll35xx_clk_ops;
1647 		break;
1648 	case pll_1417x:
1649 	case pll_1418x:
1650 	case pll_1051x:
1651 	case pll_1052x:
1652 	case pll_0818x:
1653 	case pll_0822x:
1654 	case pll_0516x:
1655 	case pll_0517x:
1656 	case pll_0518x:
1657 	case pll_0717x:
1658 	case pll_0718x:
1659 	case pll_0732x:
1660 		pll->enable_offs = PLL0822X_ENABLE_SHIFT;
1661 		pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
1662 		if (!pll->rate_table)
1663 			init.ops = &samsung_pll0822x_clk_min_ops;
1664 		else
1665 			init.ops = &samsung_pll0822x_clk_ops;
1666 		break;
1667 	case pll_4500:
1668 		init.ops = &samsung_pll45xx_clk_min_ops;
1669 		break;
1670 	case pll_4502:
1671 	case pll_4508:
1672 		if (!pll->rate_table)
1673 			init.ops = &samsung_pll45xx_clk_min_ops;
1674 		else
1675 			init.ops = &samsung_pll45xx_clk_ops;
1676 		break;
1677 	/* clk_ops for 36xx and 2650 are similar */
1678 	case pll_36xx:
1679 	case pll_2650:
1680 		pll->enable_offs = PLL36XX_ENABLE_SHIFT;
1681 		pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT;
1682 		if (!pll->rate_table)
1683 			init.ops = &samsung_pll36xx_clk_min_ops;
1684 		else
1685 			init.ops = &samsung_pll36xx_clk_ops;
1686 		break;
1687 	case pll_0831x:
1688 		pll->enable_offs = PLL0831X_ENABLE_SHIFT;
1689 		pll->lock_offs = PLL0831X_LOCK_STAT_SHIFT;
1690 		if (!pll->rate_table)
1691 			init.ops = &samsung_pll0831x_clk_min_ops;
1692 		else
1693 			init.ops = &samsung_pll0831x_clk_ops;
1694 		break;
1695 	case pll_6552:
1696 	case pll_6552_s3c2416:
1697 		init.ops = &samsung_pll6552_clk_ops;
1698 		break;
1699 	case pll_6553:
1700 		init.ops = &samsung_pll6553_clk_ops;
1701 		break;
1702 	case pll_4600:
1703 	case pll_4650:
1704 	case pll_4650c:
1705 	case pll_1460x:
1706 		if (!pll->rate_table)
1707 			init.ops = &samsung_pll46xx_clk_min_ops;
1708 		else
1709 			init.ops = &samsung_pll46xx_clk_ops;
1710 		break;
1711 	case pll_2550x:
1712 		init.ops = &samsung_pll2550x_clk_ops;
1713 		break;
1714 	case pll_2550xx:
1715 		if (!pll->rate_table)
1716 			init.ops = &samsung_pll2550xx_clk_min_ops;
1717 		else
1718 			init.ops = &samsung_pll2550xx_clk_ops;
1719 		break;
1720 	case pll_2650x:
1721 		if (!pll->rate_table)
1722 			init.ops = &samsung_pll2650x_clk_min_ops;
1723 		else
1724 			init.ops = &samsung_pll2650x_clk_ops;
1725 		break;
1726 	case pll_2650xx:
1727 		if (!pll->rate_table)
1728 			init.ops = &samsung_pll2650xx_clk_min_ops;
1729 		else
1730 			init.ops = &samsung_pll2650xx_clk_ops;
1731 		break;
1732 	case pll_531x:
1733 	case pll_4311:
1734 		init.ops = &samsung_pll531x_clk_ops;
1735 		break;
1736 	case pll_1031x:
1737 		if (!pll->rate_table)
1738 			init.ops = &samsung_pll1031x_clk_min_ops;
1739 		else
1740 			init.ops = &samsung_pll1031x_clk_ops;
1741 		break;
1742 	case pll_a9fraco:
1743 		pll->enable_offs = PLLA9FRACO_ENABLE_SHIFT;
1744 		pll->lock_offs = PLLA9FRACO_LOCK_STAT_SHIFT;
1745 		if (!pll->rate_table)
1746 			init.ops = &samsung_a9fraco_clk_min_ops;
1747 		else
1748 			init.ops = &samsung_a9fraco_clk_ops;
1749 		break;
1750 	default:
1751 		pr_warn("%s: Unknown pll type for pll clk %s\n",
1752 			__func__, pll_clk->name);
1753 	}
1754 
1755 	pll->hw.init = &init;
1756 	pll->type = pll_clk->type;
1757 	pll->lock_reg = ctx->reg_base + pll_clk->lock_offset;
1758 	pll->con_reg = ctx->reg_base + pll_clk->con_offset;
1759 
1760 	ret = clk_hw_register(ctx->dev, &pll->hw);
1761 	if (ret) {
1762 		pr_err("%s: failed to register pll clock %s : %d\n",
1763 			__func__, pll_clk->name, ret);
1764 		kfree(pll->rate_table);
1765 		kfree(pll);
1766 		return;
1767 	}
1768 
1769 	samsung_clk_add_lookup(ctx, &pll->hw, pll_clk->id);
1770 }
1771 
1772 void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1773 			const struct samsung_pll_clock *pll_list,
1774 			unsigned int nr_pll)
1775 {
1776 	int cnt;
1777 
1778 	for (cnt = 0; cnt < nr_pll; cnt++)
1779 		_samsung_clk_register_pll(ctx, &pll_list[cnt]);
1780 }
1781