1 // SPDX-License-Identifier: GPL-2.0+
3 * Renesas RCar Gen3 CPG MSSR driver
5 * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
7 * Based on the following driver from Linux kernel:
8 * r8a7796 Clock Pulse Generator / Module Standby and Software Reset
10 * Copyright (C) 2016 Glider bvba
14 #include <clk-uclass.h>
16 #include <dm/device-internal.h>
21 #include <asm/global_data.h>
23 #include <linux/bitfield.h>
24 #include <linux/bitops.h>
25 #include <linux/clk-provider.h>
26 #include <reset-uclass.h>
28 #include <dt-bindings/clock/renesas-cpg-mssr.h>
30 #include "renesas-cpg-mssr.h"
31 #include "rcar-gen3-cpg.h"
32 #include "rcar-cpg-lib.h"
34 #define CPG_PLL0CR 0x00d8
35 #define CPG_PLL2CR 0x002c
36 #define CPG_PLL4CR 0x01f4
38 #define SD0CKCR1 0x08a4
40 static const struct clk_div_table gen3_cpg_rpcsrc_div_table[] = {
41 { 2, 5 }, { 3, 6 }, { 0, 0 },
44 static const struct clk_div_table gen4_cpg_rpcsrc_div_table[] = {
45 { 0, 4 }, { 1, 6 }, { 2, 5 }, { 3, 6 }, { 0, 0 },
48 static const struct clk_div_table r8a77970_cpg_sd0h_div_table[] = {
49 { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 },
50 { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 },
51 { 8, 24 }, { 10, 36 }, { 11, 48 }, { 0, 0 },
54 static const struct clk_div_table r8a77970_cpg_sd0_div_table[] = {
55 { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 },
56 { 8, 24 }, { 10, 36 }, { 11, 48 }, { 12, 10 },
60 static int gen3_clk_get_parent(struct gen3_clk_priv *priv, struct clk *clk,
61 struct cpg_mssr_info *info, struct clk *parent)
63 const struct cpg_core_clk *core;
67 if (!renesas_clk_is_mod(clk)) {
68 ret = renesas_clk_get_core(clk, info, &core);
72 if (core->type == CLK_TYPE_GEN3_MDSEL) {
73 shift = priv->cpg_mode & BIT(core->offset) ? 16 : 0;
74 parent->dev = clk->dev;
75 parent->id = core->parent >> shift;
81 return renesas_clk_get_parent(clk, info, parent);
84 static int gen3_clk_enable(struct clk *clk)
86 struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
88 return renesas_clk_endisable(clk, priv->base, priv->info, true);
91 static int gen3_clk_disable(struct clk *clk)
93 struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
95 return renesas_clk_endisable(clk, priv->base, priv->info, false);
98 static u64 gen3_clk_get_rate64(struct clk *clk);
100 static int gen3_clk_setup_sdif_div(struct clk *clk, ulong rate)
102 struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
103 struct cpg_mssr_info *info = priv->info;
104 const struct cpg_core_clk *core;
105 struct clk parent, grandparent;
109 * The clk may be either CPG_MOD or core clock, in case this is MOD
110 * clock, use core clock one level up, otherwise use the clock as-is.
111 * Note that parent clock here always represents core clock. Also note
112 * that grandparent clock are the parent clock of the core clock here.
114 if (renesas_clk_is_mod(clk)) {
115 ret = gen3_clk_get_parent(priv, clk, info, &parent);
117 printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret);
124 if (renesas_clk_is_mod(&parent))
127 ret = renesas_clk_get_core(&parent, info, &core);
131 ret = renesas_clk_get_parent(&parent, info, &grandparent);
133 printf("%s[%i] grandparent fail, ret=%i\n", __func__, __LINE__, ret);
137 switch (core->type) {
138 case CLK_TYPE_GEN3_SDH:
140 case CLK_TYPE_GEN4_SDH:
141 return rcar_clk_set_rate64_sdh(core->parent,
142 gen3_clk_get_rate64(&grandparent),
143 rate, priv->base + core->offset);
145 case CLK_TYPE_GEN3_SD:
147 case CLK_TYPE_GEN4_SD:
148 return rcar_clk_set_rate64_sd(core->parent,
149 gen3_clk_get_rate64(&grandparent),
150 rate, priv->base + core->offset);
152 case CLK_TYPE_R8A77970_SD0:
153 return rcar_clk_set_rate64_div_table(core->parent,
154 gen3_clk_get_rate64(&grandparent),
155 rate, priv->base + core->offset,
156 CPG_SDCKCR_SD0FC_MASK,
157 r8a77970_cpg_sd0_div_table, "SD");
163 static u64 gen3_clk_get_rate64_pll_mul_reg(struct gen3_clk_priv *priv,
165 u32 mul_reg, u32 mult, u32 div,
172 value = readl(priv->base + mul_reg);
173 mult = (((value >> 24) & 0x7f) + 1) * 2;
177 rate = (gen3_clk_get_rate64(parent) * mult) / div;
179 debug("%s[%i] %s clk: mult=%u div=%u => rate=%llu\n",
180 __func__, __LINE__, name, mult, div, rate);
184 static u64 gen3_clk_get_rate64(struct clk *clk)
186 struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
187 struct cpg_mssr_info *info = priv->info;
189 const struct cpg_core_clk *core;
190 const struct rcar_gen3_cpg_pll_config *gen3_pll_config =
191 priv->gen3_cpg_pll_config;
192 const struct rcar_gen4_cpg_pll_config *gen4_pll_config =
193 priv->gen4_cpg_pll_config;
199 debug("%s[%i] Clock: id=%lu\n", __func__, __LINE__, clk->id);
201 ret = gen3_clk_get_parent(priv, clk, info, &parent);
203 printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret);
207 if (renesas_clk_is_mod(clk)) {
208 rate = gen3_clk_get_rate64(&parent);
209 debug("%s[%i] MOD clk: parent=%lu => rate=%llu\n",
210 __func__, __LINE__, parent.id, rate);
214 ret = renesas_clk_get_core(clk, info, &core);
218 switch (core->type) {
220 if (core->id == info->clk_extal_id) {
221 rate = clk_get_rate(&priv->clk_extal);
222 debug("%s[%i] EXTAL clk: rate=%llu\n",
223 __func__, __LINE__, rate);
227 if (core->id == info->clk_extalr_id) {
228 rate = clk_get_rate(&priv->clk_extalr);
229 debug("%s[%i] EXTALR clk: rate=%llu\n",
230 __func__, __LINE__, rate);
236 case CLK_TYPE_GEN3_MAIN:
237 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
238 0, 1, gen3_pll_config->extal_div,
241 case CLK_TYPE_GEN3_PLL0:
242 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
243 CPG_PLL0CR, 0, 0, "PLL0");
245 case CLK_TYPE_GEN3_PLL1:
246 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
247 0, gen3_pll_config->pll1_mult,
248 gen3_pll_config->pll1_div,
251 case CLK_TYPE_GEN3_PLL2:
252 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
253 CPG_PLL2CR, 0, 0, "PLL2");
255 case CLK_TYPE_GEN3_PLL3:
256 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
257 0, gen3_pll_config->pll3_mult,
258 gen3_pll_config->pll3_div,
261 case CLK_TYPE_GEN3_PLL4:
262 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
263 CPG_PLL4CR, 0, 0, "PLL4");
265 case CLK_TYPE_GEN4_MAIN:
266 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
267 0, 1, gen4_pll_config->extal_div,
270 case CLK_TYPE_GEN4_PLL1:
271 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
272 0, gen4_pll_config->pll1_mult,
273 gen4_pll_config->pll1_div,
276 case CLK_TYPE_GEN4_PLL2:
277 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
278 0, gen4_pll_config->pll2_mult,
279 gen4_pll_config->pll2_div,
282 case CLK_TYPE_GEN4_PLL2X_3X:
283 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
284 core->offset, 0, 0, "PLL2X_3X");
286 case CLK_TYPE_GEN4_PLL3:
287 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
288 0, gen4_pll_config->pll3_mult,
289 gen4_pll_config->pll3_div,
292 case CLK_TYPE_GEN4_PLL4:
293 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
294 0, gen4_pll_config->pll4_mult,
295 gen4_pll_config->pll4_div,
298 case CLK_TYPE_GEN4_PLL5:
299 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
300 0, gen4_pll_config->pll5_mult,
301 gen4_pll_config->pll5_div,
304 case CLK_TYPE_GEN4_PLL6:
305 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
306 0, gen4_pll_config->pll6_mult,
307 gen4_pll_config->pll6_div,
311 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
312 0, core->mult, core->div,
315 case CLK_TYPE_GEN3_MDSEL:
316 shift = priv->cpg_mode & BIT(core->offset) ? 16 : 0;
317 div = (core->div >> shift) & 0xffff;
318 rate = gen3_clk_get_rate64(&parent) / div;
319 debug("%s[%i] PE clk: parent=%i div=%u => rate=%llu\n",
320 __func__, __LINE__, (core->parent >> shift) & 0xffff,
324 case CLK_TYPE_GEN4_SDSRC:
325 div = ((readl(priv->base + SD0CKCR1) >> 29) & 0x03) + 4;
326 rate = gen3_clk_get_rate64(&parent) / div;
327 debug("%s[%i] SDSRC clk: parent=%i div=%u => rate=%llu\n",
328 __func__, __LINE__, core->parent, div, rate);
331 case CLK_TYPE_GEN3_SDH: /* Fixed factor 1:1 */
333 case CLK_TYPE_GEN4_SDH: /* Fixed factor 1:1 */
334 return rcar_clk_get_rate64_sdh(core->parent,
335 gen3_clk_get_rate64(&parent),
336 priv->base + core->offset);
338 case CLK_TYPE_R8A77970_SD0H:
339 return rcar_clk_get_rate64_div_table(core->parent,
340 gen3_clk_get_rate64(&parent),
341 priv->base + core->offset,
342 CPG_SDCKCR_SDHFC_MASK,
343 r8a77970_cpg_sd0h_div_table, "SDH");
345 case CLK_TYPE_GEN3_SD:
347 case CLK_TYPE_GEN4_SD:
348 return rcar_clk_get_rate64_sd(core->parent,
349 gen3_clk_get_rate64(&parent),
350 priv->base + core->offset);
352 case CLK_TYPE_R8A77970_SD0:
353 return rcar_clk_get_rate64_div_table(core->parent,
354 gen3_clk_get_rate64(&parent),
355 priv->base + core->offset,
356 CPG_SDCKCR_SD0FC_MASK,
357 r8a77970_cpg_sd0_div_table, "SD");
359 case CLK_TYPE_GEN3_RPCSRC:
360 return rcar_clk_get_rate64_div_table(core->parent,
361 gen3_clk_get_rate64(&parent),
362 priv->base + CPG_RPCCKCR,
363 CPG_RPCCKCR_DIV_POST_MASK,
364 gen3_cpg_rpcsrc_div_table,
367 case CLK_TYPE_GEN4_RPCSRC:
368 return rcar_clk_get_rate64_div_table(core->parent,
369 gen3_clk_get_rate64(&parent),
370 priv->base + CPG_RPCCKCR,
371 CPG_RPCCKCR_DIV_POST_MASK,
372 gen4_cpg_rpcsrc_div_table,
375 case CLK_TYPE_GEN3_D3_RPCSRC:
376 case CLK_TYPE_GEN3_E3_RPCSRC:
378 * Register RPCSRC as fixed factor clock based on the
379 * MD[4:1] pins and CPG_RPCCKCR[4:3] register value for
380 * which has been set prior to booting the kernel.
382 value = (readl(priv->base + CPG_RPCCKCR) & GENMASK(4, 3)) >> 3;
400 rate = gen3_clk_get_rate64(&parent) / div;
401 debug("%s[%i] E3/D3 RPCSRC clk: parent=%i div=%u => rate=%llu\n",
402 __func__, __LINE__, (core->parent >> 16) & 0xffff, div, rate);
406 case CLK_TYPE_GEN3_RPC:
407 case CLK_TYPE_GEN4_RPC:
408 return rcar_clk_get_rate64_rpc(core->parent,
409 gen3_clk_get_rate64(&parent),
410 priv->base + CPG_RPCCKCR);
412 case CLK_TYPE_GEN3_RPCD2:
413 case CLK_TYPE_GEN4_RPCD2:
414 return rcar_clk_get_rate64_rpcd2(core->parent,
415 gen3_clk_get_rate64(&parent));
419 printf("%s[%i] unknown fail\n", __func__, __LINE__);
424 static ulong gen3_clk_get_rate(struct clk *clk)
426 return gen3_clk_get_rate64(clk);
429 static ulong gen3_clk_set_rate(struct clk *clk, ulong rate)
431 /* Force correct SD-IF divider configuration if applicable */
432 gen3_clk_setup_sdif_div(clk, rate);
433 return gen3_clk_get_rate64(clk);
436 static int gen3_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
438 if (args->args_count != 2) {
439 debug("Invalid args_count: %d\n", args->args_count);
443 clk->id = (args->args[0] << 16) | args->args[1];
448 const struct clk_ops gen3_clk_ops = {
449 .enable = gen3_clk_enable,
450 .disable = gen3_clk_disable,
451 .get_rate = gen3_clk_get_rate,
452 .set_rate = gen3_clk_set_rate,
453 .of_xlate = gen3_clk_of_xlate,
456 static int gen3_clk_probe(struct udevice *dev)
458 struct gen3_clk_priv *priv = dev_get_priv(dev);
459 struct cpg_mssr_info *info =
460 (struct cpg_mssr_info *)dev_get_driver_data(dev);
461 const void *pll_config;
465 priv->base = dev_read_addr_ptr(dev);
470 ret = fdt_node_offset_by_compatible(gd->fdt_blob, -1, info->reset_node);
474 rst_base = fdtdec_get_addr(gd->fdt_blob, ret, "reg");
475 if (rst_base == FDT_ADDR_T_NONE)
478 priv->cpg_mode = readl(rst_base + info->reset_modemr_offset);
480 pll_config = info->get_pll_config(priv->cpg_mode);
482 if (info->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) {
483 priv->info->status_regs = mstpsr;
484 priv->info->control_regs = smstpcr;
485 priv->info->reset_regs = srcr;
486 priv->info->reset_clear_regs = srstclr;
487 priv->gen3_cpg_pll_config = pll_config;
488 if (!priv->gen3_cpg_pll_config->extal_div)
490 } else if (info->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) {
491 priv->info->status_regs = mstpsr_for_gen4;
492 priv->info->control_regs = mstpcr_for_gen4;
493 priv->info->reset_regs = srcr_for_gen4;
494 priv->info->reset_clear_regs = srstclr_for_gen4;
495 priv->gen4_cpg_pll_config = pll_config;
496 if (!priv->gen4_cpg_pll_config->extal_div)
502 ret = clk_get_by_name(dev, "extal", &priv->clk_extal);
506 if (info->extalr_node) {
507 ret = clk_get_by_name(dev, info->extalr_node, &priv->clk_extalr);
515 static int gen3_clk_remove(struct udevice *dev)
517 struct gen3_clk_priv *priv = dev_get_priv(dev);
519 return renesas_clk_remove(priv->base, priv->info);
522 U_BOOT_DRIVER(clk_gen3) = {
525 .priv_auto = sizeof(struct gen3_clk_priv),
526 .ops = &gen3_clk_ops,
527 .probe = gen3_clk_probe,
528 .remove = gen3_clk_remove,
529 .flags = DM_FLAG_OS_PREPARE | DM_FLAG_VITAL,
532 static int gen3_reset_assert(struct reset_ctl *reset_ctl)
534 struct udevice *cdev = (struct udevice *)dev_get_driver_data(reset_ctl->dev);
535 struct gen3_clk_priv *priv = dev_get_priv(cdev);
536 unsigned int packed_id = MOD_CLK_PACK(reset_ctl->id);
537 unsigned int reg = packed_id / 32;
538 unsigned int bit = packed_id % 32;
539 u32 bitmask = BIT(bit);
541 writel(bitmask, priv->base + priv->info->reset_regs[reg]);
546 static int gen3_reset_deassert(struct reset_ctl *reset_ctl)
548 struct udevice *cdev = (struct udevice *)dev_get_driver_data(reset_ctl->dev);
549 struct gen3_clk_priv *priv = dev_get_priv(cdev);
550 unsigned int packed_id = MOD_CLK_PACK(reset_ctl->id);
551 unsigned int reg = packed_id / 32;
552 unsigned int bit = packed_id % 32;
553 u32 bitmask = BIT(bit);
555 writel(bitmask, priv->base + priv->info->reset_clear_regs[reg]);
560 static const struct reset_ops rst_gen3_ops = {
561 .rst_assert = gen3_reset_assert,
562 .rst_deassert = gen3_reset_deassert,
565 U_BOOT_DRIVER(rst_gen3) = {
568 .ops = &rst_gen3_ops,
569 .flags = DM_FLAG_OS_PREPARE | DM_FLAG_VITAL,
572 int gen3_cpg_bind(struct udevice *parent)
574 struct cpg_mssr_info *info =
575 (struct cpg_mssr_info *)dev_get_driver_data(parent);
576 struct udevice *cdev, *rdev;
580 drv = lists_driver_lookup_name("clk_gen3");
584 ret = device_bind_with_driver_data(parent, drv, "clk_gen3", (ulong)info,
585 dev_ofnode(parent), &cdev);
589 drv = lists_driver_lookup_name("rst_gen3");
593 ret = device_bind_with_driver_data(parent, drv, "rst_gen3", (ulong)cdev,
594 dev_ofnode(parent), &rdev);