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 
zynqmp_clk_get_register(enum zynqmp_clk id)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 
zynqmp_clk_get_pll_src(ulong clk_ctrl,struct zynqmp_clk_priv * priv,bool is_pre_src)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 
zynqmp_clk_get_pll_rate(struct zynqmp_clk_priv * priv,enum zynqmp_clk id)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 
zynqmp_clk_get_cpu_rate(struct zynqmp_clk_priv * priv,enum zynqmp_clk id)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 
zynqmp_clk_get_ddr_rate(struct zynqmp_clk_priv * priv)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 
zynqmp_clk_get_dll_rate(struct zynqmp_clk_priv * priv)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 
zynqmp_clk_get_peripheral_rate(struct zynqmp_clk_priv * priv,enum zynqmp_clk id,bool two_divs)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 
zynqmp_clk_get_crf_crl_rate(struct zynqmp_clk_priv * priv,enum zynqmp_clk id,bool two_divs)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 
zynqmp_clk_calc_peripheral_two_divs(ulong rate,ulong pll_rate,u32 * div0,u32 * div1)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 
zynqmp_clk_set_peripheral_rate(struct zynqmp_clk_priv * priv,enum zynqmp_clk id,ulong rate,bool two_divs)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 
zynqmp_clk_get_rate(struct clk * clk)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 
zynqmp_clk_set_rate(struct clk * clk,ulong rate)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 
soc_clk_dump(void)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 
zynqmp_get_freq_by_name(char * name,struct udevice * dev,ulong * freq)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 }
zynqmp_clk_probe(struct udevice * dev)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 
zynqmp_clk_enable(struct clk * clk)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 };
880