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