blob: 510b685212d3f3a92611f4315b79175d53ecf5cc [file] [log] [blame]
Paul Burtonb0663032015-05-24 16:11:35 +01001/*
2 * Ingenic SoC CGU driver
3 *
4 * Copyright (c) 2013-2015 Imagination Technologies
Paul Burtonfb615d62017-10-25 17:04:33 -07005 * Author: Paul Burton <paul.burton@mips.com>
Paul Burtonb0663032015-05-24 16:11:35 +01006 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/bitops.h>
Stephen Boyde2a65702015-05-01 16:09:33 -070019#include <linux/clk.h>
Paul Burtonb0663032015-05-24 16:11:35 +010020#include <linux/clk-provider.h>
21#include <linux/clkdev.h>
22#include <linux/delay.h>
23#include <linux/math64.h>
24#include <linux/of.h>
25#include <linux/of_address.h>
26#include <linux/slab.h>
27#include <linux/spinlock.h>
28#include "cgu.h"
29
30#define MHZ (1000 * 1000)
31
32/**
33 * ingenic_cgu_gate_get() - get the value of clock gate register bit
34 * @cgu: reference to the CGU whose registers should be read
35 * @info: info struct describing the gate bit
36 *
37 * Retrieves the state of the clock gate bit described by info. The
38 * caller must hold cgu->lock.
39 *
40 * Return: true if the gate bit is set, else false.
41 */
42static inline bool
43ingenic_cgu_gate_get(struct ingenic_cgu *cgu,
44 const struct ingenic_cgu_gate_info *info)
45{
Paul Cercueil7ef38442018-05-20 16:31:12 +000046 return !!(readl(cgu->base + info->reg) & BIT(info->bit))
47 ^ info->clear_to_gate;
Paul Burtonb0663032015-05-24 16:11:35 +010048}
49
50/**
51 * ingenic_cgu_gate_set() - set the value of clock gate register bit
52 * @cgu: reference to the CGU whose registers should be modified
53 * @info: info struct describing the gate bit
54 * @val: non-zero to gate a clock, otherwise zero
55 *
56 * Sets the given gate bit in order to gate or ungate a clock.
57 *
58 * The caller must hold cgu->lock.
59 */
60static inline void
61ingenic_cgu_gate_set(struct ingenic_cgu *cgu,
62 const struct ingenic_cgu_gate_info *info, bool val)
63{
64 u32 clkgr = readl(cgu->base + info->reg);
65
Paul Cercueil7ef38442018-05-20 16:31:12 +000066 if (val ^ info->clear_to_gate)
Paul Burtonb0663032015-05-24 16:11:35 +010067 clkgr |= BIT(info->bit);
68 else
69 clkgr &= ~BIT(info->bit);
70
71 writel(clkgr, cgu->base + info->reg);
72}
73
74/*
75 * PLL operations
76 */
77
78static unsigned long
79ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
80{
81 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
82 struct ingenic_cgu *cgu = ingenic_clk->cgu;
83 const struct ingenic_cgu_clk_info *clk_info;
84 const struct ingenic_cgu_pll_info *pll_info;
85 unsigned m, n, od_enc, od;
YueHaibing635bd69b2019-02-26 01:57:32 +000086 bool bypass;
Paul Burtonb0663032015-05-24 16:11:35 +010087 unsigned long flags;
88 u32 ctl;
89
90 clk_info = &cgu->clock_info[ingenic_clk->idx];
91 BUG_ON(clk_info->type != CGU_CLK_PLL);
92 pll_info = &clk_info->pll;
93
94 spin_lock_irqsave(&cgu->lock, flags);
95 ctl = readl(cgu->base + pll_info->reg);
96 spin_unlock_irqrestore(&cgu->lock, flags);
97
98 m = (ctl >> pll_info->m_shift) & GENMASK(pll_info->m_bits - 1, 0);
99 m += pll_info->m_offset;
100 n = (ctl >> pll_info->n_shift) & GENMASK(pll_info->n_bits - 1, 0);
101 n += pll_info->n_offset;
102 od_enc = ctl >> pll_info->od_shift;
103 od_enc &= GENMASK(pll_info->od_bits - 1, 0);
Paul Cercueil268db072018-01-16 16:47:53 +0100104 bypass = !pll_info->no_bypass_bit &&
105 !!(ctl & BIT(pll_info->bypass_bit));
Paul Burtonb0663032015-05-24 16:11:35 +0100106
107 if (bypass)
108 return parent_rate;
109
Paul Burtonb0663032015-05-24 16:11:35 +0100110 for (od = 0; od < pll_info->od_max; od++) {
111 if (pll_info->od_encoding[od] == od_enc)
112 break;
113 }
114 BUG_ON(od == pll_info->od_max);
115 od++;
116
117 return div_u64((u64)parent_rate * m, n * od);
118}
119
120static unsigned long
121ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
122 unsigned long rate, unsigned long parent_rate,
123 unsigned *pm, unsigned *pn, unsigned *pod)
124{
125 const struct ingenic_cgu_pll_info *pll_info;
126 unsigned m, n, od;
127
128 pll_info = &clk_info->pll;
129 od = 1;
130
131 /*
132 * The frequency after the input divider must be between 10 and 50 MHz.
133 * The highest divider yields the best resolution.
134 */
135 n = parent_rate / (10 * MHZ);
136 n = min_t(unsigned, n, 1 << clk_info->pll.n_bits);
137 n = max_t(unsigned, n, pll_info->n_offset);
138
139 m = (rate / MHZ) * od * n / (parent_rate / MHZ);
140 m = min_t(unsigned, m, 1 << clk_info->pll.m_bits);
141 m = max_t(unsigned, m, pll_info->m_offset);
142
143 if (pm)
144 *pm = m;
145 if (pn)
146 *pn = n;
147 if (pod)
148 *pod = od;
149
150 return div_u64((u64)parent_rate * m, n * od);
151}
152
Paul Cercueilab27eb42018-01-16 16:47:54 +0100153static inline const struct ingenic_cgu_clk_info *to_clk_info(
154 struct ingenic_clk *ingenic_clk)
Paul Burtonb0663032015-05-24 16:11:35 +0100155{
Paul Burtonb0663032015-05-24 16:11:35 +0100156 struct ingenic_cgu *cgu = ingenic_clk->cgu;
157 const struct ingenic_cgu_clk_info *clk_info;
158
159 clk_info = &cgu->clock_info[ingenic_clk->idx];
160 BUG_ON(clk_info->type != CGU_CLK_PLL);
161
Paul Cercueilab27eb42018-01-16 16:47:54 +0100162 return clk_info;
163}
164
165static long
166ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,
167 unsigned long *prate)
168{
169 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
170 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
171
Paul Burtonb0663032015-05-24 16:11:35 +0100172 return ingenic_pll_calc(clk_info, req_rate, *prate, NULL, NULL, NULL);
173}
174
175static int
176ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
177 unsigned long parent_rate)
178{
Paul Burtonb0663032015-05-24 16:11:35 +0100179 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
180 struct ingenic_cgu *cgu = ingenic_clk->cgu;
Paul Cercueilab27eb42018-01-16 16:47:54 +0100181 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
182 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
Paul Burtonb0663032015-05-24 16:11:35 +0100183 unsigned long rate, flags;
Paul Cercueilab27eb42018-01-16 16:47:54 +0100184 unsigned int m, n, od;
Paul Burtonb0663032015-05-24 16:11:35 +0100185 u32 ctl;
186
Paul Burtonb0663032015-05-24 16:11:35 +0100187 rate = ingenic_pll_calc(clk_info, req_rate, parent_rate,
188 &m, &n, &od);
189 if (rate != req_rate)
190 pr_info("ingenic-cgu: request '%s' rate %luHz, actual %luHz\n",
191 clk_info->name, req_rate, rate);
192
193 spin_lock_irqsave(&cgu->lock, flags);
194 ctl = readl(cgu->base + pll_info->reg);
195
196 ctl &= ~(GENMASK(pll_info->m_bits - 1, 0) << pll_info->m_shift);
197 ctl |= (m - pll_info->m_offset) << pll_info->m_shift;
198
199 ctl &= ~(GENMASK(pll_info->n_bits - 1, 0) << pll_info->n_shift);
200 ctl |= (n - pll_info->n_offset) << pll_info->n_shift;
201
202 ctl &= ~(GENMASK(pll_info->od_bits - 1, 0) << pll_info->od_shift);
203 ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift;
204
Paul Cercueilab27eb42018-01-16 16:47:54 +0100205 writel(ctl, cgu->base + pll_info->reg);
206 spin_unlock_irqrestore(&cgu->lock, flags);
207
208 return 0;
209}
210
211static int ingenic_pll_enable(struct clk_hw *hw)
212{
213 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
214 struct ingenic_cgu *cgu = ingenic_clk->cgu;
215 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
216 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
217 const unsigned int timeout = 100;
218 unsigned long flags;
219 unsigned int i;
220 u32 ctl;
221
222 spin_lock_irqsave(&cgu->lock, flags);
223 ctl = readl(cgu->base + pll_info->reg);
224
Paul Burtonb0663032015-05-24 16:11:35 +0100225 ctl &= ~BIT(pll_info->bypass_bit);
226 ctl |= BIT(pll_info->enable_bit);
227
228 writel(ctl, cgu->base + pll_info->reg);
229
230 /* wait for the PLL to stabilise */
231 for (i = 0; i < timeout; i++) {
232 ctl = readl(cgu->base + pll_info->reg);
233 if (ctl & BIT(pll_info->stable_bit))
234 break;
235 mdelay(1);
236 }
237
238 spin_unlock_irqrestore(&cgu->lock, flags);
239
240 if (i == timeout)
241 return -EBUSY;
242
243 return 0;
244}
245
Paul Cercueilab27eb42018-01-16 16:47:54 +0100246static void ingenic_pll_disable(struct clk_hw *hw)
247{
248 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
249 struct ingenic_cgu *cgu = ingenic_clk->cgu;
250 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
251 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
252 unsigned long flags;
253 u32 ctl;
254
255 spin_lock_irqsave(&cgu->lock, flags);
256 ctl = readl(cgu->base + pll_info->reg);
257
258 ctl &= ~BIT(pll_info->enable_bit);
259
260 writel(ctl, cgu->base + pll_info->reg);
261 spin_unlock_irqrestore(&cgu->lock, flags);
262}
263
264static int ingenic_pll_is_enabled(struct clk_hw *hw)
265{
266 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
267 struct ingenic_cgu *cgu = ingenic_clk->cgu;
268 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
269 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
270 unsigned long flags;
271 u32 ctl;
272
273 spin_lock_irqsave(&cgu->lock, flags);
274 ctl = readl(cgu->base + pll_info->reg);
275 spin_unlock_irqrestore(&cgu->lock, flags);
276
277 return !!(ctl & BIT(pll_info->enable_bit));
278}
279
Paul Burtonb0663032015-05-24 16:11:35 +0100280static const struct clk_ops ingenic_pll_ops = {
281 .recalc_rate = ingenic_pll_recalc_rate,
282 .round_rate = ingenic_pll_round_rate,
283 .set_rate = ingenic_pll_set_rate,
Paul Cercueilab27eb42018-01-16 16:47:54 +0100284
285 .enable = ingenic_pll_enable,
286 .disable = ingenic_pll_disable,
287 .is_enabled = ingenic_pll_is_enabled,
Paul Burtonb0663032015-05-24 16:11:35 +0100288};
289
290/*
291 * Operations for all non-PLL clocks
292 */
293
294static u8 ingenic_clk_get_parent(struct clk_hw *hw)
295{
296 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
297 struct ingenic_cgu *cgu = ingenic_clk->cgu;
298 const struct ingenic_cgu_clk_info *clk_info;
299 u32 reg;
300 u8 i, hw_idx, idx = 0;
301
302 clk_info = &cgu->clock_info[ingenic_clk->idx];
303
304 if (clk_info->type & CGU_CLK_MUX) {
305 reg = readl(cgu->base + clk_info->mux.reg);
306 hw_idx = (reg >> clk_info->mux.shift) &
307 GENMASK(clk_info->mux.bits - 1, 0);
308
309 /*
310 * Convert the hardware index to the parent index by skipping
311 * over any -1's in the parents array.
312 */
313 for (i = 0; i < hw_idx; i++) {
314 if (clk_info->parents[i] != -1)
315 idx++;
316 }
317 }
318
319 return idx;
320}
321
322static int ingenic_clk_set_parent(struct clk_hw *hw, u8 idx)
323{
324 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
325 struct ingenic_cgu *cgu = ingenic_clk->cgu;
326 const struct ingenic_cgu_clk_info *clk_info;
327 unsigned long flags;
328 u8 curr_idx, hw_idx, num_poss;
329 u32 reg, mask;
330
331 clk_info = &cgu->clock_info[ingenic_clk->idx];
332
333 if (clk_info->type & CGU_CLK_MUX) {
334 /*
335 * Convert the parent index to the hardware index by adding
336 * 1 for any -1 in the parents array preceding the given
337 * index. That is, we want the index of idx'th entry in
338 * clk_info->parents which does not equal -1.
339 */
340 hw_idx = curr_idx = 0;
341 num_poss = 1 << clk_info->mux.bits;
342 for (; hw_idx < num_poss; hw_idx++) {
343 if (clk_info->parents[hw_idx] == -1)
344 continue;
345 if (curr_idx == idx)
346 break;
347 curr_idx++;
348 }
349
350 /* idx should always be a valid parent */
351 BUG_ON(curr_idx != idx);
352
353 mask = GENMASK(clk_info->mux.bits - 1, 0);
354 mask <<= clk_info->mux.shift;
355
356 spin_lock_irqsave(&cgu->lock, flags);
357
358 /* write the register */
359 reg = readl(cgu->base + clk_info->mux.reg);
360 reg &= ~mask;
361 reg |= hw_idx << clk_info->mux.shift;
362 writel(reg, cgu->base + clk_info->mux.reg);
363
364 spin_unlock_irqrestore(&cgu->lock, flags);
365 return 0;
366 }
367
368 return idx ? -EINVAL : 0;
369}
370
371static unsigned long
372ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
373{
374 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
375 struct ingenic_cgu *cgu = ingenic_clk->cgu;
376 const struct ingenic_cgu_clk_info *clk_info;
377 unsigned long rate = parent_rate;
378 u32 div_reg, div;
379
380 clk_info = &cgu->clock_info[ingenic_clk->idx];
381
382 if (clk_info->type & CGU_CLK_DIV) {
383 div_reg = readl(cgu->base + clk_info->div.reg);
384 div = (div_reg >> clk_info->div.shift) &
385 GENMASK(clk_info->div.bits - 1, 0);
386 div += 1;
Harvey Hunt4afe2d12016-05-09 17:29:52 +0100387 div *= clk_info->div.div;
Paul Burtonb0663032015-05-24 16:11:35 +0100388
389 rate /= div;
Paul Cercueile6cfa6432018-01-16 16:47:52 +0100390 } else if (clk_info->type & CGU_CLK_FIXDIV) {
391 rate /= clk_info->fixdiv.div;
Paul Burtonb0663032015-05-24 16:11:35 +0100392 }
393
394 return rate;
395}
396
397static unsigned
398ingenic_clk_calc_div(const struct ingenic_cgu_clk_info *clk_info,
399 unsigned long parent_rate, unsigned long req_rate)
400{
401 unsigned div;
402
403 /* calculate the divide */
404 div = DIV_ROUND_UP(parent_rate, req_rate);
405
406 /* and impose hardware constraints */
407 div = min_t(unsigned, div, 1 << clk_info->div.bits);
408 div = max_t(unsigned, div, 1);
409
Harvey Hunt4afe2d12016-05-09 17:29:52 +0100410 /*
411 * If the divider value itself must be divided before being written to
412 * the divider register, we must ensure we don't have any bits set that
413 * would be lost as a result of doing so.
414 */
415 div /= clk_info->div.div;
416 div *= clk_info->div.div;
417
Paul Burtonb0663032015-05-24 16:11:35 +0100418 return div;
419}
420
421static long
422ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate,
423 unsigned long *parent_rate)
424{
425 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
426 struct ingenic_cgu *cgu = ingenic_clk->cgu;
427 const struct ingenic_cgu_clk_info *clk_info;
Paul Cercueilbc5d9222019-01-27 23:09:20 -0300428 unsigned int div = 1;
Paul Burtonb0663032015-05-24 16:11:35 +0100429
430 clk_info = &cgu->clock_info[ingenic_clk->idx];
431
432 if (clk_info->type & CGU_CLK_DIV)
Paul Cercueilbc5d9222019-01-27 23:09:20 -0300433 div = ingenic_clk_calc_div(clk_info, *parent_rate, req_rate);
Paul Burtonb0663032015-05-24 16:11:35 +0100434 else if (clk_info->type & CGU_CLK_FIXDIV)
Paul Cercueilbc5d9222019-01-27 23:09:20 -0300435 div = clk_info->fixdiv.div;
Paul Burtonb0663032015-05-24 16:11:35 +0100436
Paul Cercueilbc5d9222019-01-27 23:09:20 -0300437 return DIV_ROUND_UP(*parent_rate, div);
Paul Burtonb0663032015-05-24 16:11:35 +0100438}
439
440static int
441ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
442 unsigned long parent_rate)
443{
444 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
445 struct ingenic_cgu *cgu = ingenic_clk->cgu;
446 const struct ingenic_cgu_clk_info *clk_info;
447 const unsigned timeout = 100;
448 unsigned long rate, flags;
449 unsigned div, i;
450 u32 reg, mask;
451 int ret = 0;
452
453 clk_info = &cgu->clock_info[ingenic_clk->idx];
454
455 if (clk_info->type & CGU_CLK_DIV) {
456 div = ingenic_clk_calc_div(clk_info, parent_rate, req_rate);
Paul Cercueilbc5d9222019-01-27 23:09:20 -0300457 rate = DIV_ROUND_UP(parent_rate, div);
Paul Burtonb0663032015-05-24 16:11:35 +0100458
459 if (rate != req_rate)
460 return -EINVAL;
461
462 spin_lock_irqsave(&cgu->lock, flags);
463 reg = readl(cgu->base + clk_info->div.reg);
464
465 /* update the divide */
466 mask = GENMASK(clk_info->div.bits - 1, 0);
467 reg &= ~(mask << clk_info->div.shift);
Harvey Hunt4afe2d12016-05-09 17:29:52 +0100468 reg |= ((div / clk_info->div.div) - 1) << clk_info->div.shift;
Paul Burtonb0663032015-05-24 16:11:35 +0100469
470 /* clear the stop bit */
471 if (clk_info->div.stop_bit != -1)
472 reg &= ~BIT(clk_info->div.stop_bit);
473
474 /* set the change enable bit */
475 if (clk_info->div.ce_bit != -1)
476 reg |= BIT(clk_info->div.ce_bit);
477
478 /* update the hardware */
479 writel(reg, cgu->base + clk_info->div.reg);
480
481 /* wait for the change to take effect */
482 if (clk_info->div.busy_bit != -1) {
483 for (i = 0; i < timeout; i++) {
484 reg = readl(cgu->base + clk_info->div.reg);
485 if (!(reg & BIT(clk_info->div.busy_bit)))
486 break;
487 mdelay(1);
488 }
489 if (i == timeout)
490 ret = -EBUSY;
491 }
492
493 spin_unlock_irqrestore(&cgu->lock, flags);
494 return ret;
495 }
496
497 return -EINVAL;
498}
499
500static int ingenic_clk_enable(struct clk_hw *hw)
501{
502 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
503 struct ingenic_cgu *cgu = ingenic_clk->cgu;
504 const struct ingenic_cgu_clk_info *clk_info;
505 unsigned long flags;
506
507 clk_info = &cgu->clock_info[ingenic_clk->idx];
508
509 if (clk_info->type & CGU_CLK_GATE) {
510 /* ungate the clock */
511 spin_lock_irqsave(&cgu->lock, flags);
512 ingenic_cgu_gate_set(cgu, &clk_info->gate, false);
513 spin_unlock_irqrestore(&cgu->lock, flags);
Paul Cercueil261a8312018-05-20 16:31:13 +0000514
515 if (clk_info->gate.delay_us)
516 udelay(clk_info->gate.delay_us);
Paul Burtonb0663032015-05-24 16:11:35 +0100517 }
518
519 return 0;
520}
521
522static void ingenic_clk_disable(struct clk_hw *hw)
523{
524 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
525 struct ingenic_cgu *cgu = ingenic_clk->cgu;
526 const struct ingenic_cgu_clk_info *clk_info;
527 unsigned long flags;
528
529 clk_info = &cgu->clock_info[ingenic_clk->idx];
530
531 if (clk_info->type & CGU_CLK_GATE) {
532 /* gate the clock */
533 spin_lock_irqsave(&cgu->lock, flags);
534 ingenic_cgu_gate_set(cgu, &clk_info->gate, true);
535 spin_unlock_irqrestore(&cgu->lock, flags);
536 }
537}
538
539static int ingenic_clk_is_enabled(struct clk_hw *hw)
540{
541 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
542 struct ingenic_cgu *cgu = ingenic_clk->cgu;
543 const struct ingenic_cgu_clk_info *clk_info;
544 unsigned long flags;
545 int enabled = 1;
546
547 clk_info = &cgu->clock_info[ingenic_clk->idx];
548
549 if (clk_info->type & CGU_CLK_GATE) {
550 spin_lock_irqsave(&cgu->lock, flags);
551 enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate);
552 spin_unlock_irqrestore(&cgu->lock, flags);
553 }
554
555 return enabled;
556}
557
558static const struct clk_ops ingenic_clk_ops = {
559 .get_parent = ingenic_clk_get_parent,
560 .set_parent = ingenic_clk_set_parent,
561
562 .recalc_rate = ingenic_clk_recalc_rate,
563 .round_rate = ingenic_clk_round_rate,
564 .set_rate = ingenic_clk_set_rate,
565
566 .enable = ingenic_clk_enable,
567 .disable = ingenic_clk_disable,
568 .is_enabled = ingenic_clk_is_enabled,
569};
570
571/*
572 * Setup functions.
573 */
574
575static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx)
576{
577 const struct ingenic_cgu_clk_info *clk_info = &cgu->clock_info[idx];
578 struct clk_init_data clk_init;
579 struct ingenic_clk *ingenic_clk = NULL;
580 struct clk *clk, *parent;
581 const char *parent_names[4];
582 unsigned caps, i, num_possible;
583 int err = -EINVAL;
584
585 BUILD_BUG_ON(ARRAY_SIZE(clk_info->parents) > ARRAY_SIZE(parent_names));
586
587 if (clk_info->type == CGU_CLK_EXT) {
588 clk = of_clk_get_by_name(cgu->np, clk_info->name);
589 if (IS_ERR(clk)) {
590 pr_err("%s: no external clock '%s' provided\n",
591 __func__, clk_info->name);
592 err = -ENODEV;
593 goto out;
594 }
595 err = clk_register_clkdev(clk, clk_info->name, NULL);
596 if (err) {
597 clk_put(clk);
598 goto out;
599 }
600 cgu->clocks.clks[idx] = clk;
601 return 0;
602 }
603
604 if (!clk_info->type) {
605 pr_err("%s: no clock type specified for '%s'\n", __func__,
606 clk_info->name);
607 goto out;
608 }
609
610 ingenic_clk = kzalloc(sizeof(*ingenic_clk), GFP_KERNEL);
611 if (!ingenic_clk) {
612 err = -ENOMEM;
613 goto out;
614 }
615
616 ingenic_clk->hw.init = &clk_init;
617 ingenic_clk->cgu = cgu;
618 ingenic_clk->idx = idx;
619
620 clk_init.name = clk_info->name;
621 clk_init.flags = 0;
622 clk_init.parent_names = parent_names;
623
624 caps = clk_info->type;
625
626 if (caps & (CGU_CLK_MUX | CGU_CLK_CUSTOM)) {
627 clk_init.num_parents = 0;
628
629 if (caps & CGU_CLK_MUX)
630 num_possible = 1 << clk_info->mux.bits;
631 else
632 num_possible = ARRAY_SIZE(clk_info->parents);
633
634 for (i = 0; i < num_possible; i++) {
635 if (clk_info->parents[i] == -1)
636 continue;
637
638 parent = cgu->clocks.clks[clk_info->parents[i]];
639 parent_names[clk_init.num_parents] =
640 __clk_get_name(parent);
641 clk_init.num_parents++;
642 }
643
644 BUG_ON(!clk_init.num_parents);
645 BUG_ON(clk_init.num_parents > ARRAY_SIZE(parent_names));
646 } else {
647 BUG_ON(clk_info->parents[0] == -1);
648 clk_init.num_parents = 1;
649 parent = cgu->clocks.clks[clk_info->parents[0]];
650 parent_names[0] = __clk_get_name(parent);
651 }
652
653 if (caps & CGU_CLK_CUSTOM) {
654 clk_init.ops = clk_info->custom.clk_ops;
655
656 caps &= ~CGU_CLK_CUSTOM;
657
658 if (caps) {
659 pr_err("%s: custom clock may not be combined with type 0x%x\n",
660 __func__, caps);
661 goto out;
662 }
663 } else if (caps & CGU_CLK_PLL) {
664 clk_init.ops = &ingenic_pll_ops;
Paul Cercueilab27eb42018-01-16 16:47:54 +0100665 clk_init.flags |= CLK_SET_RATE_GATE;
Paul Burtonb0663032015-05-24 16:11:35 +0100666
667 caps &= ~CGU_CLK_PLL;
668
669 if (caps) {
670 pr_err("%s: PLL may not be combined with type 0x%x\n",
671 __func__, caps);
672 goto out;
673 }
674 } else {
675 clk_init.ops = &ingenic_clk_ops;
676 }
677
678 /* nothing to do for gates or fixed dividers */
679 caps &= ~(CGU_CLK_GATE | CGU_CLK_FIXDIV);
680
681 if (caps & CGU_CLK_MUX) {
682 if (!(caps & CGU_CLK_MUX_GLITCHFREE))
683 clk_init.flags |= CLK_SET_PARENT_GATE;
684
685 caps &= ~(CGU_CLK_MUX | CGU_CLK_MUX_GLITCHFREE);
686 }
687
688 if (caps & CGU_CLK_DIV) {
689 caps &= ~CGU_CLK_DIV;
690 } else {
691 /* pass rate changes to the parent clock */
692 clk_init.flags |= CLK_SET_RATE_PARENT;
693 }
694
695 if (caps) {
696 pr_err("%s: unknown clock type 0x%x\n", __func__, caps);
697 goto out;
698 }
699
700 clk = clk_register(NULL, &ingenic_clk->hw);
701 if (IS_ERR(clk)) {
702 pr_err("%s: failed to register clock '%s'\n", __func__,
703 clk_info->name);
704 err = PTR_ERR(clk);
705 goto out;
706 }
707
708 err = clk_register_clkdev(clk, clk_info->name, NULL);
709 if (err)
710 goto out;
711
712 cgu->clocks.clks[idx] = clk;
713out:
714 if (err)
715 kfree(ingenic_clk);
716 return err;
717}
718
719struct ingenic_cgu *
720ingenic_cgu_new(const struct ingenic_cgu_clk_info *clock_info,
721 unsigned num_clocks, struct device_node *np)
722{
723 struct ingenic_cgu *cgu;
724
725 cgu = kzalloc(sizeof(*cgu), GFP_KERNEL);
726 if (!cgu)
727 goto err_out;
728
729 cgu->base = of_iomap(np, 0);
730 if (!cgu->base) {
731 pr_err("%s: failed to map CGU registers\n", __func__);
732 goto err_out_free;
733 }
734
735 cgu->np = np;
736 cgu->clock_info = clock_info;
737 cgu->clocks.clk_num = num_clocks;
738
739 spin_lock_init(&cgu->lock);
740
741 return cgu;
742
743err_out_free:
744 kfree(cgu);
745err_out:
746 return NULL;
747}
748
749int ingenic_cgu_register_clocks(struct ingenic_cgu *cgu)
750{
751 unsigned i;
752 int err;
753
754 cgu->clocks.clks = kcalloc(cgu->clocks.clk_num, sizeof(struct clk *),
755 GFP_KERNEL);
756 if (!cgu->clocks.clks) {
757 err = -ENOMEM;
758 goto err_out;
759 }
760
761 for (i = 0; i < cgu->clocks.clk_num; i++) {
762 err = ingenic_register_clock(cgu, i);
763 if (err)
764 goto err_out_unregister;
765 }
766
767 err = of_clk_add_provider(cgu->np, of_clk_src_onecell_get,
768 &cgu->clocks);
769 if (err)
770 goto err_out_unregister;
771
772 return 0;
773
774err_out_unregister:
775 for (i = 0; i < cgu->clocks.clk_num; i++) {
776 if (!cgu->clocks.clks[i])
777 continue;
778 if (cgu->clock_info[i].type & CGU_CLK_EXT)
779 clk_put(cgu->clocks.clks[i]);
780 else
781 clk_unregister(cgu->clocks.clks[i]);
782 }
783 kfree(cgu->clocks.clks);
784err_out:
785 return err;
786}