]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - drivers/clk/st/clkgen-pll.c
treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152
[mirror_ubuntu-eoan-kernel.git] / drivers / clk / st / clkgen-pll.c
CommitLineData
2874c5fd 1// SPDX-License-Identifier: GPL-2.0-or-later
b9b8e614
GF
2/*
3 * Copyright (C) 2014 STMicroelectronics (R&D) Limited
b9b8e614
GF
4 */
5
6/*
7 * Authors:
8 * Stephen Gallimore <stephen.gallimore@st.com>,
9 * Pankaj Dev <pankaj.dev@st.com>.
10 */
11
12#include <linux/slab.h>
13#include <linux/of_address.h>
d5f728ac 14#include <linux/clk.h>
b9b8e614 15#include <linux/clk-provider.h>
fb473862 16#include <linux/iopoll.h>
b9b8e614
GF
17
18#include "clkgen.h"
19
20static DEFINE_SPINLOCK(clkgena_c32_odf_lock);
46a57afd 21DEFINE_SPINLOCK(clkgen_a9_lock);
b9b8e614 22
b9b8e614
GF
23/*
24 * PLL configuration register bits for PLL3200 C32
25 */
26#define C32_NDIV_MASK (0xff)
27#define C32_IDF_MASK (0x7)
28#define C32_ODF_MASK (0x3f)
29#define C32_LDF_MASK (0x7f)
46a57afd 30#define C32_CP_MASK (0x1f)
b9b8e614
GF
31
32#define C32_MAX_ODFS (4)
33
0829ea5a
GF
34/*
35 * PLL configuration register bits for PLL4600 C28
36 */
37#define C28_NDIV_MASK (0xff)
38#define C28_IDF_MASK (0x7)
39#define C28_ODF_MASK (0x3f)
40
b9b8e614
GF
41struct clkgen_pll_data {
42 struct clkgen_field pdn_status;
fb473862 43 struct clkgen_field pdn_ctrl;
b9b8e614
GF
44 struct clkgen_field locked_status;
45 struct clkgen_field mdiv;
46 struct clkgen_field ndiv;
47 struct clkgen_field pdiv;
48 struct clkgen_field idf;
49 struct clkgen_field ldf;
46a57afd 50 struct clkgen_field cp;
b9b8e614
GF
51 unsigned int num_odfs;
52 struct clkgen_field odf[C32_MAX_ODFS];
53 struct clkgen_field odf_gate[C32_MAX_ODFS];
46a57afd
GF
54 bool switch2pll_en;
55 struct clkgen_field switch2pll;
56 spinlock_t *lock;
b9b8e614
GF
57 const struct clk_ops *ops;
58};
59
b9b8e614 60static const struct clk_ops stm_pll3200c32_ops;
46a57afd 61static const struct clk_ops stm_pll3200c32_a9_ops;
0829ea5a 62static const struct clk_ops stm_pll4600c28_ops;
b9b8e614 63
eee8f783
GF
64static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
65 /* 407 A0 */
66 .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8),
fb473862 67 .pdn_ctrl = CLKGEN_FIELD(0x2a0, 0x1, 8),
eee8f783
GF
68 .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24),
69 .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16),
70 .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0),
71 .num_odfs = 1,
72 .odf = { CLKGEN_FIELD(0x2b4, C32_ODF_MASK, 0) },
73 .odf_gate = { CLKGEN_FIELD(0x2b4, 0x1, 6) },
74 .ops = &stm_pll3200c32_ops,
75};
76
d34e210e 77static const struct clkgen_pll_data st_pll3200c32_cx_0 = {
51306d56
GF
78 /* 407 C0 PLL0 */
79 .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8),
fb473862 80 .pdn_ctrl = CLKGEN_FIELD(0x2a0, 0x1, 8),
51306d56
GF
81 .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24),
82 .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16),
83 .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0),
84 .num_odfs = 1,
85 .odf = { CLKGEN_FIELD(0x2b4, C32_ODF_MASK, 0) },
86 .odf_gate = { CLKGEN_FIELD(0x2b4, 0x1, 6) },
87 .ops = &stm_pll3200c32_ops,
88};
89
d34e210e 90static const struct clkgen_pll_data st_pll3200c32_cx_1 = {
51306d56
GF
91 /* 407 C0 PLL1 */
92 .pdn_status = CLKGEN_FIELD(0x2c8, 0x1, 8),
fb473862 93 .pdn_ctrl = CLKGEN_FIELD(0x2c8, 0x1, 8),
51306d56
GF
94 .locked_status = CLKGEN_FIELD(0x2c8, 0x1, 24),
95 .ndiv = CLKGEN_FIELD(0x2cc, C32_NDIV_MASK, 16),
96 .idf = CLKGEN_FIELD(0x2cc, C32_IDF_MASK, 0x0),
97 .num_odfs = 1,
98 .odf = { CLKGEN_FIELD(0x2dc, C32_ODF_MASK, 0) },
99 .odf_gate = { CLKGEN_FIELD(0x2dc, 0x1, 6) },
100 .ops = &stm_pll3200c32_ops,
101};
102
aaa65d77
GF
103static const struct clkgen_pll_data st_pll3200c32_407_a9 = {
104 /* 407 A9 */
105 .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0),
fb473862 106 .pdn_ctrl = CLKGEN_FIELD(0x1a8, 0x1, 0),
aaa65d77
GF
107 .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0),
108 .ndiv = CLKGEN_FIELD(0x1b0, C32_NDIV_MASK, 0),
109 .idf = CLKGEN_FIELD(0x1a8, C32_IDF_MASK, 25),
110 .num_odfs = 1,
111 .odf = { CLKGEN_FIELD(0x1b0, C32_ODF_MASK, 8) },
112 .odf_gate = { CLKGEN_FIELD(0x1ac, 0x1, 28) },
46a57afd
GF
113 .switch2pll_en = true,
114 .cp = CLKGEN_FIELD(0x1a8, C32_CP_MASK, 1),
115 .switch2pll = CLKGEN_FIELD(0x1a4, 0x1, 1),
116 .lock = &clkgen_a9_lock,
117 .ops = &stm_pll3200c32_a9_ops,
aaa65d77
GF
118};
119
0829ea5a
GF
120static struct clkgen_pll_data st_pll4600c28_418_a9 = {
121 /* 418 A9 */
122 .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0),
123 .pdn_ctrl = CLKGEN_FIELD(0x1a8, 0x1, 0),
124 .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0),
125 .ndiv = CLKGEN_FIELD(0x1b0, C28_NDIV_MASK, 0),
126 .idf = CLKGEN_FIELD(0x1a8, C28_IDF_MASK, 25),
127 .num_odfs = 1,
128 .odf = { CLKGEN_FIELD(0x1b0, C28_ODF_MASK, 8) },
129 .odf_gate = { CLKGEN_FIELD(0x1ac, 0x1, 28) },
130 .switch2pll_en = true,
131 .switch2pll = CLKGEN_FIELD(0x1a4, 0x1, 1),
132 .lock = &clkgen_a9_lock,
133 .ops = &stm_pll4600c28_ops,
134};
135
b9b8e614
GF
136/**
137 * DOC: Clock Generated by PLL, rate set and enabled by bootloader
138 *
139 * Traits of this clock:
140 * prepare - clk_(un)prepare only ensures parent is (un)prepared
141 * enable - clk_enable/disable only ensures parent is enabled
142 * rate - rate is fixed. No clk_set_rate support
143 * parent - fixed parent. No clk_set_parent support
144 */
145
146/**
147 * PLL clock that is integrated in the ClockGenA instances on the STiH415
148 * and STiH416.
149 *
150 * @hw: handle between common and hardware-specific interfaces.
151 * @type: PLL instance type.
152 * @regs_base: base of the PLL configuration register(s).
153 *
154 */
155struct clkgen_pll {
156 struct clk_hw hw;
157 struct clkgen_pll_data *data;
158 void __iomem *regs_base;
46a57afd
GF
159 spinlock_t *lock;
160
161 u32 ndiv;
162 u32 idf;
163 u32 odf;
164 u32 cp;
b9b8e614
GF
165};
166
167#define to_clkgen_pll(_hw) container_of(_hw, struct clkgen_pll, hw)
168
46a57afd
GF
169struct stm_pll {
170 unsigned long mdiv;
171 unsigned long ndiv;
172 unsigned long pdiv;
173 unsigned long odf;
174 unsigned long idf;
175 unsigned long ldf;
176 unsigned long cp;
177};
178
b9b8e614
GF
179static int clkgen_pll_is_locked(struct clk_hw *hw)
180{
181 struct clkgen_pll *pll = to_clkgen_pll(hw);
182 u32 locked = CLKGEN_READ(pll, locked_status);
183
184 return !!locked;
185}
186
187static int clkgen_pll_is_enabled(struct clk_hw *hw)
188{
189 struct clkgen_pll *pll = to_clkgen_pll(hw);
190 u32 poweroff = CLKGEN_READ(pll, pdn_status);
191 return !poweroff;
192}
193
46a57afd 194static int __clkgen_pll_enable(struct clk_hw *hw)
fb473862
GF
195{
196 struct clkgen_pll *pll = to_clkgen_pll(hw);
197 void __iomem *base = pll->regs_base;
198 struct clkgen_field *field = &pll->data->locked_status;
199 int ret = 0;
200 u32 reg;
201
202 if (clkgen_pll_is_enabled(hw))
203 return 0;
204
205 CLKGEN_WRITE(pll, pdn_ctrl, 0);
206
207 ret = readl_relaxed_poll_timeout(base + field->offset, reg,
208 !!((reg >> field->shift) & field->mask), 0, 10000);
209
46a57afd
GF
210 if (!ret) {
211 if (pll->data->switch2pll_en)
212 CLKGEN_WRITE(pll, switch2pll, 0);
213
fb473862 214 pr_debug("%s:%s enabled\n", __clk_get_name(hw->clk), __func__);
46a57afd 215 }
fb473862
GF
216
217 return ret;
218}
219
46a57afd
GF
220static int clkgen_pll_enable(struct clk_hw *hw)
221{
222 struct clkgen_pll *pll = to_clkgen_pll(hw);
223 unsigned long flags = 0;
224 int ret = 0;
225
226 if (pll->lock)
227 spin_lock_irqsave(pll->lock, flags);
228
229 ret = __clkgen_pll_enable(hw);
230
231 if (pll->lock)
232 spin_unlock_irqrestore(pll->lock, flags);
233
234 return ret;
235}
236
237static void __clkgen_pll_disable(struct clk_hw *hw)
fb473862
GF
238{
239 struct clkgen_pll *pll = to_clkgen_pll(hw);
240
241 if (!clkgen_pll_is_enabled(hw))
242 return;
243
46a57afd
GF
244 if (pll->data->switch2pll_en)
245 CLKGEN_WRITE(pll, switch2pll, 1);
246
fb473862
GF
247 CLKGEN_WRITE(pll, pdn_ctrl, 1);
248
249 pr_debug("%s:%s disabled\n", __clk_get_name(hw->clk), __func__);
250}
251
46a57afd
GF
252static void clkgen_pll_disable(struct clk_hw *hw)
253{
254 struct clkgen_pll *pll = to_clkgen_pll(hw);
255 unsigned long flags = 0;
256
257 if (pll->lock)
258 spin_lock_irqsave(pll->lock, flags);
259
260 __clkgen_pll_disable(hw);
261
262 if (pll->lock)
263 spin_unlock_irqrestore(pll->lock, flags);
264}
265
46a57afd
GF
266static int clk_pll3200c32_get_params(unsigned long input, unsigned long output,
267 struct stm_pll *pll)
268{
269 unsigned long i, n;
270 unsigned long deviation = ~0;
271 unsigned long new_freq;
272 long new_deviation;
273 /* Charge pump table: highest ndiv value for cp=6 to 25 */
274 static const unsigned char cp_table[] = {
275 48, 56, 64, 72, 80, 88, 96, 104, 112, 120,
276 128, 136, 144, 152, 160, 168, 176, 184, 192
277 };
278
279 /* Output clock range: 800Mhz to 1600Mhz */
280 if (output < 800000000 || output > 1600000000)
281 return -EINVAL;
282
283 input /= 1000;
284 output /= 1000;
285
286 for (i = 1; i <= 7 && deviation; i++) {
287 n = i * output / (2 * input);
288
289 /* Checks */
290 if (n < 8)
291 continue;
292 if (n > 200)
293 break;
294
295 new_freq = (input * 2 * n) / i;
296
297 new_deviation = abs(new_freq - output);
298
299 if (!new_deviation || new_deviation < deviation) {
300 pll->idf = i;
301 pll->ndiv = n;
302 deviation = new_deviation;
303 }
304 }
305
306 if (deviation == ~0) /* No solution found */
307 return -EINVAL;
308
309 /* Computing recommended charge pump value */
310 for (pll->cp = 6; pll->ndiv > cp_table[pll->cp-6]; (pll->cp)++)
311 ;
312
313 return 0;
314}
315
316static int clk_pll3200c32_get_rate(unsigned long input, struct stm_pll *pll,
317 unsigned long *rate)
318{
319 if (!pll->idf)
320 pll->idf = 1;
321
322 *rate = ((2 * (input / 1000) * pll->ndiv) / pll->idf) * 1000;
323
324 return 0;
325}
326
8e6dd77c 327static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
b9b8e614
GF
328 unsigned long parent_rate)
329{
330 struct clkgen_pll *pll = to_clkgen_pll(hw);
331 unsigned long ndiv, idf;
332 unsigned long rate = 0;
333
334 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
335 return 0;
336
337 ndiv = CLKGEN_READ(pll, ndiv);
338 idf = CLKGEN_READ(pll, idf);
339
340 if (idf)
341 /* Note: input is divided to avoid overflow */
342 rate = ((2 * (parent_rate/1000) * ndiv) / idf) * 1000;
343
836ee0f7 344 pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
b9b8e614
GF
345
346 return rate;
347}
348
46a57afd
GF
349static long round_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate,
350 unsigned long *prate)
351{
352 struct stm_pll params;
353
354 if (!clk_pll3200c32_get_params(*prate, rate, &params))
355 clk_pll3200c32_get_rate(*prate, &params, &rate);
356 else {
357 pr_debug("%s: %s rate %ld Invalid\n", __func__,
358 __clk_get_name(hw->clk), rate);
359 return 0;
360 }
361
362 pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n",
363 __func__, __clk_get_name(hw->clk),
364 rate, (unsigned int)params.ndiv,
365 (unsigned int)params.idf);
366
367 return rate;
368}
369
370static int set_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate,
371 unsigned long parent_rate)
372{
373 struct clkgen_pll *pll = to_clkgen_pll(hw);
374 struct stm_pll params;
375 long hwrate = 0;
376 unsigned long flags = 0;
377
378 if (!rate || !parent_rate)
379 return -EINVAL;
380
381 if (!clk_pll3200c32_get_params(parent_rate, rate, &params))
382 clk_pll3200c32_get_rate(parent_rate, &params, &hwrate);
383
384 pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n",
385 __func__, __clk_get_name(hw->clk),
386 hwrate, (unsigned int)params.ndiv,
387 (unsigned int)params.idf);
388
389 if (!hwrate)
390 return -EINVAL;
391
392 pll->ndiv = params.ndiv;
393 pll->idf = params.idf;
394 pll->cp = params.cp;
395
396 __clkgen_pll_disable(hw);
397
398 if (pll->lock)
399 spin_lock_irqsave(pll->lock, flags);
400
401 CLKGEN_WRITE(pll, ndiv, pll->ndiv);
402 CLKGEN_WRITE(pll, idf, pll->idf);
403 CLKGEN_WRITE(pll, cp, pll->cp);
404
405 if (pll->lock)
406 spin_unlock_irqrestore(pll->lock, flags);
407
408 __clkgen_pll_enable(hw);
409
410 return 0;
411}
412
0829ea5a
GF
413/* PLL output structure
414 * FVCO >> /2 >> FVCOBY2 (no output)
415 * |> Divider (ODF) >> PHI
416 *
417 * FVCOby2 output = (input * 2 * NDIV) / IDF (assuming FRAC_CONTROL==L)
418 *
419 * Rules:
420 * 4Mhz <= INFF input <= 350Mhz
421 * 4Mhz <= INFIN (INFF / IDF) <= 50Mhz
422 * 19.05Mhz <= FVCOby2 output (PHI w ODF=1) <= 3000Mhz
423 * 1 <= i (register/dec value for IDF) <= 7
424 * 8 <= n (register/dec value for NDIV) <= 246
425 */
426
427static int clk_pll4600c28_get_params(unsigned long input, unsigned long output,
428 struct stm_pll *pll)
429{
430
431 unsigned long i, infin, n;
432 unsigned long deviation = ~0;
433 unsigned long new_freq, new_deviation;
434
435 /* Output clock range: 19Mhz to 3000Mhz */
436 if (output < 19000000 || output > 3000000000u)
437 return -EINVAL;
438
439 /* For better jitter, IDF should be smallest and NDIV must be maximum */
440 for (i = 1; i <= 7 && deviation; i++) {
441 /* INFIN checks */
442 infin = input / i;
443 if (infin < 4000000 || infin > 50000000)
444 continue; /* Invalid case */
445
446 n = output / (infin * 2);
447 if (n < 8 || n > 246)
448 continue; /* Invalid case */
449 if (n < 246)
450 n++; /* To work around 'y' when n=x.y */
451
452 for (; n >= 8 && deviation; n--) {
453 new_freq = infin * 2 * n;
454 if (new_freq < output)
455 break; /* Optimization: shorting loop */
456
457 new_deviation = new_freq - output;
458 if (!new_deviation || new_deviation < deviation) {
459 pll->idf = i;
460 pll->ndiv = n;
461 deviation = new_deviation;
462 }
463 }
464 }
465
466 if (deviation == ~0) /* No solution found */
467 return -EINVAL;
468
469 return 0;
470}
471
472static int clk_pll4600c28_get_rate(unsigned long input, struct stm_pll *pll,
473 unsigned long *rate)
474{
475 if (!pll->idf)
476 pll->idf = 1;
477
478 *rate = (input / pll->idf) * 2 * pll->ndiv;
479
480 return 0;
481}
482
483static unsigned long recalc_stm_pll4600c28(struct clk_hw *hw,
484 unsigned long parent_rate)
485{
486 struct clkgen_pll *pll = to_clkgen_pll(hw);
487 struct stm_pll params;
488 unsigned long rate;
489
490 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
491 return 0;
492
493 params.ndiv = CLKGEN_READ(pll, ndiv);
494 params.idf = CLKGEN_READ(pll, idf);
495
496 clk_pll4600c28_get_rate(parent_rate, &params, &rate);
497
498 pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
499
500 return rate;
501}
502
503static long round_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate,
504 unsigned long *prate)
505{
506 struct stm_pll params;
507
508 if (!clk_pll4600c28_get_params(*prate, rate, &params)) {
509 clk_pll4600c28_get_rate(*prate, &params, &rate);
510 } else {
511 pr_debug("%s: %s rate %ld Invalid\n", __func__,
512 __clk_get_name(hw->clk), rate);
513 return 0;
514 }
515
516 pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n",
517 __func__, __clk_get_name(hw->clk),
518 rate, (unsigned int)params.ndiv,
519 (unsigned int)params.idf);
520
521 return rate;
522}
523
524static int set_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate,
525 unsigned long parent_rate)
526{
527 struct clkgen_pll *pll = to_clkgen_pll(hw);
528 struct stm_pll params;
529 long hwrate;
530 unsigned long flags = 0;
531
532 if (!rate || !parent_rate)
533 return -EINVAL;
534
535 if (!clk_pll4600c28_get_params(parent_rate, rate, &params)) {
536 clk_pll4600c28_get_rate(parent_rate, &params, &hwrate);
537 } else {
538 pr_debug("%s: %s rate %ld Invalid\n", __func__,
539 __clk_get_name(hw->clk), rate);
540 return -EINVAL;
541 }
542
543 pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n",
544 __func__, __clk_get_name(hw->clk),
545 hwrate, (unsigned int)params.ndiv,
546 (unsigned int)params.idf);
547
548 if (!hwrate)
549 return -EINVAL;
550
551 pll->ndiv = params.ndiv;
552 pll->idf = params.idf;
553
554 __clkgen_pll_disable(hw);
555
556 if (pll->lock)
557 spin_lock_irqsave(pll->lock, flags);
558
559 CLKGEN_WRITE(pll, ndiv, pll->ndiv);
560 CLKGEN_WRITE(pll, idf, pll->idf);
561
562 if (pll->lock)
563 spin_unlock_irqrestore(pll->lock, flags);
564
565 __clkgen_pll_enable(hw);
566
567 return 0;
568}
569
b9b8e614 570static const struct clk_ops stm_pll3200c32_ops = {
fb473862
GF
571 .enable = clkgen_pll_enable,
572 .disable = clkgen_pll_disable,
b9b8e614
GF
573 .is_enabled = clkgen_pll_is_enabled,
574 .recalc_rate = recalc_stm_pll3200c32,
575};
576
46a57afd
GF
577static const struct clk_ops stm_pll3200c32_a9_ops = {
578 .enable = clkgen_pll_enable,
579 .disable = clkgen_pll_disable,
580 .is_enabled = clkgen_pll_is_enabled,
581 .recalc_rate = recalc_stm_pll3200c32,
582 .round_rate = round_rate_stm_pll3200c32,
583 .set_rate = set_rate_stm_pll3200c32,
584};
585
0829ea5a
GF
586static const struct clk_ops stm_pll4600c28_ops = {
587 .enable = clkgen_pll_enable,
588 .disable = clkgen_pll_disable,
589 .is_enabled = clkgen_pll_is_enabled,
590 .recalc_rate = recalc_stm_pll4600c28,
591 .round_rate = round_rate_stm_pll4600c28,
592 .set_rate = set_rate_stm_pll4600c28,
593};
594
b9b8e614
GF
595static struct clk * __init clkgen_pll_register(const char *parent_name,
596 struct clkgen_pll_data *pll_data,
6ca59e6e 597 void __iomem *reg, unsigned long pll_flags,
46a57afd 598 const char *clk_name, spinlock_t *lock)
b9b8e614
GF
599{
600 struct clkgen_pll *pll;
601 struct clk *clk;
602 struct clk_init_data init;
603
604 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
605 if (!pll)
606 return ERR_PTR(-ENOMEM);
607
608 init.name = clk_name;
609 init.ops = pll_data->ops;
610
c179c21e 611 init.flags = pll_flags | CLK_GET_RATE_NOCACHE;
b9b8e614
GF
612 init.parent_names = &parent_name;
613 init.num_parents = 1;
614
615 pll->data = pll_data;
616 pll->regs_base = reg;
617 pll->hw.init = &init;
46a57afd 618 pll->lock = lock;
b9b8e614
GF
619
620 clk = clk_register(NULL, &pll->hw);
621 if (IS_ERR(clk)) {
622 kfree(pll);
623 return clk;
624 }
625
626 pr_debug("%s: parent %s rate %lu\n",
627 __clk_get_name(clk),
628 __clk_get_name(clk_get_parent(clk)),
629 clk_get_rate(clk));
630
631 return clk;
632}
633
b9b8e614
GF
634static void __iomem * __init clkgen_get_register_base(
635 struct device_node *np)
636{
637 struct device_node *pnode;
638 void __iomem *reg = NULL;
639
640 pnode = of_get_parent(np);
641 if (!pnode)
642 return NULL;
643
644 reg = of_iomap(pnode, 0);
645
646 of_node_put(pnode);
647 return reg;
648}
649
b9b8e614 650static struct clk * __init clkgen_odf_register(const char *parent_name,
8e6dd77c 651 void __iomem *reg,
b9b8e614 652 struct clkgen_pll_data *pll_data,
6ca59e6e 653 unsigned long pll_flags, int odf,
b9b8e614
GF
654 spinlock_t *odf_lock,
655 const char *odf_name)
656{
657 struct clk *clk;
658 unsigned long flags;
659 struct clk_gate *gate;
660 struct clk_divider *div;
661
6ca59e6e 662 flags = pll_flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT;
b9b8e614
GF
663
664 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
665 if (!gate)
666 return ERR_PTR(-ENOMEM);
667
668 gate->flags = CLK_GATE_SET_TO_DISABLE;
669 gate->reg = reg + pll_data->odf_gate[odf].offset;
670 gate->bit_idx = pll_data->odf_gate[odf].shift;
671 gate->lock = odf_lock;
672
673 div = kzalloc(sizeof(*div), GFP_KERNEL);
72b1c2c3
VI
674 if (!div) {
675 kfree(gate);
b9b8e614 676 return ERR_PTR(-ENOMEM);
72b1c2c3 677 }
b9b8e614
GF
678
679 div->flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
680 div->reg = reg + pll_data->odf[odf].offset;
681 div->shift = pll_data->odf[odf].shift;
682 div->width = fls(pll_data->odf[odf].mask);
683 div->lock = odf_lock;
684
685 clk = clk_register_composite(NULL, odf_name, &parent_name, 1,
686 NULL, NULL,
687 &div->hw, &clk_divider_ops,
688 &gate->hw, &clk_gate_ops,
689 flags);
690 if (IS_ERR(clk))
691 return clk;
692
693 pr_debug("%s: parent %s rate %lu\n",
694 __clk_get_name(clk),
695 __clk_get_name(clk_get_parent(clk)),
696 clk_get_rate(clk));
697 return clk;
698}
699
b9b8e614 700
880d54ff
GF
701static void __init clkgen_c32_pll_setup(struct device_node *np,
702 struct clkgen_pll_data *data)
b9b8e614 703{
b9b8e614
GF
704 struct clk *clk;
705 const char *parent_name, *pll_name;
706 void __iomem *pll_base;
707 int num_odfs, odf;
708 struct clk_onecell_data *clk_data;
6ca59e6e 709 unsigned long pll_flags = 0;
b9b8e614 710
b9b8e614
GF
711
712 parent_name = of_clk_get_parent_name(np, 0);
713 if (!parent_name)
714 return;
715
716 pll_base = clkgen_get_register_base(np);
717 if (!pll_base)
718 return;
719
6ca59e6e
LJ
720 of_clk_detect_critical(np, 0, &pll_flags);
721
722 clk = clkgen_pll_register(parent_name, data, pll_base, pll_flags,
723 np->name, data->lock);
b9b8e614
GF
724 if (IS_ERR(clk))
725 return;
726
727 pll_name = __clk_get_name(clk);
728
729 num_odfs = data->num_odfs;
730
731 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
732 if (!clk_data)
733 return;
734
735 clk_data->clk_num = num_odfs;
6396bb22 736 clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *),
b9b8e614
GF
737 GFP_KERNEL);
738
739 if (!clk_data->clks)
740 goto err;
741
742 for (odf = 0; odf < num_odfs; odf++) {
743 struct clk *clk;
744 const char *clk_name;
6ca59e6e 745 unsigned long odf_flags = 0;
b9b8e614
GF
746
747 if (of_property_read_string_index(np, "clock-output-names",
748 odf, &clk_name))
749 return;
750
6ca59e6e
LJ
751 of_clk_detect_critical(np, odf, &odf_flags);
752
753 clk = clkgen_odf_register(pll_name, pll_base, data, odf_flags,
b9b8e614
GF
754 odf, &clkgena_c32_odf_lock, clk_name);
755 if (IS_ERR(clk))
756 goto err;
757
758 clk_data->clks[odf] = clk;
759 }
760
761 of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
762 return;
763
764err:
765 kfree(pll_name);
766 kfree(clk_data->clks);
767 kfree(clk_data);
768}
880d54ff
GF
769static void __init clkgen_c32_pll0_setup(struct device_node *np)
770{
771 clkgen_c32_pll_setup(np,
772 (struct clkgen_pll_data *) &st_pll3200c32_cx_0);
773}
774CLK_OF_DECLARE(c32_pll0, "st,clkgen-pll0", clkgen_c32_pll0_setup);
775
776static void __init clkgen_c32_pll1_setup(struct device_node *np)
777{
778 clkgen_c32_pll_setup(np,
779 (struct clkgen_pll_data *) &st_pll3200c32_cx_1);
780}
781CLK_OF_DECLARE(c32_pll1, "st,clkgen-pll1", clkgen_c32_pll1_setup);
782
783static void __init clkgen_c32_plla9_setup(struct device_node *np)
784{
785 clkgen_c32_pll_setup(np,
786 (struct clkgen_pll_data *) &st_pll3200c32_407_a9);
787}
788CLK_OF_DECLARE(c32_plla9, "st,stih407-clkgen-plla9", clkgen_c32_plla9_setup);
789
790static void __init clkgen_c28_plla9_setup(struct device_node *np)
791{
792 clkgen_c32_pll_setup(np,
793 (struct clkgen_pll_data *) &st_pll4600c28_418_a9);
794}
795CLK_OF_DECLARE(c28_plla9, "st,stih418-clkgen-plla9", clkgen_c28_plla9_setup);