KVM: arm/arm64: GICv4: Handle INVALL applied to a vPE
[linux/fpc-iii.git] / drivers / clk / pistachio / clk-pll.c
blob7e8daab9025bd326cc74d686d5e8f166ac775312
1 /*
2 * Copyright (C) 2014 Google, Inc.
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 */
9 #define pr_fmt(fmt) "%s: " fmt, __func__
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>
17 #include "clk.h"
19 #define PLL_STATUS 0x0
20 #define PLL_STATUS_LOCK BIT(0)
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)
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)
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)
53 #define PLL_CTRL4 0x10
54 #define PLL_FRAC_CTRL4_BYPASS BIT(28)
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
68 /* Fractional PLL operating modes */
69 enum pll_mode {
70 PLL_MODE_FRAC,
71 PLL_MODE_INT,
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;
81 static inline u32 pll_readl(struct pistachio_clk_pll *pll, u32 reg)
83 return readl(pll->base + reg);
86 static inline void pll_writel(struct pistachio_clk_pll *pll, u32 val, u32 reg)
88 writel(val, pll->base + reg);
91 static inline void pll_lock(struct pistachio_clk_pll *pll)
93 while (!(pll_readl(pll, PLL_STATUS) & PLL_STATUS_LOCK))
94 cpu_relax();
97 static inline u64 do_div_round_closest(u64 dividend, u64 divisor)
99 dividend += divisor / 2;
100 return div64_u64(dividend, divisor);
103 static inline struct pistachio_clk_pll *to_pistachio_pll(struct clk_hw *hw)
105 return container_of(hw, struct pistachio_clk_pll, hw);
108 static inline enum pll_mode pll_frac_get_mode(struct clk_hw *hw)
110 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
111 u32 val;
113 val = pll_readl(pll, PLL_CTRL3) & PLL_FRAC_CTRL3_DSMPD;
114 return val ? PLL_MODE_INT : PLL_MODE_FRAC;
117 static inline void pll_frac_set_mode(struct clk_hw *hw, enum pll_mode mode)
119 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
120 u32 val;
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);
128 pll_writel(pll, val, PLL_CTRL3);
131 static struct pistachio_pll_rate_table *
132 pll_get_params(struct pistachio_clk_pll *pll, unsigned long fref,
133 unsigned long fout)
135 unsigned int i;
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];
142 return NULL;
145 static long pll_round_rate(struct clk_hw *hw, unsigned long rate,
146 unsigned long *parent_rate)
148 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
149 unsigned int i;
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;
157 return pll->rates[0].fout;
160 static int pll_gf40lp_frac_enable(struct clk_hw *hw)
162 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
163 u32 val;
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);
170 val = pll_readl(pll, PLL_CTRL4);
171 val &= ~PLL_FRAC_CTRL4_BYPASS;
172 pll_writel(pll, val, PLL_CTRL4);
174 pll_lock(pll);
176 return 0;
179 static void pll_gf40lp_frac_disable(struct clk_hw *hw)
181 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
182 u32 val;
184 val = pll_readl(pll, PLL_CTRL3);
185 val |= PLL_FRAC_CTRL3_PD;
186 pll_writel(pll, val, PLL_CTRL3);
189 static int pll_gf40lp_frac_is_enabled(struct clk_hw *hw)
191 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
193 return !(pll_readl(pll, PLL_CTRL3) & PLL_FRAC_CTRL3_PD);
196 static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate,
197 unsigned long parent_rate)
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);
205 if (rate < MIN_OUTPUT_FRAC || rate > MAX_OUTPUT_FRAC)
206 return -EINVAL;
208 params = pll_get_params(pll, parent_rate, rate);
209 if (!params || !params->refdiv)
210 return -EINVAL;
212 /* calculate vco */
213 vco = params->fref;
214 vco *= (params->fbdiv << 24) + params->frac;
215 vco = div64_u64(vco, params->refdiv << 24);
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);
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);
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);
236 val = pll_readl(pll, PLL_CTRL2);
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);
247 if (params->postdiv2 > params->postdiv1)
248 pr_warn("%s: postdiv2 should not exceed postdiv1\n", name);
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);
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);
266 if (enabled)
267 pll_lock(pll);
269 return 0;
272 static unsigned long pll_gf40lp_frac_recalc_rate(struct clk_hw *hw,
273 unsigned long parent_rate)
275 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
276 u64 val, prediv, fbdiv, frac, postdiv1, postdiv2, rate;
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;
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;
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);
296 rate = do_div_round_closest(rate, (prediv * postdiv1 * postdiv2) << 24);
298 return rate;
301 static 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,
310 static 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,
317 static int pll_gf40lp_laint_enable(struct clk_hw *hw)
319 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
320 u32 val;
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);
327 val = pll_readl(pll, PLL_CTRL2);
328 val &= ~PLL_INT_CTRL2_BYPASS;
329 pll_writel(pll, val, PLL_CTRL2);
331 pll_lock(pll);
333 return 0;
336 static void pll_gf40lp_laint_disable(struct clk_hw *hw)
338 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
339 u32 val;
341 val = pll_readl(pll, PLL_CTRL1);
342 val |= PLL_INT_CTRL1_PD;
343 pll_writel(pll, val, PLL_CTRL1);
346 static int pll_gf40lp_laint_is_enabled(struct clk_hw *hw)
348 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
350 return !(pll_readl(pll, PLL_CTRL1) & PLL_INT_CTRL1_PD);
353 static int pll_gf40lp_laint_set_rate(struct clk_hw *hw, unsigned long rate,
354 unsigned long parent_rate)
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);
362 if (rate < MIN_OUTPUT_LA || rate > MAX_OUTPUT_LA)
363 return -EINVAL;
365 params = pll_get_params(pll, parent_rate, rate);
366 if (!params || !params->refdiv)
367 return -EINVAL;
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);
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);
382 val = pll_readl(pll, PLL_CTRL1);
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);
393 if (params->postdiv2 > params->postdiv1)
394 pr_warn("%s: postdiv2 should not exceed postdiv1\n", name);
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);
406 if (enabled)
407 pll_lock(pll);
409 return 0;
412 static unsigned long pll_gf40lp_laint_recalc_rate(struct clk_hw *hw,
413 unsigned long parent_rate)
415 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
416 u32 val, prediv, fbdiv, postdiv1, postdiv2;
417 u64 rate = parent_rate;
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;
427 rate *= fbdiv;
428 rate = do_div_round_closest(rate, prediv * postdiv1 * postdiv2);
430 return rate;
433 static 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,
442 static 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,
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)
455 struct pistachio_clk_pll *pll;
456 struct clk_init_data init;
457 struct clk *clk;
459 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
460 if (!pll)
461 return ERR_PTR(-ENOMEM);
463 init.name = name;
464 init.flags = flags | CLK_GET_RATE_NOCACHE;
465 init.parent_names = &parent_name;
466 init.num_parents = 1;
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);
487 pll->hw.init = &init;
488 pll->base = base;
489 pll->rates = rates;
490 pll->nr_rates = nr_rates;
492 clk = clk_register(NULL, &pll->hw);
493 if (IS_ERR(clk))
494 kfree(pll);
496 return clk;
499 void pistachio_clk_register_pll(struct pistachio_clk_provider *p,
500 struct pistachio_pll *pll,
501 unsigned int num)
503 struct clk *clk;
504 unsigned int i;
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;