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_D DDIV_PACK(0x204, 4, 2)
27#define DIV_E DDIV_PACK(0x204, 8, 1)
28#define DIV_W DDIV_PACK(0x328, 0, 3)
29
30#define SEL_B SEL_PLL_PACK(0x214, 0, 1)
31#define SEL_CSI0 SEL_PLL_PACK(0x330, 0, 1)
32#define SEL_CSI4 SEL_PLL_PACK(0x330, 4, 1)
33#define SEL_D SEL_PLL_PACK(0x214, 1, 1)
34#define SEL_E SEL_PLL_PACK(0x214, 2, 1)
35#define SEL_SDI SEL_PLL_PACK(0x300, 0, 1)
36#define SEL_W0 SEL_PLL_PACK(0x32C, 0, 1)
37
38enum clk_ids {
39 /* Core Clock Outputs exported to DT */
40 LAST_DT_CORE_CLK = 0,
41
42 /* External Input Clocks */
43 CLK_EXTAL,
44
45 /* Internal Core Clocks */
46 CLK_MAIN,
47 CLK_MAIN_24,
48 CLK_MAIN_2,
49 CLK_PLL1,
50 CLK_PLL2,
51 CLK_PLL2_800,
52 CLK_PLL2_400,
53 CLK_PLL2_200,
54 CLK_PLL2_100,
55 CLK_PLL4,
56 CLK_DIV_A,
57 CLK_DIV_B,
58 CLK_DIV_D,
59 CLK_DIV_E,
60 CLK_DIV_W,
61 CLK_SEL_B,
62 CLK_SEL_B_D2,
63 CLK_SEL_CSI0,
64 CLK_SEL_CSI4,
65 CLK_SEL_D,
66 CLK_SEL_E,
67 CLK_SEL_SDI,
68 CLK_SEL_W0,
69
70 /* Module Clocks */
71 MOD_CLK_BASE
72};
73
74/* Divider tables */
75static const struct clk_div_table dtable_diva[] = {
76 {0, 1},
77 {1, 2},
78 {2, 3},
79 {3, 4},
80 {4, 6},
81 {5, 12},
82 {6, 24},
83 {0, 0},
84};
85
86static const struct clk_div_table dtable_divb[] = {
87 {0, 1},
88 {1, 2},
89 {2, 4},
90 {3, 8},
91 {0, 0},
92};
93
94static const struct clk_div_table dtable_divd[] = {
95 {0, 1},
96 {1, 2},
97 {2, 4},
98 {0, 0},
99};
100
101
102static const struct clk_div_table dtable_divw[] = {
103 {0, 6},
104 {1, 7},
105 {2, 8},
106 {3, 9},
107 {4, 10},
108 {5, 11},
109 {6, 12},
110 {0, 0},
111};
112
113/* Mux clock tables */
114static const char * const sel_b[] = { ".main", ".divb" };
115static const char * const sel_csi[] = { ".main_24", ".main" };
116static const char * const sel_d[] = { ".main", ".divd" };
117static const char * const sel_e[] = { ".main", ".dive" };
118static const char * const sel_w[] = { ".main", ".divw" };
119static const char * const sel_sdi[] = { ".main", ".pll2_200" };
120
121static const struct cpg_core_clk r9a09g011_core_clks[] __initconst = {
122 /* External Clock Inputs */
123 DEF_INPUT("extal", CLK_EXTAL),
124
125 /* Internal Core Clocks */
126 DEF_FIXED(".main", CLK_MAIN, CLK_EXTAL, 1, 1),
127 DEF_FIXED(".main_24", CLK_MAIN_24, CLK_MAIN, 1, 2),
128 DEF_FIXED(".main_2", CLK_MAIN_2, CLK_MAIN, 1, 24),
129 DEF_FIXED(".pll1", CLK_PLL1, CLK_MAIN_2, 498, 1),
130 DEF_FIXED(".pll2", CLK_PLL2, CLK_MAIN_2, 800, 1),
131 DEF_FIXED(".pll2_800", CLK_PLL2_800, CLK_PLL2, 1, 2),
132 DEF_FIXED(".pll2_400", CLK_PLL2_400, CLK_PLL2_800, 1, 2),
133 DEF_FIXED(".pll2_200", CLK_PLL2_200, CLK_PLL2_800, 1, 4),
134 DEF_FIXED(".pll2_100", CLK_PLL2_100, CLK_PLL2_800, 1, 8),
135 DEF_SAMPLL(".pll4", CLK_PLL4, CLK_MAIN_2, PLL4_CONF),
136
137 DEF_DIV_RO(".diva", CLK_DIV_A, CLK_PLL1, DIV_A, dtable_diva),
138 DEF_DIV_RO(".divb", CLK_DIV_B, CLK_PLL2_400, DIV_B, dtable_divb),
139 DEF_DIV_RO(".divd", CLK_DIV_D, CLK_PLL2_200, DIV_D, dtable_divd),
140 DEF_DIV_RO(".dive", CLK_DIV_E, CLK_PLL2_100, DIV_E, NULL),
141 DEF_DIV_RO(".divw", CLK_DIV_W, CLK_PLL4, DIV_W, dtable_divw),
142
143 DEF_MUX_RO(".selb", CLK_SEL_B, SEL_B, sel_b),
144 DEF_MUX_RO(".seld", CLK_SEL_D, SEL_D, sel_d),
145 DEF_MUX_RO(".sele", CLK_SEL_E, SEL_E, sel_e),
146 DEF_MUX(".selsdi", CLK_SEL_SDI, SEL_SDI, sel_sdi),
147 DEF_MUX(".selcsi0", CLK_SEL_CSI0, SEL_CSI0, sel_csi),
148 DEF_MUX(".selcsi4", CLK_SEL_CSI4, SEL_CSI4, sel_csi),
149 DEF_MUX(".selw0", CLK_SEL_W0, SEL_W0, sel_w),
150
151 DEF_FIXED(".selb_d2", CLK_SEL_B_D2, CLK_SEL_B, 1, 2),
152};
153
154static const struct rzg2l_mod_clk r9a09g011_mod_clks[] __initconst = {
155 DEF_MOD("pfc", R9A09G011_PFC_PCLK, CLK_MAIN, 0x400, 2),
156 DEF_MOD("gic", R9A09G011_GIC_CLK, CLK_SEL_B_D2, 0x400, 5),
157 DEF_MOD("sdi0_aclk", R9A09G011_SDI0_ACLK, CLK_SEL_D, 0x408, 0),
158 DEF_MOD("sdi0_imclk", R9A09G011_SDI0_IMCLK, CLK_SEL_SDI, 0x408, 1),
159 DEF_MOD("sdi0_imclk2", R9A09G011_SDI0_IMCLK2, CLK_SEL_SDI, 0x408, 2),
160 DEF_MOD("sdi0_clk_hs", R9A09G011_SDI0_CLK_HS, CLK_PLL2_800, 0x408, 3),
161 DEF_MOD("sdi1_aclk", R9A09G011_SDI1_ACLK, CLK_SEL_D, 0x408, 4),
162 DEF_MOD("sdi1_imclk", R9A09G011_SDI1_IMCLK, CLK_SEL_SDI, 0x408, 5),
163 DEF_MOD("sdi1_imclk2", R9A09G011_SDI1_IMCLK2, CLK_SEL_SDI, 0x408, 6),
164 DEF_MOD("sdi1_clk_hs", R9A09G011_SDI1_CLK_HS, CLK_PLL2_800, 0x408, 7),
165 DEF_MOD("emm_aclk", R9A09G011_EMM_ACLK, CLK_SEL_D, 0x408, 8),
166 DEF_MOD("emm_imclk", R9A09G011_EMM_IMCLK, CLK_SEL_SDI, 0x408, 9),
167 DEF_MOD("emm_imclk2", R9A09G011_EMM_IMCLK2, CLK_SEL_SDI, 0x408, 10),
168 DEF_MOD("emm_clk_hs", R9A09G011_EMM_CLK_HS, CLK_PLL2_800, 0x408, 11),
169 DEF_COUPLED("eth_axi", R9A09G011_ETH0_CLK_AXI, CLK_PLL2_200, 0x40c, 8),
170 DEF_COUPLED("eth_chi", R9A09G011_ETH0_CLK_CHI, CLK_PLL2_100, 0x40c, 8),
171 DEF_MOD("eth_clk_gptp", R9A09G011_ETH0_GPTP_EXT, CLK_PLL2_100, 0x40c, 9),
172 DEF_MOD("usb_aclk_h", R9A09G011_USB_ACLK_H, CLK_SEL_D, 0x40c, 4),
173 DEF_MOD("usb_aclk_p", R9A09G011_USB_ACLK_P, CLK_SEL_D, 0x40c, 5),
174 DEF_MOD("usb_pclk", R9A09G011_USB_PCLK, CLK_SEL_E, 0x40c, 6),
175 DEF_MOD("syc_cnt_clk", R9A09G011_SYC_CNT_CLK, CLK_MAIN_24, 0x41c, 12),
176 DEF_MOD("iic_pclk0", R9A09G011_IIC_PCLK0, CLK_SEL_E, 0x420, 12),
177 DEF_MOD("cperi_grpb", R9A09G011_CPERI_GRPB_PCLK, CLK_SEL_E, 0x424, 0),
178 DEF_MOD("tim_clk_8", R9A09G011_TIM8_CLK, CLK_MAIN_2, 0x424, 4),
179 DEF_MOD("tim_clk_9", R9A09G011_TIM9_CLK, CLK_MAIN_2, 0x424, 5),
180 DEF_MOD("tim_clk_10", R9A09G011_TIM10_CLK, CLK_MAIN_2, 0x424, 6),
181 DEF_MOD("tim_clk_11", R9A09G011_TIM11_CLK, CLK_MAIN_2, 0x424, 7),
182 DEF_MOD("tim_clk_12", R9A09G011_TIM12_CLK, CLK_MAIN_2, 0x424, 8),
183 DEF_MOD("tim_clk_13", R9A09G011_TIM13_CLK, CLK_MAIN_2, 0x424, 9),
184 DEF_MOD("tim_clk_14", R9A09G011_TIM14_CLK, CLK_MAIN_2, 0x424, 10),
185 DEF_MOD("tim_clk_15", R9A09G011_TIM15_CLK, CLK_MAIN_2, 0x424, 11),
186 DEF_MOD("iic_pclk1", R9A09G011_IIC_PCLK1, CLK_SEL_E, 0x424, 12),
187 DEF_MOD("cperi_grpc", R9A09G011_CPERI_GRPC_PCLK, CLK_SEL_E, 0x428, 0),
188 DEF_MOD("tim_clk_16", R9A09G011_TIM16_CLK, CLK_MAIN_2, 0x428, 4),
189 DEF_MOD("tim_clk_17", R9A09G011_TIM17_CLK, CLK_MAIN_2, 0x428, 5),
190 DEF_MOD("tim_clk_18", R9A09G011_TIM18_CLK, CLK_MAIN_2, 0x428, 6),
191 DEF_MOD("tim_clk_19", R9A09G011_TIM19_CLK, CLK_MAIN_2, 0x428, 7),
192 DEF_MOD("tim_clk_20", R9A09G011_TIM20_CLK, CLK_MAIN_2, 0x428, 8),
193 DEF_MOD("tim_clk_21", R9A09G011_TIM21_CLK, CLK_MAIN_2, 0x428, 9),
194 DEF_MOD("tim_clk_22", R9A09G011_TIM22_CLK, CLK_MAIN_2, 0x428, 10),
195 DEF_MOD("tim_clk_23", R9A09G011_TIM23_CLK, CLK_MAIN_2, 0x428, 11),
196 DEF_MOD("wdt0_pclk", R9A09G011_WDT0_PCLK, CLK_SEL_E, 0x428, 12),
197 DEF_MOD("wdt0_clk", R9A09G011_WDT0_CLK, CLK_MAIN, 0x428, 13),
198 DEF_MOD("cperi_grpf", R9A09G011_CPERI_GRPF_PCLK, CLK_SEL_E, 0x434, 0),
199 DEF_MOD("pwm8_clk", R9A09G011_PWM8_CLK, CLK_MAIN, 0x434, 4),
200 DEF_MOD("pwm9_clk", R9A09G011_PWM9_CLK, CLK_MAIN, 0x434, 5),
201 DEF_MOD("pwm10_clk", R9A09G011_PWM10_CLK, CLK_MAIN, 0x434, 6),
202 DEF_MOD("pwm11_clk", R9A09G011_PWM11_CLK, CLK_MAIN, 0x434, 7),
203 DEF_MOD("pwm12_clk", R9A09G011_PWM12_CLK, CLK_MAIN, 0x434, 8),
204 DEF_MOD("pwm13_clk", R9A09G011_PWM13_CLK, CLK_MAIN, 0x434, 9),
205 DEF_MOD("pwm14_clk", R9A09G011_PWM14_CLK, CLK_MAIN, 0x434, 10),
206 DEF_MOD("cperi_grpg", R9A09G011_CPERI_GRPG_PCLK, CLK_SEL_E, 0x438, 0),
207 DEF_MOD("cperi_grph", R9A09G011_CPERI_GRPH_PCLK, CLK_SEL_E, 0x438, 1),
208 DEF_MOD("urt_pclk", R9A09G011_URT_PCLK, CLK_SEL_E, 0x438, 4),
209 DEF_MOD("urt0_clk", R9A09G011_URT0_CLK, CLK_SEL_W0, 0x438, 5),
210 DEF_MOD("csi0_clk", R9A09G011_CSI0_CLK, CLK_SEL_CSI0, 0x438, 8),
211 DEF_MOD("csi4_clk", R9A09G011_CSI4_CLK, CLK_SEL_CSI4, 0x438, 12),
212 DEF_MOD("ca53", R9A09G011_CA53_CLK, CLK_DIV_A, 0x448, 0),
213};
214
215static const struct rzg2l_reset r9a09g011_resets[] = {
216 DEF_RST(R9A09G011_PFC_PRESETN, 0x600, 2),
217 DEF_RST_MON(R9A09G011_SDI0_IXRST, 0x608, 0, 6),
218 DEF_RST_MON(R9A09G011_SDI1_IXRST, 0x608, 1, 7),
219 DEF_RST_MON(R9A09G011_EMM_IXRST, 0x608, 2, 8),
220 DEF_RST(R9A09G011_USB_PRESET_N, 0x608, 7),
221 DEF_RST(R9A09G011_USB_DRD_RESET, 0x608, 8),
222 DEF_RST(R9A09G011_USB_ARESETN_P, 0x608, 9),
223 DEF_RST(R9A09G011_USB_ARESETN_H, 0x608, 10),
224 DEF_RST_MON(R9A09G011_ETH0_RST_HW_N, 0x608, 11, 11),
225 DEF_RST_MON(R9A09G011_SYC_RST_N, 0x610, 9, 13),
226 DEF_RST(R9A09G011_TIM_GPB_PRESETN, 0x614, 1),
227 DEF_RST(R9A09G011_TIM_GPC_PRESETN, 0x614, 2),
228 DEF_RST_MON(R9A09G011_PWM_GPF_PRESETN, 0x614, 5, 23),
229 DEF_RST_MON(R9A09G011_CSI_GPG_PRESETN, 0x614, 6, 22),
230 DEF_RST_MON(R9A09G011_CSI_GPH_PRESETN, 0x614, 7, 23),
231 DEF_RST(R9A09G011_IIC_GPA_PRESETN, 0x614, 8),
232 DEF_RST(R9A09G011_IIC_GPB_PRESETN, 0x614, 9),
233 DEF_RST_MON(R9A09G011_WDT0_PRESETN, 0x614, 12, 19),
234};
235
236static const unsigned int r9a09g011_crit_mod_clks[] __initconst = {
237 MOD_CLK_BASE + R9A09G011_CA53_CLK,
238 MOD_CLK_BASE + R9A09G011_CPERI_GRPB_PCLK,
239 MOD_CLK_BASE + R9A09G011_CPERI_GRPC_PCLK,
240 MOD_CLK_BASE + R9A09G011_CPERI_GRPF_PCLK,
241 MOD_CLK_BASE + R9A09G011_CPERI_GRPG_PCLK,
242 MOD_CLK_BASE + R9A09G011_CPERI_GRPH_PCLK,
243 MOD_CLK_BASE + R9A09G011_GIC_CLK,
244 MOD_CLK_BASE + R9A09G011_SYC_CNT_CLK,
245 MOD_CLK_BASE + R9A09G011_URT_PCLK,
246};
247
248const struct rzg2l_cpg_info r9a09g011_cpg_info = {
249 /* Core Clocks */
250 .core_clks = r9a09g011_core_clks,
251 .num_core_clks = ARRAY_SIZE(r9a09g011_core_clks),
252 .last_dt_core_clk = LAST_DT_CORE_CLK,
253 .num_total_core_clks = MOD_CLK_BASE,
254
255 /* Critical Module Clocks */
256 .crit_mod_clks = r9a09g011_crit_mod_clks,
257 .num_crit_mod_clks = ARRAY_SIZE(r9a09g011_crit_mod_clks),
258
259 /* Module Clocks */
260 .mod_clks = r9a09g011_mod_clks,
261 .num_mod_clks = ARRAY_SIZE(r9a09g011_mod_clks),
262 .num_hw_mod_clks = R9A09G011_CA53_CLK + 1,
263
264 /* Resets */
265 .resets = r9a09g011_resets,
266 .num_resets = ARRAY_SIZE(r9a09g011_resets),
267
268 .has_clk_mon_regs = false,
269};
270

source code of linux/drivers/clk/renesas/r9a09g011-cpg.c