1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * RZ/V2M Clock Pulse Generator / Module Standby and Software Reset
4  *
5  * Copyright (C) 2022 Renesas Electronics Corp.
6  *
7  * Based on r9a07g044-cpg.c
8  */
9 
10 #include <linux/clk-provider.h>
11 #include <linux/device.h>
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 
15 #include <dt-bindings/clock/r9a09g011-cpg.h>
16 
17 #include "rzg2l-cpg.h"
18 
19 #define RZV2M_SAMPLL4_CLK1	0x104
20 #define RZV2M_SAMPLL4_CLK2	0x108
21 
22 #define PLL4_CONF	(RZV2M_SAMPLL4_CLK1 << 22 | RZV2M_SAMPLL4_CLK2 << 12)
23 
24 #define DIV_A		DDIV_PACK(0x200, 0, 3)
25 #define DIV_B		DDIV_PACK(0x204, 0, 2)
26 #define DIV_E		DDIV_PACK(0x204, 8, 1)
27 #define DIV_W		DDIV_PACK(0x328, 0, 3)
28 
29 #define SEL_B		SEL_PLL_PACK(0x214, 0, 1)
30 #define SEL_E		SEL_PLL_PACK(0x214, 2, 1)
31 #define SEL_W0		SEL_PLL_PACK(0x32C, 0, 1)
32 
33 enum clk_ids {
34 	/* Core Clock Outputs exported to DT */
35 	LAST_DT_CORE_CLK = 0,
36 
37 	/* External Input Clocks */
38 	CLK_EXTAL,
39 
40 	/* Internal Core Clocks */
41 	CLK_MAIN,
42 	CLK_MAIN_24,
43 	CLK_MAIN_2,
44 	CLK_PLL1,
45 	CLK_PLL2,
46 	CLK_PLL2_800,
47 	CLK_PLL2_400,
48 	CLK_PLL2_200,
49 	CLK_PLL2_100,
50 	CLK_PLL4,
51 	CLK_DIV_A,
52 	CLK_DIV_B,
53 	CLK_DIV_E,
54 	CLK_DIV_W,
55 	CLK_SEL_B,
56 	CLK_SEL_B_D2,
57 	CLK_SEL_E,
58 	CLK_SEL_W0,
59 
60 	/* Module Clocks */
61 	MOD_CLK_BASE
62 };
63 
64 /* Divider tables */
65 static const struct clk_div_table dtable_diva[] = {
66 	{0, 1},
67 	{1, 2},
68 	{2, 3},
69 	{3, 4},
70 	{4, 6},
71 	{5, 12},
72 	{6, 24},
73 	{0, 0},
74 };
75 
76 static const struct clk_div_table dtable_divb[] = {
77 	{0, 1},
78 	{1, 2},
79 	{2, 4},
80 	{3, 8},
81 	{0, 0},
82 };
83 
84 static const struct clk_div_table dtable_divw[] = {
85 	{0, 6},
86 	{1, 7},
87 	{2, 8},
88 	{3, 9},
89 	{4, 10},
90 	{5, 11},
91 	{6, 12},
92 	{0, 0},
93 };
94 
95 /* Mux clock tables */
96 static const char * const sel_b[] = { ".main", ".divb" };
97 static const char * const sel_e[] = { ".main", ".dive" };
98 static const char * const sel_w[] = { ".main", ".divw" };
99 
100 static const struct cpg_core_clk r9a09g011_core_clks[] __initconst = {
101 	/* External Clock Inputs */
102 	DEF_INPUT("extal",	CLK_EXTAL),
103 
104 	/* Internal Core Clocks */
105 	DEF_FIXED(".main",	CLK_MAIN,	CLK_EXTAL,	1,	1),
106 	DEF_FIXED(".main_24",	CLK_MAIN_24,	CLK_MAIN,	1,	2),
107 	DEF_FIXED(".main_2",	CLK_MAIN_2,	CLK_MAIN,	1,	24),
108 	DEF_FIXED(".pll1",	CLK_PLL1,	CLK_MAIN_2,	498,	1),
109 	DEF_FIXED(".pll2",	CLK_PLL2,	CLK_MAIN_2,	800,	1),
110 	DEF_FIXED(".pll2_800",	CLK_PLL2_800,	CLK_PLL2,	1,	2),
111 	DEF_FIXED(".pll2_400",	CLK_PLL2_400,	CLK_PLL2_800,	1,	2),
112 	DEF_FIXED(".pll2_200",	CLK_PLL2_200,	CLK_PLL2_800,	1,	4),
113 	DEF_FIXED(".pll2_100",	CLK_PLL2_100,	CLK_PLL2_800,	1,	8),
114 	DEF_SAMPLL(".pll4",	CLK_PLL4,	CLK_MAIN_2,	PLL4_CONF),
115 
116 	DEF_DIV_RO(".diva",	CLK_DIV_A,	CLK_PLL1,	DIV_A,	dtable_diva),
117 	DEF_DIV_RO(".divb",	CLK_DIV_B,	CLK_PLL2_400,	DIV_B,	dtable_divb),
118 	DEF_DIV_RO(".dive",	CLK_DIV_E,	CLK_PLL2_100,	DIV_E,	NULL),
119 	DEF_DIV_RO(".divw",	CLK_DIV_W,	CLK_PLL4,	DIV_W,	dtable_divw),
120 
121 	DEF_MUX_RO(".selb",	CLK_SEL_B,	SEL_B,		sel_b),
122 	DEF_MUX_RO(".sele",	CLK_SEL_E,	SEL_E,		sel_e),
123 	DEF_MUX(".selw0",	CLK_SEL_W0,	SEL_W0,		sel_w),
124 
125 	DEF_FIXED(".selb_d2",	CLK_SEL_B_D2,	CLK_SEL_B,	1,	2),
126 };
127 
128 static const struct rzg2l_mod_clk r9a09g011_mod_clks[] __initconst = {
129 	DEF_MOD("pfc",		R9A09G011_PFC_PCLK,	 CLK_MAIN,     0x400, 2),
130 	DEF_MOD("gic",		R9A09G011_GIC_CLK,	 CLK_SEL_B_D2, 0x400, 5),
131 	DEF_COUPLED("eth_axi",	R9A09G011_ETH0_CLK_AXI,	 CLK_PLL2_200, 0x40c, 8),
132 	DEF_COUPLED("eth_chi",	R9A09G011_ETH0_CLK_CHI,	 CLK_PLL2_100, 0x40c, 8),
133 	DEF_MOD("eth_clk_gptp",	R9A09G011_ETH0_GPTP_EXT, CLK_PLL2_100, 0x40c, 9),
134 	DEF_MOD("syc_cnt_clk",	R9A09G011_SYC_CNT_CLK,	 CLK_MAIN_24,  0x41c, 12),
135 	DEF_MOD("wdt0_pclk",	R9A09G011_WDT0_PCLK,	 CLK_SEL_E,    0x428, 12),
136 	DEF_MOD("wdt0_clk",	R9A09G011_WDT0_CLK,	 CLK_MAIN,     0x428, 13),
137 	DEF_MOD("urt_pclk",	R9A09G011_URT_PCLK,	 CLK_SEL_E,    0x438, 4),
138 	DEF_MOD("urt0_clk",	R9A09G011_URT0_CLK,	 CLK_SEL_W0,   0x438, 5),
139 	DEF_MOD("ca53",		R9A09G011_CA53_CLK,	 CLK_DIV_A,    0x448, 0),
140 };
141 
142 static const struct rzg2l_reset r9a09g011_resets[] = {
143 	DEF_RST(R9A09G011_PFC_PRESETN,		0x600, 2),
144 	DEF_RST_MON(R9A09G011_ETH0_RST_HW_N,	0x608, 11, 11),
145 	DEF_RST_MON(R9A09G011_SYC_RST_N,	0x610, 9,  13),
146 	DEF_RST_MON(R9A09G011_WDT0_PRESETN,	0x614, 12, 19),
147 };
148 
149 static const unsigned int r9a09g011_crit_mod_clks[] __initconst = {
150 	MOD_CLK_BASE + R9A09G011_CA53_CLK,
151 	MOD_CLK_BASE + R9A09G011_GIC_CLK,
152 	MOD_CLK_BASE + R9A09G011_SYC_CNT_CLK,
153 	MOD_CLK_BASE + R9A09G011_URT_PCLK,
154 };
155 
156 const struct rzg2l_cpg_info r9a09g011_cpg_info = {
157 	/* Core Clocks */
158 	.core_clks = r9a09g011_core_clks,
159 	.num_core_clks = ARRAY_SIZE(r9a09g011_core_clks),
160 	.last_dt_core_clk = LAST_DT_CORE_CLK,
161 	.num_total_core_clks = MOD_CLK_BASE,
162 
163 	/* Critical Module Clocks */
164 	.crit_mod_clks = r9a09g011_crit_mod_clks,
165 	.num_crit_mod_clks = ARRAY_SIZE(r9a09g011_crit_mod_clks),
166 
167 	/* Module Clocks */
168 	.mod_clks = r9a09g011_mod_clks,
169 	.num_mod_clks = ARRAY_SIZE(r9a09g011_mod_clks),
170 	.num_hw_mod_clks = R9A09G011_CA53_CLK + 1,
171 
172 	/* Resets */
173 	.resets = r9a09g011_resets,
174 	.num_resets = ARRAY_SIZE(r9a09g011_resets),
175 
176 	.has_clk_mon_regs = false,
177 };
178