xref: /openbmc/linux/drivers/clk/pistachio/clk-pll.c (revision 179dd8c0)
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 struct pistachio_clk_pll {
69 	struct clk_hw hw;
70 	void __iomem *base;
71 	struct pistachio_pll_rate_table *rates;
72 	unsigned int nr_rates;
73 };
74 
75 static inline u32 pll_readl(struct pistachio_clk_pll *pll, u32 reg)
76 {
77 	return readl(pll->base + reg);
78 }
79 
80 static inline void pll_writel(struct pistachio_clk_pll *pll, u32 val, u32 reg)
81 {
82 	writel(val, pll->base + reg);
83 }
84 
85 static inline void pll_lock(struct pistachio_clk_pll *pll)
86 {
87 	while (!(pll_readl(pll, PLL_STATUS) & PLL_STATUS_LOCK))
88 		cpu_relax();
89 }
90 
91 static inline u32 do_div_round_closest(u64 dividend, u32 divisor)
92 {
93 	dividend += divisor / 2;
94 	do_div(dividend, divisor);
95 
96 	return dividend;
97 }
98 
99 static inline struct pistachio_clk_pll *to_pistachio_pll(struct clk_hw *hw)
100 {
101 	return container_of(hw, struct pistachio_clk_pll, hw);
102 }
103 
104 static struct pistachio_pll_rate_table *
105 pll_get_params(struct pistachio_clk_pll *pll, unsigned long fref,
106 	       unsigned long fout)
107 {
108 	unsigned int i;
109 
110 	for (i = 0; i < pll->nr_rates; i++) {
111 		if (pll->rates[i].fref == fref && pll->rates[i].fout == fout)
112 			return &pll->rates[i];
113 	}
114 
115 	return NULL;
116 }
117 
118 static long pll_round_rate(struct clk_hw *hw, unsigned long rate,
119 			   unsigned long *parent_rate)
120 {
121 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
122 	unsigned int i;
123 
124 	for (i = 0; i < pll->nr_rates; i++) {
125 		if (i > 0 && pll->rates[i].fref == *parent_rate &&
126 		    pll->rates[i].fout <= rate)
127 			return pll->rates[i - 1].fout;
128 	}
129 
130 	return pll->rates[0].fout;
131 }
132 
133 static int pll_gf40lp_frac_enable(struct clk_hw *hw)
134 {
135 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
136 	u32 val;
137 
138 	val = pll_readl(pll, PLL_CTRL3);
139 	val &= ~(PLL_FRAC_CTRL3_PD | PLL_FRAC_CTRL3_DACPD |
140 		 PLL_FRAC_CTRL3_DSMPD | PLL_FRAC_CTRL3_FOUTPOSTDIVPD |
141 		 PLL_FRAC_CTRL3_FOUT4PHASEPD | PLL_FRAC_CTRL3_FOUTVCOPD);
142 	pll_writel(pll, val, PLL_CTRL3);
143 
144 	val = pll_readl(pll, PLL_CTRL4);
145 	val &= ~PLL_FRAC_CTRL4_BYPASS;
146 	pll_writel(pll, val, PLL_CTRL4);
147 
148 	pll_lock(pll);
149 
150 	return 0;
151 }
152 
153 static void pll_gf40lp_frac_disable(struct clk_hw *hw)
154 {
155 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
156 	u32 val;
157 
158 	val = pll_readl(pll, PLL_CTRL3);
159 	val |= PLL_FRAC_CTRL3_PD;
160 	pll_writel(pll, val, PLL_CTRL3);
161 }
162 
163 static int pll_gf40lp_frac_is_enabled(struct clk_hw *hw)
164 {
165 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
166 
167 	return !(pll_readl(pll, PLL_CTRL3) & PLL_FRAC_CTRL3_PD);
168 }
169 
170 static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate,
171 				    unsigned long parent_rate)
172 {
173 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
174 	struct pistachio_pll_rate_table *params;
175 	int enabled = pll_gf40lp_frac_is_enabled(hw);
176 	u32 val, vco, old_postdiv1, old_postdiv2;
177 	const char *name = __clk_get_name(hw->clk);
178 
179 	if (rate < MIN_OUTPUT_FRAC || rate > MAX_OUTPUT_FRAC)
180 		return -EINVAL;
181 
182 	params = pll_get_params(pll, parent_rate, rate);
183 	if (!params || !params->refdiv)
184 		return -EINVAL;
185 
186 	vco = params->fref * params->fbdiv / params->refdiv;
187 	if (vco < MIN_VCO_FRAC_FRAC || vco > MAX_VCO_FRAC_FRAC)
188 		pr_warn("%s: VCO %u is out of range %lu..%lu\n", name, vco,
189 			MIN_VCO_FRAC_FRAC, MAX_VCO_FRAC_FRAC);
190 
191 	val = params->fref / params->refdiv;
192 	if (val < MIN_PFD)
193 		pr_warn("%s: PFD %u is too low (min %lu)\n",
194 			name, val, MIN_PFD);
195 	if (val > vco / 16)
196 		pr_warn("%s: PFD %u is too high (max %u)\n",
197 			name, val, vco / 16);
198 
199 	val = pll_readl(pll, PLL_CTRL1);
200 	val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) |
201 		 (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT));
202 	val |= (params->refdiv << PLL_CTRL1_REFDIV_SHIFT) |
203 		(params->fbdiv << PLL_CTRL1_FBDIV_SHIFT);
204 	pll_writel(pll, val, PLL_CTRL1);
205 
206 	val = pll_readl(pll, PLL_CTRL2);
207 
208 	old_postdiv1 = (val >> PLL_FRAC_CTRL2_POSTDIV1_SHIFT) &
209 		       PLL_FRAC_CTRL2_POSTDIV1_MASK;
210 	old_postdiv2 = (val >> PLL_FRAC_CTRL2_POSTDIV2_SHIFT) &
211 		       PLL_FRAC_CTRL2_POSTDIV2_MASK;
212 	if (enabled &&
213 	    (params->postdiv1 != old_postdiv1 ||
214 	     params->postdiv2 != old_postdiv2))
215 		pr_warn("%s: changing postdiv while PLL is enabled\n", name);
216 
217 	if (params->postdiv2 > params->postdiv1)
218 		pr_warn("%s: postdiv2 should not exceed postdiv1\n", name);
219 
220 	val &= ~((PLL_FRAC_CTRL2_FRAC_MASK << PLL_FRAC_CTRL2_FRAC_SHIFT) |
221 		 (PLL_FRAC_CTRL2_POSTDIV1_MASK <<
222 		  PLL_FRAC_CTRL2_POSTDIV1_SHIFT) |
223 		 (PLL_FRAC_CTRL2_POSTDIV2_MASK <<
224 		  PLL_FRAC_CTRL2_POSTDIV2_SHIFT));
225 	val |= (params->frac << PLL_FRAC_CTRL2_FRAC_SHIFT) |
226 		(params->postdiv1 << PLL_FRAC_CTRL2_POSTDIV1_SHIFT) |
227 		(params->postdiv2 << PLL_FRAC_CTRL2_POSTDIV2_SHIFT);
228 	pll_writel(pll, val, PLL_CTRL2);
229 
230 	if (enabled)
231 		pll_lock(pll);
232 
233 	return 0;
234 }
235 
236 static unsigned long pll_gf40lp_frac_recalc_rate(struct clk_hw *hw,
237 						 unsigned long parent_rate)
238 {
239 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
240 	u32 val, prediv, fbdiv, frac, postdiv1, postdiv2;
241 	u64 rate = parent_rate;
242 
243 	val = pll_readl(pll, PLL_CTRL1);
244 	prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK;
245 	fbdiv = (val >> PLL_CTRL1_FBDIV_SHIFT) & PLL_CTRL1_FBDIV_MASK;
246 
247 	val = pll_readl(pll, PLL_CTRL2);
248 	postdiv1 = (val >> PLL_FRAC_CTRL2_POSTDIV1_SHIFT) &
249 		PLL_FRAC_CTRL2_POSTDIV1_MASK;
250 	postdiv2 = (val >> PLL_FRAC_CTRL2_POSTDIV2_SHIFT) &
251 		PLL_FRAC_CTRL2_POSTDIV2_MASK;
252 	frac = (val >> PLL_FRAC_CTRL2_FRAC_SHIFT) & PLL_FRAC_CTRL2_FRAC_MASK;
253 
254 	rate *= (fbdiv << 24) + frac;
255 	rate = do_div_round_closest(rate, (prediv * postdiv1 * postdiv2) << 24);
256 
257 	return rate;
258 }
259 
260 static struct clk_ops pll_gf40lp_frac_ops = {
261 	.enable = pll_gf40lp_frac_enable,
262 	.disable = pll_gf40lp_frac_disable,
263 	.is_enabled = pll_gf40lp_frac_is_enabled,
264 	.recalc_rate = pll_gf40lp_frac_recalc_rate,
265 	.round_rate = pll_round_rate,
266 	.set_rate = pll_gf40lp_frac_set_rate,
267 };
268 
269 static struct clk_ops pll_gf40lp_frac_fixed_ops = {
270 	.enable = pll_gf40lp_frac_enable,
271 	.disable = pll_gf40lp_frac_disable,
272 	.is_enabled = pll_gf40lp_frac_is_enabled,
273 	.recalc_rate = pll_gf40lp_frac_recalc_rate,
274 };
275 
276 static int pll_gf40lp_laint_enable(struct clk_hw *hw)
277 {
278 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
279 	u32 val;
280 
281 	val = pll_readl(pll, PLL_CTRL1);
282 	val &= ~(PLL_INT_CTRL1_PD | PLL_INT_CTRL1_DSMPD |
283 		 PLL_INT_CTRL1_FOUTPOSTDIVPD | PLL_INT_CTRL1_FOUTVCOPD);
284 	pll_writel(pll, val, PLL_CTRL1);
285 
286 	val = pll_readl(pll, PLL_CTRL2);
287 	val &= ~PLL_INT_CTRL2_BYPASS;
288 	pll_writel(pll, val, PLL_CTRL2);
289 
290 	pll_lock(pll);
291 
292 	return 0;
293 }
294 
295 static void pll_gf40lp_laint_disable(struct clk_hw *hw)
296 {
297 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
298 	u32 val;
299 
300 	val = pll_readl(pll, PLL_CTRL1);
301 	val |= PLL_INT_CTRL1_PD;
302 	pll_writel(pll, val, PLL_CTRL1);
303 }
304 
305 static int pll_gf40lp_laint_is_enabled(struct clk_hw *hw)
306 {
307 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
308 
309 	return !(pll_readl(pll, PLL_CTRL1) & PLL_INT_CTRL1_PD);
310 }
311 
312 static int pll_gf40lp_laint_set_rate(struct clk_hw *hw, unsigned long rate,
313 				     unsigned long parent_rate)
314 {
315 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
316 	struct pistachio_pll_rate_table *params;
317 	int enabled = pll_gf40lp_laint_is_enabled(hw);
318 	u32 val, vco, old_postdiv1, old_postdiv2;
319 	const char *name = __clk_get_name(hw->clk);
320 
321 	if (rate < MIN_OUTPUT_LA || rate > MAX_OUTPUT_LA)
322 		return -EINVAL;
323 
324 	params = pll_get_params(pll, parent_rate, rate);
325 	if (!params || !params->refdiv)
326 		return -EINVAL;
327 
328 	vco = params->fref * params->fbdiv / params->refdiv;
329 	if (vco < MIN_VCO_LA || vco > MAX_VCO_LA)
330 		pr_warn("%s: VCO %u is out of range %lu..%lu\n", name, vco,
331 			MIN_VCO_LA, MAX_VCO_LA);
332 
333 	val = params->fref / params->refdiv;
334 	if (val < MIN_PFD)
335 		pr_warn("%s: PFD %u is too low (min %lu)\n",
336 			name, val, MIN_PFD);
337 	if (val > vco / 16)
338 		pr_warn("%s: PFD %u is too high (max %u)\n",
339 			name, val, vco / 16);
340 
341 	val = pll_readl(pll, PLL_CTRL1);
342 
343 	old_postdiv1 = (val >> PLL_INT_CTRL1_POSTDIV1_SHIFT) &
344 		       PLL_INT_CTRL1_POSTDIV1_MASK;
345 	old_postdiv2 = (val >> PLL_INT_CTRL1_POSTDIV2_SHIFT) &
346 		       PLL_INT_CTRL1_POSTDIV2_MASK;
347 	if (enabled &&
348 	    (params->postdiv1 != old_postdiv1 ||
349 	     params->postdiv2 != old_postdiv2))
350 		pr_warn("%s: changing postdiv while PLL is enabled\n", name);
351 
352 	if (params->postdiv2 > params->postdiv1)
353 		pr_warn("%s: postdiv2 should not exceed postdiv1\n", name);
354 
355 	val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) |
356 		 (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT) |
357 		 (PLL_INT_CTRL1_POSTDIV1_MASK << PLL_INT_CTRL1_POSTDIV1_SHIFT) |
358 		 (PLL_INT_CTRL1_POSTDIV2_MASK << PLL_INT_CTRL1_POSTDIV2_SHIFT));
359 	val |= (params->refdiv << PLL_CTRL1_REFDIV_SHIFT) |
360 		(params->fbdiv << PLL_CTRL1_FBDIV_SHIFT) |
361 		(params->postdiv1 << PLL_INT_CTRL1_POSTDIV1_SHIFT) |
362 		(params->postdiv2 << PLL_INT_CTRL1_POSTDIV2_SHIFT);
363 	pll_writel(pll, val, PLL_CTRL1);
364 
365 	if (enabled)
366 		pll_lock(pll);
367 
368 	return 0;
369 }
370 
371 static unsigned long pll_gf40lp_laint_recalc_rate(struct clk_hw *hw,
372 						  unsigned long parent_rate)
373 {
374 	struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
375 	u32 val, prediv, fbdiv, postdiv1, postdiv2;
376 	u64 rate = parent_rate;
377 
378 	val = pll_readl(pll, PLL_CTRL1);
379 	prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK;
380 	fbdiv = (val >> PLL_CTRL1_FBDIV_SHIFT) & PLL_CTRL1_FBDIV_MASK;
381 	postdiv1 = (val >> PLL_INT_CTRL1_POSTDIV1_SHIFT) &
382 		PLL_INT_CTRL1_POSTDIV1_MASK;
383 	postdiv2 = (val >> PLL_INT_CTRL1_POSTDIV2_SHIFT) &
384 		PLL_INT_CTRL1_POSTDIV2_MASK;
385 
386 	rate *= fbdiv;
387 	rate = do_div_round_closest(rate, prediv * postdiv1 * postdiv2);
388 
389 	return rate;
390 }
391 
392 static struct clk_ops pll_gf40lp_laint_ops = {
393 	.enable = pll_gf40lp_laint_enable,
394 	.disable = pll_gf40lp_laint_disable,
395 	.is_enabled = pll_gf40lp_laint_is_enabled,
396 	.recalc_rate = pll_gf40lp_laint_recalc_rate,
397 	.round_rate = pll_round_rate,
398 	.set_rate = pll_gf40lp_laint_set_rate,
399 };
400 
401 static struct clk_ops pll_gf40lp_laint_fixed_ops = {
402 	.enable = pll_gf40lp_laint_enable,
403 	.disable = pll_gf40lp_laint_disable,
404 	.is_enabled = pll_gf40lp_laint_is_enabled,
405 	.recalc_rate = pll_gf40lp_laint_recalc_rate,
406 };
407 
408 static struct clk *pll_register(const char *name, const char *parent_name,
409 				unsigned long flags, void __iomem *base,
410 				enum pistachio_pll_type type,
411 				struct pistachio_pll_rate_table *rates,
412 				unsigned int nr_rates)
413 {
414 	struct pistachio_clk_pll *pll;
415 	struct clk_init_data init;
416 	struct clk *clk;
417 
418 	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
419 	if (!pll)
420 		return ERR_PTR(-ENOMEM);
421 
422 	init.name = name;
423 	init.flags = flags | CLK_GET_RATE_NOCACHE;
424 	init.parent_names = &parent_name;
425 	init.num_parents = 1;
426 
427 	switch (type) {
428 	case PLL_GF40LP_FRAC:
429 		if (rates)
430 			init.ops = &pll_gf40lp_frac_ops;
431 		else
432 			init.ops = &pll_gf40lp_frac_fixed_ops;
433 		break;
434 	case PLL_GF40LP_LAINT:
435 		if (rates)
436 			init.ops = &pll_gf40lp_laint_ops;
437 		else
438 			init.ops = &pll_gf40lp_laint_fixed_ops;
439 		break;
440 	default:
441 		pr_err("Unrecognized PLL type %u\n", type);
442 		kfree(pll);
443 		return ERR_PTR(-EINVAL);
444 	}
445 
446 	pll->hw.init = &init;
447 	pll->base = base;
448 	pll->rates = rates;
449 	pll->nr_rates = nr_rates;
450 
451 	clk = clk_register(NULL, &pll->hw);
452 	if (IS_ERR(clk))
453 		kfree(pll);
454 
455 	return clk;
456 }
457 
458 void pistachio_clk_register_pll(struct pistachio_clk_provider *p,
459 				struct pistachio_pll *pll,
460 				unsigned int num)
461 {
462 	struct clk *clk;
463 	unsigned int i;
464 
465 	for (i = 0; i < num; i++) {
466 		clk = pll_register(pll[i].name, pll[i].parent,
467 				   0, p->base + pll[i].reg_base,
468 				   pll[i].type, pll[i].rates,
469 				   pll[i].nr_rates);
470 		p->clk_data.clks[pll[i].id] = clk;
471 	}
472 }
473