clk: mediatek: add support to configure clock driver parent
[platform/kernel/u-boot.git] / drivers / clk / clk_zynqmp.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * ZynqMP clock driver
4  *
5  * Copyright (C) 2016 Xilinx, Inc.
6  */
7
8 #include <common.h>
9 #include <log.h>
10 #include <malloc.h>
11 #include <dm/device_compat.h>
12 #include <linux/bitops.h>
13 #include <clk-uclass.h>
14 #include <clk.h>
15 #include <asm/arch/sys_proto.h>
16 #include <dm.h>
17 #include <linux/err.h>
18
19 static const resource_size_t zynqmp_crf_apb_clkc_base = 0xfd1a0020;
20 static const resource_size_t zynqmp_crl_apb_clkc_base = 0xff5e0020;
21
22 /* Full power domain clocks */
23 #define CRF_APB_APLL_CTRL               (zynqmp_crf_apb_clkc_base + 0x00)
24 #define CRF_APB_DPLL_CTRL               (zynqmp_crf_apb_clkc_base + 0x0c)
25 #define CRF_APB_VPLL_CTRL               (zynqmp_crf_apb_clkc_base + 0x18)
26 #define CRF_APB_PLL_STATUS              (zynqmp_crf_apb_clkc_base + 0x24)
27 #define CRF_APB_APLL_TO_LPD_CTRL        (zynqmp_crf_apb_clkc_base + 0x28)
28 #define CRF_APB_DPLL_TO_LPD_CTRL        (zynqmp_crf_apb_clkc_base + 0x2c)
29 #define CRF_APB_VPLL_TO_LPD_CTRL        (zynqmp_crf_apb_clkc_base + 0x30)
30 /* Peripheral clocks */
31 #define CRF_APB_ACPU_CTRL               (zynqmp_crf_apb_clkc_base + 0x40)
32 #define CRF_APB_DBG_TRACE_CTRL          (zynqmp_crf_apb_clkc_base + 0x44)
33 #define CRF_APB_DBG_FPD_CTRL            (zynqmp_crf_apb_clkc_base + 0x48)
34 #define CRF_APB_DP_VIDEO_REF_CTRL       (zynqmp_crf_apb_clkc_base + 0x50)
35 #define CRF_APB_DP_AUDIO_REF_CTRL       (zynqmp_crf_apb_clkc_base + 0x54)
36 #define CRF_APB_DP_STC_REF_CTRL         (zynqmp_crf_apb_clkc_base + 0x5c)
37 #define CRF_APB_DDR_CTRL                (zynqmp_crf_apb_clkc_base + 0x60)
38 #define CRF_APB_GPU_REF_CTRL            (zynqmp_crf_apb_clkc_base + 0x64)
39 #define CRF_APB_SATA_REF_CTRL           (zynqmp_crf_apb_clkc_base + 0x80)
40 #define CRF_APB_PCIE_REF_CTRL           (zynqmp_crf_apb_clkc_base + 0x94)
41 #define CRF_APB_GDMA_REF_CTRL           (zynqmp_crf_apb_clkc_base + 0x98)
42 #define CRF_APB_DPDMA_REF_CTRL          (zynqmp_crf_apb_clkc_base + 0x9c)
43 #define CRF_APB_TOPSW_MAIN_CTRL         (zynqmp_crf_apb_clkc_base + 0xa0)
44 #define CRF_APB_TOPSW_LSBUS_CTRL        (zynqmp_crf_apb_clkc_base + 0xa4)
45 #define CRF_APB_GTGREF0_REF_CTRL        (zynqmp_crf_apb_clkc_base + 0xa8)
46 #define CRF_APB_DBG_TSTMP_CTRL          (zynqmp_crf_apb_clkc_base + 0xd8)
47
48 /* Low power domain clocks */
49 #define CRL_APB_IOPLL_CTRL              (zynqmp_crl_apb_clkc_base + 0x00)
50 #define CRL_APB_RPLL_CTRL               (zynqmp_crl_apb_clkc_base + 0x10)
51 #define CRL_APB_PLL_STATUS              (zynqmp_crl_apb_clkc_base + 0x20)
52 #define CRL_APB_IOPLL_TO_FPD_CTRL       (zynqmp_crl_apb_clkc_base + 0x24)
53 #define CRL_APB_RPLL_TO_FPD_CTRL        (zynqmp_crl_apb_clkc_base + 0x28)
54 /* Peripheral clocks */
55 #define CRL_APB_USB3_DUAL_REF_CTRL      (zynqmp_crl_apb_clkc_base + 0x2c)
56 #define CRL_APB_GEM0_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x30)
57 #define CRL_APB_GEM1_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x34)
58 #define CRL_APB_GEM2_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x38)
59 #define CRL_APB_GEM3_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x3c)
60 #define CRL_APB_USB0_BUS_REF_CTRL       (zynqmp_crl_apb_clkc_base + 0x40)
61 #define CRL_APB_USB1_BUS_REF_CTRL       (zynqmp_crl_apb_clkc_base + 0x44)
62 #define CRL_APB_QSPI_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x48)
63 #define CRL_APB_SDIO0_REF_CTRL          (zynqmp_crl_apb_clkc_base + 0x4c)
64 #define CRL_APB_SDIO1_REF_CTRL          (zynqmp_crl_apb_clkc_base + 0x50)
65 #define CRL_APB_UART0_REF_CTRL          (zynqmp_crl_apb_clkc_base + 0x54)
66 #define CRL_APB_UART1_REF_CTRL          (zynqmp_crl_apb_clkc_base + 0x58)
67 #define CRL_APB_SPI0_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x5c)
68 #define CRL_APB_SPI1_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x60)
69 #define CRL_APB_CAN0_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x64)
70 #define CRL_APB_CAN1_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x68)
71 #define CRL_APB_CPU_R5_CTRL             (zynqmp_crl_apb_clkc_base + 0x70)
72 #define CRL_APB_IOU_SWITCH_CTRL         (zynqmp_crl_apb_clkc_base + 0x7c)
73 #define CRL_APB_CSU_PLL_CTRL            (zynqmp_crl_apb_clkc_base + 0x80)
74 #define CRL_APB_PCAP_CTRL               (zynqmp_crl_apb_clkc_base + 0x84)
75 #define CRL_APB_LPD_SWITCH_CTRL         (zynqmp_crl_apb_clkc_base + 0x88)
76 #define CRL_APB_LPD_LSBUS_CTRL          (zynqmp_crl_apb_clkc_base + 0x8c)
77 #define CRL_APB_DBG_LPD_CTRL            (zynqmp_crl_apb_clkc_base + 0x90)
78 #define CRL_APB_NAND_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x94)
79 #define CRL_APB_ADMA_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x98)
80 #define CRL_APB_PL0_REF_CTRL            (zynqmp_crl_apb_clkc_base + 0xa0)
81 #define CRL_APB_PL1_REF_CTRL            (zynqmp_crl_apb_clkc_base + 0xa4)
82 #define CRL_APB_PL2_REF_CTRL            (zynqmp_crl_apb_clkc_base + 0xa8)
83 #define CRL_APB_PL3_REF_CTRL            (zynqmp_crl_apb_clkc_base + 0xac)
84 #define CRL_APB_PL0_THR_CNT             (zynqmp_crl_apb_clkc_base + 0xb4)
85 #define CRL_APB_PL1_THR_CNT             (zynqmp_crl_apb_clkc_base + 0xbc)
86 #define CRL_APB_PL2_THR_CNT             (zynqmp_crl_apb_clkc_base + 0xc4)
87 #define CRL_APB_PL3_THR_CNT             (zynqmp_crl_apb_clkc_base + 0xdc)
88 #define CRL_APB_GEM_TSU_REF_CTRL        (zynqmp_crl_apb_clkc_base + 0xe0)
89 #define CRL_APB_DLL_REF_CTRL            (zynqmp_crl_apb_clkc_base + 0xe4)
90 #define CRL_APB_AMS_REF_CTRL            (zynqmp_crl_apb_clkc_base + 0xe8)
91 #define CRL_APB_I2C0_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x100)
92 #define CRL_APB_I2C1_REF_CTRL           (zynqmp_crl_apb_clkc_base + 0x104)
93 #define CRL_APB_TIMESTAMP_REF_CTRL      (zynqmp_crl_apb_clkc_base + 0x108)
94
95 #define ZYNQ_CLK_MAXDIV         0x3f
96 #define CLK_CTRL_DIV1_SHIFT     16
97 #define CLK_CTRL_DIV1_MASK      (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT)
98 #define CLK_CTRL_DIV0_SHIFT     8
99 #define CLK_CTRL_DIV0_MASK      (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT)
100 #define CLK_CTRL_SRCSEL_MASK    0x7
101 #define PLLCTRL_FBDIV_MASK      0x7f00
102 #define PLLCTRL_FBDIV_SHIFT     8
103 #define PLLCTRL_RESET_MASK      1
104 #define PLLCTRL_RESET_SHIFT     0
105 #define PLLCTRL_BYPASS_MASK     0x8
106 #define PLLCTRL_BYPASS_SHFT     3
107 #define PLLCTRL_POST_SRC_SHFT   24
108 #define PLLCTRL_POST_SRC_MASK   (0x7 << PLLCTRL_POST_SRC_SHFT)
109 #define PLLCTRL_PRE_SRC_SHFT    20
110 #define PLLCTRL_PRE_SRC_MASK    (0x7 << PLLCTRL_PRE_SRC_SHFT)
111
112
113 #define NUM_MIO_PINS    77
114
115 enum zynqmp_clk {
116         iopll, rpll,
117         apll, dpll, vpll,
118         iopll_to_fpd, rpll_to_fpd, apll_to_lpd, dpll_to_lpd, vpll_to_lpd,
119         acpu, acpu_half,
120         dbg_fpd, dbg_lpd, dbg_trace, dbg_tstmp,
121         dp_video_ref, dp_audio_ref,
122         dp_stc_ref, gdma_ref, dpdma_ref,
123         ddr_ref, sata_ref, pcie_ref,
124         gpu_ref, gpu_pp0_ref, gpu_pp1_ref,
125         topsw_main, topsw_lsbus,
126         gtgref0_ref,
127         lpd_switch, lpd_lsbus,
128         usb0_bus_ref, usb1_bus_ref, usb3_dual_ref, usb0, usb1,
129         cpu_r5, cpu_r5_core,
130         csu_spb, csu_pll, pcap,
131         iou_switch,
132         gem_tsu_ref, gem_tsu,
133         gem0_tx, gem1_tx, gem2_tx, gem3_tx,
134         gem0_rx, gem1_rx, gem2_rx, gem3_rx,
135         qspi_ref,
136         sdio0_ref, sdio1_ref,
137         uart0_ref, uart1_ref,
138         spi0_ref, spi1_ref,
139         nand_ref,
140         i2c0_ref, i2c1_ref, can0_ref, can1_ref, can0, can1,
141         dll_ref,
142         adma_ref,
143         timestamp_ref,
144         ams_ref,
145         pl0, pl1, pl2, pl3,
146         wdt,
147         gem0_ref = 104,
148         gem1_ref, gem2_ref, gem3_ref,
149         clk_max,
150 };
151
152 static const char * const clk_names[clk_max] = {
153         "iopll", "rpll", "apll", "dpll",
154         "vpll", "iopll_to_fpd", "rpll_to_fpd",
155         "apll_to_lpd", "dpll_to_lpd", "vpll_to_lpd",
156         "acpu", "acpu_half", "dbg_fpd", "dbg_lpd",
157         "dbg_trace", "dbg_tstmp", "dp_video_ref",
158         "dp_audio_ref", "dp_stc_ref", "gdma_ref",
159         "dpdma_ref", "ddr_ref", "sata_ref", "pcie_ref",
160         "gpu_ref", "gpu_pp0_ref", "gpu_pp1_ref",
161         "topsw_main", "topsw_lsbus", "gtgref0_ref",
162         "lpd_switch", "lpd_lsbus", "usb0_bus_ref",
163         "usb1_bus_ref", "usb3_dual_ref", "usb0",
164         "usb1", "cpu_r5", "cpu_r5_core", "csu_spb",
165         "csu_pll", "pcap", "iou_switch", "gem_tsu_ref",
166         "gem_tsu", "gem0_tx", "gem1_tx", "gem2_tx",
167         "gem3_tx", "gem0_rx", "gem1_rx", "gem2_rx",
168         "gem3_rx", "qspi_ref", "sdio0_ref", "sdio1_ref",
169         "uart0_ref", "uart1_ref", "spi0_ref",
170         "spi1_ref", "nand_ref", "i2c0_ref", "i2c1_ref",
171         "can0_ref", "can1_ref", "can0", "can1",
172         "dll_ref", "adma_ref", "timestamp_ref",
173         "ams_ref", "pl0", "pl1", "pl2", "pl3", "wdt",
174         NULL, NULL, NULL, NULL,
175         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
176         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
177         NULL, NULL, NULL, NULL, "gem0_ref", "gem1_ref", "gem2_ref", "gem3_ref",
178 };
179
180 static const u32 pll_src[][4] = {
181         {apll, 0xff, dpll, vpll},               /* acpu */
182         {dpll, vpll, 0xff, 0xff},               /* ddr_ref */
183         {rpll, iopll, 0xff, 0xff},              /* dll_ref */
184         {iopll, 0xff, rpll, dpll_to_lpd},       /* gem_tsu_ref */
185         {iopll, 0xff, rpll, dpll},              /* peripheral */
186         {apll, 0xff, iopll_to_fpd, dpll},       /* wdt */
187         {iopll_to_fpd, 0xff, dpll, apll},       /* dbg_fpd */
188         {iopll, 0xff, rpll, dpll_to_lpd},       /* timestamp_ref */
189         {iopll_to_fpd, 0xff, apll, dpll},       /* sata_ref */
190         {iopll_to_fpd, 0xff, rpll_to_fpd, dpll},/* pcie_ref */
191         {iopll_to_fpd, 0xff, vpll, dpll},       /* gpu_ref */
192         {apll, 0xff, vpll, dpll},               /* topsw_main_ref */
193         {rpll, 0xff, iopll, dpll_to_lpd},       /* cpu_r5_ref */
194 };
195
196 enum zynqmp_clk_pll_src {
197         ACPU_CLK_SRC = 0,
198         DDR_CLK_SRC,
199         DLL_CLK_SRC,
200         GEM_TSU_CLK_SRC,
201         PERI_CLK_SRC,
202         WDT_CLK_SRC,
203         DBG_FPD_CLK_SRC,
204         TIMESTAMP_CLK_SRC,
205         SATA_CLK_SRC,
206         PCIE_CLK_SRC,
207         GPU_CLK_SRC,
208         TOPSW_MAIN_CLK_SRC,
209         CPU_R5_CLK_SRC
210 };
211
212 struct zynqmp_clk_priv {
213         unsigned long ps_clk_freq;
214         unsigned long video_clk;
215         unsigned long pss_alt_ref_clk;
216         unsigned long gt_crx_ref_clk;
217         unsigned long aux_ref_clk;
218 };
219
220 static u32 zynqmp_clk_get_register(enum zynqmp_clk id)
221 {
222         switch (id) {
223         case iopll:
224                 return CRL_APB_IOPLL_CTRL;
225         case rpll:
226                 return CRL_APB_RPLL_CTRL;
227         case apll:
228                 return CRF_APB_APLL_CTRL;
229         case dpll:
230                 return CRF_APB_DPLL_CTRL;
231         case vpll:
232                 return CRF_APB_VPLL_CTRL;
233         case acpu:
234                 return CRF_APB_ACPU_CTRL;
235         case dbg_fpd:
236                 return CRF_APB_DBG_FPD_CTRL;
237         case dbg_trace:
238                 return CRF_APB_DBG_TRACE_CTRL;
239         case dbg_tstmp:
240                 return CRF_APB_DBG_TSTMP_CTRL;
241         case dp_video_ref:
242                 return CRF_APB_DP_VIDEO_REF_CTRL;
243         case dp_audio_ref:
244                 return CRF_APB_DP_AUDIO_REF_CTRL;
245         case dp_stc_ref:
246                 return CRF_APB_DP_STC_REF_CTRL;
247         case gpu_ref ...  gpu_pp1_ref:
248                 return CRF_APB_GPU_REF_CTRL;
249         case ddr_ref:
250                 return CRF_APB_DDR_CTRL;
251         case sata_ref:
252                 return CRF_APB_SATA_REF_CTRL;
253         case pcie_ref:
254                 return CRF_APB_PCIE_REF_CTRL;
255         case gdma_ref:
256                 return CRF_APB_GDMA_REF_CTRL;
257         case dpdma_ref:
258                 return CRF_APB_DPDMA_REF_CTRL;
259         case topsw_main:
260                 return CRF_APB_TOPSW_MAIN_CTRL;
261         case topsw_lsbus:
262                 return CRF_APB_TOPSW_LSBUS_CTRL;
263         case lpd_switch:
264                 return CRL_APB_LPD_SWITCH_CTRL;
265         case lpd_lsbus:
266                 return CRL_APB_LPD_LSBUS_CTRL;
267         case qspi_ref:
268                 return CRL_APB_QSPI_REF_CTRL;
269         case usb3_dual_ref:
270                 return CRL_APB_USB3_DUAL_REF_CTRL;
271         case gem_tsu_ref:
272                 return CRL_APB_GEM_TSU_REF_CTRL;
273         case gem0_tx:
274         case gem0_ref:
275                 return CRL_APB_GEM0_REF_CTRL;
276         case gem1_tx:
277         case gem1_ref:
278                 return CRL_APB_GEM1_REF_CTRL;
279         case gem2_tx:
280         case gem2_ref:
281                 return CRL_APB_GEM2_REF_CTRL;
282         case gem3_tx:
283         case gem3_ref:
284                 return CRL_APB_GEM3_REF_CTRL;
285         case usb0_bus_ref:
286                 return CRL_APB_USB0_BUS_REF_CTRL;
287         case usb1_bus_ref:
288                 return CRL_APB_USB1_BUS_REF_CTRL;
289         case cpu_r5:
290                 return CRL_APB_CPU_R5_CTRL;
291         case uart0_ref:
292                 return CRL_APB_UART0_REF_CTRL;
293         case uart1_ref:
294                 return CRL_APB_UART1_REF_CTRL;
295         case sdio0_ref:
296                 return CRL_APB_SDIO0_REF_CTRL;
297         case sdio1_ref:
298                 return CRL_APB_SDIO1_REF_CTRL;
299         case spi0_ref:
300                 return CRL_APB_SPI0_REF_CTRL;
301         case spi1_ref:
302                 return CRL_APB_SPI1_REF_CTRL;
303         case nand_ref:
304                 return CRL_APB_NAND_REF_CTRL;
305         case i2c0_ref:
306                 return CRL_APB_I2C0_REF_CTRL;
307         case i2c1_ref:
308                 return CRL_APB_I2C1_REF_CTRL;
309         case can0_ref:
310                 return CRL_APB_CAN0_REF_CTRL;
311         case can1_ref:
312                 return CRL_APB_CAN1_REF_CTRL;
313         case dll_ref:
314                 return CRL_APB_DLL_REF_CTRL;
315         case adma_ref:
316                 return CRL_APB_ADMA_REF_CTRL;
317         case timestamp_ref:
318                 return CRL_APB_TIMESTAMP_REF_CTRL;
319         case ams_ref:
320                 return CRL_APB_AMS_REF_CTRL;
321         case pl0:
322                 return CRL_APB_PL0_REF_CTRL;
323         case pl1:
324                 return CRL_APB_PL1_REF_CTRL;
325         case pl2:
326                 return CRL_APB_PL2_REF_CTRL;
327         case pl3:
328                 return CRL_APB_PL3_REF_CTRL;
329         case wdt:
330                 return CRF_APB_TOPSW_LSBUS_CTRL;
331         case iopll_to_fpd:
332                 return CRL_APB_IOPLL_TO_FPD_CTRL;
333         default:
334                 debug("Invalid clk id%d\n", id);
335         }
336         return 0;
337 }
338
339 static ulong zynqmp_clk_get_pll_src(ulong clk_ctrl,
340                                     struct zynqmp_clk_priv *priv,
341                                     bool is_pre_src)
342 {
343         u32 src_sel;
344
345         if (is_pre_src)
346                 src_sel = (clk_ctrl & PLLCTRL_PRE_SRC_MASK) >>
347                            PLLCTRL_PRE_SRC_SHFT;
348         else
349                 src_sel = (clk_ctrl & PLLCTRL_POST_SRC_MASK) >>
350                            PLLCTRL_POST_SRC_SHFT;
351
352         switch (src_sel) {
353         case 4:
354                 return priv->video_clk;
355         case 5:
356                 return priv->pss_alt_ref_clk;
357         case 6:
358                 return priv->aux_ref_clk;
359         case 7:
360                 return priv->gt_crx_ref_clk;
361         case 0 ... 3:
362         default:
363         return priv->ps_clk_freq;
364         }
365 }
366
367 static ulong zynqmp_clk_get_pll_rate(struct zynqmp_clk_priv *priv,
368                                      enum zynqmp_clk id)
369 {
370         u32 clk_ctrl, reset, mul;
371         ulong freq;
372         int ret;
373
374         ret = zynqmp_mmio_read(zynqmp_clk_get_register(id), &clk_ctrl);
375         if (ret) {
376                 printf("%s mio read fail\n", __func__);
377                 return -EIO;
378         }
379
380         if (clk_ctrl & PLLCTRL_BYPASS_MASK)
381                 freq = zynqmp_clk_get_pll_src(clk_ctrl, priv, 0);
382         else
383                 freq = zynqmp_clk_get_pll_src(clk_ctrl, priv, 1);
384
385         reset = (clk_ctrl & PLLCTRL_RESET_MASK) >> PLLCTRL_RESET_SHIFT;
386         if (reset && !(clk_ctrl & PLLCTRL_BYPASS_MASK))
387                 return 0;
388
389         mul = (clk_ctrl & PLLCTRL_FBDIV_MASK) >> PLLCTRL_FBDIV_SHIFT;
390
391         freq *= mul;
392
393         if (clk_ctrl & (1 << 16))
394                 freq /= 2;
395
396         return freq;
397 }
398
399 static ulong zynqmp_clk_get_cpu_rate(struct zynqmp_clk_priv *priv,
400                                      enum zynqmp_clk id)
401 {
402         u32 clk_ctrl, div, srcsel;
403         enum zynqmp_clk pll;
404         int ret;
405         unsigned long pllrate;
406
407         ret = zynqmp_mmio_read(CRF_APB_ACPU_CTRL, &clk_ctrl);
408         if (ret) {
409                 printf("%s mio read fail\n", __func__);
410                 return -EIO;
411         }
412
413         div = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
414
415         srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
416         pll = pll_src[ACPU_CLK_SRC][srcsel];
417         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
418         if (IS_ERR_VALUE(pllrate))
419                 return pllrate;
420
421         return DIV_ROUND_CLOSEST(pllrate, div);
422 }
423
424 static ulong zynqmp_clk_get_ddr_rate(struct zynqmp_clk_priv *priv)
425 {
426         u32 clk_ctrl, div, srcsel;
427         enum zynqmp_clk pll;
428         int ret;
429         ulong pllrate;
430
431         ret = zynqmp_mmio_read(CRF_APB_DDR_CTRL, &clk_ctrl);
432         if (ret) {
433                 printf("%s mio read fail\n", __func__);
434                 return -EIO;
435         }
436
437         div = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
438
439         srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
440         pll = pll_src[DDR_CLK_SRC][srcsel];
441         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
442         if (IS_ERR_VALUE(pllrate))
443                 return pllrate;
444
445         return DIV_ROUND_CLOSEST(pllrate, div);
446 }
447
448 static ulong zynqmp_clk_get_dll_rate(struct zynqmp_clk_priv *priv)
449 {
450         u32 clk_ctrl, srcsel;
451         enum zynqmp_clk pll;
452         ulong pllrate;
453         int ret;
454
455         ret = zynqmp_mmio_read(CRL_APB_DLL_REF_CTRL, &clk_ctrl);
456         if (ret) {
457                 printf("%s mio read fail\n", __func__);
458                 return -EIO;
459         }
460
461         srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
462         pll = pll_src[DLL_CLK_SRC][srcsel];
463         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
464         if (IS_ERR_VALUE(pllrate))
465                 return pllrate;
466
467         return pllrate;
468 }
469
470 static ulong zynqmp_clk_get_peripheral_rate(struct zynqmp_clk_priv *priv,
471                                             enum zynqmp_clk id, bool two_divs)
472 {
473         enum zynqmp_clk pll;
474         u32 clk_ctrl, div0, srcsel;
475         u32 div1 = 1;
476         int ret;
477         ulong pllrate;
478
479         ret = zynqmp_mmio_read(zynqmp_clk_get_register(id), &clk_ctrl);
480         if (ret) {
481                 printf("%s mio read fail\n", __func__);
482                 return -EIO;
483         }
484
485         div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
486         if (!div0)
487                 div0 = 1;
488
489         if (two_divs) {
490                 div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
491                 if (!div1)
492                         div1 = 1;
493         }
494         srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
495
496         if (id == gem_tsu_ref)
497                 pll = pll_src[GEM_TSU_CLK_SRC][srcsel];
498         else
499                 pll = pll_src[PERI_CLK_SRC][srcsel];
500
501         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
502         if (IS_ERR_VALUE(pllrate))
503                 return pllrate;
504
505         return
506                 DIV_ROUND_CLOSEST(
507                         DIV_ROUND_CLOSEST(pllrate, div0), div1);
508 }
509
510 static ulong zynqmp_clk_get_crf_crl_rate(struct zynqmp_clk_priv *priv,
511                                          enum zynqmp_clk id, bool two_divs)
512 {
513         enum zynqmp_clk pll;
514         u32 clk_ctrl, div0, srcsel;
515         u32 div1 = 1;
516         int ret;
517         ulong pllrate;
518
519         ret = zynqmp_mmio_read(zynqmp_clk_get_register(id), &clk_ctrl);
520         if (ret) {
521                 printf("%d %s mio read fail\n", __LINE__, __func__);
522                 return -EIO;
523         }
524
525         div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
526         if (!div0)
527                 div0 = 1;
528         srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
529
530         switch (id) {
531         case wdt:
532         case dbg_trace:
533         case topsw_lsbus:
534                 pll = pll_src[WDT_CLK_SRC][srcsel];
535                 break;
536         case dbg_fpd:
537         case dbg_tstmp:
538                 pll = pll_src[DBG_FPD_CLK_SRC][srcsel];
539                 break;
540         case timestamp_ref:
541                 pll = pll_src[TIMESTAMP_CLK_SRC][srcsel];
542                 break;
543         case sata_ref:
544                 pll = pll_src[SATA_CLK_SRC][srcsel];
545                 break;
546         case pcie_ref:
547                 pll = pll_src[PCIE_CLK_SRC][srcsel];
548                 break;
549         case gpu_ref ... gpu_pp1_ref:
550                 pll = pll_src[GPU_CLK_SRC][srcsel];
551                 break;
552         case gdma_ref:
553         case dpdma_ref:
554         case topsw_main:
555                 pll = pll_src[TOPSW_MAIN_CLK_SRC][srcsel];
556                 break;
557         case cpu_r5:
558         case ams_ref:
559         case adma_ref:
560         case lpd_lsbus:
561         case lpd_switch:
562                 pll = pll_src[CPU_R5_CLK_SRC][srcsel];
563                 break;
564         default:
565                 return -ENXIO;
566         }
567         if (two_divs) {
568                 ret = zynqmp_mmio_read(zynqmp_clk_get_register(pll), &clk_ctrl);
569                 if (ret) {
570                         printf("%d %s mio read fail\n", __LINE__, __func__);
571                         return -EIO;
572                 }
573                 div1 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
574                 if (!div1)
575                         div1 = 1;
576         }
577
578         if (pll == iopll_to_fpd)
579                 pll = iopll;
580
581         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
582         if (IS_ERR_VALUE(pllrate))
583                 return pllrate;
584
585         return
586                 DIV_ROUND_CLOSEST(
587                         DIV_ROUND_CLOSEST(pllrate, div0), div1);
588 }
589
590 static unsigned long zynqmp_clk_calc_peripheral_two_divs(ulong rate,
591                                                        ulong pll_rate,
592                                                        u32 *div0, u32 *div1)
593 {
594         long new_err, best_err = (long)(~0UL >> 1);
595         ulong new_rate, best_rate = 0;
596         u32 d0, d1;
597
598         for (d0 = 1; d0 <= ZYNQ_CLK_MAXDIV; d0++) {
599                 for (d1 = 1; d1 <= ZYNQ_CLK_MAXDIV >> 1; d1++) {
600                         new_rate = DIV_ROUND_CLOSEST(
601                                         DIV_ROUND_CLOSEST(pll_rate, d0), d1);
602                         new_err = abs(new_rate - rate);
603
604                         if (new_err < best_err) {
605                                 *div0 = d0;
606                                 *div1 = d1;
607                                 best_err = new_err;
608                                 best_rate = new_rate;
609                         }
610                 }
611         }
612
613         return best_rate;
614 }
615
616 static ulong zynqmp_clk_set_peripheral_rate(struct zynqmp_clk_priv *priv,
617                                           enum zynqmp_clk id, ulong rate,
618                                           bool two_divs)
619 {
620         enum zynqmp_clk pll;
621         u32 clk_ctrl, div0 = 0, div1 = 0;
622         ulong pll_rate, new_rate;
623         u32 reg, srcsel;
624         int ret;
625         u32 mask;
626
627         reg = zynqmp_clk_get_register(id);
628         ret = zynqmp_mmio_read(reg, &clk_ctrl);
629         if (ret) {
630                 printf("%s mio read fail\n", __func__);
631                 return -EIO;
632         }
633
634         srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
635         pll = pll_src[PERI_CLK_SRC][srcsel];
636         pll_rate = zynqmp_clk_get_pll_rate(priv, pll);
637         if (IS_ERR_VALUE(pll_rate))
638                 return pll_rate;
639
640         clk_ctrl &= ~CLK_CTRL_DIV0_MASK;
641         if (two_divs) {
642                 clk_ctrl &= ~CLK_CTRL_DIV1_MASK;
643                 new_rate = zynqmp_clk_calc_peripheral_two_divs(rate, pll_rate,
644                                 &div0, &div1);
645                 clk_ctrl |= div1 << CLK_CTRL_DIV1_SHIFT;
646         } else {
647                 div0 = DIV_ROUND_CLOSEST(pll_rate, rate);
648                 if (div0 > ZYNQ_CLK_MAXDIV)
649                         div0 = ZYNQ_CLK_MAXDIV;
650                 new_rate = DIV_ROUND_CLOSEST(rate, div0);
651         }
652         clk_ctrl |= div0 << CLK_CTRL_DIV0_SHIFT;
653
654         mask = (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT) |
655                (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT);
656
657         ret = zynqmp_mmio_write(reg, mask, clk_ctrl);
658         if (ret) {
659                 printf("%s mio write fail\n", __func__);
660                 return -EIO;
661         }
662
663         return new_rate;
664 }
665
666 static ulong zynqmp_clk_get_rate(struct clk *clk)
667 {
668         struct zynqmp_clk_priv *priv = dev_get_priv(clk->dev);
669         enum zynqmp_clk id = clk->id;
670         bool two_divs = false;
671
672         switch (id) {
673         case iopll ... vpll:
674                 return zynqmp_clk_get_pll_rate(priv, id);
675         case acpu:
676                 return zynqmp_clk_get_cpu_rate(priv, id);
677         case ddr_ref:
678                 return zynqmp_clk_get_ddr_rate(priv);
679         case dll_ref:
680                 return zynqmp_clk_get_dll_rate(priv);
681         case gem_tsu_ref:
682         case dp_video_ref ... dp_stc_ref:
683         case pl0 ... pl3:
684         case gem0_ref ... gem3_ref:
685         case gem0_tx ... gem3_tx:
686         case qspi_ref ... can1_ref:
687         case usb0_bus_ref ... usb3_dual_ref:
688                 two_divs = true;
689                 return zynqmp_clk_get_peripheral_rate(priv, id, two_divs);
690         case wdt:
691         case topsw_lsbus:
692         case sata_ref ... gpu_pp1_ref:
693                 two_divs = true;
694         case cpu_r5:
695         case dbg_fpd:
696         case ams_ref:
697         case adma_ref:
698         case lpd_lsbus:
699         case dbg_trace:
700         case dbg_tstmp:
701         case lpd_switch:
702         case topsw_main:
703         case timestamp_ref:
704         case gdma_ref ... dpdma_ref:
705                 return zynqmp_clk_get_crf_crl_rate(priv, id, two_divs);
706         default:
707                 return -ENXIO;
708         }
709 }
710
711 static ulong zynqmp_clk_set_rate(struct clk *clk, ulong rate)
712 {
713         struct zynqmp_clk_priv *priv = dev_get_priv(clk->dev);
714         enum zynqmp_clk id = clk->id;
715         bool two_divs = true;
716
717         switch (id) {
718         case gem0_ref ... gem3_ref:
719         case gem0_tx ... gem3_tx:
720         case qspi_ref ... can1_ref:
721         case usb0_bus_ref ... usb3_dual_ref:
722                 return zynqmp_clk_set_peripheral_rate(priv, id,
723                                                       rate, two_divs);
724         default:
725                 return -ENXIO;
726         }
727 }
728
729 int soc_clk_dump(void)
730 {
731         struct udevice *dev;
732         int i, ret;
733
734         ret = uclass_get_device_by_driver(UCLASS_CLK,
735                 DM_DRIVER_GET(zynqmp_clk), &dev);
736         if (ret)
737                 return ret;
738
739         printf("clk\t\tfrequency\n");
740         for (i = 0; i < clk_max; i++) {
741                 const char *name = clk_names[i];
742                 if (name) {
743                         struct clk clk;
744                         unsigned long rate;
745
746                         clk.id = i;
747                         ret = clk_request(dev, &clk);
748                         if (ret < 0)
749                                 return ret;
750
751                         rate = clk_get_rate(&clk);
752
753                         clk_free(&clk);
754
755                         if ((rate == (unsigned long)-ENOSYS) ||
756                             (rate == (unsigned long)-ENXIO) ||
757                             (rate == (unsigned long)-EIO))
758                                 printf("%10s%20s\n", name, "unknown");
759                         else
760                                 printf("%10s%20lu\n", name, rate);
761                 }
762         }
763
764         return 0;
765 }
766
767 static int zynqmp_get_freq_by_name(char *name, struct udevice *dev, ulong *freq)
768 {
769         struct clk clk;
770         int ret;
771
772         ret = clk_get_by_name(dev, name, &clk);
773         if (ret < 0) {
774                 dev_err(dev, "failed to get %s\n", name);
775                 return ret;
776         }
777
778         *freq = clk_get_rate(&clk);
779         if (IS_ERR_VALUE(*freq)) {
780                 dev_err(dev, "failed to get rate %s\n", name);
781                 return -EINVAL;
782         }
783
784         return 0;
785 }
786 static int zynqmp_clk_probe(struct udevice *dev)
787 {
788         int ret;
789         struct zynqmp_clk_priv *priv = dev_get_priv(dev);
790
791         debug("%s\n", __func__);
792         ret = zynqmp_get_freq_by_name("pss_ref_clk", dev, &priv->ps_clk_freq);
793         if (ret < 0)
794                 return -EINVAL;
795
796         ret = zynqmp_get_freq_by_name("video_clk", dev, &priv->video_clk);
797         if (ret < 0)
798                 return -EINVAL;
799
800         ret = zynqmp_get_freq_by_name("pss_alt_ref_clk", dev,
801                                       &priv->pss_alt_ref_clk);
802         if (ret < 0)
803                 return -EINVAL;
804
805         ret = zynqmp_get_freq_by_name("aux_ref_clk", dev, &priv->aux_ref_clk);
806         if (ret < 0)
807                 return -EINVAL;
808
809         ret = zynqmp_get_freq_by_name("gt_crx_ref_clk", dev,
810                                       &priv->gt_crx_ref_clk);
811         if (ret < 0)
812                 return -EINVAL;
813
814         return 0;
815 }
816
817 static int zynqmp_clk_enable(struct clk *clk)
818 {
819         enum zynqmp_clk id = clk->id;
820         u32 reg, clk_ctrl, clkact_shift, mask;
821         int ret;
822
823         reg = zynqmp_clk_get_register(id);
824         debug("%s, clk_id:%x, clk_base:0x%x\n", __func__, id, reg);
825
826         switch (id) {
827         case usb0_bus_ref ... usb1:
828                 clkact_shift = 25;
829                 mask = 0x1;
830                 break;
831         case gem0_tx ... gem3_tx:
832         case gem0_ref ... gem3_ref:
833                 clkact_shift = 25;
834                 mask = 0x3;
835                 break;
836         case qspi_ref ... can1_ref:
837         case lpd_lsbus:
838                 clkact_shift = 24;
839                 mask = 0x1;
840                 break;
841         default:
842                 return -ENXIO;
843         }
844
845         ret = zynqmp_mmio_read(reg, &clk_ctrl);
846         if (ret) {
847                 printf("%s mio read fail\n", __func__);
848                 return -EIO;
849         }
850
851         clk_ctrl |= (mask << clkact_shift);
852         ret = zynqmp_mmio_write(reg, mask << clkact_shift, clk_ctrl);
853         if (ret) {
854                 printf("%s mio write fail\n", __func__);
855                 return -EIO;
856         }
857
858         return ret;
859 }
860
861 static struct clk_ops zynqmp_clk_ops = {
862         .set_rate = zynqmp_clk_set_rate,
863         .get_rate = zynqmp_clk_get_rate,
864         .enable = zynqmp_clk_enable,
865 };
866
867 static const struct udevice_id zynqmp_clk_ids[] = {
868         { .compatible = "xlnx,zynqmp-clk" },
869         { }
870 };
871
872 U_BOOT_DRIVER(zynqmp_clk) = {
873         .name = "zynqmp_clk",
874         .id = UCLASS_CLK,
875         .of_match = zynqmp_clk_ids,
876         .probe = zynqmp_clk_probe,
877         .ops = &zynqmp_clk_ops,
878         .priv_auto      = sizeof(struct zynqmp_clk_priv),
879 };