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