xref: /linux/drivers/clk/clk-axi-clkgen.c (revision 522ba450b56fff29f868b1552bdc2965f55de7ed)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * AXI clkgen driver
4  *
5  * Copyright 2012-2013 Analog Devices Inc.
6  *  Author: Lars-Peter Clausen <lars@metafoo.de>
7  */
8 
9 #include <linux/adi-axi-common.h>
10 #include <linux/bits.h>
11 #include <linux/clk.h>
12 #include <linux/clk-provider.h>
13 #include <linux/err.h>
14 #include <linux/io.h>
15 #include <linux/module.h>
16 #include <linux/mod_devicetable.h>
17 #include <linux/of.h>
18 #include <linux/platform_device.h>
19 #include <linux/slab.h>
20 
21 #define AXI_CLKGEN_V2_REG_RESET		0x40
22 #define AXI_CLKGEN_V2_REG_CLKSEL	0x44
23 #define AXI_CLKGEN_V2_REG_DRP_CNTRL	0x70
24 #define AXI_CLKGEN_V2_REG_DRP_STATUS	0x74
25 
26 #define AXI_CLKGEN_V2_RESET_MMCM_ENABLE	BIT(1)
27 #define AXI_CLKGEN_V2_RESET_ENABLE	BIT(0)
28 
29 #define AXI_CLKGEN_V2_DRP_CNTRL_SEL	BIT(29)
30 #define AXI_CLKGEN_V2_DRP_CNTRL_READ	BIT(28)
31 
32 #define AXI_CLKGEN_V2_DRP_STATUS_BUSY	BIT(16)
33 
34 #define ADI_CLKGEN_REG_FPGA_VOLTAGE		0x0140
35 #define ADI_CLKGEN_INFO_FPGA_VOLTAGE(val)	((val) & GENMASK(15, 0))
36 
37 #define MMCM_REG_CLKOUT5_2	0x07
38 #define MMCM_REG_CLKOUT0_1	0x08
39 #define MMCM_REG_CLKOUT0_2	0x09
40 #define MMCM_REG_CLKOUT6_2	0x13
41 #define MMCM_REG_CLK_FB1	0x14
42 #define MMCM_REG_CLK_FB2	0x15
43 #define MMCM_REG_CLK_DIV	0x16
44 #define MMCM_REG_LOCK1		0x18
45 #define MMCM_REG_LOCK2		0x19
46 #define MMCM_REG_LOCK3		0x1a
47 #define MMCM_REG_POWER		0x28
48 #define MMCM_REG_FILTER1	0x4e
49 #define MMCM_REG_FILTER2	0x4f
50 
51 #define MMCM_CLKOUT_NOCOUNT	BIT(6)
52 
53 #define MMCM_CLK_DIV_DIVIDE	BIT(11)
54 #define MMCM_CLK_DIV_NOCOUNT	BIT(12)
55 
56 struct axi_clkgen_limits {
57 	unsigned int fpfd_min;
58 	unsigned int fpfd_max;
59 	unsigned int fvco_min;
60 	unsigned int fvco_max;
61 };
62 
63 struct axi_clkgen {
64 	void __iomem *base;
65 	struct clk_hw clk_hw;
66 	struct axi_clkgen_limits limits;
67 };
68 
axi_clkgen_lookup_filter(unsigned int m)69 static uint32_t axi_clkgen_lookup_filter(unsigned int m)
70 {
71 	switch (m) {
72 	case 0:
73 		return 0x01001990;
74 	case 1:
75 		return 0x01001190;
76 	case 2:
77 		return 0x01009890;
78 	case 3:
79 		return 0x01001890;
80 	case 4:
81 		return 0x01008890;
82 	case 5 ... 8:
83 		return 0x01009090;
84 	case 9 ... 11:
85 		return 0x01000890;
86 	case 12:
87 		return 0x08009090;
88 	case 13 ... 22:
89 		return 0x01001090;
90 	case 23 ... 36:
91 		return 0x01008090;
92 	case 37 ... 46:
93 		return 0x08001090;
94 	default:
95 		return 0x08008090;
96 	}
97 }
98 
99 static const u32 axi_clkgen_lock_table[] = {
100 	0x060603e8, 0x060603e8, 0x080803e8, 0x0b0b03e8,
101 	0x0e0e03e8, 0x111103e8, 0x131303e8, 0x161603e8,
102 	0x191903e8, 0x1c1c03e8, 0x1f1f0384, 0x1f1f0339,
103 	0x1f1f02ee, 0x1f1f02bc, 0x1f1f028a, 0x1f1f0271,
104 	0x1f1f023f, 0x1f1f0226, 0x1f1f020d, 0x1f1f01f4,
105 	0x1f1f01db, 0x1f1f01c2, 0x1f1f01a9, 0x1f1f0190,
106 	0x1f1f0190, 0x1f1f0177, 0x1f1f015e, 0x1f1f015e,
107 	0x1f1f0145, 0x1f1f0145, 0x1f1f012c, 0x1f1f012c,
108 	0x1f1f012c, 0x1f1f0113, 0x1f1f0113, 0x1f1f0113,
109 };
110 
axi_clkgen_lookup_lock(unsigned int m)111 static u32 axi_clkgen_lookup_lock(unsigned int m)
112 {
113 	if (m < ARRAY_SIZE(axi_clkgen_lock_table))
114 		return axi_clkgen_lock_table[m];
115 	return 0x1f1f00fa;
116 }
117 
118 static const struct axi_clkgen_limits axi_clkgen_zynqmp_default_limits = {
119 	.fpfd_min = 10000,
120 	.fpfd_max = 450000,
121 	.fvco_min = 800000,
122 	.fvco_max = 1600000,
123 };
124 
125 static const struct axi_clkgen_limits axi_clkgen_zynq_default_limits = {
126 	.fpfd_min = 10000,
127 	.fpfd_max = 450000,
128 	.fvco_min = 600000,
129 	.fvco_max = 1200000,
130 };
131 
axi_clkgen_calc_params(const struct axi_clkgen_limits * limits,unsigned long fin,unsigned long fout,unsigned int * best_d,unsigned int * best_m,unsigned int * best_dout)132 static void axi_clkgen_calc_params(const struct axi_clkgen_limits *limits,
133 				   unsigned long fin, unsigned long fout,
134 				   unsigned int *best_d, unsigned int *best_m,
135 				   unsigned int *best_dout)
136 {
137 	unsigned long d, d_min, d_max, _d_min, _d_max;
138 	unsigned long m, m_min, m_max;
139 	unsigned long f, dout, best_f, fvco;
140 	unsigned long fract_shift = 0;
141 	unsigned long fvco_min_fract, fvco_max_fract;
142 
143 	fin /= 1000;
144 	fout /= 1000;
145 
146 	best_f = ULONG_MAX;
147 	*best_d = 0;
148 	*best_m = 0;
149 	*best_dout = 0;
150 
151 	d_min = max(DIV_ROUND_UP(fin, limits->fpfd_max), 1);
152 	d_max = min(fin / limits->fpfd_min, 80);
153 
154 again:
155 	fvco_min_fract = limits->fvco_min << fract_shift;
156 	fvco_max_fract = limits->fvco_max << fract_shift;
157 
158 	m_min = max(DIV_ROUND_UP(fvco_min_fract, fin) * d_min, 1);
159 	m_max = min(fvco_max_fract * d_max / fin, 64 << fract_shift);
160 
161 	for (m = m_min; m <= m_max; m++) {
162 		_d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max_fract));
163 		_d_max = min(d_max, fin * m / fvco_min_fract);
164 
165 		for (d = _d_min; d <= _d_max; d++) {
166 			fvco = fin * m / d;
167 
168 			dout = DIV_ROUND_CLOSEST(fvco, fout);
169 			dout = clamp_t(unsigned long, dout, 1, 128 << fract_shift);
170 			f = fvco / dout;
171 			if (abs(f - fout) < abs(best_f - fout)) {
172 				best_f = f;
173 				*best_d = d;
174 				*best_m = m << (3 - fract_shift);
175 				*best_dout = dout << (3 - fract_shift);
176 				if (best_f == fout)
177 					return;
178 			}
179 		}
180 	}
181 
182 	/* Let's see if we find a better setting in fractional mode */
183 	if (fract_shift == 0) {
184 		fract_shift = 3;
185 		goto again;
186 	}
187 }
188 
189 struct axi_clkgen_div_params {
190 	unsigned int low;
191 	unsigned int high;
192 	unsigned int edge;
193 	unsigned int nocount;
194 	unsigned int frac_en;
195 	unsigned int frac;
196 	unsigned int frac_wf_f;
197 	unsigned int frac_wf_r;
198 	unsigned int frac_phase;
199 };
200 
axi_clkgen_calc_clk_params(unsigned int divider,unsigned int frac_divider,struct axi_clkgen_div_params * params)201 static void axi_clkgen_calc_clk_params(unsigned int divider,
202 				       unsigned int frac_divider,
203 				       struct axi_clkgen_div_params *params)
204 {
205 	memset(params, 0x0, sizeof(*params));
206 
207 	if (divider == 1) {
208 		params->nocount = 1;
209 		return;
210 	}
211 
212 	if (frac_divider == 0) {
213 		params->high = divider / 2;
214 		params->edge = divider % 2;
215 		params->low = divider - params->high;
216 	} else {
217 		params->frac_en = 1;
218 		params->frac = frac_divider;
219 
220 		params->high = divider / 2;
221 		params->edge = divider % 2;
222 		params->low = params->high;
223 
224 		if (params->edge == 0) {
225 			params->high--;
226 			params->frac_wf_r = 1;
227 		}
228 
229 		if (params->edge == 0 || frac_divider == 1)
230 			params->low--;
231 		if (((params->edge == 0) ^ (frac_divider == 1)) ||
232 		    (divider == 2 && frac_divider == 1))
233 			params->frac_wf_f = 1;
234 
235 		params->frac_phase = params->edge * 4 + frac_divider / 2;
236 	}
237 }
238 
axi_clkgen_write(struct axi_clkgen * axi_clkgen,unsigned int reg,unsigned int val)239 static void axi_clkgen_write(struct axi_clkgen *axi_clkgen,
240 			     unsigned int reg, unsigned int val)
241 {
242 	writel(val, axi_clkgen->base + reg);
243 }
244 
axi_clkgen_read(struct axi_clkgen * axi_clkgen,unsigned int reg,unsigned int * val)245 static void axi_clkgen_read(struct axi_clkgen *axi_clkgen,
246 			    unsigned int reg, unsigned int *val)
247 {
248 	*val = readl(axi_clkgen->base + reg);
249 }
250 
axi_clkgen_wait_non_busy(struct axi_clkgen * axi_clkgen)251 static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen)
252 {
253 	unsigned int timeout = 10000;
254 	unsigned int val;
255 
256 	do {
257 		axi_clkgen_read(axi_clkgen, AXI_CLKGEN_V2_REG_DRP_STATUS, &val);
258 	} while ((val & AXI_CLKGEN_V2_DRP_STATUS_BUSY) && --timeout);
259 
260 	if (val & AXI_CLKGEN_V2_DRP_STATUS_BUSY)
261 		return -EIO;
262 
263 	return val & 0xffff;
264 }
265 
axi_clkgen_mmcm_read(struct axi_clkgen * axi_clkgen,unsigned int reg,unsigned int * val)266 static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen,
267 				unsigned int reg, unsigned int *val)
268 {
269 	unsigned int reg_val;
270 	int ret;
271 
272 	ret = axi_clkgen_wait_non_busy(axi_clkgen);
273 	if (ret < 0)
274 		return ret;
275 
276 	reg_val = AXI_CLKGEN_V2_DRP_CNTRL_SEL | AXI_CLKGEN_V2_DRP_CNTRL_READ;
277 	reg_val |= (reg << 16);
278 
279 	axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_DRP_CNTRL, reg_val);
280 
281 	ret = axi_clkgen_wait_non_busy(axi_clkgen);
282 	if (ret < 0)
283 		return ret;
284 
285 	*val = ret;
286 
287 	return 0;
288 }
289 
axi_clkgen_mmcm_write(struct axi_clkgen * axi_clkgen,unsigned int reg,unsigned int val,unsigned int mask)290 static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen,
291 				 unsigned int reg, unsigned int val,
292 				 unsigned int mask)
293 {
294 	unsigned int reg_val = 0;
295 	int ret;
296 
297 	ret = axi_clkgen_wait_non_busy(axi_clkgen);
298 	if (ret < 0)
299 		return ret;
300 
301 	if (mask != 0xffff) {
302 		axi_clkgen_mmcm_read(axi_clkgen, reg, &reg_val);
303 		reg_val &= ~mask;
304 	}
305 
306 	reg_val |= AXI_CLKGEN_V2_DRP_CNTRL_SEL | (reg << 16) | (val & mask);
307 
308 	axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_DRP_CNTRL, reg_val);
309 
310 	return 0;
311 }
312 
axi_clkgen_mmcm_enable(struct axi_clkgen * axi_clkgen,bool enable)313 static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen, bool enable)
314 {
315 	unsigned int val = AXI_CLKGEN_V2_RESET_ENABLE;
316 
317 	if (enable)
318 		val |= AXI_CLKGEN_V2_RESET_MMCM_ENABLE;
319 
320 	axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_RESET, val);
321 }
322 
clk_hw_to_axi_clkgen(struct clk_hw * clk_hw)323 static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw)
324 {
325 	return container_of(clk_hw, struct axi_clkgen, clk_hw);
326 }
327 
axi_clkgen_set_div(struct axi_clkgen * axi_clkgen,unsigned int reg1,unsigned int reg2,unsigned int reg3,struct axi_clkgen_div_params * params)328 static void axi_clkgen_set_div(struct axi_clkgen *axi_clkgen,
329 			       unsigned int reg1, unsigned int reg2,
330 			       unsigned int reg3,
331 			       struct axi_clkgen_div_params *params)
332 {
333 	axi_clkgen_mmcm_write(axi_clkgen, reg1,
334 			      (params->high << 6) | params->low, 0xefff);
335 	axi_clkgen_mmcm_write(axi_clkgen, reg2,
336 			      (params->frac << 12) | (params->frac_en << 11) |
337 			      (params->frac_wf_r << 10) | (params->edge << 7) |
338 			      (params->nocount << 6), 0x7fff);
339 	if (reg3 != 0) {
340 		axi_clkgen_mmcm_write(axi_clkgen, reg3,
341 				      (params->frac_phase << 11) | (params->frac_wf_f << 10),
342 				      0x3c00);
343 	}
344 }
345 
axi_clkgen_set_rate(struct clk_hw * clk_hw,unsigned long rate,unsigned long parent_rate)346 static int axi_clkgen_set_rate(struct clk_hw *clk_hw, unsigned long rate,
347 			       unsigned long parent_rate)
348 {
349 	struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
350 	const struct axi_clkgen_limits *limits = &axi_clkgen->limits;
351 	unsigned int d, m, dout;
352 	struct axi_clkgen_div_params params;
353 	u32 power = 0, filter, lock;
354 
355 	if (parent_rate == 0 || rate == 0)
356 		return -EINVAL;
357 
358 	axi_clkgen_calc_params(limits, parent_rate, rate, &d, &m, &dout);
359 
360 	if (d == 0 || dout == 0 || m == 0)
361 		return -EINVAL;
362 
363 	if ((dout & 0x7) != 0 || (m & 0x7) != 0)
364 		power |= 0x9800;
365 
366 	axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_POWER, power, 0x9800);
367 
368 	filter = axi_clkgen_lookup_filter(m - 1);
369 	lock = axi_clkgen_lookup_lock(m - 1);
370 
371 	axi_clkgen_calc_clk_params(dout >> 3, dout & 0x7, &params);
372 	axi_clkgen_set_div(axi_clkgen,  MMCM_REG_CLKOUT0_1, MMCM_REG_CLKOUT0_2,
373 			   MMCM_REG_CLKOUT5_2, &params);
374 
375 	axi_clkgen_calc_clk_params(d, 0, &params);
376 	axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_DIV,
377 			      (params.edge << 13) | (params.nocount << 12) |
378 			      (params.high << 6) | params.low, 0x3fff);
379 
380 	axi_clkgen_calc_clk_params(m >> 3, m & 0x7, &params);
381 	axi_clkgen_set_div(axi_clkgen,  MMCM_REG_CLK_FB1, MMCM_REG_CLK_FB2,
382 			   MMCM_REG_CLKOUT6_2, &params);
383 
384 	axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK1, lock & 0x3ff, 0x3ff);
385 	axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK2,
386 			      (((lock >> 16) & 0x1f) << 10) | 0x1, 0x7fff);
387 	axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK3,
388 			      (((lock >> 24) & 0x1f) << 10) | 0x3e9, 0x7fff);
389 	axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_FILTER1, filter >> 16, 0x9900);
390 	axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_FILTER2, filter, 0x9900);
391 
392 	return 0;
393 }
394 
axi_clkgen_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)395 static int axi_clkgen_determine_rate(struct clk_hw *hw,
396 				     struct clk_rate_request *req)
397 {
398 	struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(hw);
399 	const struct axi_clkgen_limits *limits = &axi_clkgen->limits;
400 	unsigned int d, m, dout;
401 	unsigned long long tmp;
402 
403 	axi_clkgen_calc_params(limits, req->best_parent_rate, req->rate,
404 			       &d, &m, &dout);
405 
406 	if (d == 0 || dout == 0 || m == 0)
407 		return -EINVAL;
408 
409 	tmp = (unsigned long long)req->best_parent_rate * m;
410 	tmp = DIV_ROUND_CLOSEST_ULL(tmp, dout * d);
411 
412 	req->rate = min_t(unsigned long long, tmp, LONG_MAX);
413 	return 0;
414 }
415 
axi_clkgen_get_div(struct axi_clkgen * axi_clkgen,unsigned int reg1,unsigned int reg2)416 static unsigned int axi_clkgen_get_div(struct axi_clkgen *axi_clkgen,
417 				       unsigned int reg1, unsigned int reg2)
418 {
419 	unsigned int val1, val2;
420 	unsigned int div;
421 
422 	axi_clkgen_mmcm_read(axi_clkgen, reg2, &val2);
423 	if (val2 & MMCM_CLKOUT_NOCOUNT)
424 		return 8;
425 
426 	axi_clkgen_mmcm_read(axi_clkgen, reg1, &val1);
427 
428 	div = (val1 & 0x3f) + ((val1 >> 6) & 0x3f);
429 	div <<= 3;
430 
431 	if (val2 & MMCM_CLK_DIV_DIVIDE) {
432 		if ((val2 & BIT(7)) && (val2 & 0x7000) != 0x1000)
433 			div += 8;
434 		else
435 			div += 16;
436 
437 		div += (val2 >> 12) & 0x7;
438 	}
439 
440 	return div;
441 }
442 
axi_clkgen_recalc_rate(struct clk_hw * clk_hw,unsigned long parent_rate)443 static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
444 					    unsigned long parent_rate)
445 {
446 	struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
447 	unsigned int d, m, dout;
448 	unsigned long long tmp;
449 	unsigned int val;
450 
451 	dout = axi_clkgen_get_div(axi_clkgen, MMCM_REG_CLKOUT0_1,
452 				  MMCM_REG_CLKOUT0_2);
453 	m = axi_clkgen_get_div(axi_clkgen, MMCM_REG_CLK_FB1,
454 			       MMCM_REG_CLK_FB2);
455 
456 	axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, &val);
457 	if (val & MMCM_CLK_DIV_NOCOUNT)
458 		d = 1;
459 	else
460 		d = (val & 0x3f) + ((val >> 6) & 0x3f);
461 
462 	if (d == 0 || dout == 0)
463 		return 0;
464 
465 	tmp = (unsigned long long)parent_rate * m;
466 	tmp = DIV_ROUND_CLOSEST_ULL(tmp, dout * d);
467 
468 	return min_t(unsigned long long, tmp, ULONG_MAX);
469 }
470 
axi_clkgen_enable(struct clk_hw * clk_hw)471 static int axi_clkgen_enable(struct clk_hw *clk_hw)
472 {
473 	struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
474 
475 	axi_clkgen_mmcm_enable(axi_clkgen, true);
476 
477 	return 0;
478 }
479 
axi_clkgen_disable(struct clk_hw * clk_hw)480 static void axi_clkgen_disable(struct clk_hw *clk_hw)
481 {
482 	struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
483 
484 	axi_clkgen_mmcm_enable(axi_clkgen, false);
485 }
486 
axi_clkgen_set_parent(struct clk_hw * clk_hw,u8 index)487 static int axi_clkgen_set_parent(struct clk_hw *clk_hw, u8 index)
488 {
489 	struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
490 
491 	axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, index);
492 
493 	return 0;
494 }
495 
axi_clkgen_get_parent(struct clk_hw * clk_hw)496 static u8 axi_clkgen_get_parent(struct clk_hw *clk_hw)
497 {
498 	struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
499 	unsigned int parent;
500 
501 	axi_clkgen_read(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, &parent);
502 
503 	return parent;
504 }
505 
axi_clkgen_setup_limits(struct axi_clkgen * axi_clkgen,struct device * dev)506 static int axi_clkgen_setup_limits(struct axi_clkgen *axi_clkgen,
507 				   struct device *dev)
508 {
509 	unsigned int tech, family, speed_grade, reg_value;
510 
511 	axi_clkgen_read(axi_clkgen, ADI_AXI_REG_FPGA_INFO, &reg_value);
512 	tech = ADI_AXI_INFO_FPGA_TECH(reg_value);
513 	family = ADI_AXI_INFO_FPGA_FAMILY(reg_value);
514 	speed_grade = ADI_AXI_INFO_FPGA_SPEED_GRADE(reg_value);
515 
516 	axi_clkgen->limits.fpfd_min = 10000;
517 	axi_clkgen->limits.fvco_min = 600000;
518 
519 	switch (speed_grade) {
520 	case ADI_AXI_FPGA_SPEED_1 ... ADI_AXI_FPGA_SPEED_1LV:
521 		axi_clkgen->limits.fvco_max = 1200000;
522 		axi_clkgen->limits.fpfd_max = 450000;
523 		break;
524 	case ADI_AXI_FPGA_SPEED_2 ... ADI_AXI_FPGA_SPEED_2LV:
525 		axi_clkgen->limits.fvco_max = 1440000;
526 		axi_clkgen->limits.fpfd_max = 500000;
527 		if (family == ADI_AXI_FPGA_FAMILY_KINTEX || family == ADI_AXI_FPGA_FAMILY_ARTIX) {
528 			axi_clkgen_read(axi_clkgen, ADI_CLKGEN_REG_FPGA_VOLTAGE,
529 					&reg_value);
530 			if (ADI_CLKGEN_INFO_FPGA_VOLTAGE(reg_value) < 950) {
531 				axi_clkgen->limits.fvco_max = 1200000;
532 				axi_clkgen->limits.fpfd_max = 450000;
533 			}
534 		}
535 		break;
536 	case ADI_AXI_FPGA_SPEED_3:
537 		axi_clkgen->limits.fvco_max = 1600000;
538 		axi_clkgen->limits.fpfd_max = 550000;
539 		break;
540 	default:
541 		return dev_err_probe(dev, -ENODEV, "Unknown speed grade %d\n",
542 				     speed_grade);
543 	}
544 
545 	/* Overwrite vco limits for ultrascale+ */
546 	if (tech == ADI_AXI_FPGA_TECH_ULTRASCALE_PLUS) {
547 		axi_clkgen->limits.fvco_max = 1600000;
548 		axi_clkgen->limits.fvco_min = 800000;
549 	}
550 
551 	return 0;
552 }
553 
554 static const struct clk_ops axi_clkgen_ops = {
555 	.recalc_rate = axi_clkgen_recalc_rate,
556 	.determine_rate = axi_clkgen_determine_rate,
557 	.set_rate = axi_clkgen_set_rate,
558 	.enable = axi_clkgen_enable,
559 	.disable = axi_clkgen_disable,
560 	.set_parent = axi_clkgen_set_parent,
561 	.get_parent = axi_clkgen_get_parent,
562 };
563 
axi_clkgen_probe(struct platform_device * pdev)564 static int axi_clkgen_probe(struct platform_device *pdev)
565 {
566 	const struct axi_clkgen_limits *dflt_limits;
567 	struct axi_clkgen *axi_clkgen;
568 	unsigned int pcore_version;
569 	struct clk_init_data init;
570 	const char *parent_names[2];
571 	const char *clk_name;
572 	struct clk *axi_clk;
573 	unsigned int i;
574 	int ret;
575 
576 	dflt_limits = device_get_match_data(&pdev->dev);
577 	if (!dflt_limits)
578 		return -ENODEV;
579 
580 	axi_clkgen = devm_kzalloc(&pdev->dev, sizeof(*axi_clkgen), GFP_KERNEL);
581 	if (!axi_clkgen)
582 		return -ENOMEM;
583 
584 	axi_clkgen->base = devm_platform_ioremap_resource(pdev, 0);
585 	if (IS_ERR(axi_clkgen->base))
586 		return PTR_ERR(axi_clkgen->base);
587 
588 	init.num_parents = of_clk_get_parent_count(pdev->dev.of_node);
589 
590 	axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk");
591 	if (!IS_ERR(axi_clk)) {
592 		if (init.num_parents < 2 || init.num_parents > 3)
593 			return -EINVAL;
594 
595 		init.num_parents -= 1;
596 	} else {
597 		/*
598 		 * Legacy... So that old DTs which do not have clock-names still
599 		 * work. In this case we don't explicitly enable the AXI bus
600 		 * clock.
601 		 */
602 		if (PTR_ERR(axi_clk) != -ENOENT)
603 			return PTR_ERR(axi_clk);
604 		if (init.num_parents < 1 || init.num_parents > 2)
605 			return -EINVAL;
606 	}
607 
608 	for (i = 0; i < init.num_parents; i++) {
609 		parent_names[i] = of_clk_get_parent_name(pdev->dev.of_node, i);
610 		if (!parent_names[i])
611 			return -EINVAL;
612 	}
613 
614 	axi_clkgen_read(axi_clkgen, ADI_AXI_REG_VERSION, &pcore_version);
615 
616 	if (ADI_AXI_PCORE_VER_MAJOR(pcore_version) > 0x04) {
617 		ret = axi_clkgen_setup_limits(axi_clkgen, &pdev->dev);
618 		if (ret)
619 			return ret;
620 	} else {
621 		memcpy(&axi_clkgen->limits, dflt_limits,
622 		       sizeof(axi_clkgen->limits));
623 	}
624 
625 	clk_name = pdev->dev.of_node->name;
626 	of_property_read_string(pdev->dev.of_node, "clock-output-names",
627 				&clk_name);
628 
629 	init.name = clk_name;
630 	init.ops = &axi_clkgen_ops;
631 	init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
632 	init.parent_names = parent_names;
633 
634 	axi_clkgen_mmcm_enable(axi_clkgen, false);
635 
636 	axi_clkgen->clk_hw.init = &init;
637 	ret = devm_clk_hw_register(&pdev->dev, &axi_clkgen->clk_hw);
638 	if (ret)
639 		return ret;
640 
641 	return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get,
642 					   &axi_clkgen->clk_hw);
643 }
644 
645 static const struct of_device_id axi_clkgen_ids[] = {
646 	{
647 		.compatible = "adi,zynqmp-axi-clkgen-2.00.a",
648 		.data = &axi_clkgen_zynqmp_default_limits,
649 	},
650 	{
651 		.compatible = "adi,axi-clkgen-2.00.a",
652 		.data = &axi_clkgen_zynq_default_limits,
653 	},
654 	{ }
655 };
656 MODULE_DEVICE_TABLE(of, axi_clkgen_ids);
657 
658 static struct platform_driver axi_clkgen_driver = {
659 	.driver = {
660 		.name = "adi-axi-clkgen",
661 		.of_match_table = axi_clkgen_ids,
662 	},
663 	.probe = axi_clkgen_probe,
664 };
665 module_platform_driver(axi_clkgen_driver);
666 
667 MODULE_LICENSE("GPL v2");
668 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
669 MODULE_DESCRIPTION("Driver for the Analog Devices' AXI clkgen pcore clock generator");
670