1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * R-Car Gen3 Clock Pulse Generator |
4 | * |
5 | * Copyright (C) 2015-2018 Glider bvba |
6 | * Copyright (C) 2019 Renesas Electronics Corp. |
7 | * |
8 | * Based on clk-rcar-gen3.c |
9 | * |
10 | * Copyright (C) 2015 Renesas Electronics Corp. |
11 | */ |
12 | |
13 | #include <linux/bug.h> |
14 | #include <linux/bitfield.h> |
15 | #include <linux/clk.h> |
16 | #include <linux/clk-provider.h> |
17 | #include <linux/device.h> |
18 | #include <linux/err.h> |
19 | #include <linux/init.h> |
20 | #include <linux/io.h> |
21 | #include <linux/pm.h> |
22 | #include <linux/slab.h> |
23 | #include <linux/sys_soc.h> |
24 | |
25 | #include "renesas-cpg-mssr.h" |
26 | #include "rcar-cpg-lib.h" |
27 | #include "rcar-gen3-cpg.h" |
28 | |
29 | #define CPG_PLLECR 0x00d0 /* PLL Enable Control Register */ |
30 | |
31 | #define CPG_PLLECR_PLLST(n) BIT(8 + (n)) /* PLLn Circuit Status */ |
32 | |
33 | #define CPG_PLL0CR 0x00d8 /* PLLn Control Registers */ |
34 | #define CPG_PLL2CR 0x002c |
35 | #define CPG_PLL4CR 0x01f4 |
36 | |
37 | #define CPG_PLLnCR_STC_MASK GENMASK(30, 24) /* PLL Circuit Mult. Ratio */ |
38 | |
39 | #define CPG_RCKCR_CKSEL BIT(15) /* RCLK Clock Source Select */ |
40 | |
41 | /* PLL Clocks */ |
42 | struct cpg_pll_clk { |
43 | struct clk_hw hw; |
44 | void __iomem *pllcr_reg; |
45 | void __iomem *pllecr_reg; |
46 | unsigned int fixed_mult; |
47 | u32 pllecr_pllst_mask; |
48 | }; |
49 | |
50 | #define to_pll_clk(_hw) container_of(_hw, struct cpg_pll_clk, hw) |
51 | |
52 | static unsigned long cpg_pll_clk_recalc_rate(struct clk_hw *hw, |
53 | unsigned long parent_rate) |
54 | { |
55 | struct cpg_pll_clk *pll_clk = to_pll_clk(hw); |
56 | unsigned int mult; |
57 | u32 val; |
58 | |
59 | val = readl(addr: pll_clk->pllcr_reg) & CPG_PLLnCR_STC_MASK; |
60 | mult = (val >> __ffs(CPG_PLLnCR_STC_MASK)) + 1; |
61 | |
62 | return parent_rate * mult * pll_clk->fixed_mult; |
63 | } |
64 | |
65 | static int cpg_pll_clk_determine_rate(struct clk_hw *hw, |
66 | struct clk_rate_request *req) |
67 | { |
68 | struct cpg_pll_clk *pll_clk = to_pll_clk(hw); |
69 | unsigned int min_mult, max_mult, mult; |
70 | unsigned long prate; |
71 | |
72 | prate = req->best_parent_rate * pll_clk->fixed_mult; |
73 | min_mult = max(div64_ul(req->min_rate, prate), 1ULL); |
74 | max_mult = min(div64_ul(req->max_rate, prate), 128ULL); |
75 | if (max_mult < min_mult) |
76 | return -EINVAL; |
77 | |
78 | mult = DIV_ROUND_CLOSEST_ULL(req->rate, prate); |
79 | mult = clamp(mult, min_mult, max_mult); |
80 | |
81 | req->rate = prate * mult; |
82 | return 0; |
83 | } |
84 | |
85 | static int cpg_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate, |
86 | unsigned long parent_rate) |
87 | { |
88 | struct cpg_pll_clk *pll_clk = to_pll_clk(hw); |
89 | unsigned int mult, i; |
90 | u32 val; |
91 | |
92 | mult = DIV_ROUND_CLOSEST_ULL(rate, parent_rate * pll_clk->fixed_mult); |
93 | mult = clamp(mult, 1U, 128U); |
94 | |
95 | val = readl(addr: pll_clk->pllcr_reg); |
96 | val &= ~CPG_PLLnCR_STC_MASK; |
97 | val |= (mult - 1) << __ffs(CPG_PLLnCR_STC_MASK); |
98 | writel(val, addr: pll_clk->pllcr_reg); |
99 | |
100 | for (i = 1000; i; i--) { |
101 | if (readl(addr: pll_clk->pllecr_reg) & pll_clk->pllecr_pllst_mask) |
102 | return 0; |
103 | |
104 | cpu_relax(); |
105 | } |
106 | |
107 | return -ETIMEDOUT; |
108 | } |
109 | |
110 | static const struct clk_ops cpg_pll_clk_ops = { |
111 | .recalc_rate = cpg_pll_clk_recalc_rate, |
112 | .determine_rate = cpg_pll_clk_determine_rate, |
113 | .set_rate = cpg_pll_clk_set_rate, |
114 | }; |
115 | |
116 | static struct clk * __init cpg_pll_clk_register(const char *name, |
117 | const char *parent_name, |
118 | void __iomem *base, |
119 | unsigned int mult, |
120 | unsigned int offset, |
121 | unsigned int index) |
122 | |
123 | { |
124 | struct cpg_pll_clk *pll_clk; |
125 | struct clk_init_data init = {}; |
126 | struct clk *clk; |
127 | |
128 | pll_clk = kzalloc(size: sizeof(*pll_clk), GFP_KERNEL); |
129 | if (!pll_clk) |
130 | return ERR_PTR(error: -ENOMEM); |
131 | |
132 | init.name = name; |
133 | init.ops = &cpg_pll_clk_ops; |
134 | init.parent_names = &parent_name; |
135 | init.num_parents = 1; |
136 | |
137 | pll_clk->hw.init = &init; |
138 | pll_clk->pllcr_reg = base + offset; |
139 | pll_clk->pllecr_reg = base + CPG_PLLECR; |
140 | pll_clk->fixed_mult = mult; /* PLL refclk x (setting + 1) x mult */ |
141 | pll_clk->pllecr_pllst_mask = CPG_PLLECR_PLLST(index); |
142 | |
143 | clk = clk_register(NULL, hw: &pll_clk->hw); |
144 | if (IS_ERR(ptr: clk)) |
145 | kfree(objp: pll_clk); |
146 | |
147 | return clk; |
148 | } |
149 | |
150 | /* |
151 | * Z Clock & Z2 Clock |
152 | * |
153 | * Traits of this clock: |
154 | * prepare - clk_prepare only ensures that parents are prepared |
155 | * enable - clk_enable only ensures that parents are enabled |
156 | * rate - rate is adjustable. |
157 | * clk->rate = (parent->rate * mult / 32 ) / fixed_div |
158 | * parent - fixed parent. No clk_set_parent support |
159 | */ |
160 | #define CPG_FRQCRB 0x00000004 |
161 | #define CPG_FRQCRB_KICK BIT(31) |
162 | #define CPG_FRQCRC 0x000000e0 |
163 | |
164 | struct cpg_z_clk { |
165 | struct clk_hw hw; |
166 | void __iomem *reg; |
167 | void __iomem *kick_reg; |
168 | unsigned long max_rate; /* Maximum rate for normal mode */ |
169 | unsigned int fixed_div; |
170 | u32 mask; |
171 | }; |
172 | |
173 | #define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) |
174 | |
175 | static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, |
176 | unsigned long parent_rate) |
177 | { |
178 | struct cpg_z_clk *zclk = to_z_clk(hw); |
179 | unsigned int mult; |
180 | u32 val; |
181 | |
182 | val = readl(addr: zclk->reg) & zclk->mask; |
183 | mult = 32 - (val >> __ffs(zclk->mask)); |
184 | |
185 | return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, |
186 | 32 * zclk->fixed_div); |
187 | } |
188 | |
189 | static int cpg_z_clk_determine_rate(struct clk_hw *hw, |
190 | struct clk_rate_request *req) |
191 | { |
192 | struct cpg_z_clk *zclk = to_z_clk(hw); |
193 | unsigned int min_mult, max_mult, mult; |
194 | unsigned long rate, prate; |
195 | |
196 | rate = min(req->rate, req->max_rate); |
197 | if (rate <= zclk->max_rate) { |
198 | /* Set parent rate to initial value for normal modes */ |
199 | prate = zclk->max_rate; |
200 | } else { |
201 | /* Set increased parent rate for boost modes */ |
202 | prate = rate; |
203 | } |
204 | req->best_parent_rate = clk_hw_round_rate(hw: clk_hw_get_parent(hw), |
205 | rate: prate * zclk->fixed_div); |
206 | |
207 | prate = req->best_parent_rate / zclk->fixed_div; |
208 | min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL); |
209 | max_mult = min(div64_ul(req->max_rate * 32ULL, prate), 32ULL); |
210 | if (max_mult < min_mult) |
211 | return -EINVAL; |
212 | |
213 | mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL, prate); |
214 | mult = clamp(mult, min_mult, max_mult); |
215 | |
216 | req->rate = DIV_ROUND_CLOSEST_ULL((u64)prate * mult, 32); |
217 | return 0; |
218 | } |
219 | |
220 | static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, |
221 | unsigned long parent_rate) |
222 | { |
223 | struct cpg_z_clk *zclk = to_z_clk(hw); |
224 | unsigned int mult; |
225 | unsigned int i; |
226 | |
227 | mult = DIV64_U64_ROUND_CLOSEST(rate * 32ULL * zclk->fixed_div, |
228 | parent_rate); |
229 | mult = clamp(mult, 1U, 32U); |
230 | |
231 | if (readl(addr: zclk->kick_reg) & CPG_FRQCRB_KICK) |
232 | return -EBUSY; |
233 | |
234 | cpg_reg_modify(reg: zclk->reg, clear: zclk->mask, set: (32 - mult) << __ffs(zclk->mask)); |
235 | |
236 | /* |
237 | * Set KICK bit in FRQCRB to update hardware setting and wait for |
238 | * clock change completion. |
239 | */ |
240 | cpg_reg_modify(reg: zclk->kick_reg, clear: 0, CPG_FRQCRB_KICK); |
241 | |
242 | /* |
243 | * Note: There is no HW information about the worst case latency. |
244 | * |
245 | * Using experimental measurements, it seems that no more than |
246 | * ~10 iterations are needed, independently of the CPU rate. |
247 | * Since this value might be dependent on external xtal rate, pll1 |
248 | * rate or even the other emulation clocks rate, use 1000 as a |
249 | * "super" safe value. |
250 | */ |
251 | for (i = 1000; i; i--) { |
252 | if (!(readl(addr: zclk->kick_reg) & CPG_FRQCRB_KICK)) |
253 | return 0; |
254 | |
255 | cpu_relax(); |
256 | } |
257 | |
258 | return -ETIMEDOUT; |
259 | } |
260 | |
261 | static const struct clk_ops cpg_z_clk_ops = { |
262 | .recalc_rate = cpg_z_clk_recalc_rate, |
263 | .determine_rate = cpg_z_clk_determine_rate, |
264 | .set_rate = cpg_z_clk_set_rate, |
265 | }; |
266 | |
267 | static struct clk * __init __cpg_z_clk_register(const char *name, |
268 | const char *parent_name, |
269 | void __iomem *reg, |
270 | unsigned int div, |
271 | unsigned int offset, |
272 | unsigned int fcr, |
273 | unsigned int flags) |
274 | { |
275 | struct clk_init_data init = {}; |
276 | struct cpg_z_clk *zclk; |
277 | struct clk *clk; |
278 | |
279 | zclk = kzalloc(size: sizeof(*zclk), GFP_KERNEL); |
280 | if (!zclk) |
281 | return ERR_PTR(error: -ENOMEM); |
282 | |
283 | init.name = name; |
284 | init.ops = &cpg_z_clk_ops; |
285 | init.flags = flags; |
286 | init.parent_names = &parent_name; |
287 | init.num_parents = 1; |
288 | |
289 | zclk->reg = reg + fcr; |
290 | zclk->kick_reg = reg + CPG_FRQCRB; |
291 | zclk->hw.init = &init; |
292 | zclk->mask = GENMASK(offset + 4, offset); |
293 | zclk->fixed_div = div; /* PLLVCO x 1/div x SYS-CPU divider */ |
294 | |
295 | clk = clk_register(NULL, hw: &zclk->hw); |
296 | if (IS_ERR(ptr: clk)) { |
297 | kfree(objp: zclk); |
298 | return clk; |
299 | } |
300 | |
301 | zclk->max_rate = clk_hw_get_rate(hw: clk_hw_get_parent(hw: &zclk->hw)) / |
302 | zclk->fixed_div; |
303 | return clk; |
304 | } |
305 | |
306 | static struct clk * __init cpg_z_clk_register(const char *name, |
307 | const char *parent_name, |
308 | void __iomem *reg, |
309 | unsigned int div, |
310 | unsigned int offset) |
311 | { |
312 | return __cpg_z_clk_register(name, parent_name, reg, div, offset, |
313 | CPG_FRQCRC, CLK_SET_RATE_PARENT); |
314 | } |
315 | |
316 | static struct clk * __init cpg_zg_clk_register(const char *name, |
317 | const char *parent_name, |
318 | void __iomem *reg, |
319 | unsigned int div, |
320 | unsigned int offset) |
321 | { |
322 | return __cpg_z_clk_register(name, parent_name, reg, div, offset, |
323 | CPG_FRQCRB, flags: 0); |
324 | |
325 | } |
326 | |
327 | static const struct clk_div_table cpg_rpcsrc_div_table[] = { |
328 | { 2, 5 }, { 3, 6 }, { 0, 0 }, |
329 | }; |
330 | |
331 | static const struct rcar_gen3_cpg_pll_config *cpg_pll_config __initdata; |
332 | static unsigned int cpg_clk_extalr __initdata; |
333 | static u32 cpg_mode __initdata; |
334 | static u32 cpg_quirks __initdata; |
335 | |
336 | #define RCKCR_CKSEL BIT(1) /* Manual RCLK parent selection */ |
337 | |
338 | |
339 | static const struct soc_device_attribute cpg_quirks_match[] __initconst = { |
340 | { |
341 | .soc_id = "r8a7796" , .revision = "ES1.0" , |
342 | .data = (void *)(RCKCR_CKSEL), |
343 | }, |
344 | { /* sentinel */ } |
345 | }; |
346 | |
347 | struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, |
348 | const struct cpg_core_clk *core, const struct cpg_mssr_info *info, |
349 | struct clk **clks, void __iomem *base, |
350 | struct raw_notifier_head *notifiers) |
351 | { |
352 | const struct clk *parent; |
353 | unsigned int mult = 1; |
354 | unsigned int div = 1; |
355 | u32 value; |
356 | |
357 | parent = clks[core->parent & 0xffff]; /* some types use high bits */ |
358 | if (IS_ERR(ptr: parent)) |
359 | return ERR_CAST(ptr: parent); |
360 | |
361 | switch (core->type) { |
362 | case CLK_TYPE_GEN3_MAIN: |
363 | div = cpg_pll_config->extal_div; |
364 | break; |
365 | |
366 | case CLK_TYPE_GEN3_PLL0: |
367 | /* |
368 | * PLL0 is implemented as a custom clock, to change the |
369 | * multiplier when cpufreq changes between normal and boost |
370 | * modes. |
371 | */ |
372 | return cpg_pll_clk_register(name: core->name, parent_name: __clk_get_name(clk: parent), |
373 | base, mult: 2, CPG_PLL0CR, index: 0); |
374 | |
375 | case CLK_TYPE_GEN3_PLL1: |
376 | mult = cpg_pll_config->pll1_mult; |
377 | div = cpg_pll_config->pll1_div; |
378 | break; |
379 | |
380 | case CLK_TYPE_GEN3_PLL2: |
381 | /* |
382 | * PLL2 is implemented as a custom clock, to change the |
383 | * multiplier when cpufreq changes between normal and boost |
384 | * modes. |
385 | */ |
386 | return cpg_pll_clk_register(name: core->name, parent_name: __clk_get_name(clk: parent), |
387 | base, mult: 2, CPG_PLL2CR, index: 2); |
388 | |
389 | case CLK_TYPE_GEN3_PLL3: |
390 | mult = cpg_pll_config->pll3_mult; |
391 | div = cpg_pll_config->pll3_div; |
392 | break; |
393 | |
394 | case CLK_TYPE_GEN3_PLL4: |
395 | /* |
396 | * PLL4 is a configurable multiplier clock. Register it as a |
397 | * fixed factor clock for now as there's no generic multiplier |
398 | * clock implementation and we currently have no need to change |
399 | * the multiplier value. |
400 | */ |
401 | value = readl(addr: base + CPG_PLL4CR); |
402 | mult = (((value >> 24) & 0x7f) + 1) * 2; |
403 | break; |
404 | |
405 | case CLK_TYPE_GEN3_SDH: |
406 | return cpg_sdh_clk_register(name: core->name, sdnckcr: base + core->offset, |
407 | parent_name: __clk_get_name(clk: parent), notifiers); |
408 | |
409 | case CLK_TYPE_GEN3_SD: |
410 | return cpg_sd_clk_register(name: core->name, sdnckcr: base + core->offset, |
411 | parent_name: __clk_get_name(clk: parent)); |
412 | |
413 | case CLK_TYPE_GEN3_R: |
414 | if (cpg_quirks & RCKCR_CKSEL) { |
415 | struct cpg_simple_notifier *csn; |
416 | |
417 | csn = kzalloc(size: sizeof(*csn), GFP_KERNEL); |
418 | if (!csn) |
419 | return ERR_PTR(error: -ENOMEM); |
420 | |
421 | csn->reg = base + CPG_RCKCR; |
422 | |
423 | /* |
424 | * RINT is default. |
425 | * Only if EXTALR is populated, we switch to it. |
426 | */ |
427 | value = readl(addr: csn->reg) & 0x3f; |
428 | |
429 | if (clk_get_rate(clk: clks[cpg_clk_extalr])) { |
430 | parent = clks[cpg_clk_extalr]; |
431 | value |= CPG_RCKCR_CKSEL; |
432 | } |
433 | |
434 | writel(val: value, addr: csn->reg); |
435 | cpg_simple_notifier_register(notifiers, csn); |
436 | break; |
437 | } |
438 | |
439 | /* Select parent clock of RCLK by MD28 */ |
440 | if (cpg_mode & BIT(28)) |
441 | parent = clks[cpg_clk_extalr]; |
442 | break; |
443 | |
444 | case CLK_TYPE_GEN3_MDSEL: |
445 | /* |
446 | * Clock selectable between two parents and two fixed dividers |
447 | * using a mode pin |
448 | */ |
449 | if (cpg_mode & BIT(core->offset)) { |
450 | div = core->div & 0xffff; |
451 | } else { |
452 | parent = clks[core->parent >> 16]; |
453 | if (IS_ERR(ptr: parent)) |
454 | return ERR_CAST(ptr: parent); |
455 | div = core->div >> 16; |
456 | } |
457 | mult = 1; |
458 | break; |
459 | |
460 | case CLK_TYPE_GEN3_Z: |
461 | return cpg_z_clk_register(name: core->name, parent_name: __clk_get_name(clk: parent), |
462 | reg: base, div: core->div, offset: core->offset); |
463 | |
464 | case CLK_TYPE_GEN3_ZG: |
465 | return cpg_zg_clk_register(name: core->name, parent_name: __clk_get_name(clk: parent), |
466 | reg: base, div: core->div, offset: core->offset); |
467 | |
468 | case CLK_TYPE_GEN3_OSC: |
469 | /* |
470 | * Clock combining OSC EXTAL predivider and a fixed divider |
471 | */ |
472 | div = cpg_pll_config->osc_prediv * core->div; |
473 | break; |
474 | |
475 | case CLK_TYPE_GEN3_RCKSEL: |
476 | /* |
477 | * Clock selectable between two parents and two fixed dividers |
478 | * using RCKCR.CKSEL |
479 | */ |
480 | if (readl(addr: base + CPG_RCKCR) & CPG_RCKCR_CKSEL) { |
481 | div = core->div & 0xffff; |
482 | } else { |
483 | parent = clks[core->parent >> 16]; |
484 | if (IS_ERR(ptr: parent)) |
485 | return ERR_CAST(ptr: parent); |
486 | div = core->div >> 16; |
487 | } |
488 | break; |
489 | |
490 | case CLK_TYPE_GEN3_RPCSRC: |
491 | return clk_register_divider_table(NULL, name: core->name, |
492 | parent_name: __clk_get_name(clk: parent), flags: 0, |
493 | reg: base + CPG_RPCCKCR, shift: 3, width: 2, clk_divider_flags: 0, |
494 | table: cpg_rpcsrc_div_table, |
495 | lock: &cpg_lock); |
496 | |
497 | case CLK_TYPE_GEN3_E3_RPCSRC: |
498 | /* |
499 | * Register RPCSRC as fixed factor clock based on the |
500 | * MD[4:1] pins and CPG_RPCCKCR[4:3] register value for |
501 | * which has been set prior to booting the kernel. |
502 | */ |
503 | value = (readl(addr: base + CPG_RPCCKCR) & GENMASK(4, 3)) >> 3; |
504 | |
505 | switch (value) { |
506 | case 0: |
507 | div = 5; |
508 | break; |
509 | case 1: |
510 | div = 3; |
511 | break; |
512 | case 2: |
513 | parent = clks[core->parent >> 16]; |
514 | if (IS_ERR(ptr: parent)) |
515 | return ERR_CAST(ptr: parent); |
516 | div = core->div; |
517 | break; |
518 | case 3: |
519 | default: |
520 | div = 2; |
521 | break; |
522 | } |
523 | break; |
524 | |
525 | case CLK_TYPE_GEN3_RPC: |
526 | return cpg_rpc_clk_register(name: core->name, rpcckcr: base + CPG_RPCCKCR, |
527 | parent_name: __clk_get_name(clk: parent), notifiers); |
528 | |
529 | case CLK_TYPE_GEN3_RPCD2: |
530 | return cpg_rpcd2_clk_register(name: core->name, rpcckcr: base + CPG_RPCCKCR, |
531 | parent_name: __clk_get_name(clk: parent)); |
532 | |
533 | default: |
534 | return ERR_PTR(error: -EINVAL); |
535 | } |
536 | |
537 | return clk_register_fixed_factor(NULL, name: core->name, |
538 | parent_name: __clk_get_name(clk: parent), flags: 0, mult, div); |
539 | } |
540 | |
541 | int __init rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config, |
542 | unsigned int clk_extalr, u32 mode) |
543 | { |
544 | const struct soc_device_attribute *attr; |
545 | |
546 | cpg_pll_config = config; |
547 | cpg_clk_extalr = clk_extalr; |
548 | cpg_mode = mode; |
549 | attr = soc_device_match(matches: cpg_quirks_match); |
550 | if (attr) |
551 | cpg_quirks = (uintptr_t)attr->data; |
552 | pr_debug("%s: mode = 0x%x quirks = 0x%x\n" , __func__, mode, cpg_quirks); |
553 | |
554 | spin_lock_init(&cpg_lock); |
555 | |
556 | return 0; |
557 | } |
558 | |