Merge tag 'xilinx-for-v2022.07-rc1' of https://source.denx.de/u-boot/custodians/u...
[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 gpu_ref ...  gpu_pp1_ref:
242                 return CRF_APB_GPU_REF_CTRL;
243         case ddr_ref:
244                 return CRF_APB_DDR_CTRL;
245         case sata_ref:
246                 return CRF_APB_SATA_REF_CTRL;
247         case pcie_ref:
248                 return CRF_APB_PCIE_REF_CTRL;
249         case gdma_ref:
250                 return CRF_APB_GDMA_REF_CTRL;
251         case dpdma_ref:
252                 return CRF_APB_DPDMA_REF_CTRL;
253         case topsw_main:
254                 return CRF_APB_TOPSW_MAIN_CTRL;
255         case topsw_lsbus:
256                 return CRF_APB_TOPSW_LSBUS_CTRL;
257         case lpd_switch:
258                 return CRL_APB_LPD_SWITCH_CTRL;
259         case lpd_lsbus:
260                 return CRL_APB_LPD_LSBUS_CTRL;
261         case qspi_ref:
262                 return CRL_APB_QSPI_REF_CTRL;
263         case usb3_dual_ref:
264                 return CRL_APB_USB3_DUAL_REF_CTRL;
265         case gem_tsu_ref:
266                 return CRL_APB_GEM_TSU_REF_CTRL;
267         case gem0_tx:
268         case gem0_ref:
269                 return CRL_APB_GEM0_REF_CTRL;
270         case gem1_tx:
271         case gem1_ref:
272                 return CRL_APB_GEM1_REF_CTRL;
273         case gem2_tx:
274         case gem2_ref:
275                 return CRL_APB_GEM2_REF_CTRL;
276         case gem3_tx:
277         case gem3_ref:
278                 return CRL_APB_GEM3_REF_CTRL;
279         case usb0_bus_ref:
280                 return CRL_APB_USB0_BUS_REF_CTRL;
281         case usb1_bus_ref:
282                 return CRL_APB_USB1_BUS_REF_CTRL;
283         case cpu_r5:
284                 return CRL_APB_CPU_R5_CTRL;
285         case uart0_ref:
286                 return CRL_APB_UART0_REF_CTRL;
287         case uart1_ref:
288                 return CRL_APB_UART1_REF_CTRL;
289         case sdio0_ref:
290                 return CRL_APB_SDIO0_REF_CTRL;
291         case sdio1_ref:
292                 return CRL_APB_SDIO1_REF_CTRL;
293         case spi0_ref:
294                 return CRL_APB_SPI0_REF_CTRL;
295         case spi1_ref:
296                 return CRL_APB_SPI1_REF_CTRL;
297         case nand_ref:
298                 return CRL_APB_NAND_REF_CTRL;
299         case i2c0_ref:
300                 return CRL_APB_I2C0_REF_CTRL;
301         case i2c1_ref:
302                 return CRL_APB_I2C1_REF_CTRL;
303         case can0_ref:
304                 return CRL_APB_CAN0_REF_CTRL;
305         case can1_ref:
306                 return CRL_APB_CAN1_REF_CTRL;
307         case dll_ref:
308                 return CRL_APB_DLL_REF_CTRL;
309         case adma_ref:
310                 return CRL_APB_ADMA_REF_CTRL;
311         case timestamp_ref:
312                 return CRL_APB_TIMESTAMP_REF_CTRL;
313         case ams_ref:
314                 return CRL_APB_AMS_REF_CTRL;
315         case pl0:
316                 return CRL_APB_PL0_REF_CTRL;
317         case pl1:
318                 return CRL_APB_PL1_REF_CTRL;
319         case pl2:
320                 return CRL_APB_PL2_REF_CTRL;
321         case pl3:
322                 return CRL_APB_PL3_REF_CTRL;
323         case wdt:
324                 return CRF_APB_TOPSW_LSBUS_CTRL;
325         case iopll_to_fpd:
326                 return CRL_APB_IOPLL_TO_FPD_CTRL;
327         default:
328                 debug("Invalid clk id%d\n", id);
329         }
330         return 0;
331 }
332
333 static ulong zynqmp_clk_get_pll_src(ulong clk_ctrl,
334                                     struct zynqmp_clk_priv *priv,
335                                     bool is_pre_src)
336 {
337         u32 src_sel;
338
339         if (is_pre_src)
340                 src_sel = (clk_ctrl & PLLCTRL_PRE_SRC_MASK) >>
341                            PLLCTRL_PRE_SRC_SHFT;
342         else
343                 src_sel = (clk_ctrl & PLLCTRL_POST_SRC_MASK) >>
344                            PLLCTRL_POST_SRC_SHFT;
345
346         switch (src_sel) {
347         case 4:
348                 return priv->video_clk;
349         case 5:
350                 return priv->pss_alt_ref_clk;
351         case 6:
352                 return priv->aux_ref_clk;
353         case 7:
354                 return priv->gt_crx_ref_clk;
355         case 0 ... 3:
356         default:
357         return priv->ps_clk_freq;
358         }
359 }
360
361 static ulong zynqmp_clk_get_pll_rate(struct zynqmp_clk_priv *priv,
362                                      enum zynqmp_clk id)
363 {
364         u32 clk_ctrl, reset, mul;
365         ulong freq;
366         int ret;
367
368         ret = zynqmp_mmio_read(zynqmp_clk_get_register(id), &clk_ctrl);
369         if (ret) {
370                 printf("%s mio read fail\n", __func__);
371                 return -EIO;
372         }
373
374         if (clk_ctrl & PLLCTRL_BYPASS_MASK)
375                 freq = zynqmp_clk_get_pll_src(clk_ctrl, priv, 0);
376         else
377                 freq = zynqmp_clk_get_pll_src(clk_ctrl, priv, 1);
378
379         reset = (clk_ctrl & PLLCTRL_RESET_MASK) >> PLLCTRL_RESET_SHIFT;
380         if (reset && !(clk_ctrl & PLLCTRL_BYPASS_MASK))
381                 return 0;
382
383         mul = (clk_ctrl & PLLCTRL_FBDIV_MASK) >> PLLCTRL_FBDIV_SHIFT;
384
385         freq *= mul;
386
387         if (clk_ctrl & (1 << 16))
388                 freq /= 2;
389
390         return freq;
391 }
392
393 static ulong zynqmp_clk_get_cpu_rate(struct zynqmp_clk_priv *priv,
394                                      enum zynqmp_clk id)
395 {
396         u32 clk_ctrl, div, srcsel;
397         enum zynqmp_clk pll;
398         int ret;
399         unsigned long pllrate;
400
401         ret = zynqmp_mmio_read(CRF_APB_ACPU_CTRL, &clk_ctrl);
402         if (ret) {
403                 printf("%s mio read fail\n", __func__);
404                 return -EIO;
405         }
406
407         div = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
408
409         srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
410         pll = pll_src[ACPU_CLK_SRC][srcsel];
411         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
412         if (IS_ERR_VALUE(pllrate))
413                 return pllrate;
414
415         return DIV_ROUND_CLOSEST(pllrate, div);
416 }
417
418 static ulong zynqmp_clk_get_ddr_rate(struct zynqmp_clk_priv *priv)
419 {
420         u32 clk_ctrl, div, srcsel;
421         enum zynqmp_clk pll;
422         int ret;
423         ulong pllrate;
424
425         ret = zynqmp_mmio_read(CRF_APB_DDR_CTRL, &clk_ctrl);
426         if (ret) {
427                 printf("%s mio read fail\n", __func__);
428                 return -EIO;
429         }
430
431         div = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
432
433         srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
434         pll = pll_src[DDR_CLK_SRC][srcsel];
435         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
436         if (IS_ERR_VALUE(pllrate))
437                 return pllrate;
438
439         return DIV_ROUND_CLOSEST(pllrate, div);
440 }
441
442 static ulong zynqmp_clk_get_dll_rate(struct zynqmp_clk_priv *priv)
443 {
444         u32 clk_ctrl, srcsel;
445         enum zynqmp_clk pll;
446         ulong pllrate;
447         int ret;
448
449         ret = zynqmp_mmio_read(CRL_APB_DLL_REF_CTRL, &clk_ctrl);
450         if (ret) {
451                 printf("%s mio read fail\n", __func__);
452                 return -EIO;
453         }
454
455         srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
456         pll = pll_src[DLL_CLK_SRC][srcsel];
457         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
458         if (IS_ERR_VALUE(pllrate))
459                 return pllrate;
460
461         return pllrate;
462 }
463
464 static ulong zynqmp_clk_get_peripheral_rate(struct zynqmp_clk_priv *priv,
465                                             enum zynqmp_clk id, bool two_divs)
466 {
467         enum zynqmp_clk pll;
468         u32 clk_ctrl, div0, srcsel;
469         u32 div1 = 1;
470         int ret;
471         ulong pllrate;
472
473         ret = zynqmp_mmio_read(zynqmp_clk_get_register(id), &clk_ctrl);
474         if (ret) {
475                 printf("%s mio read fail\n", __func__);
476                 return -EIO;
477         }
478
479         div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
480         if (!div0)
481                 div0 = 1;
482
483         if (two_divs) {
484                 div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
485                 if (!div1)
486                         div1 = 1;
487         }
488         srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
489
490         if (id == gem_tsu_ref)
491                 pll = pll_src[GEM_TSU_CLK_SRC][srcsel];
492         else
493                 pll = pll_src[PERI_CLK_SRC][srcsel];
494
495         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
496         if (IS_ERR_VALUE(pllrate))
497                 return pllrate;
498
499         return
500                 DIV_ROUND_CLOSEST(
501                         DIV_ROUND_CLOSEST(pllrate, div0), div1);
502 }
503
504 static ulong zynqmp_clk_get_crf_crl_rate(struct zynqmp_clk_priv *priv,
505                                          enum zynqmp_clk id, bool two_divs)
506 {
507         enum zynqmp_clk pll;
508         u32 clk_ctrl, div0, srcsel;
509         u32 div1 = 1;
510         int ret;
511         ulong pllrate;
512
513         ret = zynqmp_mmio_read(zynqmp_clk_get_register(id), &clk_ctrl);
514         if (ret) {
515                 printf("%d %s mio read fail\n", __LINE__, __func__);
516                 return -EIO;
517         }
518
519         div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
520         if (!div0)
521                 div0 = 1;
522         srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
523
524         switch (id) {
525         case wdt:
526         case dbg_trace:
527         case topsw_lsbus:
528                 pll = pll_src[WDT_CLK_SRC][srcsel];
529                 break;
530         case dbg_fpd:
531         case dbg_tstmp:
532                 pll = pll_src[DBG_FPD_CLK_SRC][srcsel];
533                 break;
534         case timestamp_ref:
535                 pll = pll_src[TIMESTAMP_CLK_SRC][srcsel];
536                 break;
537         case sata_ref:
538                 pll = pll_src[SATA_CLK_SRC][srcsel];
539                 break;
540         case pcie_ref:
541                 pll = pll_src[PCIE_CLK_SRC][srcsel];
542                 break;
543         case gpu_ref ... gpu_pp1_ref:
544                 pll = pll_src[GPU_CLK_SRC][srcsel];
545                 break;
546         case gdma_ref:
547         case dpdma_ref:
548         case topsw_main:
549                 pll = pll_src[TOPSW_MAIN_CLK_SRC][srcsel];
550                 break;
551         case cpu_r5:
552         case ams_ref:
553         case adma_ref:
554         case lpd_lsbus:
555         case lpd_switch:
556                 pll = pll_src[CPU_R5_CLK_SRC][srcsel];
557                 break;
558         default:
559                 return -ENXIO;
560         }
561         if (two_divs) {
562                 ret = zynqmp_mmio_read(zynqmp_clk_get_register(pll), &clk_ctrl);
563                 if (ret) {
564                         printf("%d %s mio read fail\n", __LINE__, __func__);
565                         return -EIO;
566                 }
567                 div1 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
568                 if (!div1)
569                         div1 = 1;
570         }
571
572         if (pll == iopll_to_fpd)
573                 pll = iopll;
574
575         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
576         if (IS_ERR_VALUE(pllrate))
577                 return pllrate;
578
579         return
580                 DIV_ROUND_CLOSEST(
581                         DIV_ROUND_CLOSEST(pllrate, div0), div1);
582 }
583
584 static unsigned long zynqmp_clk_calc_peripheral_two_divs(ulong rate,
585                                                        ulong pll_rate,
586                                                        u32 *div0, u32 *div1)
587 {
588         long new_err, best_err = (long)(~0UL >> 1);
589         ulong new_rate, best_rate = 0;
590         u32 d0, d1;
591
592         for (d0 = 1; d0 <= ZYNQ_CLK_MAXDIV; d0++) {
593                 for (d1 = 1; d1 <= ZYNQ_CLK_MAXDIV >> 1; d1++) {
594                         new_rate = DIV_ROUND_CLOSEST(
595                                         DIV_ROUND_CLOSEST(pll_rate, d0), d1);
596                         new_err = abs(new_rate - rate);
597
598                         if (new_err < best_err) {
599                                 *div0 = d0;
600                                 *div1 = d1;
601                                 best_err = new_err;
602                                 best_rate = new_rate;
603                         }
604                 }
605         }
606
607         return best_rate;
608 }
609
610 static ulong zynqmp_clk_set_peripheral_rate(struct zynqmp_clk_priv *priv,
611                                           enum zynqmp_clk id, ulong rate,
612                                           bool two_divs)
613 {
614         enum zynqmp_clk pll;
615         u32 clk_ctrl, div0 = 0, div1 = 0;
616         ulong pll_rate, new_rate;
617         u32 reg, srcsel;
618         int ret;
619         u32 mask;
620
621         reg = zynqmp_clk_get_register(id);
622         ret = zynqmp_mmio_read(reg, &clk_ctrl);
623         if (ret) {
624                 printf("%s mio read fail\n", __func__);
625                 return -EIO;
626         }
627
628         srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
629         pll = pll_src[PERI_CLK_SRC][srcsel];
630         pll_rate = zynqmp_clk_get_pll_rate(priv, pll);
631         if (IS_ERR_VALUE(pll_rate))
632                 return pll_rate;
633
634         clk_ctrl &= ~CLK_CTRL_DIV0_MASK;
635         if (two_divs) {
636                 clk_ctrl &= ~CLK_CTRL_DIV1_MASK;
637                 new_rate = zynqmp_clk_calc_peripheral_two_divs(rate, pll_rate,
638                                 &div0, &div1);
639                 clk_ctrl |= div1 << CLK_CTRL_DIV1_SHIFT;
640         } else {
641                 div0 = DIV_ROUND_CLOSEST(pll_rate, rate);
642                 if (div0 > ZYNQ_CLK_MAXDIV)
643                         div0 = ZYNQ_CLK_MAXDIV;
644                 new_rate = DIV_ROUND_CLOSEST(rate, div0);
645         }
646         clk_ctrl |= div0 << CLK_CTRL_DIV0_SHIFT;
647
648         mask = (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT) |
649                (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT);
650
651         ret = zynqmp_mmio_write(reg, mask, clk_ctrl);
652         if (ret) {
653                 printf("%s mio write fail\n", __func__);
654                 return -EIO;
655         }
656
657         return new_rate;
658 }
659
660 static ulong zynqmp_clk_get_rate(struct clk *clk)
661 {
662         struct zynqmp_clk_priv *priv = dev_get_priv(clk->dev);
663         enum zynqmp_clk id = clk->id;
664         bool two_divs = false;
665
666         switch (id) {
667         case iopll ... vpll:
668                 return zynqmp_clk_get_pll_rate(priv, id);
669         case acpu:
670                 return zynqmp_clk_get_cpu_rate(priv, id);
671         case ddr_ref:
672                 return zynqmp_clk_get_ddr_rate(priv);
673         case dll_ref:
674                 return zynqmp_clk_get_dll_rate(priv);
675         case gem_tsu_ref:
676         case pl0 ... pl3:
677         case gem0_ref ... gem3_ref:
678         case gem0_tx ... gem3_tx:
679         case qspi_ref ... can1_ref:
680         case usb0_bus_ref ... usb3_dual_ref:
681                 two_divs = true;
682                 return zynqmp_clk_get_peripheral_rate(priv, id, two_divs);
683         case wdt:
684         case topsw_lsbus:
685         case sata_ref ... gpu_pp1_ref:
686                 two_divs = true;
687         case cpu_r5:
688         case dbg_fpd:
689         case ams_ref:
690         case adma_ref:
691         case lpd_lsbus:
692         case dbg_trace:
693         case dbg_tstmp:
694         case lpd_switch:
695         case topsw_main:
696         case timestamp_ref:
697         case gdma_ref ... dpdma_ref:
698                 return zynqmp_clk_get_crf_crl_rate(priv, id, two_divs);
699         default:
700                 return -ENXIO;
701         }
702 }
703
704 static ulong zynqmp_clk_set_rate(struct clk *clk, ulong rate)
705 {
706         struct zynqmp_clk_priv *priv = dev_get_priv(clk->dev);
707         enum zynqmp_clk id = clk->id;
708         bool two_divs = true;
709
710         switch (id) {
711         case gem0_ref ... gem3_ref:
712         case gem0_tx ... gem3_tx:
713         case qspi_ref ... can1_ref:
714         case usb0_bus_ref ... usb3_dual_ref:
715                 return zynqmp_clk_set_peripheral_rate(priv, id,
716                                                       rate, two_divs);
717         default:
718                 return -ENXIO;
719         }
720 }
721
722 int soc_clk_dump(void)
723 {
724         struct udevice *dev;
725         int i, ret;
726
727         ret = uclass_get_device_by_driver(UCLASS_CLK,
728                 DM_DRIVER_GET(zynqmp_clk), &dev);
729         if (ret)
730                 return ret;
731
732         printf("clk\t\tfrequency\n");
733         for (i = 0; i < clk_max; i++) {
734                 const char *name = clk_names[i];
735                 if (name) {
736                         struct clk clk;
737                         unsigned long rate;
738
739                         clk.id = i;
740                         ret = clk_request(dev, &clk);
741                         if (ret < 0)
742                                 return ret;
743
744                         rate = clk_get_rate(&clk);
745
746                         clk_free(&clk);
747
748                         if ((rate == (unsigned long)-ENOSYS) ||
749                             (rate == (unsigned long)-ENXIO) ||
750                             (rate == (unsigned long)-EIO))
751                                 printf("%10s%20s\n", name, "unknown");
752                         else
753                                 printf("%10s%20lu\n", name, rate);
754                 }
755         }
756
757         return 0;
758 }
759
760 static int zynqmp_get_freq_by_name(char *name, struct udevice *dev, ulong *freq)
761 {
762         struct clk clk;
763         int ret;
764
765         ret = clk_get_by_name(dev, name, &clk);
766         if (ret < 0) {
767                 dev_err(dev, "failed to get %s\n", name);
768                 return ret;
769         }
770
771         *freq = clk_get_rate(&clk);
772         if (IS_ERR_VALUE(*freq)) {
773                 dev_err(dev, "failed to get rate %s\n", name);
774                 return -EINVAL;
775         }
776
777         return 0;
778 }
779 static int zynqmp_clk_probe(struct udevice *dev)
780 {
781         int ret;
782         struct zynqmp_clk_priv *priv = dev_get_priv(dev);
783
784         debug("%s\n", __func__);
785         ret = zynqmp_get_freq_by_name("pss_ref_clk", dev, &priv->ps_clk_freq);
786         if (ret < 0)
787                 return -EINVAL;
788
789         ret = zynqmp_get_freq_by_name("video_clk", dev, &priv->video_clk);
790         if (ret < 0)
791                 return -EINVAL;
792
793         ret = zynqmp_get_freq_by_name("pss_alt_ref_clk", dev,
794                                       &priv->pss_alt_ref_clk);
795         if (ret < 0)
796                 return -EINVAL;
797
798         ret = zynqmp_get_freq_by_name("aux_ref_clk", dev, &priv->aux_ref_clk);
799         if (ret < 0)
800                 return -EINVAL;
801
802         ret = zynqmp_get_freq_by_name("gt_crx_ref_clk", dev,
803                                       &priv->gt_crx_ref_clk);
804         if (ret < 0)
805                 return -EINVAL;
806
807         return 0;
808 }
809
810 static int zynqmp_clk_enable(struct clk *clk)
811 {
812         enum zynqmp_clk id = clk->id;
813         u32 reg, clk_ctrl, clkact_shift, mask;
814         int ret;
815
816         reg = zynqmp_clk_get_register(id);
817         debug("%s, clk_id:%x, clk_base:0x%x\n", __func__, id, reg);
818
819         switch (id) {
820         case usb0_bus_ref ... usb1:
821                 clkact_shift = 25;
822                 mask = 0x1;
823                 break;
824         case gem0_tx ... gem3_tx:
825         case gem0_ref ... gem3_ref:
826                 clkact_shift = 25;
827                 mask = 0x3;
828                 break;
829         case qspi_ref ... can1_ref:
830         case lpd_lsbus:
831                 clkact_shift = 24;
832                 mask = 0x1;
833                 break;
834         default:
835                 return -ENXIO;
836         }
837
838         ret = zynqmp_mmio_read(reg, &clk_ctrl);
839         if (ret) {
840                 printf("%s mio read fail\n", __func__);
841                 return -EIO;
842         }
843
844         clk_ctrl |= (mask << clkact_shift);
845         ret = zynqmp_mmio_write(reg, mask << clkact_shift, clk_ctrl);
846         if (ret) {
847                 printf("%s mio write fail\n", __func__);
848                 return -EIO;
849         }
850
851         return ret;
852 }
853
854 static struct clk_ops zynqmp_clk_ops = {
855         .set_rate = zynqmp_clk_set_rate,
856         .get_rate = zynqmp_clk_get_rate,
857         .enable = zynqmp_clk_enable,
858 };
859
860 static const struct udevice_id zynqmp_clk_ids[] = {
861         { .compatible = "xlnx,zynqmp-clk" },
862         { }
863 };
864
865 U_BOOT_DRIVER(zynqmp_clk) = {
866         .name = "zynqmp_clk",
867         .id = UCLASS_CLK,
868         .of_match = zynqmp_clk_ids,
869         .probe = zynqmp_clk_probe,
870         .ops = &zynqmp_clk_ops,
871         .priv_auto      = sizeof(struct zynqmp_clk_priv),
872 };