2 * Renesas RCar Gen3 CPG MSSR driver
4 * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
6 * Based on the following driver from Linux kernel:
7 * r8a7796 Clock Pulse Generator / Module Standby and Software Reset
9 * Copyright (C) 2016 Glider bvba
11 * SPDX-License-Identifier: GPL-2.0+
15 #include <clk-uclass.h>
21 #include <dt-bindings/clock/renesas-cpg-mssr.h>
23 #include "renesas-cpg-mssr.h"
25 #define CPG_RST_MODEMR 0x0060
27 #define CPG_PLL0CR 0x00d8
28 #define CPG_PLL2CR 0x002c
29 #define CPG_PLL4CR 0x01f4
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
37 * Module Standby and Software Reset register offets.
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!
45 * Module Stop Status Register offsets
48 static const u16 mstpsr
[] = {
49 0x030, 0x038, 0x040, 0x048, 0x04C, 0x03C, 0x1C0, 0x1C4,
50 0x9A0, 0x9A4, 0x9A8, 0x9AC,
53 #define MSTPSR(i) mstpsr[i]
57 * System Module Stop Control Register offsets
60 static const u16 smstpcr
[] = {
61 0x130, 0x134, 0x138, 0x13C, 0x140, 0x144, 0x148, 0x14C,
62 0x990, 0x994, 0x998, 0x99C,
65 #define SMSTPCR(i) smstpcr[i]
68 /* Realtime Module Stop Control Register offsets */
69 #define RMSTPCR(i) (smstpcr[i] - 0x20)
71 /* Modem Module Stop Control Register offsets (r8a73a4) */
72 #define MMSTPCR(i) (smstpcr[i] + 0x20)
74 /* Software Reset Clearing Register offsets */
75 #define SRSTCLR(i) (0x940 + (i) * 4)
82 * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4
84 *-------------------------------------------------------------------
85 * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144
86 * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144
87 * 0 0 1 0 Prohibited setting
88 * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144
89 * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120
90 * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120
91 * 0 1 1 0 Prohibited setting
92 * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120
93 * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96
94 * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96
95 * 1 0 1 0 Prohibited setting
96 * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96
97 * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144
98 * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144
99 * 1 1 1 0 Prohibited setting
100 * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144
102 #define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \
103 (((md) & BIT(13)) >> 11) | \
104 (((md) & BIT(19)) >> 18) | \
105 (((md) & BIT(17)) >> 17))
107 static const struct rcar_gen3_cpg_pll_config cpg_pll_configs
[16] = {
108 /* EXTAL div PLL1 mult PLL3 mult */
111 { 0, /* Prohibited setting */ },
115 { 0, /* Prohibited setting */ },
119 { 0, /* Prohibited setting */ },
123 { 0, /* Prohibited setting */ },
130 #define CPG_SD_STP_HCK BIT(9)
131 #define CPG_SD_STP_CK BIT(8)
133 #define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK)
134 #define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0)
136 #define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \
138 .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \
139 ((stp_ck) ? CPG_SD_STP_CK : 0) | \
140 ((sd_srcfc) << 2) | \
145 struct sd_div_table
{
152 * stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc
153 *-------------------------------------------------------------------
158 * 1 0 4 (16) 1 (4) 64
163 * 1 0 4 (16) 0 (2) 32
165 static const struct sd_div_table cpg_sd_div_table
[] = {
166 /* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */
167 CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4),
168 CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8),
169 CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16),
170 CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32),
171 CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64),
172 CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2),
173 CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4),
174 CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8),
175 CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16),
176 CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32),
179 static bool gen3_clk_is_mod(struct clk
*clk
)
181 return (clk
->id
>> 16) == CPG_MOD
;
184 static int gen3_clk_get_mod(struct clk
*clk
, const struct mssr_mod_clk
**mssr
)
186 struct gen3_clk_priv
*priv
= dev_get_priv(clk
->dev
);
187 struct cpg_mssr_info
*info
= priv
->info
;
188 const unsigned long clkid
= clk
->id
& 0xffff;
191 if (!gen3_clk_is_mod(clk
))
194 for (i
= 0; i
< info
->mod_clk_size
; i
++) {
195 if (info
->mod_clk
[i
].id
!=
196 (info
->mod_clk_base
+ MOD_CLK_PACK(clkid
)))
199 *mssr
= &info
->mod_clk
[i
];
206 static int gen3_clk_get_core(struct clk
*clk
, const struct cpg_core_clk
**core
)
208 struct gen3_clk_priv
*priv
= dev_get_priv(clk
->dev
);
209 struct cpg_mssr_info
*info
= priv
->info
;
210 const unsigned long clkid
= clk
->id
& 0xffff;
213 if (gen3_clk_is_mod(clk
))
216 for (i
= 0; i
< info
->core_clk_size
; i
++) {
217 if (info
->core_clk
[i
].id
!= clkid
)
220 *core
= &info
->core_clk
[i
];
227 static int gen3_clk_get_parent(struct clk
*clk
, struct clk
*parent
)
229 const struct cpg_core_clk
*core
;
230 const struct mssr_mod_clk
*mssr
;
233 if (gen3_clk_is_mod(clk
)) {
234 ret
= gen3_clk_get_mod(clk
, &mssr
);
238 parent
->id
= mssr
->parent
;
240 ret
= gen3_clk_get_core(clk
, &core
);
244 if (core
->type
== CLK_TYPE_IN
)
245 parent
->id
= ~0; /* Top-level clock */
247 parent
->id
= core
->parent
;
250 parent
->dev
= clk
->dev
;
255 static int gen3_clk_setup_sdif_div(struct clk
*clk
)
257 struct gen3_clk_priv
*priv
= dev_get_priv(clk
->dev
);
258 const struct cpg_core_clk
*core
;
262 ret
= gen3_clk_get_parent(clk
, &parent
);
264 printf("%s[%i] parent fail, ret=%i\n", __func__
, __LINE__
, ret
);
268 if (gen3_clk_is_mod(&parent
))
271 ret
= gen3_clk_get_core(&parent
, &core
);
275 if (core
->type
!= CLK_TYPE_GEN3_SD
)
278 debug("%s[%i] SDIF offset=%x\n", __func__
, __LINE__
, core
->offset
);
280 writel(1, priv
->base
+ core
->offset
);
285 static int gen3_clk_endisable(struct clk
*clk
, bool enable
)
287 struct gen3_clk_priv
*priv
= dev_get_priv(clk
->dev
);
288 const unsigned long clkid
= clk
->id
& 0xffff;
289 const unsigned int reg
= clkid
/ 100;
290 const unsigned int bit
= clkid
% 100;
291 const u32 bitmask
= BIT(bit
);
294 if (!gen3_clk_is_mod(clk
))
297 debug("%s[%i] MSTP %lu=%02u/%02u %s\n", __func__
, __LINE__
,
298 clkid
, reg
, bit
, enable
? "ON" : "OFF");
301 ret
= gen3_clk_setup_sdif_div(clk
);
304 clrbits_le32(priv
->base
+ SMSTPCR(reg
), bitmask
);
305 return wait_for_bit("MSTP", priv
->base
+ MSTPSR(reg
),
308 setbits_le32(priv
->base
+ SMSTPCR(reg
), bitmask
);
313 static int gen3_clk_enable(struct clk
*clk
)
315 return gen3_clk_endisable(clk
, true);
318 static int gen3_clk_disable(struct clk
*clk
)
320 return gen3_clk_endisable(clk
, false);
323 static ulong
gen3_clk_get_rate(struct clk
*clk
)
325 struct gen3_clk_priv
*priv
= dev_get_priv(clk
->dev
);
326 struct cpg_mssr_info
*info
= priv
->info
;
328 const struct cpg_core_clk
*core
;
329 const struct rcar_gen3_cpg_pll_config
*pll_config
=
330 priv
->cpg_pll_config
;
331 u32 value
, mult
, prediv
, postdiv
, rate
= 0;
334 debug("%s[%i] Clock: id=%lu\n", __func__
, __LINE__
, clk
->id
);
336 ret
= gen3_clk_get_parent(clk
, &parent
);
338 printf("%s[%i] parent fail, ret=%i\n", __func__
, __LINE__
, ret
);
342 if (gen3_clk_is_mod(clk
)) {
343 rate
= gen3_clk_get_rate(&parent
);
344 debug("%s[%i] MOD clk: parent=%lu => rate=%u\n",
345 __func__
, __LINE__
, parent
.id
, rate
);
349 ret
= gen3_clk_get_core(clk
, &core
);
353 switch (core
->type
) {
355 if (core
->id
== info
->clk_extal_id
) {
356 rate
= clk_get_rate(&priv
->clk_extal
);
357 debug("%s[%i] EXTAL clk: rate=%u\n",
358 __func__
, __LINE__
, rate
);
362 if (core
->id
== info
->clk_extalr_id
) {
363 rate
= clk_get_rate(&priv
->clk_extalr
);
364 debug("%s[%i] EXTALR clk: rate=%u\n",
365 __func__
, __LINE__
, rate
);
371 case CLK_TYPE_GEN3_MAIN
:
372 rate
= gen3_clk_get_rate(&parent
) / pll_config
->extal_div
;
373 debug("%s[%i] MAIN clk: parent=%i extal_div=%i => rate=%u\n",
375 core
->parent
, pll_config
->extal_div
, rate
);
378 case CLK_TYPE_GEN3_PLL0
:
379 value
= readl(priv
->base
+ CPG_PLL0CR
);
380 mult
= (((value
>> 24) & 0x7f) + 1) * 2;
381 rate
= gen3_clk_get_rate(&parent
) * mult
;
382 debug("%s[%i] PLL0 clk: parent=%i mult=%u => rate=%u\n",
383 __func__
, __LINE__
, core
->parent
, mult
, rate
);
386 case CLK_TYPE_GEN3_PLL1
:
387 rate
= gen3_clk_get_rate(&parent
) * pll_config
->pll1_mult
;
388 debug("%s[%i] PLL1 clk: parent=%i mul=%i => rate=%u\n",
390 core
->parent
, pll_config
->pll1_mult
, rate
);
393 case CLK_TYPE_GEN3_PLL2
:
394 value
= readl(priv
->base
+ CPG_PLL2CR
);
395 mult
= (((value
>> 24) & 0x7f) + 1) * 2;
396 rate
= gen3_clk_get_rate(&parent
) * mult
;
397 debug("%s[%i] PLL2 clk: parent=%i mult=%u => rate=%u\n",
398 __func__
, __LINE__
, core
->parent
, mult
, rate
);
401 case CLK_TYPE_GEN3_PLL3
:
402 rate
= gen3_clk_get_rate(&parent
) * pll_config
->pll3_mult
;
403 debug("%s[%i] PLL3 clk: parent=%i mul=%i => rate=%u\n",
405 core
->parent
, pll_config
->pll3_mult
, rate
);
408 case CLK_TYPE_GEN3_PLL4
:
409 value
= readl(priv
->base
+ CPG_PLL4CR
);
410 mult
= (((value
>> 24) & 0x7f) + 1) * 2;
411 rate
= gen3_clk_get_rate(&parent
) * mult
;
412 debug("%s[%i] PLL4 clk: parent=%i mult=%u => rate=%u\n",
413 __func__
, __LINE__
, core
->parent
, mult
, rate
);
417 case CLK_TYPE_GEN3_PE
: /* FIXME */
418 rate
= (gen3_clk_get_rate(&parent
) * core
->mult
) / core
->div
;
419 debug("%s[%i] FIXED clk: parent=%i div=%i mul=%i => rate=%u\n",
421 core
->parent
, core
->mult
, core
->div
, rate
);
424 case CLK_TYPE_GEN3_SD
: /* FIXME */
425 value
= readl(priv
->base
+ core
->offset
);
426 value
&= CPG_SD_STP_MASK
| CPG_SD_FC_MASK
;
428 for (i
= 0; i
< ARRAY_SIZE(cpg_sd_div_table
); i
++) {
429 if (cpg_sd_div_table
[i
].val
!= value
)
432 rate
= gen3_clk_get_rate(&parent
) /
433 cpg_sd_div_table
[i
].div
;
434 debug("%s[%i] SD clk: parent=%i div=%i => rate=%u\n",
436 core
->parent
, cpg_sd_div_table
[i
].div
, rate
);
443 case CLK_TYPE_GEN3_RPC
:
444 rate
= gen3_clk_get_rate(&parent
);
446 value
= readl(priv
->base
+ core
->offset
);
448 prediv
= (value
>> CPG_RPC_PREDIV_OFFSET
) &
452 else if (prediv
== 3)
457 postdiv
= (value
>> CPG_RPC_POSTDIV_OFFSET
) &
458 CPG_RPC_POSTDIV_MASK
;
461 debug("%s[%i] RPC clk: parent=%i prediv=%i postdiv=%i => rate=%u\n",
463 core
->parent
, prediv
, postdiv
, rate
);
469 printf("%s[%i] unknown fail\n", __func__
, __LINE__
);
474 static ulong
gen3_clk_set_rate(struct clk
*clk
, ulong rate
)
476 return gen3_clk_get_rate(clk
);
479 static int gen3_clk_of_xlate(struct clk
*clk
, struct ofnode_phandle_args
*args
)
481 if (args
->args_count
!= 2) {
482 debug("Invaild args_count: %d\n", args
->args_count
);
486 clk
->id
= (args
->args
[0] << 16) | args
->args
[1];
491 const struct clk_ops gen3_clk_ops
= {
492 .enable
= gen3_clk_enable
,
493 .disable
= gen3_clk_disable
,
494 .get_rate
= gen3_clk_get_rate
,
495 .set_rate
= gen3_clk_set_rate
,
496 .of_xlate
= gen3_clk_of_xlate
,
499 int gen3_clk_probe(struct udevice
*dev
)
501 struct gen3_clk_priv
*priv
= dev_get_priv(dev
);
502 struct cpg_mssr_info
*info
=
503 (struct cpg_mssr_info
*)dev_get_driver_data(dev
);
508 priv
->base
= (struct gen3_base
*)devfdt_get_addr(dev
);
513 ret
= fdt_node_offset_by_compatible(gd
->fdt_blob
, -1, info
->reset_node
);
517 rst_base
= fdtdec_get_addr(gd
->fdt_blob
, ret
, "reg");
518 if (rst_base
== FDT_ADDR_T_NONE
)
521 cpg_mode
= readl(rst_base
+ CPG_RST_MODEMR
);
523 priv
->cpg_pll_config
= &cpg_pll_configs
[CPG_PLL_CONFIG_INDEX(cpg_mode
)];
524 if (!priv
->cpg_pll_config
->extal_div
)
527 ret
= clk_get_by_name(dev
, "extal", &priv
->clk_extal
);
531 if (info
->extalr_node
) {
532 ret
= clk_get_by_name(dev
, info
->extalr_node
, &priv
->clk_extalr
);
540 int gen3_clk_remove(struct udevice
*dev
)
542 struct gen3_clk_priv
*priv
= dev_get_priv(dev
);
543 struct cpg_mssr_info
*info
= priv
->info
;
547 clrbits_le32(TMU_BASE
+ TSTR0
, TSTR0_STR0
);
549 /* Stop module clock */
550 for (i
= 0; i
< info
->mstp_table_size
; i
++) {
551 clrsetbits_le32(priv
->base
+ SMSTPCR(i
),
552 info
->mstp_table
[i
].dis
,
553 info
->mstp_table
[i
].en
);
554 clrsetbits_le32(priv
->base
+ RMSTPCR(i
),
555 info
->mstp_table
[i
].dis
, 0x0);