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