]> git.sur5r.net Git - u-boot/blob - drivers/clk/renesas/clk-rcar-gen3.c
ba3c6da3261c54ae2dbdcfa9f42d965dae87fef4
[u-boot] / drivers / clk / renesas / clk-rcar-gen3.c
1 /*
2  * Renesas RCar Gen3 CPG MSSR driver
3  *
4  * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
5  *
6  * Based on the following driver from Linux kernel:
7  * r8a7796 Clock Pulse Generator / Module Standby and Software Reset
8  *
9  * Copyright (C) 2016 Glider bvba
10  *
11  * SPDX-License-Identifier:     GPL-2.0+
12  */
13
14 #include <common.h>
15 #include <clk-uclass.h>
16 #include <dm.h>
17 #include <errno.h>
18 #include <wait_bit.h>
19 #include <asm/io.h>
20
21 #include <dt-bindings/clock/renesas-cpg-mssr.h>
22
23 #include "renesas-cpg-mssr.h"
24
25 #define CPG_RST_MODEMR          0x0060
26
27 #define CPG_PLL0CR              0x00d8
28 #define CPG_PLL2CR              0x002c
29 #define CPG_PLL4CR              0x01f4
30
31 #define CPG_RPC_PREDIV_MASK     0x3
32 #define CPG_RPC_PREDIV_OFFSET   3
33 #define CPG_RPC_POSTDIV_MASK    0x7
34 #define CPG_RPC_POSTDIV_OFFSET  0
35
36 /*
37  * Module Standby and Software Reset register offets.
38  *
39  * If the registers exist, these are valid for SH-Mobile, R-Mobile,
40  * R-Car Gen2, R-Car Gen3, and RZ/G1.
41  * These are NOT valid for R-Car Gen1 and RZ/A1!
42  */
43
44 /*
45  * Module Stop Status Register offsets
46  */
47
48 static const u16 mstpsr[] = {
49         0x030, 0x038, 0x040, 0x048, 0x04C, 0x03C, 0x1C0, 0x1C4,
50         0x9A0, 0x9A4, 0x9A8, 0x9AC,
51 };
52
53 #define MSTPSR(i)       mstpsr[i]
54
55
56 /*
57  * System Module Stop Control Register offsets
58  */
59
60 static const u16 smstpcr[] = {
61         0x130, 0x134, 0x138, 0x13C, 0x140, 0x144, 0x148, 0x14C,
62         0x990, 0x994, 0x998, 0x99C,
63 };
64
65 #define SMSTPCR(i)      smstpcr[i]
66
67
68 /* Realtime Module Stop Control Register offsets */
69 #define RMSTPCR(i)      (smstpcr[i] - 0x20)
70
71 /* Modem Module Stop Control Register offsets (r8a73a4) */
72 #define MMSTPCR(i)      (smstpcr[i] + 0x20)
73
74 /* Software Reset Clearing Register offsets */
75 #define SRSTCLR(i)      (0x940 + (i) * 4)
76
77 /*
78  * SDn Clock
79  */
80 #define CPG_SD_STP_HCK          BIT(9)
81 #define CPG_SD_STP_CK           BIT(8)
82
83 #define CPG_SD_STP_MASK         (CPG_SD_STP_HCK | CPG_SD_STP_CK)
84 #define CPG_SD_FC_MASK          (0x7 << 2 | 0x3 << 0)
85
86 #define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \
87 { \
88         .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \
89                ((stp_ck) ? CPG_SD_STP_CK : 0) | \
90                ((sd_srcfc) << 2) | \
91                ((sd_fc) << 0), \
92         .div = (sd_div), \
93 }
94
95 struct sd_div_table {
96         u32 val;
97         unsigned int div;
98 };
99
100 /* SDn divider
101  *                     sd_srcfc   sd_fc   div
102  * stp_hck   stp_ck    (div)      (div)     = sd_srcfc x sd_fc
103  *-------------------------------------------------------------------
104  *  0         0         0 (1)      1 (4)      4
105  *  0         0         1 (2)      1 (4)      8
106  *  1         0         2 (4)      1 (4)     16
107  *  1         0         3 (8)      1 (4)     32
108  *  1         0         4 (16)     1 (4)     64
109  *  0         0         0 (1)      0 (2)      2
110  *  0         0         1 (2)      0 (2)      4
111  *  1         0         2 (4)      0 (2)      8
112  *  1         0         3 (8)      0 (2)     16
113  *  1         0         4 (16)     0 (2)     32
114  */
115 static const struct sd_div_table cpg_sd_div_table[] = {
116 /*      CPG_SD_DIV_TABLE_DATA(stp_hck,  stp_ck,   sd_srcfc,   sd_fc,  sd_div) */
117         CPG_SD_DIV_TABLE_DATA(0,        0,        0,          1,        4),
118         CPG_SD_DIV_TABLE_DATA(0,        0,        1,          1,        8),
119         CPG_SD_DIV_TABLE_DATA(1,        0,        2,          1,       16),
120         CPG_SD_DIV_TABLE_DATA(1,        0,        3,          1,       32),
121         CPG_SD_DIV_TABLE_DATA(1,        0,        4,          1,       64),
122         CPG_SD_DIV_TABLE_DATA(0,        0,        0,          0,        2),
123         CPG_SD_DIV_TABLE_DATA(0,        0,        1,          0,        4),
124         CPG_SD_DIV_TABLE_DATA(1,        0,        2,          0,        8),
125         CPG_SD_DIV_TABLE_DATA(1,        0,        3,          0,       16),
126         CPG_SD_DIV_TABLE_DATA(1,        0,        4,          0,       32),
127 };
128
129 static bool gen3_clk_is_mod(struct clk *clk)
130 {
131         return (clk->id >> 16) == CPG_MOD;
132 }
133
134 static int gen3_clk_get_mod(struct clk *clk, const struct mssr_mod_clk **mssr)
135 {
136         struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
137         struct cpg_mssr_info *info = priv->info;
138         const unsigned long clkid = clk->id & 0xffff;
139         int i;
140
141         if (!gen3_clk_is_mod(clk))
142                 return -EINVAL;
143
144         for (i = 0; i < info->mod_clk_size; i++) {
145                 if (info->mod_clk[i].id !=
146                     (info->mod_clk_base + MOD_CLK_PACK(clkid)))
147                         continue;
148
149                 *mssr = &info->mod_clk[i];
150                 return 0;
151         }
152
153         return -ENODEV;
154 }
155
156 static int gen3_clk_get_core(struct clk *clk, const struct cpg_core_clk **core)
157 {
158         struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
159         struct cpg_mssr_info *info = priv->info;
160         const unsigned long clkid = clk->id & 0xffff;
161         int i;
162
163         if (gen3_clk_is_mod(clk))
164                 return -EINVAL;
165
166         for (i = 0; i < info->core_clk_size; i++) {
167                 if (info->core_clk[i].id != clkid)
168                         continue;
169
170                 *core = &info->core_clk[i];
171                 return 0;
172         }
173
174         return -ENODEV;
175 }
176
177 static int gen3_clk_get_parent(struct clk *clk, struct clk *parent)
178 {
179         const struct cpg_core_clk *core;
180         const struct mssr_mod_clk *mssr;
181         int ret;
182
183         if (gen3_clk_is_mod(clk)) {
184                 ret = gen3_clk_get_mod(clk, &mssr);
185                 if (ret)
186                         return ret;
187
188                 parent->id = mssr->parent;
189         } else {
190                 ret = gen3_clk_get_core(clk, &core);
191                 if (ret)
192                         return ret;
193
194                 if (core->type == CLK_TYPE_IN)
195                         parent->id = ~0;        /* Top-level clock */
196                 else
197                         parent->id = core->parent;
198         }
199
200         parent->dev = clk->dev;
201
202         return 0;
203 }
204
205 static int gen3_clk_setup_sdif_div(struct clk *clk)
206 {
207         struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
208         const struct cpg_core_clk *core;
209         struct clk parent;
210         int ret;
211
212         ret = gen3_clk_get_parent(clk, &parent);
213         if (ret) {
214                 printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret);
215                 return ret;
216         }
217
218         if (gen3_clk_is_mod(&parent))
219                 return 0;
220
221         ret = gen3_clk_get_core(&parent, &core);
222         if (ret)
223                 return ret;
224
225         if (core->type != CLK_TYPE_GEN3_SD)
226                 return 0;
227
228         debug("%s[%i] SDIF offset=%x\n", __func__, __LINE__, core->offset);
229
230         writel(1, priv->base + core->offset);
231
232         return 0;
233 }
234
235 static int gen3_clk_endisable(struct clk *clk, bool enable)
236 {
237         struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
238         const unsigned long clkid = clk->id & 0xffff;
239         const unsigned int reg = clkid / 100;
240         const unsigned int bit = clkid % 100;
241         const u32 bitmask = BIT(bit);
242         int ret;
243
244         if (!gen3_clk_is_mod(clk))
245                 return -EINVAL;
246
247         debug("%s[%i] MSTP %lu=%02u/%02u %s\n", __func__, __LINE__,
248               clkid, reg, bit, enable ? "ON" : "OFF");
249
250         if (enable) {
251                 ret = gen3_clk_setup_sdif_div(clk);
252                 if (ret)
253                         return ret;
254                 clrbits_le32(priv->base + SMSTPCR(reg), bitmask);
255                 return wait_for_bit("MSTP", priv->base + MSTPSR(reg),
256                                     bitmask, 0, 100, 0);
257         } else {
258                 setbits_le32(priv->base + SMSTPCR(reg), bitmask);
259                 return 0;
260         }
261 }
262
263 static int gen3_clk_enable(struct clk *clk)
264 {
265         return gen3_clk_endisable(clk, true);
266 }
267
268 static int gen3_clk_disable(struct clk *clk)
269 {
270         return gen3_clk_endisable(clk, false);
271 }
272
273 static ulong gen3_clk_get_rate(struct clk *clk)
274 {
275         struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
276         struct cpg_mssr_info *info = priv->info;
277         struct clk parent;
278         const struct cpg_core_clk *core;
279         const struct rcar_gen3_cpg_pll_config *pll_config =
280                                         priv->cpg_pll_config;
281         u32 value, mult, prediv, postdiv, rate = 0;
282         int i, ret;
283
284         debug("%s[%i] Clock: id=%lu\n", __func__, __LINE__, clk->id);
285
286         ret = gen3_clk_get_parent(clk, &parent);
287         if (ret) {
288                 printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret);
289                 return ret;
290         }
291
292         if (gen3_clk_is_mod(clk)) {
293                 rate = gen3_clk_get_rate(&parent);
294                 debug("%s[%i] MOD clk: parent=%lu => rate=%u\n",
295                       __func__, __LINE__, parent.id, rate);
296                 return rate;
297         }
298
299         ret = gen3_clk_get_core(clk, &core);
300         if (ret)
301                 return ret;
302
303         switch (core->type) {
304         case CLK_TYPE_IN:
305                 if (core->id == info->clk_extal_id) {
306                         rate = clk_get_rate(&priv->clk_extal);
307                         debug("%s[%i] EXTAL clk: rate=%u\n",
308                               __func__, __LINE__, rate);
309                         return rate;
310                 }
311
312                 if (core->id == info->clk_extalr_id) {
313                         rate = clk_get_rate(&priv->clk_extalr);
314                         debug("%s[%i] EXTALR clk: rate=%u\n",
315                               __func__, __LINE__, rate);
316                         return rate;
317                 }
318
319                 return -EINVAL;
320
321         case CLK_TYPE_GEN3_MAIN:
322                 rate = gen3_clk_get_rate(&parent) / pll_config->extal_div;
323                 debug("%s[%i] MAIN clk: parent=%i extal_div=%i => rate=%u\n",
324                       __func__, __LINE__,
325                       core->parent, pll_config->extal_div, rate);
326                 return rate;
327
328         case CLK_TYPE_GEN3_PLL0:
329                 value = readl(priv->base + CPG_PLL0CR);
330                 mult = (((value >> 24) & 0x7f) + 1) * 2;
331                 rate = gen3_clk_get_rate(&parent) * mult;
332                 debug("%s[%i] PLL0 clk: parent=%i mult=%u => rate=%u\n",
333                       __func__, __LINE__, core->parent, mult, rate);
334                 return rate;
335
336         case CLK_TYPE_GEN3_PLL1:
337                 rate = gen3_clk_get_rate(&parent) * pll_config->pll1_mult;
338                 debug("%s[%i] PLL1 clk: parent=%i mul=%i => rate=%u\n",
339                       __func__, __LINE__,
340                       core->parent, pll_config->pll1_mult, rate);
341                 return rate;
342
343         case CLK_TYPE_GEN3_PLL2:
344                 value = readl(priv->base + CPG_PLL2CR);
345                 mult = (((value >> 24) & 0x7f) + 1) * 2;
346                 rate = gen3_clk_get_rate(&parent) * mult;
347                 debug("%s[%i] PLL2 clk: parent=%i mult=%u => rate=%u\n",
348                       __func__, __LINE__, core->parent, mult, rate);
349                 return rate;
350
351         case CLK_TYPE_GEN3_PLL3:
352                 rate = gen3_clk_get_rate(&parent) * pll_config->pll3_mult;
353                 debug("%s[%i] PLL3 clk: parent=%i mul=%i => rate=%u\n",
354                       __func__, __LINE__,
355                       core->parent, pll_config->pll3_mult, rate);
356                 return rate;
357
358         case CLK_TYPE_GEN3_PLL4:
359                 value = readl(priv->base + CPG_PLL4CR);
360                 mult = (((value >> 24) & 0x7f) + 1) * 2;
361                 rate = gen3_clk_get_rate(&parent) * mult;
362                 debug("%s[%i] PLL4 clk: parent=%i mult=%u => rate=%u\n",
363                       __func__, __LINE__, core->parent, mult, rate);
364                 return rate;
365
366         case CLK_TYPE_FF:
367         case CLK_TYPE_GEN3_PE:          /* FIXME */
368                 rate = (gen3_clk_get_rate(&parent) * core->mult) / core->div;
369                 debug("%s[%i] FIXED clk: parent=%i div=%i mul=%i => rate=%u\n",
370                       __func__, __LINE__,
371                       core->parent, core->mult, core->div, rate);
372                 return rate;
373
374         case CLK_TYPE_GEN3_SD:          /* FIXME */
375                 value = readl(priv->base + core->offset);
376                 value &= CPG_SD_STP_MASK | CPG_SD_FC_MASK;
377
378                 for (i = 0; i < ARRAY_SIZE(cpg_sd_div_table); i++) {
379                         if (cpg_sd_div_table[i].val != value)
380                                 continue;
381
382                         rate = gen3_clk_get_rate(&parent) /
383                                cpg_sd_div_table[i].div;
384                         debug("%s[%i] SD clk: parent=%i div=%i => rate=%u\n",
385                               __func__, __LINE__,
386                               core->parent, cpg_sd_div_table[i].div, rate);
387
388                         return rate;
389                 }
390
391                 return -EINVAL;
392
393         case CLK_TYPE_GEN3_RPC:
394                 rate = gen3_clk_get_rate(&parent);
395
396                 value = readl(priv->base + core->offset);
397
398                 prediv = (value >> CPG_RPC_PREDIV_OFFSET) &
399                          CPG_RPC_PREDIV_MASK;
400                 if (prediv == 2)
401                         rate /= 5;
402                 else if (prediv == 3)
403                         rate /= 6;
404                 else
405                         return -EINVAL;
406
407                 postdiv = (value >> CPG_RPC_POSTDIV_OFFSET) &
408                           CPG_RPC_POSTDIV_MASK;
409                 rate /= postdiv + 1;
410
411                 debug("%s[%i] RPC clk: parent=%i prediv=%i postdiv=%i => rate=%u\n",
412                       __func__, __LINE__,
413                       core->parent, prediv, postdiv, rate);
414
415                 return -EINVAL;
416
417         }
418
419         printf("%s[%i] unknown fail\n", __func__, __LINE__);
420
421         return -ENOENT;
422 }
423
424 static ulong gen3_clk_set_rate(struct clk *clk, ulong rate)
425 {
426         return gen3_clk_get_rate(clk);
427 }
428
429 static int gen3_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
430 {
431         if (args->args_count != 2) {
432                 debug("Invaild args_count: %d\n", args->args_count);
433                 return -EINVAL;
434         }
435
436         clk->id = (args->args[0] << 16) | args->args[1];
437
438         return 0;
439 }
440
441 const struct clk_ops gen3_clk_ops = {
442         .enable         = gen3_clk_enable,
443         .disable        = gen3_clk_disable,
444         .get_rate       = gen3_clk_get_rate,
445         .set_rate       = gen3_clk_set_rate,
446         .of_xlate       = gen3_clk_of_xlate,
447 };
448
449 int gen3_clk_probe(struct udevice *dev)
450 {
451         struct gen3_clk_priv *priv = dev_get_priv(dev);
452         struct cpg_mssr_info *info =
453                 (struct cpg_mssr_info *)dev_get_driver_data(dev);
454         fdt_addr_t rst_base;
455         u32 cpg_mode;
456         int ret;
457
458         priv->base = (struct gen3_base *)devfdt_get_addr(dev);
459         if (!priv->base)
460                 return -EINVAL;
461
462         priv->info = info;
463         ret = fdt_node_offset_by_compatible(gd->fdt_blob, -1, info->reset_node);
464         if (ret < 0)
465                 return ret;
466
467         rst_base = fdtdec_get_addr(gd->fdt_blob, ret, "reg");
468         if (rst_base == FDT_ADDR_T_NONE)
469                 return -EINVAL;
470
471         cpg_mode = readl(rst_base + CPG_RST_MODEMR);
472
473         priv->cpg_pll_config =
474                 (struct rcar_gen3_cpg_pll_config *)info->get_pll_config(cpg_mode);
475         if (!priv->cpg_pll_config->extal_div)
476                 return -EINVAL;
477
478         ret = clk_get_by_name(dev, "extal", &priv->clk_extal);
479         if (ret < 0)
480                 return ret;
481
482         if (info->extalr_node) {
483                 ret = clk_get_by_name(dev, info->extalr_node, &priv->clk_extalr);
484                 if (ret < 0)
485                         return ret;
486         }
487
488         return 0;
489 }
490
491 int gen3_clk_remove(struct udevice *dev)
492 {
493         struct gen3_clk_priv *priv = dev_get_priv(dev);
494         struct cpg_mssr_info *info = priv->info;
495         unsigned int i;
496
497         /* Stop TMU0 */
498         clrbits_le32(TMU_BASE + TSTR0, TSTR0_STR0);
499
500         /* Stop module clock */
501         for (i = 0; i < info->mstp_table_size; i++) {
502                 clrsetbits_le32(priv->base + SMSTPCR(i),
503                                 info->mstp_table[i].sdis,
504                                 info->mstp_table[i].sen);
505                 clrsetbits_le32(priv->base + RMSTPCR(i),
506                                 info->mstp_table[i].rdis,
507                                 info->mstp_table[i].ren);
508         }
509
510         return 0;
511 }