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