Prepare v2023.10
[platform/kernel/u-boot.git] / drivers / clk / renesas / clk-rcar-gen3.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Renesas RCar Gen3 CPG MSSR driver
4  *
5  * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
6  *
7  * Based on the following driver from Linux kernel:
8  * r8a7796 Clock Pulse Generator / Module Standby and Software Reset
9  *
10  * Copyright (C) 2016 Glider bvba
11  */
12
13 #include <common.h>
14 #include <clk-uclass.h>
15 #include <dm.h>
16 #include <dm/device-internal.h>
17 #include <dm/lists.h>
18 #include <errno.h>
19 #include <log.h>
20 #include <wait_bit.h>
21 #include <asm/global_data.h>
22 #include <asm/io.h>
23 #include <linux/bitfield.h>
24 #include <linux/bitops.h>
25 #include <linux/clk-provider.h>
26 #include <reset-uclass.h>
27
28 #include <dt-bindings/clock/renesas-cpg-mssr.h>
29
30 #include "renesas-cpg-mssr.h"
31 #include "rcar-gen3-cpg.h"
32 #include "rcar-cpg-lib.h"
33
34 #define CPG_PLL0CR              0x00d8
35 #define CPG_PLL2CR              0x002c
36 #define CPG_PLL4CR              0x01f4
37
38 #define SD0CKCR1                0x08a4
39
40 static const struct clk_div_table gen3_cpg_rpcsrc_div_table[] = {
41         { 2, 5 }, { 3, 6 }, { 0, 0 },
42 };
43
44 static const struct clk_div_table gen4_cpg_rpcsrc_div_table[] = {
45         { 0, 4 }, { 1, 6 }, { 2, 5 }, { 3, 6 }, { 0, 0 },
46 };
47
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 },
52 };
53
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 },
57         {  0,  0 },
58 };
59
60 static int gen3_clk_get_parent(struct gen3_clk_priv *priv, struct clk *clk,
61                                struct cpg_mssr_info *info, struct clk *parent)
62 {
63         const struct cpg_core_clk *core;
64         u8 shift;
65         int ret;
66
67         if (!renesas_clk_is_mod(clk)) {
68                 ret = renesas_clk_get_core(clk, info, &core);
69                 if (ret)
70                         return ret;
71
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;
76                         parent->id &= 0xffff;
77                         return 0;
78                 }
79         }
80
81         return renesas_clk_get_parent(clk, info, parent);
82 }
83
84 static int gen3_clk_enable(struct clk *clk)
85 {
86         struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
87
88         return renesas_clk_endisable(clk, priv->base, priv->info, true);
89 }
90
91 static int gen3_clk_disable(struct clk *clk)
92 {
93         struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
94
95         return renesas_clk_endisable(clk, priv->base, priv->info, false);
96 }
97
98 static u64 gen3_clk_get_rate64(struct clk *clk);
99
100 static int gen3_clk_setup_sdif_div(struct clk *clk, ulong rate)
101 {
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;
106         int ret;
107
108         /*
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.
113          */
114         if (renesas_clk_is_mod(clk)) {
115                 ret = gen3_clk_get_parent(priv, clk, info, &parent);
116                 if (ret) {
117                         printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret);
118                         return ret;
119                 }
120         } else {
121                 parent = *clk;
122         }
123
124         if (renesas_clk_is_mod(&parent))
125                 return 0;
126
127         ret = renesas_clk_get_core(&parent, info, &core);
128         if (ret)
129                 return ret;
130
131         ret = renesas_clk_get_parent(&parent, info, &grandparent);
132         if (ret) {
133                 printf("%s[%i] grandparent fail, ret=%i\n", __func__, __LINE__, ret);
134                 return ret;
135         }
136
137         switch (core->type) {
138         case CLK_TYPE_GEN3_SDH:
139                 fallthrough;
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);
144
145         case CLK_TYPE_GEN3_SD:
146                 fallthrough;
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);
151
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");
158         }
159
160         return 0;
161 }
162
163 static u64 gen3_clk_get_rate64_pll_mul_reg(struct gen3_clk_priv *priv,
164                                            struct clk *parent,
165                                            u32 mul_reg, u32 mult, u32 div,
166                                            char *name)
167 {
168         u32 value;
169         u64 rate;
170
171         if (mul_reg) {
172                 value = readl(priv->base + mul_reg);
173                 mult = (((value >> 24) & 0x7f) + 1) * 2;
174                 div = 1;
175         }
176
177         rate = (gen3_clk_get_rate64(parent) * mult) / div;
178
179         debug("%s[%i] %s clk: mult=%u div=%u => rate=%llu\n",
180               __func__, __LINE__, name, mult, div, rate);
181         return rate;
182 }
183
184 static u64 gen3_clk_get_rate64(struct clk *clk)
185 {
186         struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
187         struct cpg_mssr_info *info = priv->info;
188         struct clk parent;
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;
194         u32 value, div;
195         u64 rate = 0;
196         u8 shift;
197         int ret;
198
199         debug("%s[%i] Clock: id=%lu\n", __func__, __LINE__, clk->id);
200
201         ret = gen3_clk_get_parent(priv, clk, info, &parent);
202         if (ret) {
203                 printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret);
204                 return ret;
205         }
206
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);
211                 return rate;
212         }
213
214         ret = renesas_clk_get_core(clk, info, &core);
215         if (ret)
216                 return ret;
217
218         switch (core->type) {
219         case CLK_TYPE_IN:
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);
224                         return rate;
225                 }
226
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);
231                         return rate;
232                 }
233
234                 return -EINVAL;
235
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,
239                                                 "MAIN");
240
241         case CLK_TYPE_GEN3_PLL0:
242                 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
243                                                 CPG_PLL0CR, 0, 0, "PLL0");
244
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,
249                                                 "PLL1");
250
251         case CLK_TYPE_GEN3_PLL2:
252                 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
253                                                 CPG_PLL2CR, 0, 0, "PLL2");
254
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,
259                                                 "PLL3");
260
261         case CLK_TYPE_GEN3_PLL4:
262                 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
263                                                 CPG_PLL4CR, 0, 0, "PLL4");
264
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,
268                                                 "MAIN");
269
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,
274                                                 "PLL1");
275
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,
280                                                 "PLL2");
281
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");
285
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,
290                                                 "PLL3");
291
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,
296                                                 "PLL4");
297
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,
302                                                 "PLL5");
303
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,
308                                                 "PLL6");
309
310         case CLK_TYPE_FF:
311                 return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
312                                                 0, core->mult, core->div,
313                                                 "FIXED");
314
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,
321                       div, rate);
322                 return rate;
323
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);
329                 return rate;
330
331         case CLK_TYPE_GEN3_SDH: /* Fixed factor 1:1 */
332                 fallthrough;
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);
337
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");
344
345         case CLK_TYPE_GEN3_SD:
346                 fallthrough;
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);
351
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");
358
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,
365                                                      "RPCSRC");
366
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,
373                                                      "RPCSRC");
374
375         case CLK_TYPE_GEN3_D3_RPCSRC:
376         case CLK_TYPE_GEN3_E3_RPCSRC:
377                 /*
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.
381                  */
382                 value = (readl(priv->base + CPG_RPCCKCR) & GENMASK(4, 3)) >> 3;
383
384                 switch (value) {
385                 case 0:
386                         div = 5;
387                         break;
388                 case 1:
389                         div = 3;
390                         break;
391                 case 2:
392                         div = core->div;
393                         break;
394                 case 3:
395                 default:
396                         div = 2;
397                         break;
398                 }
399
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);
403
404                 return rate;
405
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);
411
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));
416
417         }
418
419         printf("%s[%i] unknown fail\n", __func__, __LINE__);
420
421         return -ENOENT;
422 }
423
424 static ulong gen3_clk_get_rate(struct clk *clk)
425 {
426         return gen3_clk_get_rate64(clk);
427 }
428
429 static ulong gen3_clk_set_rate(struct clk *clk, ulong rate)
430 {
431         /* Force correct SD-IF divider configuration if applicable */
432         gen3_clk_setup_sdif_div(clk, rate);
433         return gen3_clk_get_rate64(clk);
434 }
435
436 static int gen3_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
437 {
438         if (args->args_count != 2) {
439                 debug("Invalid args_count: %d\n", args->args_count);
440                 return -EINVAL;
441         }
442
443         clk->id = (args->args[0] << 16) | args->args[1];
444
445         return 0;
446 }
447
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,
454 };
455
456 static int gen3_clk_probe(struct udevice *dev)
457 {
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;
462         fdt_addr_t rst_base;
463         int ret;
464
465         priv->base = dev_read_addr_ptr(dev);
466         if (!priv->base)
467                 return -EINVAL;
468
469         priv->info = info;
470         ret = fdt_node_offset_by_compatible(gd->fdt_blob, -1, info->reset_node);
471         if (ret < 0)
472                 return ret;
473
474         rst_base = fdtdec_get_addr(gd->fdt_blob, ret, "reg");
475         if (rst_base == FDT_ADDR_T_NONE)
476                 return -EINVAL;
477
478         priv->cpg_mode = readl(rst_base + info->reset_modemr_offset);
479
480         pll_config = info->get_pll_config(priv->cpg_mode);
481
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)
489                         return -EINVAL;
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)
497                         return -EINVAL;
498         } else {
499                 return -EINVAL;
500         }
501
502         ret = clk_get_by_name(dev, "extal", &priv->clk_extal);
503         if (ret < 0)
504                 return ret;
505
506         if (info->extalr_node) {
507                 ret = clk_get_by_name(dev, info->extalr_node, &priv->clk_extalr);
508                 if (ret < 0)
509                         return ret;
510         }
511
512         return 0;
513 }
514
515 static int gen3_clk_remove(struct udevice *dev)
516 {
517         struct gen3_clk_priv *priv = dev_get_priv(dev);
518
519         return renesas_clk_remove(priv->base, priv->info);
520 }
521
522 U_BOOT_DRIVER(clk_gen3) = {
523         .name           = "clk_gen3",
524         .id             = UCLASS_CLK,
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,
530 };
531
532 static int gen3_reset_assert(struct reset_ctl *reset_ctl)
533 {
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);
540
541         writel(bitmask, priv->base + priv->info->reset_regs[reg]);
542
543         return 0;
544 }
545
546 static int gen3_reset_deassert(struct reset_ctl *reset_ctl)
547 {
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);
554
555         writel(bitmask, priv->base + priv->info->reset_clear_regs[reg]);
556
557         return 0;
558 }
559
560 static const struct reset_ops rst_gen3_ops = {
561         .rst_assert = gen3_reset_assert,
562         .rst_deassert = gen3_reset_deassert,
563 };
564
565 U_BOOT_DRIVER(rst_gen3) = {
566         .name = "rst_gen3",
567         .id = UCLASS_RESET,
568         .ops = &rst_gen3_ops,
569         .flags = DM_FLAG_OS_PREPARE | DM_FLAG_VITAL,
570 };
571
572 int gen3_cpg_bind(struct udevice *parent)
573 {
574         struct cpg_mssr_info *info =
575                 (struct cpg_mssr_info *)dev_get_driver_data(parent);
576         struct udevice *cdev, *rdev;
577         struct driver *drv;
578         int ret;
579
580         drv = lists_driver_lookup_name("clk_gen3");
581         if (!drv)
582                 return -ENOENT;
583
584         ret = device_bind_with_driver_data(parent, drv, "clk_gen3", (ulong)info,
585                                            dev_ofnode(parent), &cdev);
586         if (ret)
587                 return ret;
588
589         drv = lists_driver_lookup_name("rst_gen3");
590         if (!drv)
591                 return -ENOENT;
592
593         ret = device_bind_with_driver_data(parent, drv, "rst_gen3", (ulong)cdev,
594                                            dev_ofnode(parent), &rdev);
595         if (ret)
596                 device_unbind(cdev);
597
598         return ret;
599 }