2 * Zynq UltraScale+ MPSoC clock controller
4 * Copyright (C) 2016 Xilinx
6 * Based on drivers/clk/zynq/clkc.c
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License v2 as published by
10 * the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <linux/clk.h>
22 #include <linux/clk-provider.h>
23 #include <linux/clk/zynqmp.h>
26 #include <linux/of_address.h>
27 #include <linux/slab.h>
28 #include <linux/string.h>
30 static const resource_size_t zynqmp_crf_apb_clkc_base = 0xfd1a0020;
31 static const resource_size_t zynqmp_crl_apb_clkc_base = 0xff5e0020;
32 static const resource_size_t zynqmp_iou_clkc_base = 0xff180000;
34 /* Full power domain clocks */
35 #define CRF_APB_APLL_CTRL (zynqmp_crf_apb_clkc_base + 0x00)
36 #define CRF_APB_DPLL_CTRL (zynqmp_crf_apb_clkc_base + 0x0c)
37 #define CRF_APB_VPLL_CTRL (zynqmp_crf_apb_clkc_base + 0x18)
38 #define CRF_APB_PLL_STATUS (zynqmp_crf_apb_clkc_base + 0x24)
39 #define CRF_APB_APLL_TO_LPD_CTRL (zynqmp_crf_apb_clkc_base + 0x28)
40 #define CRF_APB_DPLL_TO_LPD_CTRL (zynqmp_crf_apb_clkc_base + 0x2c)
41 #define CRF_APB_VPLL_TO_LPD_CTRL (zynqmp_crf_apb_clkc_base + 0x30)
42 /* Peripheral clocks */
43 #define CRF_APB_ACPU_CTRL (zynqmp_crf_apb_clkc_base + 0x40)
44 #define CRF_APB_DBG_TRACE_CTRL (zynqmp_crf_apb_clkc_base + 0x44)
45 #define CRF_APB_DBG_FPD_CTRL (zynqmp_crf_apb_clkc_base + 0x48)
46 #define CRF_APB_DP_VIDEO_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x50)
47 #define CRF_APB_DP_AUDIO_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x54)
48 #define CRF_APB_DP_STC_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x5c)
49 #define CRF_APB_DDR_CTRL (zynqmp_crf_apb_clkc_base + 0x60)
50 #define CRF_APB_GPU_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x64)
51 #define CRF_APB_SATA_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x80)
52 #define CRF_APB_PCIE_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x94)
53 #define CRF_APB_GDMA_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x98)
54 #define CRF_APB_DPDMA_REF_CTRL (zynqmp_crf_apb_clkc_base + 0x9c)
55 #define CRF_APB_TOPSW_MAIN_CTRL (zynqmp_crf_apb_clkc_base + 0xa0)
56 #define CRF_APB_TOPSW_LSBUS_CTRL (zynqmp_crf_apb_clkc_base + 0xa4)
57 #define CRF_APB_GTGREF0_REF_CTRL (zynqmp_crf_apb_clkc_base + 0xa8)
58 #define CRF_APB_DBG_TSTMP_CTRL (zynqmp_crf_apb_clkc_base + 0xd8)
60 /* Low power domain clocks */
61 #define CRL_APB_IOPLL_CTRL (zynqmp_crl_apb_clkc_base + 0x00)
62 #define CRL_APB_RPLL_CTRL (zynqmp_crl_apb_clkc_base + 0x10)
63 #define CRL_APB_PLL_STATUS (zynqmp_crl_apb_clkc_base + 0x20)
64 #define CRL_APB_IOPLL_TO_FPD_CTRL (zynqmp_crl_apb_clkc_base + 0x24)
65 #define CRL_APB_RPLL_TO_FPD_CTRL (zynqmp_crl_apb_clkc_base + 0x28)
66 /* Peripheral clocks */
67 #define CRL_APB_USB3_DUAL_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x2c)
68 #define CRL_APB_GEM0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x30)
69 #define CRL_APB_GEM1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x34)
70 #define CRL_APB_GEM2_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x38)
71 #define CRL_APB_GEM3_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x3c)
72 #define CRL_APB_USB0_BUS_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x40)
73 #define CRL_APB_USB1_BUS_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x44)
74 #define CRL_APB_QSPI_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x48)
75 #define CRL_APB_SDIO0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x4c)
76 #define CRL_APB_SDIO1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x50)
77 #define CRL_APB_UART0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x54)
78 #define CRL_APB_UART1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x58)
79 #define CRL_APB_SPI0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x5c)
80 #define CRL_APB_SPI1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x60)
81 #define CRL_APB_CAN0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x64)
82 #define CRL_APB_CAN1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x68)
83 #define CRL_APB_CPU_R5_CTRL (zynqmp_crl_apb_clkc_base + 0x70)
84 #define CRL_APB_IOU_SWITCH_CTRL (zynqmp_crl_apb_clkc_base + 0x7c)
85 #define CRL_APB_CSU_PLL_CTRL (zynqmp_crl_apb_clkc_base + 0x80)
86 #define CRL_APB_PCAP_CTRL (zynqmp_crl_apb_clkc_base + 0x84)
87 #define CRL_APB_LPD_SWITCH_CTRL (zynqmp_crl_apb_clkc_base + 0x88)
88 #define CRL_APB_LPD_LSBUS_CTRL (zynqmp_crl_apb_clkc_base + 0x8c)
89 #define CRL_APB_DBG_LPD_CTRL (zynqmp_crl_apb_clkc_base + 0x90)
90 #define CRL_APB_NAND_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x94)
91 #define CRL_APB_ADMA_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x98)
92 #define CRL_APB_PL0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xa0)
93 #define CRL_APB_PL1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xa4)
94 #define CRL_APB_PL2_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xa8)
95 #define CRL_APB_PL3_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xac)
96 #define CRL_APB_PL0_THR_CNT (zynqmp_crl_apb_clkc_base + 0xb4)
97 #define CRL_APB_PL1_THR_CNT (zynqmp_crl_apb_clkc_base + 0xbc)
98 #define CRL_APB_PL2_THR_CNT (zynqmp_crl_apb_clkc_base + 0xc4)
99 #define CRL_APB_PL3_THR_CNT (zynqmp_crl_apb_clkc_base + 0xdc)
100 #define CRL_APB_GEM_TSU_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xe0)
101 #define CRL_APB_DLL_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xe4)
102 #define CRL_APB_AMS_REF_CTRL (zynqmp_crl_apb_clkc_base + 0xe8)
103 #define CRL_APB_I2C0_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x100)
104 #define CRL_APB_I2C1_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x104)
105 #define CRL_APB_TIMESTAMP_REF_CTRL (zynqmp_crl_apb_clkc_base + 0x108)
106 #define IOU_SLCR_GEM_CLK_CTRL (zynqmp_iou_clkc_base + 0x308)
107 #define IOU_SLCR_CAN_MIO_CTRL (zynqmp_iou_clkc_base + 0x304)
108 #define IOU_SLCR_WDT_CLK_SEL (zynqmp_iou_clkc_base + 0x300)
110 #define NUM_MIO_PINS 77
115 iopll_to_fpd, rpll_to_fpd, apll_to_lpd, dpll_to_lpd, vpll_to_lpd,
117 dbg_fpd, dbg_lpd, dbg_trace, dbg_tstmp,
118 dp_video_ref, dp_audio_ref,
119 dp_stc_ref, gdma_ref, dpdma_ref,
120 ddr_ref, sata_ref, pcie_ref,
121 gpu_ref, gpu_pp0_ref, gpu_pp1_ref,
122 topsw_main, topsw_lsbus,
124 lpd_switch, lpd_lsbus,
125 usb0_bus_ref, usb1_bus_ref, usb3_dual_ref, usb0, usb1,
127 csu_spb, csu_pll, pcap,
129 gem_tsu_ref, gem_tsu,
130 gem0_ref, gem1_ref, gem2_ref, gem3_ref,
131 gem0_rx, gem1_rx, gem2_rx, gem3_rx,
133 sdio0_ref, sdio1_ref,
134 uart0_ref, uart1_ref,
137 i2c0_ref, i2c1_ref, can0_ref, can1_ref, can0, can1,
147 static struct clk *clks[clk_max];
148 static struct clk_onecell_data clk_data;
151 static const char *can0_mio_mux2_parents[] __initconst = {"can0_ref",
153 static const char *can1_mio_mux2_parents[] __initconst = {"can1_ref",
155 static const char *usb0_mio_mux_parents[] __initconst = {"usb0_bus_ref",
156 "usb0_mio_ulpi_clk"};
157 static const char *usb1_mio_mux_parents[] __initconst = {"usb1_bus_ref",
158 "usb1_mio_ulpi_clk"};
159 static const char *swdt_ext_clk_input_names[] __initconst = {"swdt0_ext_clk",
161 static const char *gem0_tx_mux_parents[] __initconst = {"gem0_ref_div1",
163 static const char *gem1_tx_mux_parents[] __initconst = {"gem1_ref_div1",
165 static const char *gem2_tx_mux_parents[] __initconst = {"gem2_ref_div1",
167 static const char *gem3_tx_mux_parents[] __initconst = {"gem3_ref_div1",
169 static const char *gem0_emio_input_names[] __initconst = {"gem0_emio_clk"};
170 static const char *gem1_emio_input_names[] __initconst = {"gem1_emio_clk"};
171 static const char *gem2_emio_input_names[] __initconst = {"gem2_emio_clk"};
172 static const char *gem3_emio_input_names[] __initconst = {"gem3_emio_clk"};
174 static const char *timestamp_ref_parents[8];
175 static const char *pll_src_mux_parents[8];
176 static const char *input_clks[5];
177 static const char *clk_output_name[clk_max];
178 static const char *acpu_parents[4];
179 static const char *ddr_parents[2];
180 static const char *wdt_ext_clk_mux_parents[3];
181 static const char *periph_parents[clk_max][4];
182 static const char *gem_tsu_mux_parents[4];
183 static const char *can_mio_mux_parents[NUM_MIO_PINS];
184 static const char *dll_ref_parents[2];
185 static const char *dummy_nm = "dummy_name";
187 * zynqmp_clk_register_pl_clk - Register a PL clock with the clock framework
188 * @pl_clk: Sequence number of the clock
189 * @clk_name: Clock name
190 * @pl_clk_ctrl_reg: Control register address
191 * @parents: Source clocks
194 static void __init zynqmp_clk_register_pl_clk(enum zynqmp_clk pl_clk,
195 const char *clk_name, resource_size_t *pl_clk_ctrl_reg,
196 const char **parents)
202 mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name);
205 div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name);
208 div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name);
212 zynqmp_clk_register_mux(NULL, mux_name, parents, 4,
213 CLK_SET_RATE_NO_REPARENT, pl_clk_ctrl_reg, 0, 3, 0);
215 zynqmp_clk_register_divider(NULL, div0_name, mux_name, 0,
216 pl_clk_ctrl_reg, 8, 6,
217 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
219 zynqmp_clk_register_divider(NULL, div1_name, div0_name,
220 CLK_SET_RATE_PARENT, pl_clk_ctrl_reg, 16, 6,
221 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
223 clks[pl_clk] = zynqmp_clk_register_gate(NULL, clk_name, div1_name,
224 CLK_SET_RATE_PARENT, pl_clk_ctrl_reg, 24, 0);
237 clks[pl_clk] = ERR_PTR(-ENOMEM);
241 * zynqmp_clk_register_pll_clk - Register a PLL clock with the clock framework
242 * @pll_clk: Sequence number of the clock
243 * @clk_name: Clock name
244 * @flags: pass the flag values
245 * @clk_ctrl_reg: Control register address
246 * @status_reg: PLL status register address
247 * @lock_index: bit index of the pll in the status register
249 * Return: Error code on failure
251 static int __init zynqmp_clk_register_pll_clk(enum zynqmp_clk pll_clk,
252 const char *clk_name, unsigned long flags,
253 resource_size_t *clk_ctrl_reg,
254 resource_size_t *status_reg, u8 lock_index)
257 char *pre_src_mux_name;
258 char *post_src_mux_name;
261 const char *int_mux_parents[2];
262 const char *bypass_parents[2];
264 pll_src_mux_parents[0] = input_clks[0];
265 pll_src_mux_parents[1] = input_clks[0];
266 pll_src_mux_parents[2] = input_clks[0];
267 pll_src_mux_parents[3] = input_clks[0];
268 pll_src_mux_parents[4] = input_clks[1];
269 pll_src_mux_parents[5] = input_clks[2];
270 pll_src_mux_parents[6] = input_clks[3];
271 pll_src_mux_parents[7] = input_clks[4];
273 clk_int_name = kasprintf(GFP_KERNEL, "%s_int", clk_name);
275 goto err_clk_int_name;
276 pre_src_mux_name = kasprintf(GFP_KERNEL, "%s_pre_src_mux", clk_name);
277 if (!pre_src_mux_name)
278 goto err_pre_src_mux_name;
279 post_src_mux_name = kasprintf(GFP_KERNEL, "%s_post_src_mux", clk_name);
280 if (!post_src_mux_name)
281 goto err_post_src_mux_name;
282 int_half_name = kasprintf(GFP_KERNEL, "%s_int_half", clk_name);
284 goto err_int_half_name;
285 int_mux_name = kasprintf(GFP_KERNEL, "%s_int_mux", clk_name);
287 goto err_int_mux_name;
289 int_mux_parents[0] = clk_int_name;
290 int_mux_parents[1] = int_half_name;
292 bypass_parents[0] = int_mux_name;
293 bypass_parents[1] = post_src_mux_name;
295 clks[pll_clk] = clk_register_zynqmp_pll(clk_int_name, pre_src_mux_name,
296 flags | CLK_SET_RATE_NO_REPARENT,
297 clk_ctrl_reg, status_reg, lock_index);
299 zynqmp_clk_register_mux(NULL, pre_src_mux_name,
300 pll_src_mux_parents, 8, 0, clk_ctrl_reg, 20, 3, 0);
302 clk_register_fixed_factor(NULL, int_half_name, clk_int_name,
303 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, 1, 2);
305 zynqmp_clk_register_mux(NULL, int_mux_name, int_mux_parents, 2,
306 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
307 clk_ctrl_reg, 16, 1, 0);
309 zynqmp_clk_register_mux(NULL, post_src_mux_name,
310 pll_src_mux_parents, 8, 0, clk_ctrl_reg, 24, 3, 0);
312 zynqmp_clk_register_mux(NULL, clk_name, bypass_parents,
313 2, CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
314 clk_ctrl_reg, 3, 1, 0);
317 kfree(pre_src_mux_name);
318 kfree(post_src_mux_name);
319 kfree(int_half_name);
325 kfree(int_half_name);
327 kfree(post_src_mux_name);
328 err_post_src_mux_name:
329 kfree(pre_src_mux_name);
330 err_pre_src_mux_name:
333 clks[pll_clk] = ERR_PTR(-ENOMEM);
338 * zynqmp_clk_register_periph_clk - Register a peripheral clock
340 * @periph_clk: Sequence number of the clock
341 * @clk_name: Clock name
342 * @clk_ctrl_reg: Control register address
343 * @parents: Source clocks
344 * @gated: 0 = no gate registered gate flag value otherwise
345 * @two_divisors: 1 = two divisors, 0 = 1 divisor
346 * @clk_bit_idx: Clock gate control bit index
348 * Return: Error code on failure
350 static int __init zynqmp_clk_register_periph_clk(
352 enum zynqmp_clk periph_clk,
353 const char *clk_name, resource_size_t clk_ctrl_reg,
354 const char **parents, unsigned int gated,
355 unsigned int two_divisors, u8 clk_bit_idx)
360 char *div1_name = NULL;
361 char *parent_div_name;
363 flags |= CLK_SET_RATE_NO_REPARENT;
365 mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name);
368 div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name);
372 div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name);
377 clk = zynqmp_clk_register_mux(NULL, mux_name, parents, 4,
378 flags, (resource_size_t *)clk_ctrl_reg, 0, 3, 0);
382 clk = zynqmp_clk_register_divider(NULL, div0_name, mux_name, flags,
383 (resource_size_t *)clk_ctrl_reg, 8, 6,
384 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
389 parent_div_name = div0_name;
391 clk = zynqmp_clk_register_divider(NULL, div1_name, div0_name,
392 flags, (resource_size_t *)clk_ctrl_reg, 16, 6,
393 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
394 parent_div_name = div1_name;
398 clks[periph_clk] = zynqmp_clk_register_gate(NULL, clk_name,
400 CLK_SET_RATE_PARENT | gated,
401 (resource_size_t *)clk_ctrl_reg,
404 clks[periph_clk] = clk;
406 parent_div_name = NULL;
418 pr_err("%s: clock output name not in DT\n", __func__);
419 clks[periph_clk] = ERR_PTR(-ENOMEM);
424 * zynqmp_clk_get_parents - Assign source clocks for the given clock
425 * @clk_output_name: Array of clock names
426 * @parents: Requested source clocks array
427 * @pll_0: Source PLL sequence number
428 * @pll_1: Source PLL sequence number
429 * @pll_2: Source PLL sequence number
431 * Return: Error code on failure
433 static inline void zynqmp_clk_get_parents(const char **clk_output_name,
434 const char **parents, enum zynqmp_clk pll_0,
435 enum zynqmp_clk pll_1, enum zynqmp_clk pll_2)
437 parents[0] = clk_output_name[pll_0];
438 parents[1] = "dummy_name";
439 parents[2] = clk_output_name[pll_1];
440 parents[3] = clk_output_name[pll_2];
444 * zynqmp_clk_setup - Setup the clock framework and register clocks
447 * Return: Error code on failure
449 static void __init zynqmp_clk_setup(struct device_node *np)
456 idx = of_property_match_string(np, "clock-names", "pss_ref_clk");
458 pr_err("pss_ref_clk not provided\n");
461 input_clks[0] = of_clk_get_parent_name(np, idx);
463 idx = of_property_match_string(np, "clock-names", "video_clk");
465 pr_err("video_clk not provided\n");
468 input_clks[1] = of_clk_get_parent_name(np, idx);
470 idx = of_property_match_string(np, "clock-names", "pss_alt_ref_clk");
472 pr_err("pss_alt_ref_clk not provided\n");
475 input_clks[2] = of_clk_get_parent_name(np, idx);
477 idx = of_property_match_string(np, "clock-names", "aux_ref_clk");
479 pr_err("aux_ref_clk not provided\n");
482 input_clks[3] = of_clk_get_parent_name(np, idx);
484 idx = of_property_match_string(np, "clock-names", "gt_crx_ref_clk");
486 pr_err("aux_ref_clk not provided\n");
489 input_clks[4] = of_clk_get_parent_name(np, idx);
491 /* get clock output names from DT */
492 for (i = 0; i < clk_max; i++) {
493 if (of_property_read_string_index(np, "clock-output-names",
494 i, &clk_output_name[i])) {
495 pr_err("%s: clock output name not in DT\n", __func__);
500 acpu_parents[0] = clk_output_name[apll];
501 acpu_parents[1] = dummy_nm;
502 acpu_parents[2] = clk_output_name[dpll];
503 acpu_parents[3] = clk_output_name[vpll];
506 zynqmp_clk_register_pll_clk(apll, clk_output_name[apll],
508 (resource_size_t *)CRF_APB_APLL_CTRL,
509 (resource_size_t *)CRF_APB_PLL_STATUS, 0);
511 zynqmp_clk_register_pll_clk(dpll, clk_output_name[dpll], 0,
512 (resource_size_t *)CRF_APB_DPLL_CTRL,
513 (resource_size_t *)CRF_APB_PLL_STATUS, 1);
515 zynqmp_clk_register_pll_clk(vpll, clk_output_name[vpll],
517 (resource_size_t *)CRF_APB_VPLL_CTRL,
518 (resource_size_t *)CRF_APB_PLL_STATUS, 2);
520 zynqmp_clk_register_pll_clk(iopll, clk_output_name[iopll], 0,
521 (resource_size_t *)CRL_APB_IOPLL_CTRL,
522 (resource_size_t *)CRL_APB_PLL_STATUS, 0);
524 zynqmp_clk_register_pll_clk(rpll, clk_output_name[rpll], 0,
525 (resource_size_t *)CRL_APB_RPLL_CTRL,
526 (resource_size_t *)CRL_APB_PLL_STATUS, 1);
528 /* Domain crossing PLL clock dividers */
529 clks[apll_to_lpd] = zynqmp_clk_register_divider(NULL, "apll_to_lpd",
530 clk_output_name[apll], 0,
531 (resource_size_t *)CRF_APB_APLL_TO_LPD_CTRL, 8,
532 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
534 clks[dpll_to_lpd] = zynqmp_clk_register_divider(NULL, "dpll_to_lpd",
535 clk_output_name[dpll], 0,
536 (resource_size_t *)CRF_APB_DPLL_TO_LPD_CTRL, 8,
537 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
539 clks[vpll_to_lpd] = zynqmp_clk_register_divider(NULL, "vpll_to_lpd",
540 clk_output_name[vpll], 0,
541 (resource_size_t *)CRF_APB_VPLL_TO_LPD_CTRL, 8,
542 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
544 clks[iopll_to_fpd] = zynqmp_clk_register_divider(NULL, "iopll_to_fpd",
545 clk_output_name[iopll], 0,
546 (resource_size_t *)CRL_APB_IOPLL_TO_FPD_CTRL,
547 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
549 clks[rpll_to_fpd] = zynqmp_clk_register_divider(NULL, "rpll_to_fpd",
550 clk_output_name[rpll], CLK_SET_RATE_PARENT,
551 (resource_size_t *)CRL_APB_RPLL_TO_FPD_CTRL, 8,
552 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
554 zynqmp_clk_register_mux(NULL, "acpu_mux", acpu_parents, 4,
555 CLK_SET_RATE_NO_REPARENT,
556 (resource_size_t *)CRF_APB_ACPU_CTRL, 0, 3, 0);
558 zynqmp_clk_register_divider(NULL, "acpu_div0", "acpu_mux", 0,
559 (resource_size_t *)CRF_APB_ACPU_CTRL, 8, 6,
560 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
562 clks[acpu] = zynqmp_clk_register_gate(NULL, clk_output_name[acpu],
563 "acpu_div0", CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
564 (resource_size_t *)CRF_APB_ACPU_CTRL, 24, 0);
566 clk_prepare_enable(clks[acpu]);
568 clk_register_fixed_factor(NULL, "acpu_half_div", "acpu_div0", 0,
571 clks[acpu_half] = zynqmp_clk_register_gate(NULL,
572 clk_output_name[acpu_half], "acpu_half_div",
573 CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
574 (resource_size_t *)CRF_APB_ACPU_CTRL, 25, 0);
577 /* The first parent clock source will be changed in the future.
578 * Currently, using the acpu clock as the parent based on the
579 * assumption that it comes from APB.
581 wdt_ext_clk_mux_parents[0] = clk_output_name[topsw_lsbus];
582 for (i = 0; i < ARRAY_SIZE(swdt_ext_clk_input_names); i++) {
583 int idx = of_property_match_string(np, "clock-names",
584 swdt_ext_clk_input_names[i]);
586 wdt_ext_clk_mux_parents[i + 1] =
587 of_clk_get_parent_name(np, idx);
589 wdt_ext_clk_mux_parents[i + 1] = dummy_nm;
591 clks[wdt] = zynqmp_clk_register_mux(NULL, clk_output_name[wdt],
592 wdt_ext_clk_mux_parents, 2,
593 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
594 (resource_size_t *)IOU_SLCR_WDT_CLK_SEL, 0, 1, 0);
597 ddr_parents[0] = clk_output_name[dpll];
598 ddr_parents[1] = clk_output_name[vpll];
600 zynqmp_clk_register_mux(NULL, "ddr_mux", ddr_parents, 2,
601 CLK_SET_RATE_NO_REPARENT,
602 (resource_size_t *)CRF_APB_DDR_CTRL, 0, 3, 0);
604 clks[ddr_ref] = zynqmp_clk_register_divider(NULL,
605 clk_output_name[ddr_ref],
606 "ddr_mux", 0, (resource_size_t *)CRF_APB_DDR_CTRL, 8, 6,
607 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
609 clk_prepare_enable(clks[ddr_ref]);
611 /* Peripheral clock parents */
612 zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_trace],
613 iopll_to_fpd, dpll, apll);
614 zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_fpd],
615 iopll_to_fpd, dpll, apll);
616 zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_lpd],
618 zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_tstmp],
619 iopll_to_fpd, dpll, apll);
620 zynqmp_clk_get_parents(clk_output_name, periph_parents[dp_video_ref],
621 vpll, dpll, rpll_to_fpd);
622 zynqmp_clk_get_parents(clk_output_name, periph_parents[dp_audio_ref],
623 vpll, dpll, rpll_to_fpd);
624 zynqmp_clk_get_parents(clk_output_name, periph_parents[dp_stc_ref],
625 vpll, dpll, rpll_to_fpd);
626 zynqmp_clk_get_parents(clk_output_name, periph_parents[gpu_ref],
627 iopll_to_fpd, vpll, dpll);
628 zynqmp_clk_get_parents(clk_output_name, periph_parents[sata_ref],
629 iopll_to_fpd, apll, dpll);
630 zynqmp_clk_get_parents(clk_output_name, periph_parents[pcie_ref],
631 iopll_to_fpd, rpll_to_fpd, dpll);
632 zynqmp_clk_get_parents(clk_output_name, periph_parents[gdma_ref],
634 zynqmp_clk_get_parents(clk_output_name, periph_parents[dpdma_ref],
636 zynqmp_clk_get_parents(clk_output_name, periph_parents[topsw_main],
638 zynqmp_clk_get_parents(clk_output_name, periph_parents[topsw_lsbus],
639 apll, iopll_to_fpd, dpll);
640 zynqmp_clk_get_parents(clk_output_name, periph_parents[gtgref0_ref],
641 iopll_to_fpd, apll, dpll);
642 zynqmp_clk_get_parents(clk_output_name, periph_parents[usb3_dual_ref],
643 iopll, rpll, dpll_to_lpd);
644 zynqmp_clk_get_parents(clk_output_name, periph_parents[usb0_bus_ref],
645 iopll, rpll, dpll_to_lpd);
646 zynqmp_clk_get_parents(clk_output_name, periph_parents[usb1_bus_ref],
647 iopll, apll, dpll_to_lpd);
648 zynqmp_clk_get_parents(clk_output_name, periph_parents[gem0_ref],
649 iopll, rpll, dpll_to_lpd);
650 zynqmp_clk_get_parents(clk_output_name, periph_parents[gem1_ref],
651 iopll, rpll, dpll_to_lpd);
652 zynqmp_clk_get_parents(clk_output_name, periph_parents[gem2_ref],
653 iopll, rpll, dpll_to_lpd);
654 zynqmp_clk_get_parents(clk_output_name, periph_parents[gem3_ref],
655 iopll, rpll, dpll_to_lpd);
656 zynqmp_clk_get_parents(clk_output_name, periph_parents[qspi_ref],
657 iopll, rpll, dpll_to_lpd);
658 zynqmp_clk_get_parents(clk_output_name, periph_parents[sdio0_ref],
659 iopll, rpll, vpll_to_lpd);
660 zynqmp_clk_get_parents(clk_output_name, periph_parents[sdio1_ref],
661 iopll, rpll, vpll_to_lpd);
662 zynqmp_clk_get_parents(clk_output_name, periph_parents[uart0_ref],
663 iopll, rpll, dpll_to_lpd);
664 zynqmp_clk_get_parents(clk_output_name, periph_parents[uart1_ref],
665 iopll, rpll, dpll_to_lpd);
666 zynqmp_clk_get_parents(clk_output_name, periph_parents[spi0_ref],
667 iopll, rpll, dpll_to_lpd);
668 zynqmp_clk_get_parents(clk_output_name, periph_parents[spi1_ref],
669 iopll, rpll, dpll_to_lpd);
670 zynqmp_clk_get_parents(clk_output_name, periph_parents[can0_ref],
671 iopll, rpll, dpll_to_lpd);
672 zynqmp_clk_get_parents(clk_output_name, periph_parents[can1_ref],
673 iopll, rpll, dpll_to_lpd);
674 zynqmp_clk_get_parents(clk_output_name, periph_parents[cpu_r5],
675 rpll, iopll, dpll_to_lpd);
676 zynqmp_clk_get_parents(clk_output_name, periph_parents[iou_switch],
677 rpll, iopll, dpll_to_lpd);
678 zynqmp_clk_get_parents(clk_output_name, periph_parents[csu_pll],
679 iopll, rpll, dpll_to_lpd);
680 zynqmp_clk_get_parents(clk_output_name, periph_parents[pcap],
681 iopll, rpll, dpll_to_lpd);
682 zynqmp_clk_get_parents(clk_output_name, periph_parents[lpd_switch],
683 rpll, iopll, dpll_to_lpd);
684 zynqmp_clk_get_parents(clk_output_name, periph_parents[lpd_lsbus],
685 rpll, iopll, dpll_to_lpd);
686 zynqmp_clk_get_parents(clk_output_name, periph_parents[nand_ref],
687 iopll, rpll, dpll_to_lpd);
688 zynqmp_clk_get_parents(clk_output_name, periph_parents[adma_ref],
689 rpll, iopll, dpll_to_lpd);
690 zynqmp_clk_get_parents(clk_output_name, periph_parents[gem_tsu_ref],
691 iopll, rpll, dpll_to_lpd);
692 zynqmp_clk_get_parents(clk_output_name, periph_parents[ams_ref],
693 rpll, iopll, dpll_to_lpd);
694 zynqmp_clk_get_parents(clk_output_name, periph_parents[i2c0_ref],
695 iopll, rpll, dpll_to_lpd);
696 zynqmp_clk_get_parents(clk_output_name, periph_parents[i2c1_ref],
697 iopll, rpll, dpll_to_lpd);
698 zynqmp_clk_get_parents(clk_output_name, periph_parents[pl0],
699 iopll, rpll, dpll_to_lpd);
700 zynqmp_clk_get_parents(clk_output_name, periph_parents[pl1],
701 iopll, rpll, dpll_to_lpd);
702 zynqmp_clk_get_parents(clk_output_name, periph_parents[pl2],
703 iopll, rpll, dpll_to_lpd);
704 zynqmp_clk_get_parents(clk_output_name, periph_parents[pl3],
705 iopll, rpll, dpll_to_lpd);
708 zynqmp_clk_register_pl_clk(pl0, clk_output_name[pl0],
709 (resource_size_t *)CRL_APB_PL0_REF_CTRL,
710 periph_parents[pl0]);
711 zynqmp_clk_register_pl_clk(pl1, clk_output_name[pl1],
712 (resource_size_t *)CRL_APB_PL1_REF_CTRL,
713 periph_parents[pl1]);
714 zynqmp_clk_register_pl_clk(pl2, clk_output_name[pl2],
715 (resource_size_t *)CRL_APB_PL2_REF_CTRL,
716 periph_parents[pl2]);
717 zynqmp_clk_register_pl_clk(pl3, clk_output_name[pl3],
718 (resource_size_t *)CRL_APB_PL3_REF_CTRL,
719 periph_parents[pl3]);
721 /* Peripheral clock */
722 zynqmp_clk_register_periph_clk(0, dbg_trace, clk_output_name[dbg_trace],
723 CRF_APB_DBG_TRACE_CTRL, periph_parents[dbg_trace], 1,
726 zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_fpd],
727 iopll_to_fpd, dpll, apll);
728 zynqmp_clk_register_periph_clk(0, dbg_fpd, clk_output_name[dbg_fpd],
729 CRF_APB_DBG_FPD_CTRL, periph_parents[dbg_fpd], 1, 0,
732 zynqmp_clk_register_periph_clk(0, dbg_lpd, clk_output_name[dbg_lpd],
733 CRL_APB_DBG_LPD_CTRL, periph_parents[dbg_lpd], 1, 0,
736 zynqmp_clk_register_periph_clk(0, dbg_tstmp, clk_output_name[dbg_tstmp],
737 CRF_APB_DBG_TSTMP_CTRL, periph_parents[dbg_tstmp], 0,
740 zynqmp_clk_register_periph_clk(CLK_SET_RATE_PARENT | CLK_FRAC,
742 clk_output_name[dp_video_ref],
743 CRF_APB_DP_VIDEO_REF_CTRL,
744 periph_parents[dp_video_ref], 1, 1, 24);
746 zynqmp_clk_register_periph_clk(CLK_SET_RATE_PARENT | CLK_FRAC,
748 clk_output_name[dp_audio_ref],
749 CRF_APB_DP_AUDIO_REF_CTRL,
750 periph_parents[dp_audio_ref], 1, 1, 24);
752 zynqmp_clk_register_periph_clk(0, dp_stc_ref,
753 clk_output_name[dp_stc_ref], CRF_APB_DP_STC_REF_CTRL,
754 periph_parents[dp_stc_ref], 1, 1, 24);
756 zynqmp_clk_register_periph_clk(0, gpu_ref, clk_output_name[gpu_ref],
757 CRF_APB_GPU_REF_CTRL, periph_parents[gpu_ref], 1, 0,
759 clks[gpu_pp0_ref] = zynqmp_clk_register_gate(NULL,
760 clk_output_name[gpu_pp0_ref], "gpu_ref_div0",
762 (resource_size_t *)CRF_APB_GPU_REF_CTRL, 25, 0);
763 clks[gpu_pp1_ref] = zynqmp_clk_register_gate(NULL,
764 clk_output_name[gpu_pp1_ref], "gpu_ref_div0",
766 (resource_size_t *)CRF_APB_GPU_REF_CTRL, 26, 0);
768 zynqmp_clk_register_periph_clk(0, sata_ref, clk_output_name[sata_ref],
769 CRF_APB_SATA_REF_CTRL, periph_parents[sata_ref], 1, 0,
772 zynqmp_clk_register_periph_clk(0, pcie_ref, clk_output_name[pcie_ref],
773 CRF_APB_PCIE_REF_CTRL, periph_parents[pcie_ref], 1, 0,
776 zynqmp_clk_register_periph_clk(0, gdma_ref, clk_output_name[gdma_ref],
777 CRF_APB_GDMA_REF_CTRL, periph_parents[gdma_ref], 1, 0,
780 zynqmp_clk_register_periph_clk(0, dpdma_ref, clk_output_name[dpdma_ref],
781 CRF_APB_DPDMA_REF_CTRL, periph_parents[dpdma_ref], 1, 0,
784 zynqmp_clk_register_periph_clk(0, topsw_main,
785 clk_output_name[topsw_main],
786 CRF_APB_TOPSW_MAIN_CTRL, periph_parents[topsw_main],
787 CLK_IGNORE_UNUSED, 0, 24);
789 zynqmp_clk_register_periph_clk(0, topsw_lsbus,
790 clk_output_name[topsw_lsbus], CRF_APB_TOPSW_LSBUS_CTRL,
791 periph_parents[topsw_lsbus], CLK_IGNORE_UNUSED, 0, 24);
793 zynqmp_clk_register_periph_clk(0, gtgref0_ref,
794 clk_output_name[gtgref0_ref], CRF_APB_GTGREF0_REF_CTRL,
795 periph_parents[gtgref0_ref], 1, 0, 24);
797 zynqmp_clk_register_periph_clk(0, usb3_dual_ref,
798 clk_output_name[usb3_dual_ref],
799 CRL_APB_USB3_DUAL_REF_CTRL,
800 periph_parents[usb3_dual_ref], 1, 1, 25);
802 zynqmp_clk_register_periph_clk(0, usb0_bus_ref,
803 clk_output_name[usb0_bus_ref],
804 CRL_APB_USB0_BUS_REF_CTRL,
805 periph_parents[usb0_bus_ref], 1, 1, 25);
807 zynqmp_clk_register_periph_clk(0, usb1_bus_ref,
808 clk_output_name[usb1_bus_ref],
809 CRL_APB_USB1_BUS_REF_CTRL,
810 periph_parents[usb1_bus_ref], 1, 1, 25);
812 /* Ethernet clocks */
813 for (i = 0; i < ARRAY_SIZE(gem0_emio_input_names); i++) {
814 int idx = of_property_match_string(np, "clock-names",
815 gem0_emio_input_names[i]);
817 gem0_tx_mux_parents[i + 1] = of_clk_get_parent_name(np,
820 zynqmp_clk_register_mux(NULL, "gem0_ref_mux",
821 periph_parents[gem0_ref], 4, CLK_SET_RATE_NO_REPARENT,
822 (resource_size_t *)CRL_APB_GEM0_REF_CTRL, 0, 3, 0);
823 zynqmp_clk_register_divider(NULL, "gem0_ref_div0", "gem0_ref_mux",
824 0, (resource_size_t *)CRL_APB_GEM0_REF_CTRL, 8, 6,
825 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
826 zynqmp_clk_register_divider(NULL, "gem0_ref_div1",
828 (resource_size_t *)CRL_APB_GEM0_REF_CTRL, 16, 6,
829 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
831 zynqmp_clk_register_mux(NULL, "gem0_tx_mux", gem0_tx_mux_parents,
832 2, CLK_SET_RATE_NO_REPARENT,
833 (resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 1, 1, 0);
834 clks[gem0_rx] = zynqmp_clk_register_gate(NULL, clk_output_name[gem0_rx],
837 (resource_size_t *)CRL_APB_GEM0_REF_CTRL, 26, 0);
838 clks[gem0_ref] = zynqmp_clk_register_gate(NULL,
839 clk_output_name[gem0_ref],
840 "gem0_ref_div1", CLK_SET_RATE_PARENT,
841 (resource_size_t *)CRL_APB_GEM0_REF_CTRL, 25, 0);
844 for (i = 0; i < ARRAY_SIZE(gem1_emio_input_names); i++) {
845 int idx = of_property_match_string(np, "clock-names",
846 gem1_emio_input_names[i]);
848 gem1_tx_mux_parents[i + 1] = of_clk_get_parent_name(np,
852 zynqmp_clk_register_mux(NULL, "gem1_ref_mux",
853 periph_parents[gem1_ref],
854 4, CLK_SET_RATE_NO_REPARENT,
855 (resource_size_t *)CRL_APB_GEM1_REF_CTRL, 0, 3, 0);
856 zynqmp_clk_register_divider(NULL, "gem1_ref_div0", "gem1_ref_mux",
857 0, (resource_size_t *)CRL_APB_GEM1_REF_CTRL, 8, 6,
858 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
859 zynqmp_clk_register_divider(NULL, "gem1_ref_div1",
861 (resource_size_t *)CRL_APB_GEM1_REF_CTRL, 16, 6,
862 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
863 zynqmp_clk_register_mux(NULL, "gem1_tx_mux", gem1_tx_mux_parents,
864 2, CLK_SET_RATE_NO_REPARENT,
865 (resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 6, 1, 0);
866 clks[gem1_rx] = zynqmp_clk_register_gate(NULL, clk_output_name[gem1_rx],
867 "gem1_tx_mux", CLK_SET_RATE_PARENT,
868 (resource_size_t *)CRL_APB_GEM1_REF_CTRL, 26, 0);
869 clks[gem1_ref] = zynqmp_clk_register_gate(NULL,
870 clk_output_name[gem1_ref], "gem1_ref_div1",
872 (resource_size_t *)CRL_APB_GEM1_REF_CTRL, 25, 0);
875 for (i = 0; i < ARRAY_SIZE(gem2_emio_input_names); i++) {
876 int idx = of_property_match_string(np, "clock-names",
877 gem2_emio_input_names[i]);
879 gem2_tx_mux_parents[i + 1] = of_clk_get_parent_name(np,
882 zynqmp_clk_register_mux(NULL, "gem2_ref_mux",
883 periph_parents[gem2_ref], 4, CLK_SET_RATE_NO_REPARENT,
884 (resource_size_t *)CRL_APB_GEM2_REF_CTRL, 0, 3, 0);
885 zynqmp_clk_register_divider(NULL, "gem2_ref_div0",
887 (resource_size_t *)CRL_APB_GEM2_REF_CTRL, 8, 6,
888 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
889 zynqmp_clk_register_divider(NULL, "gem2_ref_div1",
891 (resource_size_t *)CRL_APB_GEM2_REF_CTRL, 16, 6,
892 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
893 zynqmp_clk_register_mux(NULL, "gem2_tx_mux", gem2_tx_mux_parents,
894 2, CLK_SET_RATE_NO_REPARENT,
895 (resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 11, 1, 0);
896 clks[gem2_rx] = zynqmp_clk_register_gate(NULL, clk_output_name[gem2_rx],
897 "gem2_tx_mux", CLK_SET_RATE_PARENT,
898 (resource_size_t *)CRL_APB_GEM2_REF_CTRL, 26, 0);
899 clks[gem2_ref] = zynqmp_clk_register_gate(NULL,
900 clk_output_name[gem2_ref], "gem2_ref_div1",
902 (resource_size_t *)CRL_APB_GEM2_REF_CTRL, 25, 0);
905 for (i = 0; i < ARRAY_SIZE(gem3_emio_input_names); i++) {
906 int idx = of_property_match_string(np, "clock-names",
907 gem3_emio_input_names[i]);
909 gem3_tx_mux_parents[i + 1] = of_clk_get_parent_name(np,
913 zynqmp_clk_register_mux(NULL, "gem3_ref_mux",
914 periph_parents[gem3_ref], 4, CLK_SET_RATE_NO_REPARENT,
915 (resource_size_t *)CRL_APB_GEM3_REF_CTRL, 0,
917 zynqmp_clk_register_divider(NULL, "gem3_ref_div0",
919 (resource_size_t *)CRL_APB_GEM3_REF_CTRL, 8, 6,
920 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
921 zynqmp_clk_register_divider(NULL, "gem3_ref_div1",
923 (resource_size_t *)CRL_APB_GEM3_REF_CTRL, 16, 6,
924 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
925 zynqmp_clk_register_mux(NULL, "gem3_tx_mux", gem3_tx_mux_parents,
926 2, CLK_SET_RATE_NO_REPARENT,
927 (resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 16, 1, 0);
928 clks[gem3_rx] = zynqmp_clk_register_gate(NULL, clk_output_name[gem3_rx],
929 "gem3_tx_mux", CLK_SET_RATE_PARENT,
930 (resource_size_t *)CRL_APB_GEM3_REF_CTRL, 26, 0);
931 clks[gem3_ref] = zynqmp_clk_register_gate(NULL,
932 clk_output_name[gem3_ref], "gem3_ref_div1",
934 (resource_size_t *)CRL_APB_GEM3_REF_CTRL, 25, 0);
936 gem_tsu_mux_parents[0] = clk_output_name[gem_tsu_ref];
937 gem_tsu_mux_parents[1] = clk_output_name[gem_tsu_ref];
938 gem_tsu_mux_parents[2] = "mio_clk_26";
939 gem_tsu_mux_parents[3] = "mio_clk_50_or_51";
941 zynqmp_clk_register_periph_clk(0, gem_tsu_ref,
942 clk_output_name[gem_tsu_ref], CRL_APB_GEM_TSU_REF_CTRL,
943 periph_parents[gem_tsu_ref], 1, 1, 24);
945 clks[gem_tsu] = zynqmp_clk_register_mux(NULL, clk_output_name[gem_tsu],
946 gem_tsu_mux_parents, 2,
947 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
948 (resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 20, 2, 0);
950 zynqmp_clk_register_periph_clk(0, qspi_ref, clk_output_name[qspi_ref],
951 CRL_APB_QSPI_REF_CTRL, periph_parents[qspi_ref], 1, 1,
954 zynqmp_clk_register_periph_clk(0, sdio0_ref, clk_output_name[sdio0_ref],
955 CRL_APB_SDIO0_REF_CTRL, periph_parents[sdio0_ref], 1,
958 zynqmp_clk_register_periph_clk(0, sdio1_ref, clk_output_name[sdio1_ref],
959 CRL_APB_SDIO1_REF_CTRL, periph_parents[sdio1_ref], 1,
962 zynqmp_clk_register_periph_clk(0, uart0_ref, clk_output_name[uart0_ref],
963 CRL_APB_UART0_REF_CTRL, periph_parents[uart0_ref], 1,
966 zynqmp_clk_register_periph_clk(0, uart1_ref, clk_output_name[uart1_ref],
967 CRL_APB_UART1_REF_CTRL, periph_parents[uart1_ref], 1,
970 zynqmp_clk_register_periph_clk(0, spi0_ref, clk_output_name[spi0_ref],
971 CRL_APB_SPI0_REF_CTRL, periph_parents[spi0_ref], 1, 1,
974 zynqmp_clk_register_periph_clk(0, spi1_ref, clk_output_name[spi1_ref],
975 CRL_APB_SPI1_REF_CTRL, periph_parents[spi1_ref], 1, 1,
978 tmp = strlen("mio_clk_00x");
979 clk_name = kmalloc(tmp, GFP_KERNEL);
980 for (i = 0; i < NUM_MIO_PINS; i++) {
983 snprintf(clk_name, tmp, "mio_clk_%2.2d", i);
984 idx = of_property_match_string(np, "clock-names", clk_name);
986 can_mio_mux_parents[i] = of_clk_get_parent_name(np,
989 can_mio_mux_parents[i] = dummy_nm;
992 zynqmp_clk_register_periph_clk(0, can0_ref, clk_output_name[can0_ref],
993 CRL_APB_CAN0_REF_CTRL, periph_parents[can0_ref], 1, 1,
995 zynqmp_clk_register_mux(NULL, "can0_mio_mux",
996 can_mio_mux_parents, NUM_MIO_PINS,
997 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
998 (resource_size_t *)IOU_SLCR_CAN_MIO_CTRL, 0, 7, 0);
999 clks[can0] = zynqmp_clk_register_mux(NULL, clk_output_name[can0],
1000 can0_mio_mux2_parents, 2,
1001 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
1002 (resource_size_t *)IOU_SLCR_CAN_MIO_CTRL, 7, 1, 0);
1004 zynqmp_clk_register_periph_clk(0, can1_ref, clk_output_name[can1_ref],
1005 CRL_APB_CAN1_REF_CTRL, periph_parents[can1_ref], 1, 1,
1007 zynqmp_clk_register_mux(NULL, "can1_mio_mux",
1008 can_mio_mux_parents, NUM_MIO_PINS,
1009 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
1010 (resource_size_t *)IOU_SLCR_CAN_MIO_CTRL, 15, 7, 0);
1011 clks[can1] = zynqmp_clk_register_mux(NULL, clk_output_name[can1],
1012 can1_mio_mux2_parents, 2,
1013 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
1014 (resource_size_t *)IOU_SLCR_CAN_MIO_CTRL, 22, 1, 0);
1016 zynqmp_clk_register_periph_clk(0, cpu_r5, clk_output_name[cpu_r5],
1017 CRL_APB_CPU_R5_CTRL, periph_parents[cpu_r5],
1018 CLK_IGNORE_UNUSED, 0, 24);
1019 zynqmp_clk_register_gate(NULL, "cpu_r5_core_gate", "cpu_r5_div0",
1021 (resource_size_t *)CRL_APB_CPU_R5_CTRL, 25, 0);
1023 zynqmp_clk_register_periph_clk(0, iou_switch,
1024 clk_output_name[iou_switch], CRL_APB_IOU_SWITCH_CTRL,
1025 periph_parents[iou_switch], CLK_IGNORE_UNUSED, 0, 24);
1027 zynqmp_clk_register_periph_clk(0, csu_pll, clk_output_name[csu_pll],
1028 CRL_APB_CSU_PLL_CTRL, periph_parents[csu_pll], 1, 0,
1031 zynqmp_clk_register_periph_clk(0, pcap, clk_output_name[pcap],
1032 CRL_APB_PCAP_CTRL, periph_parents[pcap], 1, 0, 24);
1034 zynqmp_clk_register_periph_clk(0, lpd_switch,
1035 clk_output_name[lpd_switch], CRL_APB_LPD_SWITCH_CTRL,
1036 periph_parents[lpd_switch], CLK_IGNORE_UNUSED, 0, 24);
1038 zynqmp_clk_register_periph_clk(0, lpd_lsbus, clk_output_name[lpd_lsbus],
1039 CRL_APB_LPD_LSBUS_CTRL, periph_parents[lpd_lsbus],
1040 CLK_IGNORE_UNUSED, 0, 24);
1042 zynqmp_clk_register_periph_clk(0, nand_ref, clk_output_name[nand_ref],
1043 CRL_APB_NAND_REF_CTRL, periph_parents[nand_ref], 1, 1,
1046 zynqmp_clk_register_periph_clk(0, adma_ref, clk_output_name[adma_ref],
1047 CRL_APB_ADMA_REF_CTRL, periph_parents[adma_ref], 1, 0,
1050 dll_ref_parents[0] = clk_output_name[iopll];
1051 dll_ref_parents[1] = clk_output_name[rpll];
1052 clks[dll_ref] = zynqmp_clk_register_mux(NULL, clk_output_name[dll_ref],
1054 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
1055 (resource_size_t *)CRL_APB_DLL_REF_CTRL,
1058 zynqmp_clk_register_periph_clk(0, ams_ref, clk_output_name[ams_ref],
1059 CRL_APB_AMS_REF_CTRL, periph_parents[ams_ref], 1, 1,
1062 zynqmp_clk_register_periph_clk(0, i2c0_ref, clk_output_name[i2c0_ref],
1063 CRL_APB_I2C0_REF_CTRL, periph_parents[i2c0_ref], 1,
1066 zynqmp_clk_register_periph_clk(0, i2c1_ref, clk_output_name[i2c1_ref],
1067 CRL_APB_I2C1_REF_CTRL, periph_parents[i2c1_ref], 1,
1070 timestamp_ref_parents[0] = clk_output_name[rpll];
1071 timestamp_ref_parents[1] = dummy_nm;
1072 timestamp_ref_parents[2] = clk_output_name[iopll];
1073 timestamp_ref_parents[3] = clk_output_name[dpll_to_lpd];
1074 timestamp_ref_parents[4] = input_clks[0];
1075 timestamp_ref_parents[5] = input_clks[0];
1076 timestamp_ref_parents[6] = input_clks[0];
1077 timestamp_ref_parents[7] = input_clks[0];
1078 zynqmp_clk_register_mux(NULL, "timestamp_ref_mux",
1079 timestamp_ref_parents, 8, CLK_SET_RATE_NO_REPARENT,
1080 (resource_size_t *)CRL_APB_TIMESTAMP_REF_CTRL, 0, 3, 0);
1081 zynqmp_clk_register_divider(NULL, "timestamp_ref_div0",
1082 "timestamp_ref_mux", 0,
1083 (resource_size_t *)CRL_APB_TIMESTAMP_REF_CTRL,
1084 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
1085 clks[timestamp_ref] = zynqmp_clk_register_gate(NULL,
1086 clk_output_name[timestamp_ref], "timestamp_ref_div0",
1087 CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1088 (resource_size_t *)CRL_APB_TIMESTAMP_REF_CTRL, 24, 0);
1090 for (i = 0; i < ARRAY_SIZE(clks); i++) {
1091 if (IS_ERR(clks[i])) {
1092 pr_err("Zynq Ultrascale+ MPSoC clk %d: register failed with %ld\n",
1093 i, PTR_ERR(clks[i]));
1098 clk_data.clks = clks;
1099 clk_data.clk_num = ARRAY_SIZE(clks);
1100 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
1103 static int __init zynqmp_clock_init(void)
1105 struct device_node *np;
1107 np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp-clkc");
1109 pr_err("%s: clkc node not found\n", __func__);
1114 zynqmp_clk_setup(np);
1117 arch_initcall(zynqmp_clock_init);