xref: /openbmc/linux/drivers/clk/pistachio/clk-pll.c (revision df687341)
1 /*
2  * Copyright (C) 2014 Google, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  */
8 
9 #define pr_fmt(fmt) "%s: " fmt, __func__
10 
11 #include <linux/clk-provider.h>
12 #include <linux/io.h>
13 #include <linux/kernel.h>
14 #include <linux/printk.h>
15 #include <linux/slab.h>
16 
17 #include "clk.h"
18 
19 #define PLL_STATUS			0x0
20 #define PLL_STATUS_LOCK			BIT(0)
21 
22 #define PLL_CTRL1			0x4
23 #define PLL_CTRL1_REFDIV_SHIFT		0
24 #define PLL_CTRL1_REFDIV_MASK		0x3f
25 #define PLL_CTRL1_FBDIV_SHIFT		6
26 #define PLL_CTRL1_FBDIV_MASK		0xfff
27 #define PLL_INT_CTRL1_POSTDIV1_SHIFT	18
28 #define PLL_INT_CTRL1_POSTDIV1_MASK	0x7
29 #define PLL_INT_CTRL1_POSTDIV2_SHIFT	21
30 #define PLL_INT_CTRL1_POSTDIV2_MASK	0x7
31 #define PLL_INT_CTRL1_PD		BIT(24)
32 #define PLL_INT_CTRL1_DSMPD		BIT(25)
33 #define PLL_INT_CTRL1_FOUTPOSTDIVPD	BIT(26)
34 #define PLL_INT_CTRL1_FOUTVCOPD		BIT(27)
35 
36 #define PLL_CTRL2			0x8
37 #define PLL_FRAC_CTRL2_FRAC_SHIFT	0
38 #define PLL_FRAC_CTRL2_FRAC_MASK	0xffffff
39 #define PLL_FRAC_CTRL2_POSTDIV1_SHIFT	24
40 #define PLL_FRAC_CTRL2_POSTDIV1_MASK	0x7
41 #define PLL_FRAC_CTRL2_POSTDIV2_SHIFT	27
42 #define PLL_FRAC_CTRL2_POSTDIV2_MASK	0x7
43 #define PLL_INT_CTRL2_BYPASS		BIT(28)
44 
45 #define PLL_CTRL3			0xc
46 #define PLL_FRAC_CTRL3_PD		BIT(0)
47 #define PLL_FRAC_CTRL3_DACPD		BIT(1)
48 #define PLL_FRAC_CTRL3_DSMPD		BIT(2)
49 #define PLL_FRAC_CTRL3_FOUTPOSTDIVPD	BIT(3)
50 #define PLL_FRAC_CTRL3_FOUT4PHASEPD	BIT(4)
51 #define PLL_FRAC_CTRL3_FOUTVCOPD	BIT(5)
52 
53 #define PLL_CTRL4			0x10
54 #define PLL_FRAC_CTRL4_BYPASS		BIT(28)
55 
56 #define MIN_PFD				9600000UL
57 #define MIN_VCO_LA			400000000UL
58 #define MAX_VCO_LA			1600000000UL
59 #define MIN_VCO_FRAC_INT		600000000UL
60 #define MAX_VCO_FRAC_INT		1600000000UL
61 #define MIN_VCO_FRAC_FRAC		600000000UL
62 #define MAX_VCO_FRAC_FRAC		2400000000UL
63 #define MIN_OUTPUT_LA			8000000UL
64 #define MAX_OUTPUT_LA			1600000000UL
65 #define MIN_OUTPUT_FRAC			12000000UL
66 #define MAX_OUTPUT_FRAC			1600000000UL
67 
68 /* Fractional PLL operating modes */
69 enum pll_mode {
70 	PLL_MODE_FRAC,
71 	PLL_MODE_INT,
72 };
73 
74 struct pistachio_clk_pll {
75 	struct clk_hw hw;
76 	void __iomem *base;
77 	struct pistachio_pll_rate_table *rates;
78 	unsigned int nr_rates;
79 };
80 
81 static inline u32 pll_readl(struct pistachio_clk_pll *pll, u32 reg)
82 {
83 	return readl(pll->base + reg);
84 }
85 
86 static inline void pll_writel(struct pistachio_clk_pll *pll, u32 val, u32 reg)
87 {
88 	writel(val, pll->base + reg);
89 }
90 
91 static inline void pll_lock(struct pistachio_clk_pll *pll)
92 {
93 	while (!(pll_readl(pll, PLL_STATUS) & PLL_STATUS_LOCK))
94 		cpu_relax();
95 }
96 
97 static inline u64 do_div_round_closest(u64 dividend, u64 divisor)
98 {
99 	dividend += divisor / 2;
100 	return div64_u64(dividend, divisor);
101 }
102 
103 static inline struct pistachio_clk_pll *to_pistachio_pll(struct clk_hw *hw)
104 {
105 	return container_of(hw, struct pistachio_clk_pll, hw);
106 }
107 
108 static inline enum pll_mode pll_frac_get_mode(struct clk_hw *hw)
109 {
110 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
111 	u32 val;
112 
113 	val = pll_readl(pll, PLL_CTRL3) & PLL_FRAC_CTRL3_DSMPD;
114 	return val ? PLL_MODE_INT : PLL_MODE_FRAC;
115 }
116 
117 static inline void pll_frac_set_mode(struct clk_hw *hw, enum pll_mode mode)
118 {
119 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
120 	u32 val;
121 
122 	val = pll_readl(pll, PLL_CTRL3);
123 	if (mode == PLL_MODE_INT)
124 		val |= PLL_FRAC_CTRL3_DSMPD | PLL_FRAC_CTRL3_DACPD;
125 	else
126 		val &= ~(PLL_FRAC_CTRL3_DSMPD | PLL_FRAC_CTRL3_DACPD);
127 
128 	pll_writel(pll, val, PLL_CTRL3);
129 }
130 
131 static struct pistachio_pll_rate_table *
132 pll_get_params(struct pistachio_clk_pll *pll, unsigned long fref,
133 	       unsigned long fout)
134 {
135 	unsigned int i;
136 
137 	for (i = 0; i < pll->nr_rates; i++) {
138 		if (pll->rates[i].fref == fref && pll->rates[i].fout == fout)
139 			return &pll->rates[i];
140 	}
141 
142 	return NULL;
143 }
144 
145 static long pll_round_rate(struct clk_hw *hw, unsigned long rate,
146 			   unsigned long *parent_rate)
147 {
148 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
149 	unsigned int i;
150 
151 	for (i = 0; i < pll->nr_rates; i++) {
152 		if (i > 0 && pll->rates[i].fref == *parent_rate &&
153 		    pll->rates[i].fout <= rate)
154 			return pll->rates[i - 1].fout;
155 	}
156 
157 	return pll->rates[0].fout;
158 }
159 
160 static int pll_gf40lp_frac_enable(struct clk_hw *hw)
161 {
162 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
163 	u32 val;
164 
165 	val = pll_readl(pll, PLL_CTRL3);
166 	val &= ~(PLL_FRAC_CTRL3_PD | PLL_FRAC_CTRL3_FOUTPOSTDIVPD |
167 		 PLL_FRAC_CTRL3_FOUT4PHASEPD | PLL_FRAC_CTRL3_FOUTVCOPD);
168 	pll_writel(pll, val, PLL_CTRL3);
169 
170 	val = pll_readl(pll, PLL_CTRL4);
171 	val &= ~PLL_FRAC_CTRL4_BYPASS;
172 	pll_writel(pll, val, PLL_CTRL4);
173 
174 	pll_lock(pll);
175 
176 	return 0;
177 }
178 
179 static void pll_gf40lp_frac_disable(struct clk_hw *hw)
180 {
181 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
182 	u32 val;
183 
184 	val = pll_readl(pll, PLL_CTRL3);
185 	val |= PLL_FRAC_CTRL3_PD;
186 	pll_writel(pll, val, PLL_CTRL3);
187 }
188 
189 static int pll_gf40lp_frac_is_enabled(struct clk_hw *hw)
190 {
191 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
192 
193 	return !(pll_readl(pll, PLL_CTRL3) & PLL_FRAC_CTRL3_PD);
194 }
195 
196 static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate,
197 				    unsigned long parent_rate)
198 {
199 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
200 	struct pistachio_pll_rate_table *params;
201 	int enabled = pll_gf40lp_frac_is_enabled(hw);
202 	u64 val, vco, old_postdiv1, old_postdiv2;
203 	const char *name = clk_hw_get_name(hw);
204 
205 	if (rate < MIN_OUTPUT_FRAC || rate > MAX_OUTPUT_FRAC)
206 		return -EINVAL;
207 
208 	params = pll_get_params(pll, parent_rate, rate);
209 	if (!params || !params->refdiv)
210 		return -EINVAL;
211 
212 	/* calculate vco */
213 	vco = params->fref;
214 	vco *= (params->fbdiv << 24) + params->frac;
215 	vco = div64_u64(vco, params->refdiv << 24);
216 
217 	if (vco < MIN_VCO_FRAC_FRAC || vco > MAX_VCO_FRAC_FRAC)
218 		pr_warn("%s: VCO %llu is out of range %lu..%lu\n", name, vco,
219 			MIN_VCO_FRAC_FRAC, MAX_VCO_FRAC_FRAC);
220 
221 	val = div64_u64(params->fref, params->refdiv);
222 	if (val < MIN_PFD)
223 		pr_warn("%s: PFD %llu is too low (min %lu)\n",
224 			name, val, MIN_PFD);
225 	if (val > vco / 16)
226 		pr_warn("%s: PFD %llu is too high (max %llu)\n",
227 			name, val, vco / 16);
228 
229 	val = pll_readl(pll, PLL_CTRL1);
230 	val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) |
231 		 (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT));
232 	val |= (params->refdiv << PLL_CTRL1_REFDIV_SHIFT) |
233 		(params->fbdiv << PLL_CTRL1_FBDIV_SHIFT);
234 	pll_writel(pll, val, PLL_CTRL1);
235 
236 	val = pll_readl(pll, PLL_CTRL2);
237 
238 	old_postdiv1 = (val >> PLL_FRAC_CTRL2_POSTDIV1_SHIFT) &
239 		       PLL_FRAC_CTRL2_POSTDIV1_MASK;
240 	old_postdiv2 = (val >> PLL_FRAC_CTRL2_POSTDIV2_SHIFT) &
241 		       PLL_FRAC_CTRL2_POSTDIV2_MASK;
242 	if (enabled &&
243 	    (params->postdiv1 != old_postdiv1 ||
244 	     params->postdiv2 != old_postdiv2))
245 		pr_warn("%s: changing postdiv while PLL is enabled\n", name);
246 
247 	if (params->postdiv2 > params->postdiv1)
248 		pr_warn("%s: postdiv2 should not exceed postdiv1\n", name);
249 
250 	val &= ~((PLL_FRAC_CTRL2_FRAC_MASK << PLL_FRAC_CTRL2_FRAC_SHIFT) |
251 		 (PLL_FRAC_CTRL2_POSTDIV1_MASK <<
252 		  PLL_FRAC_CTRL2_POSTDIV1_SHIFT) |
253 		 (PLL_FRAC_CTRL2_POSTDIV2_MASK <<
254 		  PLL_FRAC_CTRL2_POSTDIV2_SHIFT));
255 	val |= (params->frac << PLL_FRAC_CTRL2_FRAC_SHIFT) |
256 		(params->postdiv1 << PLL_FRAC_CTRL2_POSTDIV1_SHIFT) |
257 		(params->postdiv2 << PLL_FRAC_CTRL2_POSTDIV2_SHIFT);
258 	pll_writel(pll, val, PLL_CTRL2);
259 
260 	/* set operating mode */
261 	if (params->frac)
262 		pll_frac_set_mode(hw, PLL_MODE_FRAC);
263 	else
264 		pll_frac_set_mode(hw, PLL_MODE_INT);
265 
266 	if (enabled)
267 		pll_lock(pll);
268 
269 	return 0;
270 }
271 
272 static unsigned long pll_gf40lp_frac_recalc_rate(struct clk_hw *hw,
273 						 unsigned long parent_rate)
274 {
275 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
276 	u64 val, prediv, fbdiv, frac, postdiv1, postdiv2, rate;
277 
278 	val = pll_readl(pll, PLL_CTRL1);
279 	prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK;
280 	fbdiv = (val >> PLL_CTRL1_FBDIV_SHIFT) & PLL_CTRL1_FBDIV_MASK;
281 
282 	val = pll_readl(pll, PLL_CTRL2);
283 	postdiv1 = (val >> PLL_FRAC_CTRL2_POSTDIV1_SHIFT) &
284 		PLL_FRAC_CTRL2_POSTDIV1_MASK;
285 	postdiv2 = (val >> PLL_FRAC_CTRL2_POSTDIV2_SHIFT) &
286 		PLL_FRAC_CTRL2_POSTDIV2_MASK;
287 	frac = (val >> PLL_FRAC_CTRL2_FRAC_SHIFT) & PLL_FRAC_CTRL2_FRAC_MASK;
288 
289 	/* get operating mode (int/frac) and calculate rate accordingly */
290 	rate = parent_rate;
291 	if (pll_frac_get_mode(hw) == PLL_MODE_FRAC)
292 		rate *= (fbdiv << 24) + frac;
293 	else
294 		rate *= (fbdiv << 24);
295 
296 	rate = do_div_round_closest(rate, (prediv * postdiv1 * postdiv2) << 24);
297 
298 	return rate;
299 }
300 
301 static const struct clk_ops pll_gf40lp_frac_ops = {
302 	.enable = pll_gf40lp_frac_enable,
303 	.disable = pll_gf40lp_frac_disable,
304 	.is_enabled = pll_gf40lp_frac_is_enabled,
305 	.recalc_rate = pll_gf40lp_frac_recalc_rate,
306 	.round_rate = pll_round_rate,
307 	.set_rate = pll_gf40lp_frac_set_rate,
308 };
309 
310 static const struct clk_ops pll_gf40lp_frac_fixed_ops = {
311 	.enable = pll_gf40lp_frac_enable,
312 	.disable = pll_gf40lp_frac_disable,
313 	.is_enabled = pll_gf40lp_frac_is_enabled,
314 	.recalc_rate = pll_gf40lp_frac_recalc_rate,
315 };
316 
317 static int pll_gf40lp_laint_enable(struct clk_hw *hw)
318 {
319 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
320 	u32 val;
321 
322 	val = pll_readl(pll, PLL_CTRL1);
323 	val &= ~(PLL_INT_CTRL1_PD |
324 		 PLL_INT_CTRL1_FOUTPOSTDIVPD | PLL_INT_CTRL1_FOUTVCOPD);
325 	pll_writel(pll, val, PLL_CTRL1);
326 
327 	val = pll_readl(pll, PLL_CTRL2);
328 	val &= ~PLL_INT_CTRL2_BYPASS;
329 	pll_writel(pll, val, PLL_CTRL2);
330 
331 	pll_lock(pll);
332 
333 	return 0;
334 }
335 
336 static void pll_gf40lp_laint_disable(struct clk_hw *hw)
337 {
338 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
339 	u32 val;
340 
341 	val = pll_readl(pll, PLL_CTRL1);
342 	val |= PLL_INT_CTRL1_PD;
343 	pll_writel(pll, val, PLL_CTRL1);
344 }
345 
346 static int pll_gf40lp_laint_is_enabled(struct clk_hw *hw)
347 {
348 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
349 
350 	return !(pll_readl(pll, PLL_CTRL1) & PLL_INT_CTRL1_PD);
351 }
352 
353 static int pll_gf40lp_laint_set_rate(struct clk_hw *hw, unsigned long rate,
354 				     unsigned long parent_rate)
355 {
356 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
357 	struct pistachio_pll_rate_table *params;
358 	int enabled = pll_gf40lp_laint_is_enabled(hw);
359 	u32 val, vco, old_postdiv1, old_postdiv2;
360 	const char *name = clk_hw_get_name(hw);
361 
362 	if (rate < MIN_OUTPUT_LA || rate > MAX_OUTPUT_LA)
363 		return -EINVAL;
364 
365 	params = pll_get_params(pll, parent_rate, rate);
366 	if (!params || !params->refdiv)
367 		return -EINVAL;
368 
369 	vco = div_u64(params->fref * params->fbdiv, params->refdiv);
370 	if (vco < MIN_VCO_LA || vco > MAX_VCO_LA)
371 		pr_warn("%s: VCO %u is out of range %lu..%lu\n", name, vco,
372 			MIN_VCO_LA, MAX_VCO_LA);
373 
374 	val = div_u64(params->fref, params->refdiv);
375 	if (val < MIN_PFD)
376 		pr_warn("%s: PFD %u is too low (min %lu)\n",
377 			name, val, MIN_PFD);
378 	if (val > vco / 16)
379 		pr_warn("%s: PFD %u is too high (max %u)\n",
380 			name, val, vco / 16);
381 
382 	val = pll_readl(pll, PLL_CTRL1);
383 
384 	old_postdiv1 = (val >> PLL_INT_CTRL1_POSTDIV1_SHIFT) &
385 		       PLL_INT_CTRL1_POSTDIV1_MASK;
386 	old_postdiv2 = (val >> PLL_INT_CTRL1_POSTDIV2_SHIFT) &
387 		       PLL_INT_CTRL1_POSTDIV2_MASK;
388 	if (enabled &&
389 	    (params->postdiv1 != old_postdiv1 ||
390 	     params->postdiv2 != old_postdiv2))
391 		pr_warn("%s: changing postdiv while PLL is enabled\n", name);
392 
393 	if (params->postdiv2 > params->postdiv1)
394 		pr_warn("%s: postdiv2 should not exceed postdiv1\n", name);
395 
396 	val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) |
397 		 (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT) |
398 		 (PLL_INT_CTRL1_POSTDIV1_MASK << PLL_INT_CTRL1_POSTDIV1_SHIFT) |
399 		 (PLL_INT_CTRL1_POSTDIV2_MASK << PLL_INT_CTRL1_POSTDIV2_SHIFT));
400 	val |= (params->refdiv << PLL_CTRL1_REFDIV_SHIFT) |
401 		(params->fbdiv << PLL_CTRL1_FBDIV_SHIFT) |
402 		(params->postdiv1 << PLL_INT_CTRL1_POSTDIV1_SHIFT) |
403 		(params->postdiv2 << PLL_INT_CTRL1_POSTDIV2_SHIFT);
404 	pll_writel(pll, val, PLL_CTRL1);
405 
406 	if (enabled)
407 		pll_lock(pll);
408 
409 	return 0;
410 }
411 
412 static unsigned long pll_gf40lp_laint_recalc_rate(struct clk_hw *hw,
413 						  unsigned long parent_rate)
414 {
415 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
416 	u32 val, prediv, fbdiv, postdiv1, postdiv2;
417 	u64 rate = parent_rate;
418 
419 	val = pll_readl(pll, PLL_CTRL1);
420 	prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK;
421 	fbdiv = (val >> PLL_CTRL1_FBDIV_SHIFT) & PLL_CTRL1_FBDIV_MASK;
422 	postdiv1 = (val >> PLL_INT_CTRL1_POSTDIV1_SHIFT) &
423 		PLL_INT_CTRL1_POSTDIV1_MASK;
424 	postdiv2 = (val >> PLL_INT_CTRL1_POSTDIV2_SHIFT) &
425 		PLL_INT_CTRL1_POSTDIV2_MASK;
426 
427 	rate *= fbdiv;
428 	rate = do_div_round_closest(rate, prediv * postdiv1 * postdiv2);
429 
430 	return rate;
431 }
432 
433 static const struct clk_ops pll_gf40lp_laint_ops = {
434 	.enable = pll_gf40lp_laint_enable,
435 	.disable = pll_gf40lp_laint_disable,
436 	.is_enabled = pll_gf40lp_laint_is_enabled,
437 	.recalc_rate = pll_gf40lp_laint_recalc_rate,
438 	.round_rate = pll_round_rate,
439 	.set_rate = pll_gf40lp_laint_set_rate,
440 };
441 
442 static const struct clk_ops pll_gf40lp_laint_fixed_ops = {
443 	.enable = pll_gf40lp_laint_enable,
444 	.disable = pll_gf40lp_laint_disable,
445 	.is_enabled = pll_gf40lp_laint_is_enabled,
446 	.recalc_rate = pll_gf40lp_laint_recalc_rate,
447 };
448 
449 static struct clk *pll_register(const char *name, const char *parent_name,
450 				unsigned long flags, void __iomem *base,
451 				enum pistachio_pll_type type,
452 				struct pistachio_pll_rate_table *rates,
453 				unsigned int nr_rates)
454 {
455 	struct pistachio_clk_pll *pll;
456 	struct clk_init_data init;
457 	struct clk *clk;
458 
459 	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
460 	if (!pll)
461 		return ERR_PTR(-ENOMEM);
462 
463 	init.name = name;
464 	init.flags = flags | CLK_GET_RATE_NOCACHE;
465 	init.parent_names = &parent_name;
466 	init.num_parents = 1;
467 
468 	switch (type) {
469 	case PLL_GF40LP_FRAC:
470 		if (rates)
471 			init.ops = &pll_gf40lp_frac_ops;
472 		else
473 			init.ops = &pll_gf40lp_frac_fixed_ops;
474 		break;
475 	case PLL_GF40LP_LAINT:
476 		if (rates)
477 			init.ops = &pll_gf40lp_laint_ops;
478 		else
479 			init.ops = &pll_gf40lp_laint_fixed_ops;
480 		break;
481 	default:
482 		pr_err("Unrecognized PLL type %u\n", type);
483 		kfree(pll);
484 		return ERR_PTR(-EINVAL);
485 	}
486 
487 	pll->hw.init = &init;
488 	pll->base = base;
489 	pll->rates = rates;
490 	pll->nr_rates = nr_rates;
491 
492 	clk = clk_register(NULL, &pll->hw);
493 	if (IS_ERR(clk))
494 		kfree(pll);
495 
496 	return clk;
497 }
498 
499 void pistachio_clk_register_pll(struct pistachio_clk_provider *p,
500 				struct pistachio_pll *pll,
501 				unsigned int num)
502 {
503 	struct clk *clk;
504 	unsigned int i;
505 
506 	for (i = 0; i < num; i++) {
507 		clk = pll_register(pll[i].name, pll[i].parent,
508 				   0, p->base + pll[i].reg_base,
509 				   pll[i].type, pll[i].rates,
510 				   pll[i].nr_rates);
511 		p->clk_data.clks[pll[i].id] = clk;
512 	}
513 }
514