1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/clk.h>
22#include <linux/clk-provider.h>
23#include <linux/clk/zynqmp.h>
24#include <linux/io.h>
25#include <linux/of.h>
26#include <linux/of_address.h>
27#include <linux/slab.h>
28#include <linux/string.h>
29#include <linux/soc/xilinx/zynqmp/pm.h>
30
31static const resource_size_t zynqmp_crf_apb_clkc_base = 0xfd1a0020;
32static const resource_size_t zynqmp_crl_apb_clkc_base = 0xff5e0020;
33static const resource_size_t zynqmp_iou_clkc_base = 0xff180000;
34
35
36#define CRF_APB_APLL_CTRL (zynqmp_crf_apb_clkc_base + 0x00)
37#define CRF_APB_DPLL_CTRL (zynqmp_crf_apb_clkc_base + 0x0c)
38#define CRF_APB_VPLL_CTRL (zynqmp_crf_apb_clkc_base + 0x18)
39#define CRF_APB_PLL_STATUS (zynqmp_crf_apb_clkc_base + 0x24)
40#define CRF_APB_APLL_TO_LPD_CTRL (zynqmp_crf_apb_clkc_base + 0x28)
41#define CRF_APB_DPLL_TO_LPD_CTRL (zynqmp_crf_apb_clkc_base + 0x2c)
42#define CRF_APB_VPLL_TO_LPD_CTRL (zynqmp_crf_apb_clkc_base + 0x30)
43
44#define CRF_APB_ACPU_CTRL (zynqmp_crf_apb_clkc_base + 0x40)
45#define CRF_APB_DBG_TRACE_CTRL (zynqmp_crf_apb_clkc_base + 0x44)
46#define CRF_APB_DBG_FPD_CTRL (zynqmp_crf_apb_clkc_base + 0x48)
47#define CRF_APB_DP_VIDEO_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x50)
48#define CRF_APB_DP_AUDIO_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x54)
49#define CRF_APB_DP_STC_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x5c)
50#define CRF_APB_DDR_CTRL (zynqmp_crf_apb_clkc_base + 0x60)
51#define CRF_APB_GPU_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x64)
52#define CRF_APB_SATA_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x80)
53#define CRF_APB_PCIE_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x94)
54#define CRF_APB_GDMA_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x98)
55#define CRF_APB_DPDMA_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x9c)
56#define CRF_APB_TOPSW_MAIN_CTRL (zynqmp_crf_apb_clkc_base + 0xa0)
57#define CRF_APB_TOPSW_LSBUS_CTRL (zynqmp_crf_apb_clkc_base + 0xa4)
58#define CRF_APB_GTGREF0_REF_CTRL (zynqmp_crf_apb_clkc_base + 0xa8)
59#define CRF_APB_DBG_TSTMP_CTRL (zynqmp_crf_apb_clkc_base + 0xd8)
60
61
62#define CRL_APB_IOPLL_CTRL (zynqmp_crl_apb_clkc_base + 0x00)
63#define CRL_APB_RPLL_CTRL (zynqmp_crl_apb_clkc_base + 0x10)
64#define CRL_APB_PLL_STATUS (zynqmp_crl_apb_clkc_base + 0x20)
65#define CRL_APB_IOPLL_TO_FPD_CTRL (zynqmp_crl_apb_clkc_base + 0x24)
66#define CRL_APB_RPLL_TO_FPD_CTRL (zynqmp_crl_apb_clkc_base + 0x28)
67
68#define CRL_APB_USB3_DUAL_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x2c)
69#define CRL_APB_GEM0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x30)
70#define CRL_APB_GEM1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x34)
71#define CRL_APB_GEM2_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x38)
72#define CRL_APB_GEM3_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x3c)
73#define CRL_APB_USB0_BUS_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x40)
74#define CRL_APB_USB1_BUS_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x44)
75#define CRL_APB_QSPI_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x48)
76#define CRL_APB_SDIO0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x4c)
77#define CRL_APB_SDIO1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x50)
78#define CRL_APB_UART0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x54)
79#define CRL_APB_UART1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x58)
80#define CRL_APB_SPI0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x5c)
81#define CRL_APB_SPI1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x60)
82#define CRL_APB_CAN0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x64)
83#define CRL_APB_CAN1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x68)
84#define CRL_APB_CPU_R5_CTRL (zynqmp_crl_apb_clkc_base + 0x70)
85#define CRL_APB_IOU_SWITCH_CTRL (zynqmp_crl_apb_clkc_base + 0x7c)
86#define CRL_APB_CSU_PLL_CTRL (zynqmp_crl_apb_clkc_base + 0x80)
87#define CRL_APB_PCAP_CTRL (zynqmp_crl_apb_clkc_base + 0x84)
88#define CRL_APB_LPD_SWITCH_CTRL (zynqmp_crl_apb_clkc_base + 0x88)
89#define CRL_APB_LPD_LSBUS_CTRL (zynqmp_crl_apb_clkc_base + 0x8c)
90#define CRL_APB_DBG_LPD_CTRL (zynqmp_crl_apb_clkc_base + 0x90)
91#define CRL_APB_NAND_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x94)
92#define CRL_APB_ADMA_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x98)
93#define CRL_APB_PL0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xa0)
94#define CRL_APB_PL1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xa4)
95#define CRL_APB_PL2_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xa8)
96#define CRL_APB_PL3_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xac)
97#define CRL_APB_PL0_THR_CNT (zynqmp_crl_apb_clkc_base + 0xb4)
98#define CRL_APB_PL1_THR_CNT (zynqmp_crl_apb_clkc_base + 0xbc)
99#define CRL_APB_PL2_THR_CNT (zynqmp_crl_apb_clkc_base + 0xc4)
100#define CRL_APB_PL3_THR_CNT (zynqmp_crl_apb_clkc_base + 0xdc)
101#define CRL_APB_GEM_TSU_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xe0)
102#define CRL_APB_DLL_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xe4)
103#define CRL_APB_AMS_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xe8)
104#define CRL_APB_I2C0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x100)
105#define CRL_APB_I2C1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x104)
106#define CRL_APB_TIMESTAMP_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x108)
107#define IOU_SLCR_GEM_CLK_CTRL (zynqmp_iou_clkc_base + 0x308)
108#define IOU_SLCR_CAN_MIO_CTRL (zynqmp_iou_clkc_base + 0x304)
109#define IOU_SLCR_WDT_CLK_SEL (zynqmp_iou_clkc_base + 0x300)
110
111#define NUM_MIO_PINS 77
112
113enum zynqmp_clk {
114 iopll, rpll,
115 apll, dpll, vpll,
116 iopll_to_fpd, rpll_to_fpd, apll_to_lpd, dpll_to_lpd, vpll_to_lpd,
117 acpu, acpu_half,
118 dbg_fpd, dbg_lpd, dbg_trace, dbg_tstmp,
119 dp_video_ref, dp_audio_ref,
120 dp_stc_ref, gdma_ref, dpdma_ref,
121 ddr_ref, sata_ref, pcie_ref,
122 gpu_ref, gpu_pp0_ref, gpu_pp1_ref,
123 topsw_main, topsw_lsbus,
124 gtgref0_ref,
125 lpd_switch, lpd_lsbus,
126 usb0_bus_ref, usb1_bus_ref, usb3_dual_ref, usb0, usb1,
127 cpu_r5, cpu_r5_core,
128 csu_spb, csu_pll, pcap,
129 iou_switch,
130 gem_tsu_ref, gem_tsu,
131 gem0_ref, gem1_ref, gem2_ref, gem3_ref,
132 gem0_rx, gem1_rx, gem2_rx, gem3_rx,
133 qspi_ref,
134 sdio0_ref, sdio1_ref,
135 uart0_ref, uart1_ref,
136 spi0_ref, spi1_ref,
137 nand_ref,
138 i2c0_ref, i2c1_ref, can0_ref, can1_ref, can0, can1,
139 dll_ref,
140 adma_ref,
141 timestamp_ref,
142 ams_ref,
143 pl0, pl1, pl2, pl3,
144 wdt,
145 clk_max,
146};
147
148static struct clk *clks[clk_max];
149static struct clk_onecell_data clk_data;
150
151
152static const char *can0_mio_mux2_parents[] __initconst = {"can0_ref",
153 "can0_mio_mux"};
154static const char *can1_mio_mux2_parents[] __initconst = {"can1_ref",
155 "can1_mio_mux"};
156static const char *usb0_mio_mux_parents[] __initconst = {"usb0_bus_ref",
157 "usb0_mio_ulpi_clk"};
158static const char *usb1_mio_mux_parents[] __initconst = {"usb1_bus_ref",
159 "usb1_mio_ulpi_clk"};
160static const char *swdt_ext_clk_input_names[] __initconst = {"swdt0_ext_clk",
161 "swdt1_ext_clk"};
162static const char *gem0_tx_mux_parents[] __initconst = {"gem0_ref_div1",
163 "dummy_name"};
164static const char *gem1_tx_mux_parents[] __initconst = {"gem1_ref_div1",
165 "dummy_name"};
166static const char *gem2_tx_mux_parents[] __initconst = {"gem2_ref_div1",
167 "dummy_name"};
168static const char *gem3_tx_mux_parents[] __initconst = {"gem3_ref_div1",
169 "dummy_name"};
170static const char *gem0_emio_input_names[] __initconst = {"gem0_emio_clk"};
171static const char *gem1_emio_input_names[] __initconst = {"gem1_emio_clk"};
172static const char *gem2_emio_input_names[] __initconst = {"gem2_emio_clk"};
173static const char *gem3_emio_input_names[] __initconst = {"gem3_emio_clk"};
174
175static const char *timestamp_ref_parents[8];
176static const char *pll_src_mux_parents[8];
177static const char *input_clks[5];
178static const char *clk_output_name[clk_max];
179static const char *acpu_parents[4];
180static const char *ddr_parents[2];
181static const char *wdt_ext_clk_mux_parents[3];
182static const char *periph_parents[clk_max][4];
183static const char *gem_tsu_mux_parents[4];
184static const char *can_mio_mux_parents[NUM_MIO_PINS];
185static const char *dll_ref_parents[2];
186static const char *dummy_nm = "dummy_name";
187
188
189
190
191
192
193
194
195static void __init zynqmp_clk_register_pl_clk(enum zynqmp_clk pl_clk,
196 const char *clk_name, resource_size_t *pl_clk_ctrl_reg,
197 const char **parents)
198{
199 struct clk *clk;
200 char *mux_name;
201 char *div0_name;
202 char *div1_name;
203
204 mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name);
205 if (!mux_name)
206 goto err_mux_name;
207 div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name);
208 if (!div0_name)
209 goto err_div0_name;
210 div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name);
211 if (!div1_name)
212 goto err_div1_name;
213
214 clk = zynqmp_clk_register_mux(NULL, mux_name, parents, 4,
215 CLK_SET_RATE_NO_REPARENT, pl_clk_ctrl_reg, 0, 3, 0);
216
217 clk = zynqmp_clk_register_divider(NULL, div0_name, mux_name, 0,
218 pl_clk_ctrl_reg, 8, 6,
219 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
220
221 clk = zynqmp_clk_register_divider(NULL, div1_name, div0_name,
222 CLK_SET_RATE_PARENT, pl_clk_ctrl_reg, 16, 6,
223 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
224
225 clks[pl_clk] = zynqmp_clk_register_gate(NULL, clk_name, div1_name,
226 CLK_SET_RATE_PARENT, pl_clk_ctrl_reg, 24, 0);
227
228 kfree(mux_name);
229 kfree(div0_name);
230 kfree(div1_name);
231
232 return;
233
234err_div1_name:
235 kfree(div0_name);
236err_div0_name:
237 kfree(mux_name);
238err_mux_name:
239 clks[pl_clk] = ERR_PTR(-ENOMEM);
240}
241
242
243
244
245
246
247
248
249
250
251
252
253static int __init zynqmp_clk_register_pll_clk(enum zynqmp_clk pll_clk,
254 const char *clk_name, unsigned long flags,
255 resource_size_t *clk_ctrl_reg,
256 resource_size_t *status_reg, u8 lock_index)
257{
258 struct clk *clk;
259 char *clk_int_name;
260 char *pre_src_mux_name;
261 char *post_src_mux_name;
262 char *int_half_name;
263 char *int_mux_name;
264 const char *int_mux_parents[2];
265 const char *bypass_parents[2];
266
267 pll_src_mux_parents[0] = input_clks[0];
268 pll_src_mux_parents[1] = input_clks[0];
269 pll_src_mux_parents[2] = input_clks[0];
270 pll_src_mux_parents[3] = input_clks[0];
271 pll_src_mux_parents[4] = input_clks[1];
272 pll_src_mux_parents[5] = input_clks[2];
273 pll_src_mux_parents[6] = input_clks[3];
274 pll_src_mux_parents[7] = input_clks[4];
275
276 clk_int_name = kasprintf(GFP_KERNEL, "%s_int", clk_name);
277 if (!clk_int_name)
278 goto err_clk_int_name;
279 pre_src_mux_name = kasprintf(GFP_KERNEL, "%s_pre_src_mux", clk_name);
280 if (!pre_src_mux_name)
281 goto err_pre_src_mux_name;
282 post_src_mux_name = kasprintf(GFP_KERNEL, "%s_post_src_mux", clk_name);
283 if (!post_src_mux_name)
284 goto err_post_src_mux_name;
285 int_half_name = kasprintf(GFP_KERNEL, "%s_int_half", clk_name);
286 if (!int_half_name)
287 goto err_int_half_name;
288 int_mux_name = kasprintf(GFP_KERNEL, "%s_int_mux", clk_name);
289 if (!int_mux_name)
290 goto err_int_mux_name;
291
292 int_mux_parents[0] = clk_int_name;
293 int_mux_parents[1] = int_half_name;
294
295 bypass_parents[0] = int_mux_name;
296 bypass_parents[1] = post_src_mux_name;
297
298 clks[pll_clk] = clk_register_zynqmp_pll(clk_int_name, pre_src_mux_name,
299 flags | CLK_SET_RATE_NO_REPARENT,
300 clk_ctrl_reg, status_reg, lock_index);
301
302 clk = zynqmp_clk_register_mux(NULL, pre_src_mux_name,
303 pll_src_mux_parents, 8, 0, clk_ctrl_reg, 20, 3, 0);
304
305 clk = clk_register_fixed_factor(NULL, int_half_name, clk_int_name,
306 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, 1, 2);
307
308 clk = zynqmp_clk_register_mux(NULL, int_mux_name, int_mux_parents, 2,
309 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
310 clk_ctrl_reg, 16, 1, 0);
311
312 clk = zynqmp_clk_register_mux(NULL, post_src_mux_name,
313 pll_src_mux_parents, 8, 0, clk_ctrl_reg, 24, 3, 0);
314
315 clk = zynqmp_clk_register_mux(NULL, clk_name, bypass_parents,
316 2, CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
317 clk_ctrl_reg, 3, 1, 0);
318
319 kfree(clk_int_name);
320 kfree(pre_src_mux_name);
321 kfree(post_src_mux_name);
322 kfree(int_half_name);
323 kfree(int_mux_name);
324
325 return 0;
326
327err_int_mux_name:
328 kfree(int_half_name);
329err_int_half_name:
330 kfree(post_src_mux_name);
331err_post_src_mux_name:
332 kfree(pre_src_mux_name);
333err_pre_src_mux_name:
334 kfree(clk_int_name);
335err_clk_int_name:
336 clks[pll_clk] = ERR_PTR(-ENOMEM);
337 return -ENOMEM;
338}
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353static int __init zynqmp_clk_register_periph_clk(
354 unsigned long flags,
355 enum zynqmp_clk periph_clk,
356 const char *clk_name, resource_size_t clk_ctrl_reg,
357 const char **parents, unsigned int gated,
358 unsigned int two_divisors, u8 clk_bit_idx)
359{
360 struct clk *clk;
361 char *mux_name;
362 char *div0_name;
363 char *div1_name = NULL;
364 char *parent_div_name;
365
366 flags |= CLK_SET_RATE_NO_REPARENT;
367
368 mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name);
369 if (!mux_name)
370 goto err_mux_name;
371 div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name);
372 if (!div0_name)
373 goto err_div0_name;
374 if (two_divisors) {
375 div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name);
376 if (!div1_name)
377 goto err_div1_name;
378 }
379
380 clk = zynqmp_clk_register_mux(NULL, mux_name, parents, 4,
381 flags, (resource_size_t *)clk_ctrl_reg, 0, 3, 0);
382 if (!clk)
383 goto err_div1_name;
384
385 clk = zynqmp_clk_register_divider(NULL, div0_name, mux_name, flags,
386 (resource_size_t *)clk_ctrl_reg, 8, 6,
387 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
388
389 if (!clk)
390 goto err_div1_name;
391
392 parent_div_name = div0_name;
393 if (two_divisors) {
394 clk = zynqmp_clk_register_divider(NULL, div1_name, div0_name,
395 flags, (resource_size_t *)clk_ctrl_reg, 16, 6,
396 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
397 parent_div_name = div1_name;
398 }
399
400 if (gated)
401 clks[periph_clk] = zynqmp_clk_register_gate(NULL, clk_name,
402 parent_div_name,
403 CLK_SET_RATE_PARENT | gated,
404 (resource_size_t *)clk_ctrl_reg,
405 clk_bit_idx, 0);
406 else
407 clks[periph_clk] = clk;
408
409 parent_div_name = NULL;
410 kfree(mux_name);
411 kfree(div0_name);
412 if (two_divisors)
413 kfree(div1_name);
414 return 0;
415
416err_div1_name:
417 kfree(div0_name);
418err_div0_name:
419 kfree(mux_name);
420err_mux_name:
421 pr_err("%s: clock output name not in DT\n", __func__);
422 clks[periph_clk] = ERR_PTR(-ENOMEM);
423 return -ENOMEM;
424}
425
426
427
428
429
430
431
432
433
434
435
436static inline void zynqmp_clk_get_parents(const char **clk_output_name,
437 const char **parents, enum zynqmp_clk pll_0,
438 enum zynqmp_clk pll_1, enum zynqmp_clk pll_2)
439{
440 parents[0] = clk_output_name[pll_0];
441 parents[1] = "dummy_name";
442 parents[2] = clk_output_name[pll_1];
443 parents[3] = clk_output_name[pll_2];
444}
445
446
447
448
449
450
451
452static void __init zynqmp_clk_setup(struct device_node *np)
453{
454 int i;
455 u32 tmp;
456 struct clk *clk;
457 char *clk_name;
458 int idx;
459
460 idx = of_property_match_string(np, "clock-names", "pss_ref_clk");
461 if (idx < 0) {
462 pr_err("pss_ref_clk not provided\n");
463 return;
464 }
465 input_clks[0] = of_clk_get_parent_name(np, idx);
466
467 idx = of_property_match_string(np, "clock-names", "video_clk");
468 if (idx < 0) {
469 pr_err("video_clk not provided\n");
470 return;
471 }
472 input_clks[1] = of_clk_get_parent_name(np, idx);
473
474 idx = of_property_match_string(np, "clock-names", "pss_alt_ref_clk");
475 if (idx < 0) {
476 pr_err("pss_alt_ref_clk not provided\n");
477 return;
478 }
479 input_clks[2] = of_clk_get_parent_name(np, idx);
480
481 idx = of_property_match_string(np, "clock-names", "aux_ref_clk");
482 if (idx < 0) {
483 pr_err("aux_ref_clk not provided\n");
484 return;
485 }
486 input_clks[3] = of_clk_get_parent_name(np, idx);
487
488 idx = of_property_match_string(np, "clock-names", "gt_crx_ref_clk");
489 if (idx < 0) {
490 pr_err("aux_ref_clk not provided\n");
491 return;
492 }
493 input_clks[4] = of_clk_get_parent_name(np, idx);
494
495
496 for (i = 0; i < clk_max; i++) {
497 if (of_property_read_string_index(np, "clock-output-names",
498 i, &clk_output_name[i])) {
499 pr_err("%s: clock output name not in DT\n", __func__);
500 BUG();
501 }
502 }
503
504 acpu_parents[0] = clk_output_name[apll];
505 acpu_parents[1] = dummy_nm;
506 acpu_parents[2] = clk_output_name[dpll];
507 acpu_parents[3] = clk_output_name[vpll];
508
509
510 zynqmp_clk_register_pll_clk(apll, clk_output_name[apll],
511 CLK_IGNORE_UNUSED,
512 (resource_size_t *)CRF_APB_APLL_CTRL,
513 (resource_size_t *)CRF_APB_PLL_STATUS, 0);
514
515 zynqmp_clk_register_pll_clk(dpll, clk_output_name[dpll], 0,
516 (resource_size_t *)CRF_APB_DPLL_CTRL,
517 (resource_size_t *)CRF_APB_PLL_STATUS, 1);
518
519 zynqmp_clk_register_pll_clk(vpll, clk_output_name[vpll],
520 CLK_IGNORE_UNUSED,
521 (resource_size_t *)CRF_APB_VPLL_CTRL,
522 (resource_size_t *)CRF_APB_PLL_STATUS, 2);
523
524 zynqmp_clk_register_pll_clk(iopll, clk_output_name[iopll], 0,
525 (resource_size_t *)CRL_APB_IOPLL_CTRL,
526 (resource_size_t *)CRL_APB_PLL_STATUS, 0);
527
528 zynqmp_clk_register_pll_clk(rpll, clk_output_name[rpll], 0,
529 (resource_size_t *)CRL_APB_RPLL_CTRL,
530 (resource_size_t *)CRL_APB_PLL_STATUS, 1);
531
532
533 clks[apll_to_lpd] = zynqmp_clk_register_divider(NULL, "apll_to_lpd",
534 clk_output_name[apll], 0,
535 (resource_size_t *)CRF_APB_APLL_TO_LPD_CTRL, 8,
536 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
537
538 clks[dpll_to_lpd] = zynqmp_clk_register_divider(NULL, "dpll_to_lpd",
539 clk_output_name[dpll], 0,
540 (resource_size_t *)CRF_APB_DPLL_TO_LPD_CTRL, 8,
541 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
542
543 clks[vpll_to_lpd] = zynqmp_clk_register_divider(NULL, "vpll_to_lpd",
544 clk_output_name[vpll], 0,
545 (resource_size_t *)CRF_APB_VPLL_TO_LPD_CTRL, 8,
546 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
547
548 clks[iopll_to_fpd] = zynqmp_clk_register_divider(NULL, "iopll_to_fpd",
549 clk_output_name[iopll], 0,
550 (resource_size_t *)CRL_APB_IOPLL_TO_FPD_CTRL,
551 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
552
553 clks[rpll_to_fpd] = zynqmp_clk_register_divider(NULL, "rpll_to_fpd",
554 clk_output_name[rpll], CLK_SET_RATE_PARENT,
555 (resource_size_t *)CRL_APB_RPLL_TO_FPD_CTRL, 8,
556 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
557
558 clk = zynqmp_clk_register_mux(NULL, "acpu_mux", acpu_parents, 4,
559 CLK_SET_RATE_NO_REPARENT,
560 (resource_size_t *)CRF_APB_ACPU_CTRL, 0, 3, 0);
561
562 clk = zynqmp_clk_register_divider(NULL, "acpu_div0", "acpu_mux", 0,
563 (resource_size_t *)CRF_APB_ACPU_CTRL, 8, 6,
564 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
565
566 clks[acpu] = zynqmp_clk_register_gate(NULL, clk_output_name[acpu],
567 "acpu_div0", CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
568 (resource_size_t *)CRF_APB_ACPU_CTRL, 24, 0);
569
570 clk_prepare_enable(clks[acpu]);
571
572 clk = clk_register_fixed_factor(NULL, "acpu_half_div", "acpu_div0", 0,
573 1, 2);
574
575 clks[acpu_half] = zynqmp_clk_register_gate(NULL,
576 clk_output_name[acpu_half], "acpu_half_div",
577 CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
578 (resource_size_t *)CRF_APB_ACPU_CTRL, 25, 0);
579
580
581
582
583
584
585 wdt_ext_clk_mux_parents[0] = clk_output_name[topsw_lsbus];
586 for (i = 0; i < ARRAY_SIZE(swdt_ext_clk_input_names); i++) {
587 int idx = of_property_match_string(np, "clock-names",
588 swdt_ext_clk_input_names[i]);
589 if (idx >= 0)
590 wdt_ext_clk_mux_parents[i + 1] =
591 of_clk_get_parent_name(np, idx);
592 else
593 wdt_ext_clk_mux_parents[i + 1] = dummy_nm;
594 }
595 clks[wdt] = zynqmp_clk_register_mux(NULL, clk_output_name[wdt],
596 wdt_ext_clk_mux_parents, 2,
597 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
598 (resource_size_t *)IOU_SLCR_WDT_CLK_SEL, 0, 1, 0);
599
600
601 ddr_parents[0] = clk_output_name[dpll];
602 ddr_parents[1] = clk_output_name[vpll];
603
604 clk = zynqmp_clk_register_mux(NULL, "ddr_mux", ddr_parents, 2,
605 CLK_SET_RATE_NO_REPARENT,
606 (resource_size_t *)CRF_APB_DDR_CTRL, 0, 3, 0);
607
608 clks[ddr_ref] = zynqmp_clk_register_divider(NULL,
609 clk_output_name[ddr_ref],
610 "ddr_mux", 0, (resource_size_t *)CRF_APB_DDR_CTRL, 8, 6,
611 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
612
613 clk_prepare_enable(clks[ddr_ref]);
614
615
616 zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_trace],
617 iopll_to_fpd, dpll, apll);
618 zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_fpd],
619 iopll_to_fpd, dpll, apll);
620 zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_lpd],
621 rpll, iopll, dpll);
622 zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_tstmp],
623 iopll_to_fpd, dpll, apll);
624 zynqmp_clk_get_parents(clk_output_name, periph_parents[dp_video_ref],
625 vpll, dpll, rpll_to_fpd);
626 zynqmp_clk_get_parents(clk_output_name, periph_parents[dp_audio_ref],
627 vpll, dpll, rpll_to_fpd);
628 zynqmp_clk_get_parents(clk_output_name, periph_parents[dp_stc_ref],
629 vpll, dpll, rpll_to_fpd);
630 zynqmp_clk_get_parents(clk_output_name, periph_parents[gpu_ref],
631 iopll_to_fpd, vpll, dpll);
632 zynqmp_clk_get_parents(clk_output_name, periph_parents[sata_ref],
633 iopll_to_fpd, apll, dpll);
634 zynqmp_clk_get_parents(clk_output_name, periph_parents[pcie_ref],
635 iopll_to_fpd, rpll_to_fpd, dpll);
636 zynqmp_clk_get_parents(clk_output_name, periph_parents[gdma_ref],
637 apll, vpll, dpll);
638 zynqmp_clk_get_parents(clk_output_name, periph_parents[dpdma_ref],
639 apll, vpll, dpll);
640 zynqmp_clk_get_parents(clk_output_name, periph_parents[topsw_main],
641 apll, vpll, dpll);
642 zynqmp_clk_get_parents(clk_output_name, periph_parents[topsw_lsbus],
643 apll, iopll_to_fpd, dpll);
644 zynqmp_clk_get_parents(clk_output_name, periph_parents[gtgref0_ref],
645 iopll_to_fpd, apll, dpll);
646 zynqmp_clk_get_parents(clk_output_name, periph_parents[usb3_dual_ref],
647 iopll, rpll, dpll_to_lpd);
648 zynqmp_clk_get_parents(clk_output_name, periph_parents[usb0_bus_ref],
649 iopll, rpll, dpll_to_lpd);
650 zynqmp_clk_get_parents(clk_output_name, periph_parents[usb1_bus_ref],
651 iopll, apll, dpll_to_lpd);
652 zynqmp_clk_get_parents(clk_output_name, periph_parents[gem0_ref],
653 iopll, rpll, dpll_to_lpd);
654 zynqmp_clk_get_parents(clk_output_name, periph_parents[gem1_ref],
655 iopll, rpll, dpll_to_lpd);
656 zynqmp_clk_get_parents(clk_output_name, periph_parents[gem2_ref],
657 iopll, rpll, dpll_to_lpd);
658 zynqmp_clk_get_parents(clk_output_name, periph_parents[gem3_ref],
659 iopll, rpll, dpll_to_lpd);
660 zynqmp_clk_get_parents(clk_output_name, periph_parents[qspi_ref],
661 iopll, rpll, dpll_to_lpd);
662 zynqmp_clk_get_parents(clk_output_name, periph_parents[sdio0_ref],
663 iopll, rpll, vpll_to_lpd);
664 zynqmp_clk_get_parents(clk_output_name, periph_parents[sdio1_ref],
665 iopll, rpll, vpll_to_lpd);
666 zynqmp_clk_get_parents(clk_output_name, periph_parents[uart0_ref],
667 iopll, rpll, dpll_to_lpd);
668 zynqmp_clk_get_parents(clk_output_name, periph_parents[uart1_ref],
669 iopll, rpll, dpll_to_lpd);
670 zynqmp_clk_get_parents(clk_output_name, periph_parents[spi0_ref],
671 iopll, rpll, dpll_to_lpd);
672 zynqmp_clk_get_parents(clk_output_name, periph_parents[spi1_ref],
673 iopll, rpll, dpll_to_lpd);
674 zynqmp_clk_get_parents(clk_output_name, periph_parents[can0_ref],
675 iopll, rpll, dpll_to_lpd);
676 zynqmp_clk_get_parents(clk_output_name, periph_parents[can1_ref],
677 iopll, rpll, dpll_to_lpd);
678 zynqmp_clk_get_parents(clk_output_name, periph_parents[cpu_r5],
679 rpll, iopll, dpll_to_lpd);
680 zynqmp_clk_get_parents(clk_output_name, periph_parents[iou_switch],
681 rpll, iopll, dpll_to_lpd);
682 zynqmp_clk_get_parents(clk_output_name, periph_parents[csu_pll],
683 iopll, rpll, dpll_to_lpd);
684 zynqmp_clk_get_parents(clk_output_name, periph_parents[pcap],
685 iopll, rpll, dpll_to_lpd);
686 zynqmp_clk_get_parents(clk_output_name, periph_parents[lpd_switch],
687 rpll, iopll, dpll_to_lpd);
688 zynqmp_clk_get_parents(clk_output_name, periph_parents[lpd_lsbus],
689 rpll, iopll, dpll_to_lpd);
690 zynqmp_clk_get_parents(clk_output_name, periph_parents[nand_ref],
691 iopll, rpll, dpll_to_lpd);
692 zynqmp_clk_get_parents(clk_output_name, periph_parents[adma_ref],
693 rpll, iopll, dpll_to_lpd);
694 zynqmp_clk_get_parents(clk_output_name, periph_parents[gem_tsu_ref],
695 iopll, rpll, dpll_to_lpd);
696 zynqmp_clk_get_parents(clk_output_name, periph_parents[ams_ref],
697 rpll, iopll, dpll_to_lpd);
698 zynqmp_clk_get_parents(clk_output_name, periph_parents[i2c0_ref],
699 iopll, rpll, dpll_to_lpd);
700 zynqmp_clk_get_parents(clk_output_name, periph_parents[i2c1_ref],
701 iopll, rpll, dpll_to_lpd);
702 zynqmp_clk_get_parents(clk_output_name, periph_parents[pl0],
703 iopll, rpll, dpll_to_lpd);
704 zynqmp_clk_get_parents(clk_output_name, periph_parents[pl1],
705 iopll, rpll, dpll_to_lpd);
706 zynqmp_clk_get_parents(clk_output_name, periph_parents[pl2],
707 iopll, rpll, dpll_to_lpd);
708 zynqmp_clk_get_parents(clk_output_name, periph_parents[pl3],
709 iopll, rpll, dpll_to_lpd);
710
711
712 zynqmp_clk_register_pl_clk(pl0, clk_output_name[pl0],
713 (resource_size_t *)CRL_APB_PL0_REF_CTRL,
714 periph_parents[pl0]);
715 zynqmp_clk_register_pl_clk(pl1, clk_output_name[pl1],
716 (resource_size_t *)CRL_APB_PL1_REF_CTRL,
717 periph_parents[pl1]);
718 zynqmp_clk_register_pl_clk(pl2, clk_output_name[pl2],
719 (resource_size_t *)CRL_APB_PL2_REF_CTRL,
720 periph_parents[pl2]);
721 zynqmp_clk_register_pl_clk(pl3, clk_output_name[pl3],
722 (resource_size_t *)CRL_APB_PL3_REF_CTRL,
723 periph_parents[pl3]);
724
725
726 zynqmp_clk_register_periph_clk(0, dbg_trace, clk_output_name[dbg_trace],
727 CRF_APB_DBG_TRACE_CTRL, periph_parents[dbg_trace], 1,
728 0, 24);
729
730 zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_fpd],
731 iopll_to_fpd, dpll, apll);
732 zynqmp_clk_register_periph_clk(0, dbg_fpd, clk_output_name[dbg_fpd],
733 CRF_APB_DBG_FPD_CTRL, periph_parents[dbg_fpd], 1, 0,
734 24);
735
736 zynqmp_clk_register_periph_clk(0, dbg_lpd, clk_output_name[dbg_lpd],
737 CRL_APB_DBG_LPD_CTRL, periph_parents[dbg_lpd], 1, 0,
738 24);
739
740 zynqmp_clk_register_periph_clk(0, dbg_tstmp, clk_output_name[dbg_tstmp],
741 CRF_APB_DBG_TSTMP_CTRL, periph_parents[dbg_tstmp], 0,
742 0, 0);
743
744 zynqmp_clk_register_periph_clk(CLK_SET_RATE_PARENT | CLK_FRAC,
745 dp_video_ref,
746 clk_output_name[dp_video_ref],
747 CRF_APB_DP_VIDEO_REF_CTRL,
748 periph_parents[dp_video_ref], 1, 1, 24);
749
750 zynqmp_clk_register_periph_clk(CLK_SET_RATE_PARENT | CLK_FRAC,
751 dp_audio_ref,
752 clk_output_name[dp_audio_ref],
753 CRF_APB_DP_AUDIO_REF_CTRL,
754 periph_parents[dp_audio_ref], 1, 1, 24);
755
756 zynqmp_clk_register_periph_clk(0, dp_stc_ref,
757 clk_output_name[dp_stc_ref], CRF_APB_DP_STC_REF_CTRL,
758 periph_parents[dp_stc_ref], 1, 1, 24);
759
760 zynqmp_clk_register_periph_clk(0, gpu_ref, clk_output_name[gpu_ref],
761 CRF_APB_GPU_REF_CTRL, periph_parents[gpu_ref], 1, 0,
762 24);
763 clks[gpu_pp0_ref] = zynqmp_clk_register_gate(NULL,
764 clk_output_name[gpu_pp0_ref], "gpu_ref_div0",
765 CLK_SET_RATE_PARENT,
766 (resource_size_t *)CRF_APB_GPU_REF_CTRL, 25, 0);
767 clks[gpu_pp1_ref] = zynqmp_clk_register_gate(NULL,
768 clk_output_name[gpu_pp1_ref], "gpu_ref_div0",
769 CLK_SET_RATE_PARENT,
770 (resource_size_t *)CRF_APB_GPU_REF_CTRL, 26, 0);
771
772 zynqmp_clk_register_periph_clk(0, sata_ref, clk_output_name[sata_ref],
773 CRF_APB_SATA_REF_CTRL, periph_parents[sata_ref], 1, 0,
774 24);
775
776 zynqmp_clk_register_periph_clk(0, pcie_ref, clk_output_name[pcie_ref],
777 CRF_APB_PCIE_REF_CTRL, periph_parents[pcie_ref], 1, 0,
778 24);
779
780 zynqmp_clk_register_periph_clk(0, gdma_ref, clk_output_name[gdma_ref],
781 CRF_APB_GDMA_REF_CTRL, periph_parents[gdma_ref], 1, 0,
782 24);
783
784 zynqmp_clk_register_periph_clk(0, dpdma_ref, clk_output_name[dpdma_ref],
785 CRF_APB_DPDMA_REF_CTRL, periph_parents[dpdma_ref], 1, 0,
786 24);
787
788 zynqmp_clk_register_periph_clk(0, topsw_main,
789 clk_output_name[topsw_main],
790 CRF_APB_TOPSW_MAIN_CTRL, periph_parents[topsw_main],
791 CLK_IGNORE_UNUSED, 0, 24);
792
793 zynqmp_clk_register_periph_clk(0, topsw_lsbus,
794 clk_output_name[topsw_lsbus], CRF_APB_TOPSW_LSBUS_CTRL,
795 periph_parents[topsw_lsbus], CLK_IGNORE_UNUSED, 0, 24);
796
797 zynqmp_clk_register_periph_clk(0, gtgref0_ref,
798 clk_output_name[gtgref0_ref], CRF_APB_GTGREF0_REF_CTRL,
799 periph_parents[gtgref0_ref], 1, 0, 24);
800
801 zynqmp_clk_register_periph_clk(0, usb3_dual_ref,
802 clk_output_name[usb3_dual_ref],
803 CRL_APB_USB3_DUAL_REF_CTRL,
804 periph_parents[usb3_dual_ref], 1, 1, 25);
805
806 zynqmp_clk_register_periph_clk(0, usb0_bus_ref,
807 clk_output_name[usb0_bus_ref],
808 CRL_APB_USB0_BUS_REF_CTRL,
809 periph_parents[usb0_bus_ref], 1, 1, 25);
810
811 clks[usb0] = zynqmp_clk_register_mux(NULL, clk_output_name[usb0],
812 usb0_mio_mux_parents, 2,
813 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
814 (resource_size_t *)CRL_APB_USB0_BUS_REF_CTRL, 2, 1, 0);
815
816 zynqmp_clk_register_periph_clk(0, usb1_bus_ref,
817 clk_output_name[usb1_bus_ref],
818 CRL_APB_USB1_BUS_REF_CTRL,
819 periph_parents[usb1_bus_ref], 1, 1, 25);
820 clks[usb1] = zynqmp_clk_register_mux(NULL, clk_output_name[usb1],
821 usb1_mio_mux_parents, 2,
822 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
823 (resource_size_t *)CRL_APB_USB1_BUS_REF_CTRL, 2, 1, 0);
824
825
826 for (i = 0; i < ARRAY_SIZE(gem0_emio_input_names); i++) {
827 int idx = of_property_match_string(np, "clock-names",
828 gem0_emio_input_names[i]);
829 if (idx >= 0)
830 gem0_tx_mux_parents[i + 1] = of_clk_get_parent_name(np,
831 idx);
832 }
833 clk = zynqmp_clk_register_mux(NULL, "gem0_ref_mux",
834 periph_parents[gem0_ref], 4, CLK_SET_RATE_NO_REPARENT,
835 (resource_size_t *)CRL_APB_GEM0_REF_CTRL, 0, 3, 0);
836 clk = zynqmp_clk_register_divider(NULL, "gem0_ref_div0", "gem0_ref_mux",
837 0, (resource_size_t *)CRL_APB_GEM0_REF_CTRL, 8, 6,
838 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
839 clk = zynqmp_clk_register_divider(NULL, "gem0_ref_div1",
840 "gem0_ref_div0", 0,
841 (resource_size_t *)CRL_APB_GEM0_REF_CTRL, 16, 6,
842 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
843
844 clk = zynqmp_clk_register_mux(NULL, "gem0_tx_mux", gem0_tx_mux_parents,
845 2, CLK_SET_RATE_NO_REPARENT,
846 (resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 1, 1, 0);
847 clks[gem0_rx] = zynqmp_clk_register_gate(NULL, clk_output_name[gem0_rx],
848 "gem0_tx_mux",
849 CLK_SET_RATE_PARENT,
850 (resource_size_t *)CRL_APB_GEM0_REF_CTRL, 26, 0);
851 clks[gem0_ref] = zynqmp_clk_register_gate(NULL,
852 clk_output_name[gem0_ref],
853 "gem0_ref_div1", CLK_SET_RATE_PARENT,
854 (resource_size_t *)CRL_APB_GEM0_REF_CTRL, 25, 0);
855
856
857 for (i = 0; i < ARRAY_SIZE(gem1_emio_input_names); i++) {
858 int idx = of_property_match_string(np, "clock-names",
859 gem1_emio_input_names[i]);
860 if (idx >= 0)
861 gem1_tx_mux_parents[i + 1] = of_clk_get_parent_name(np,
862 idx);
863 }
864
865 clk = zynqmp_clk_register_mux(NULL, "gem1_ref_mux",
866 periph_parents[gem1_ref],
867 4, CLK_SET_RATE_NO_REPARENT,
868 (resource_size_t *)CRL_APB_GEM1_REF_CTRL, 0, 3, 0);
869 clk = zynqmp_clk_register_divider(NULL, "gem1_ref_div0", "gem1_ref_mux",
870 0, (resource_size_t *)CRL_APB_GEM1_REF_CTRL, 8, 6,
871 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
872 clk = zynqmp_clk_register_divider(NULL, "gem1_ref_div1",
873 "gem1_ref_div0", 0,
874 (resource_size_t *)CRL_APB_GEM1_REF_CTRL, 16, 6,
875 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
876 clk = zynqmp_clk_register_mux(NULL, "gem1_tx_mux", gem1_tx_mux_parents,
877 2, CLK_SET_RATE_NO_REPARENT,
878 (resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 6, 1, 0);
879 clks[gem1_rx] = zynqmp_clk_register_gate(NULL, clk_output_name[gem1_rx],
880 "gem1_tx_mux", CLK_SET_RATE_PARENT,
881 (resource_size_t *)CRL_APB_GEM1_REF_CTRL, 26, 0);
882 clks[gem1_ref] = zynqmp_clk_register_gate(NULL,
883 clk_output_name[gem1_ref], "gem1_ref_div1",
884 CLK_SET_RATE_PARENT,
885 (resource_size_t *)CRL_APB_GEM1_REF_CTRL, 25, 0);
886
887
888 for (i = 0; i < ARRAY_SIZE(gem2_emio_input_names); i++) {
889 int idx = of_property_match_string(np, "clock-names",
890 gem2_emio_input_names[i]);
891 if (idx >= 0)
892 gem2_tx_mux_parents[i + 1] = of_clk_get_parent_name(np,
893 idx);
894 }
895 clk = zynqmp_clk_register_mux(NULL, "gem2_ref_mux",
896 periph_parents[gem2_ref], 4, CLK_SET_RATE_NO_REPARENT,
897 (resource_size_t *)CRL_APB_GEM2_REF_CTRL, 0, 3, 0);
898 clk = zynqmp_clk_register_divider(NULL, "gem2_ref_div0",
899 "gem2_ref_mux", 0,
900 (resource_size_t *)CRL_APB_GEM2_REF_CTRL, 8, 6,
901 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
902 clk = zynqmp_clk_register_divider(NULL, "gem2_ref_div1",
903 "gem2_ref_div0", 0,
904 (resource_size_t *)CRL_APB_GEM2_REF_CTRL, 16, 6,
905 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
906 clk = zynqmp_clk_register_mux(NULL, "gem2_tx_mux", gem2_tx_mux_parents,
907 2, CLK_SET_RATE_NO_REPARENT,
908 (resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 11, 1, 0);
909 clks[gem2_rx] = zynqmp_clk_register_gate(NULL, clk_output_name[gem2_rx],
910 "gem2_tx_mux", CLK_SET_RATE_PARENT,
911 (resource_size_t *)CRL_APB_GEM2_REF_CTRL, 26, 0);
912 clks[gem2_ref] = zynqmp_clk_register_gate(NULL,
913 clk_output_name[gem2_ref], "gem2_ref_div1",
914 CLK_SET_RATE_PARENT,
915 (resource_size_t *)CRL_APB_GEM2_REF_CTRL, 25, 0);
916
917
918 for (i = 0; i < ARRAY_SIZE(gem3_emio_input_names); i++) {
919 int idx = of_property_match_string(np, "clock-names",
920 gem3_emio_input_names[i]);
921 if (idx >= 0)
922 gem3_tx_mux_parents[i + 1] = of_clk_get_parent_name(np,
923 idx);
924 }
925
926 clk = zynqmp_clk_register_mux(NULL, "gem3_ref_mux",
927 periph_parents[gem3_ref], 4, CLK_SET_RATE_NO_REPARENT,
928 (resource_size_t *)CRL_APB_GEM3_REF_CTRL, 0,
929 3, 0);
930 clk = zynqmp_clk_register_divider(NULL, "gem3_ref_div0",
931 "gem3_ref_mux", 0,
932 (resource_size_t *)CRL_APB_GEM3_REF_CTRL, 8, 6,
933 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
934 clk = zynqmp_clk_register_divider(NULL, "gem3_ref_div1",
935 "gem3_ref_div0", CLK_SET_RATE_PARENT,
936 (resource_size_t *)CRL_APB_GEM3_REF_CTRL, 16, 6,
937 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
938 clk = zynqmp_clk_register_mux(NULL, "gem3_tx_mux", gem3_tx_mux_parents,
939 2, CLK_SET_RATE_NO_REPARENT,
940 (resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 16, 1, 0);
941 clks[gem3_rx] = zynqmp_clk_register_gate(NULL, clk_output_name[gem3_rx],
942 "gem3_tx_mux", CLK_SET_RATE_PARENT,
943 (resource_size_t *)CRL_APB_GEM3_REF_CTRL, 26, 0);
944 clks[gem3_ref] = zynqmp_clk_register_gate(NULL,
945 clk_output_name[gem3_ref], "gem3_ref_div1",
946 CLK_SET_RATE_PARENT,
947 (resource_size_t *)CRL_APB_GEM3_REF_CTRL, 25, 0);
948
949 gem_tsu_mux_parents[0] = clk_output_name[gem_tsu_ref];
950 gem_tsu_mux_parents[1] = clk_output_name[gem_tsu_ref];
951 gem_tsu_mux_parents[2] = "mio_clk_26";
952 gem_tsu_mux_parents[3] = "mio_clk_50_or_51";
953
954 zynqmp_clk_register_periph_clk(0, gem_tsu_ref,
955 clk_output_name[gem_tsu_ref], CRL_APB_GEM_TSU_REF_CTRL,
956 periph_parents[gem_tsu_ref], 1, 1, 24);
957
958 clks[gem_tsu] = zynqmp_clk_register_mux(NULL, clk_output_name[gem_tsu],
959 gem_tsu_mux_parents, 2,
960 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
961 (resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 20, 2, 0);
962
963 zynqmp_clk_register_periph_clk(0, qspi_ref, clk_output_name[qspi_ref],
964 CRL_APB_QSPI_REF_CTRL, periph_parents[qspi_ref], 1, 1,
965 24);
966
967 zynqmp_clk_register_periph_clk(0, sdio0_ref, clk_output_name[sdio0_ref],
968 CRL_APB_SDIO0_REF_CTRL, periph_parents[sdio0_ref], 1,
969 1, 24);
970
971 zynqmp_clk_register_periph_clk(0, sdio1_ref, clk_output_name[sdio1_ref],
972 CRL_APB_SDIO1_REF_CTRL, periph_parents[sdio1_ref], 1,
973 1, 24);
974
975 zynqmp_clk_register_periph_clk(0, uart0_ref, clk_output_name[uart0_ref],
976 CRL_APB_UART0_REF_CTRL, periph_parents[uart0_ref], 1,
977 1, 24);
978
979 zynqmp_clk_register_periph_clk(0, uart1_ref, clk_output_name[uart1_ref],
980 CRL_APB_UART1_REF_CTRL, periph_parents[uart1_ref], 1,
981 1, 24);
982
983 zynqmp_clk_register_periph_clk(0, spi0_ref, clk_output_name[spi0_ref],
984 CRL_APB_SPI0_REF_CTRL, periph_parents[spi0_ref], 1, 1,
985 24);
986
987 zynqmp_clk_register_periph_clk(0, spi1_ref, clk_output_name[spi1_ref],
988 CRL_APB_SPI1_REF_CTRL, periph_parents[spi1_ref], 1, 1,
989 24);
990
991 tmp = strlen("mio_clk_00x");
992 clk_name = kmalloc(tmp, GFP_KERNEL);
993 for (i = 0; i < NUM_MIO_PINS; i++) {
994 int idx;
995
996 snprintf(clk_name, tmp, "mio_clk_%2.2d", i);
997 idx = of_property_match_string(np, "clock-names", clk_name);
998 if (idx >= 0)
999 can_mio_mux_parents[i] = of_clk_get_parent_name(np,
1000 idx);
1001 else
1002 can_mio_mux_parents[i] = dummy_nm;
1003 }
1004 kfree(clk_name);
1005 zynqmp_clk_register_periph_clk(0, can0_ref, clk_output_name[can0_ref],
1006 CRL_APB_CAN0_REF_CTRL, periph_parents[can0_ref], 1, 1,
1007 24);
1008 clk = zynqmp_clk_register_mux(NULL, "can0_mio_mux",
1009 can_mio_mux_parents, NUM_MIO_PINS,
1010 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
1011 (resource_size_t *)IOU_SLCR_CAN_MIO_CTRL, 0, 7, 0);
1012 clks[can0] = zynqmp_clk_register_mux(NULL, clk_output_name[can0],
1013 can0_mio_mux2_parents, 2,
1014 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
1015 (resource_size_t *)IOU_SLCR_CAN_MIO_CTRL, 7, 1, 0);
1016
1017 zynqmp_clk_register_periph_clk(0, can1_ref, clk_output_name[can1_ref],
1018 CRL_APB_CAN1_REF_CTRL, periph_parents[can1_ref], 1, 1,
1019 24);
1020 clk = zynqmp_clk_register_mux(NULL, "can1_mio_mux",
1021 can_mio_mux_parents, NUM_MIO_PINS,
1022 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
1023 (resource_size_t *)IOU_SLCR_CAN_MIO_CTRL, 15, 7, 0);
1024 clks[can1] = zynqmp_clk_register_mux(NULL, clk_output_name[can1],
1025 can1_mio_mux2_parents, 2,
1026 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
1027 (resource_size_t *)IOU_SLCR_CAN_MIO_CTRL, 22, 1, 0);
1028
1029 zynqmp_clk_register_periph_clk(0, cpu_r5, clk_output_name[cpu_r5],
1030 CRL_APB_CPU_R5_CTRL, periph_parents[cpu_r5],
1031 CLK_IGNORE_UNUSED, 0, 24);
1032 clk = zynqmp_clk_register_gate(NULL, "cpu_r5_core_gate", "cpu_r5_div0",
1033 CLK_IGNORE_UNUSED,
1034 (resource_size_t *)CRL_APB_CPU_R5_CTRL, 25, 0);
1035
1036 zynqmp_clk_register_periph_clk(0, iou_switch,
1037 clk_output_name[iou_switch], CRL_APB_IOU_SWITCH_CTRL,
1038 periph_parents[iou_switch], CLK_IGNORE_UNUSED, 0, 24);
1039
1040 zynqmp_clk_register_periph_clk(0, csu_pll, clk_output_name[csu_pll],
1041 CRL_APB_CSU_PLL_CTRL, periph_parents[csu_pll], 1, 0,
1042 24);
1043
1044 zynqmp_clk_register_periph_clk(0, pcap, clk_output_name[pcap],
1045 CRL_APB_PCAP_CTRL, periph_parents[pcap], 1, 0, 24);
1046
1047 zynqmp_clk_register_periph_clk(0, lpd_switch,
1048 clk_output_name[lpd_switch], CRL_APB_LPD_SWITCH_CTRL,
1049 periph_parents[lpd_switch], CLK_IGNORE_UNUSED, 0, 24);
1050
1051 zynqmp_clk_register_periph_clk(0, lpd_lsbus, clk_output_name[lpd_lsbus],
1052 CRL_APB_LPD_LSBUS_CTRL, periph_parents[lpd_lsbus],
1053 CLK_IGNORE_UNUSED, 0, 24);
1054
1055 zynqmp_clk_register_periph_clk(0, nand_ref, clk_output_name[nand_ref],
1056 CRL_APB_NAND_REF_CTRL, periph_parents[nand_ref], 1, 1,
1057 24);
1058
1059 zynqmp_clk_register_periph_clk(0, adma_ref, clk_output_name[adma_ref],
1060 CRL_APB_ADMA_REF_CTRL, periph_parents[adma_ref], 1, 0,
1061 24);
1062
1063 dll_ref_parents[0] = clk_output_name[iopll];
1064 dll_ref_parents[1] = clk_output_name[rpll];
1065 clks[dll_ref] = zynqmp_clk_register_mux(NULL, clk_output_name[dll_ref],
1066 dll_ref_parents, 2,
1067 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
1068 (resource_size_t *)CRL_APB_DLL_REF_CTRL,
1069 0, 3, 0);
1070
1071 zynqmp_clk_register_periph_clk(0, ams_ref, clk_output_name[ams_ref],
1072 CRL_APB_AMS_REF_CTRL, periph_parents[ams_ref], 1, 1,
1073 24);
1074
1075 zynqmp_clk_register_periph_clk(0, i2c0_ref, clk_output_name[i2c0_ref],
1076 CRL_APB_I2C0_REF_CTRL, periph_parents[i2c0_ref], 1,
1077 1, 24);
1078
1079 zynqmp_clk_register_periph_clk(0, i2c1_ref, clk_output_name[i2c1_ref],
1080 CRL_APB_I2C1_REF_CTRL, periph_parents[i2c1_ref], 1,
1081 1, 24);
1082
1083 timestamp_ref_parents[0] = clk_output_name[rpll];
1084 timestamp_ref_parents[1] = dummy_nm;
1085 timestamp_ref_parents[2] = clk_output_name[iopll];
1086 timestamp_ref_parents[3] = clk_output_name[dpll_to_lpd];
1087 timestamp_ref_parents[4] = input_clks[0];
1088 timestamp_ref_parents[5] = input_clks[0];
1089 timestamp_ref_parents[6] = input_clks[0];
1090 timestamp_ref_parents[7] = input_clks[0];
1091 clk = zynqmp_clk_register_mux(NULL, "timestamp_ref_mux",
1092 timestamp_ref_parents, 8, CLK_SET_RATE_NO_REPARENT,
1093 (resource_size_t *)CRL_APB_TIMESTAMP_REF_CTRL, 0, 3, 0);
1094 clk = zynqmp_clk_register_divider(NULL, "timestamp_ref_div0",
1095 "timestamp_ref_mux", 0,
1096 (resource_size_t *)CRL_APB_TIMESTAMP_REF_CTRL,
1097 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
1098 clks[timestamp_ref] = zynqmp_clk_register_gate(NULL,
1099 clk_output_name[timestamp_ref], "timestamp_ref_div0",
1100 CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1101 (resource_size_t *)CRL_APB_TIMESTAMP_REF_CTRL, 24, 0);
1102
1103 for (i = 0; i < ARRAY_SIZE(clks); i++) {
1104 if (IS_ERR(clks[i])) {
1105 pr_err("Zynq Ultrascale+ MPSoC clk %d: register failed with %ld\n",
1106 i, PTR_ERR(clks[i]));
1107 BUG();
1108 }
1109 }
1110
1111 clk_data.clks = clks;
1112 clk_data.clk_num = ARRAY_SIZE(clks);
1113 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
1114}
1115
1116static int __init zynqmp_clock_init(void)
1117{
1118 struct device_node *np;
1119
1120 np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp-clkc");
1121 if (!np) {
1122 pr_err("%s: clkc node not found\n", __func__);
1123 of_node_put(np);
1124 return 0;
1125 }
1126
1127 zynqmp_clk_setup(np);
1128 return 0;
1129}
1130arch_initcall(zynqmp_clock_init);
1131