xref: /linux/drivers/clk/clk-eyeq.c (revision 502d45774af09f1c681c754c4b7cdfb5d7f72fd9)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * PLL clock driver for the Mobileye EyeQ platforms.
4  *
5  * This controller handles:
6  *  - Read-only PLLs, all derived from the same main crystal clock.
7  *  - It also exposes divider clocks, those are children to PLLs.
8  *  - Fixed factor clocks, children to PLLs.
9  *
10  * Parent clock is expected to be constant. This driver's registers live in a
11  * shared region called OLB. Some PLLs and fixed-factors are initialised early
12  * by of_clk_init(); if so, two clk providers are registered.
13  *
14  * We use eqc_ as prefix, as-in "EyeQ Clock", but way shorter.
15  *
16  * Copyright (C) 2024 Mobileye Vision Technologies Ltd.
17  */
18 
19 /*
20  * Set pr_fmt() for printing from eqc_early_init().
21  * It is called at of_clk_init() stage (read: really early).
22  */
23 #define pr_fmt(fmt) "clk-eyeq: " fmt
24 
25 #include <linux/array_size.h>
26 #include <linux/auxiliary_bus.h>
27 #include <linux/bitfield.h>
28 #include <linux/bits.h>
29 #include <linux/clk-provider.h>
30 #include <linux/device.h>
31 #include <linux/err.h>
32 #include <linux/errno.h>
33 #include <linux/init.h>
34 #include <linux/io-64-nonatomic-hi-lo.h>
35 #include <linux/io.h>
36 #include <linux/module.h>
37 #include <linux/of.h>
38 #include <linux/of_address.h>
39 #include <linux/overflow.h>
40 #include <linux/platform_device.h>
41 #include <linux/printk.h>
42 #include <linux/slab.h>
43 #include <linux/spinlock.h>
44 #include <linux/types.h>
45 
46 #include <dt-bindings/clock/mobileye,eyeq5-clk.h>
47 #include <dt-bindings/clock/mobileye,eyeq6lplus-clk.h>
48 #include <dt-bindings/clock/mobileye,eyeq7h-clk.h>
49 
50 /* In frac mode, it enables fractional noise canceling DAC. Else, no function. */
51 #define FRACG_PCSR0_DAC_EN			BIT(0)
52 /* Fractional or integer mode */
53 #define FRACG_PCSR0_DSM_EN			BIT(1)
54 #define FRACG_PCSR0_PLL_EN			BIT(2)
55 /* All clocks output held at 0 */
56 #define FRACG_PCSR0_FOUTPOSTDIV_EN		BIT(3)
57 #define FRACG_PCSR0_POST_DIV1			GENMASK(6, 4)
58 #define FRACG_PCSR0_POST_DIV2			GENMASK(9, 7)
59 #define FRACG_PCSR0_REF_DIV			GENMASK(15, 10)
60 #define FRACG_PCSR0_INTIN			GENMASK(27, 16)
61 #define FRACG_PCSR0_BYPASS			BIT(28)
62 /* Bits 30..29 are reserved */
63 #define FRACG_PCSR0_PLL_LOCKED			BIT(31)
64 
65 #define FRACG_PCSR1_RESET			BIT(0)
66 #define FRACG_PCSR1_SSGC_DIV			GENMASK(4, 1)
67 /* Spread amplitude (% = 0.1 * SPREAD[4:0]) */
68 #define FRACG_PCSR1_SPREAD			GENMASK(9, 5)
69 #define FRACG_PCSR1_DIS_SSCG			BIT(10)
70 /* Down-spread or center-spread */
71 #define FRACG_PCSR1_DOWN_SPREAD			BIT(11)
72 #define FRACG_PCSR1_FRAC_IN			GENMASK(31, 12)
73 
74 #define JFRACR_PCSR0_BYPASS			BIT(0)
75 #define JFRACR_PCSR0_PLL_EN			BIT(1)
76 #define JFRACR_PCSR0_FOUTVCO_EN			BIT(2)
77 #define JFRACR_PCSR0_FOUTPOSTDIV_EN		BIT(3)
78 #define JFRACR_PCSR0_POST_DIV1			GENMASK(6, 4)
79 #define JFRACR_PCSR0_POST_DIV2			GENMASK(9, 7)
80 #define JFRACR_PCSR0_REF_DIV			GENMASK(15, 10)
81 #define JFRACR_PCSR0_FB_DIV			GENMASK(27, 16)
82 #define JFRACR_PCSR0_VCO_SEL			GENMASK(29, 28)
83 #define JFRACR_PCSR0_PLL_LOCKED			GENMASK(31, 30)
84 
85 #define JFRACR_PCSR1_FRAC_IN			GENMASK(23, 0)
86 #define JFRACR_PCSR1_FOUT4PHASE_EN		BIT(24)
87 #define JFRACR_PCSR1_DAC_EN			BIT(25)
88 #define JFRACR_PCSR1_DSM_EN			BIT(26)
89 /* Bits 31..27 are reserved */
90 #define JFRACR_PCSR2_RESET			BIT(0)
91 #define JFRACR_PCSR2_DIS_SSCG			BIT(1)
92 #define JFRACR_PCSR2_DOWN_SPREAD		BIT(2)
93 #define JFRACR_PCSR2_SSGC_DIV			GENMASK(7, 4)
94 #define JFRACR_PCSR2_SPREAD			GENMASK(12, 8)
95 /* Bits 31..13 are reserved */
96 
97 #define AINTP_PCSR_BYPASS			BIT(0)
98 #define AINTP_PCSR_PLL_EN			BIT(1)
99 #define AINTP_PCSR_FOUTVCO_EN			BIT(2)
100 #define AINTP_PCSR_FOUTPOSTDIV_EN		BIT(3)
101 #define AINTP_PCSR_POST_DIV1			GENMASK(6, 4)
102 #define AINTP_PCSR_POST_DIV2			GENMASK(9, 7)
103 #define AINTP_PCSR_REF_DIV			GENMASK(15, 10)
104 #define AINTP_PCSR_FB_DIV			GENMASK(27, 16)
105 #define AINTP_PCSR_VCO_SEL			GENMASK(29, 28)
106 /* bit 30 is reserved */
107 #define AINTP_PCSR_PLL_LOCKED			BIT(31)
108 
109 /*
110  * Special index values to lookup a parent clock by its name
111  * from the device tree or by its globally unique name.
112  */
113 #define PARENT_BY_FWNAME			(-1)
114 #define PARENT_BY_NAME				(-2)
115 
116 struct eqc_clock {
117 	int		index;
118 	int		parent_idx;
119 	const char	*name;
120 	const char	*parent_name;
121 	int		(*probe)(struct device *dev, struct device_node *np,
122 				 const struct eqc_clock *clk, void __iomem *base,
123 				 struct clk_hw_onecell_data *cells);
124 	void		(*unregister)(struct clk_hw *hw);
125 	union {
126 		struct {
127 			unsigned int			reg;
128 			u8				shift;
129 			u8				width;
130 			unsigned long			flags;
131 			const struct clk_div_table	*table;
132 		} div;
133 		struct {
134 			unsigned int			mult;
135 			unsigned int			div;
136 		} ff;
137 		struct {
138 			unsigned int			reg;
139 		} pll;
140 	};
141 };
142 
143 struct eqc_match_data {
144 	unsigned int		clk_count;
145 	const struct eqc_clock	*clks;
146 
147 	const char		*reset_auxdev_name;
148 	const char		*pinctrl_auxdev_name;
149 	const char		*eth_phy_auxdev_name;
150 
151 	unsigned int		early_clk_count;
152 };
153 
154 struct eqc_early_match_data {
155 	unsigned int		early_clk_count;
156 	const struct eqc_clock	*early_clks;
157 
158 	/*
159 	 * We want our of_xlate callback to EPROBE_DEFER instead of dev_err()
160 	 * and EINVAL. For that, we must know the total clock count.
161 	 */
162 	unsigned int		late_clk_count;
163 };
164 
165 /*
166  * All Mobileye EyeQ SoC have 64 bits long, but both factors (mult and div)
167  * must fit in 32 bits as clk_fixed_factor uses unsigned int. When an
168  * operation overflows, this function throws away low bits so that
169  * factors still fit in 32 bits.
170  *
171  * Precision loss depends on amplitude of mult and div. Worst theoretical
172  * loss is: (UINT_MAX+1) / UINT_MAX - 1 = 2.3e-10.
173  * This is 1Hz every 4.3GHz.
174  */
eqc_pll_downshift_factors(unsigned long * mult,unsigned long * div)175 static void eqc_pll_downshift_factors(unsigned long *mult, unsigned long *div)
176 {
177 	unsigned long biggest;
178 	unsigned int shift;
179 
180 	/* This function can be removed if mult/div switch to unsigned long. */
181 	static_assert(sizeof_field(struct clk_fixed_factor, mult) == sizeof(unsigned int));
182 	static_assert(sizeof_field(struct clk_fixed_factor, div) == sizeof(unsigned int));
183 
184 	/* No overflow, nothing to be done. */
185 	if (*mult <= UINT_MAX && *div <= UINT_MAX)
186 		return;
187 
188 	/*
189 	 * Compute the shift required to bring the biggest factor into unsigned
190 	 * int range. That is, shift its highest set bit to the unsigned int
191 	 * most significant bit.
192 	 */
193 	biggest = max(*mult, *div);
194 	shift = __fls(biggest) - (BITS_PER_BYTE * sizeof(unsigned int)) + 1;
195 
196 	*mult >>= shift;
197 	*div >>= shift;
198 }
199 
eqc_pll_parse_aintp(void __iomem * base,unsigned long * mult,unsigned long * div)200 static int eqc_pll_parse_aintp(void __iomem *base, unsigned long *mult, unsigned long *div)
201 {
202 	u32 r0;
203 
204 	r0 = readl(base);
205 	if (r0 & AINTP_PCSR_BYPASS) {
206 		*mult = 1;
207 		*div = 1;
208 		return 0;
209 	}
210 
211 	if (!(r0 & AINTP_PCSR_PLL_LOCKED))
212 		return -EINVAL;
213 
214 	*mult = FIELD_GET(AINTP_PCSR_FB_DIV, r0);
215 	*div = FIELD_GET(AINTP_PCSR_REF_DIV, r0);
216 
217 	if (!*mult || !*div)
218 		return -EINVAL;
219 
220 	return 0;
221 }
222 
eqc_pll_parse_fracg(void __iomem * base,unsigned long * mult,unsigned long * div,unsigned long * acc)223 static int eqc_pll_parse_fracg(void __iomem *base, unsigned long *mult,
224 			       unsigned long *div, unsigned long *acc)
225 {
226 	unsigned long spread;
227 	u32 r0, r1;
228 	u64 val;
229 
230 	val = readq(base);
231 	r0 = val;
232 	r1 = val >> 32;
233 
234 	if (r0 & FRACG_PCSR0_BYPASS) {
235 		*mult = 1;
236 		*div = 1;
237 		*acc = 0;
238 		return 0;
239 	}
240 
241 	if (!(r0 & FRACG_PCSR0_PLL_LOCKED))
242 		return -EINVAL;
243 
244 	*mult = FIELD_GET(FRACG_PCSR0_INTIN, r0);
245 	*div = FIELD_GET(FRACG_PCSR0_REF_DIV, r0);
246 
247 	/* Fractional mode, in 2^20 (0x100000) parts. */
248 	if (r0 & FRACG_PCSR0_DSM_EN) {
249 		*div *= (1ULL << 20);
250 		*mult = *mult * (1ULL << 20) + FIELD_GET(FRACG_PCSR1_FRAC_IN, r1);
251 	}
252 
253 	if (!*mult || !*div)
254 		return -EINVAL;
255 
256 	if (r1 & (FRACG_PCSR1_RESET | FRACG_PCSR1_DIS_SSCG)) {
257 		*acc = 0;
258 		return 0;
259 	}
260 
261 	/*
262 	 * Spread spectrum.
263 	 *
264 	 * Spread is in 1/1024 parts of frequency. Clock accuracy
265 	 * is half the spread value expressed in parts per billion.
266 	 *
267 	 * accuracy = (spread * 1e9) / (1024 * 2)
268 	 *
269 	 * Care is taken to avoid overflowing or losing precision.
270 	 */
271 	spread = FIELD_GET(FRACG_PCSR1_SPREAD, r1);
272 	*acc = DIV_ROUND_CLOSEST(spread * 1000000000, 1024 * 2);
273 
274 	if (r1 & FRACG_PCSR1_DOWN_SPREAD) {
275 		/*
276 		 * Downspreading: the central frequency is half a
277 		 * spread lower.
278 		 */
279 		*mult *= 2048 - spread;
280 		*div *= 2048;
281 
282 		/*
283 		 * Previous operation might overflow 32 bits. If it
284 		 * does, throw away the least amount of low bits.
285 		 */
286 		eqc_pll_downshift_factors(mult, div);
287 	}
288 
289 	return 0;
290 }
291 
eqc_pll_parse_jfracr(void __iomem * base,unsigned long * mult,unsigned long * div,unsigned long * acc)292 static int eqc_pll_parse_jfracr(void __iomem *base, unsigned long *mult,
293 				unsigned long *div, unsigned long *acc)
294 {
295 	unsigned long spread;
296 	u32 r0, r1, r2;
297 	u64 val;
298 
299 	val = readq(base);
300 	r0 = val;
301 	r1 = val >> 32;
302 	r2 = readl(base + 8);
303 
304 	if (r0 & JFRACR_PCSR0_BYPASS) {
305 		*mult = 1;
306 		*div = 1;
307 		*acc = 0;
308 		return 0;
309 	}
310 
311 	/* Consider the PLL locked if either the phase or the frequency is locked */
312 	if (!(r0 & JFRACR_PCSR0_PLL_LOCKED))
313 		return -EINVAL;
314 
315 	*mult = FIELD_GET(JFRACR_PCSR0_FB_DIV, r0);
316 	*div = FIELD_GET(JFRACR_PCSR0_REF_DIV, r0);
317 
318 	/* fractional part on 24 bits */
319 	if (r1 & JFRACR_PCSR1_DSM_EN) {
320 		*div *= (1ULL << 24);
321 		*mult = *mult * (1ULL << 24) + FIELD_GET(JFRACR_PCSR1_FRAC_IN, r1);
322 	}
323 
324 	if (!*mult || !*div)
325 		return -EINVAL;
326 
327 	if (r2 & (JFRACR_PCSR2_RESET | JFRACR_PCSR2_DIS_SSCG)) {
328 		*acc = 0;
329 	} else {
330 		/* spread spectrum is identical to FRACG PLL */
331 		spread = FIELD_GET(JFRACR_PCSR2_SPREAD, r2);
332 		*acc = DIV_ROUND_CLOSEST(spread * 1000000000, 1024 * 2);
333 
334 		if (r2 & JFRACR_PCSR2_DOWN_SPREAD) {
335 			*mult *= 2048 - spread;
336 			*div *= 2048;
337 		}
338 	}
339 
340 	/* make sure mult and div fit in 32 bits */
341 	eqc_pll_downshift_factors(mult, div);
342 
343 	return 0;
344 }
345 
eqc_auxdev_create_optional(struct device * dev,void __iomem * base,const char * name)346 static void eqc_auxdev_create_optional(struct device *dev, void __iomem *base,
347 				       const char *name)
348 {
349 	struct auxiliary_device *adev;
350 
351 	if (name) {
352 		adev = devm_auxiliary_device_create(dev, name,
353 						    (void __force *)base);
354 		if (!adev)
355 			dev_warn(dev, "failed creating auxiliary device %s.%s\n",
356 				 KBUILD_MODNAME, name);
357 	}
358 }
359 
eqc_fill_parent_data(const struct eqc_clock * clk,struct clk_hw_onecell_data * cells,struct clk_parent_data * parent_data)360 static int eqc_fill_parent_data(const struct eqc_clock *clk,
361 				struct clk_hw_onecell_data *cells,
362 				struct clk_parent_data *parent_data)
363 {
364 	int pidx = clk->parent_idx;
365 
366 	memset(parent_data, 0, sizeof(struct clk_parent_data));
367 
368 	if (pidx == PARENT_BY_FWNAME) {
369 		/* lookup the parent clock by its fw_name */
370 		parent_data->index = -1;
371 		parent_data->fw_name = clk->parent_name;
372 	} else if (pidx == PARENT_BY_NAME) {
373 		/* lookup the parent clock by its global name */
374 		parent_data->index = -1;
375 		parent_data->name = clk->parent_name;
376 	} else if (pidx >= 0 && pidx < cells->num && !IS_ERR(cells->hws[pidx])) {
377 		/* get the parent hw directly */
378 		parent_data->hw = cells->hws[pidx];
379 	} else {
380 		/* no parent lookup by index: explicitly fail */
381 		return -EINVAL;
382 	}
383 
384 	return 0;
385 }
386 
eqc_probe_divider(struct device * dev,struct device_node * np,const struct eqc_clock * clk,void __iomem * base,struct clk_hw_onecell_data * cells)387 static int eqc_probe_divider(struct device *dev, struct device_node *np,
388 			     const struct eqc_clock *clk, void __iomem *base,
389 			     struct clk_hw_onecell_data *cells)
390 {
391 	struct clk_parent_data parent_data;
392 	struct clk_hw *hw;
393 	int ret;
394 
395 	ret = eqc_fill_parent_data(clk, cells, &parent_data);
396 	if (ret)
397 		return ret;
398 
399 	hw = clk_hw_register_divider_table_parent_data(dev, clk->name,
400 			&parent_data, 0, base + clk->div.reg, clk->div.shift,
401 			clk->div.width, clk->div.flags, clk->div.table, NULL);
402 	if (IS_ERR(hw))
403 		return PTR_ERR(hw);
404 
405 	cells->hws[clk->index] = hw;
406 	return 0;
407 }
408 
eqc_probe_fixed_factor(struct device * dev,struct device_node * np,const struct eqc_clock * clk,void __iomem * base,struct clk_hw_onecell_data * cells)409 static int eqc_probe_fixed_factor(struct device *dev, struct device_node *np,
410 				  const struct eqc_clock *clk, void __iomem *base,
411 				  struct clk_hw_onecell_data *cells)
412 {
413 	struct clk_parent_data parent_data;
414 	struct clk_hw *hw;
415 	int ret;
416 
417 	ret = eqc_fill_parent_data(clk, cells, &parent_data);
418 	if (ret)
419 		return ret;
420 
421 	hw = clk_hw_register_fixed_factor_pdata(dev, np, clk->name, &parent_data, 0,
422 						clk->ff.mult, clk->ff.div, 0, 0);
423 	if (IS_ERR(hw))
424 		return PTR_ERR(hw);
425 
426 	cells->hws[clk->index] = hw;
427 	return 0;
428 }
429 
eqc_probe_pll_aintp(struct device * dev,struct device_node * np,const struct eqc_clock * clk,void __iomem * base,struct clk_hw_onecell_data * cells)430 static int eqc_probe_pll_aintp(struct device *dev, struct device_node *np,
431 			       const struct eqc_clock *clk, void __iomem *base,
432 			       struct clk_hw_onecell_data *cells)
433 {
434 	struct clk_parent_data parent_data = { };
435 	unsigned long mult, div;
436 	struct clk_hw *hw;
437 	int ret;
438 
439 	ret = eqc_pll_parse_aintp(base + clk->pll.reg, &mult, &div);
440 	if (ret)
441 		return ret;
442 
443 	ret = eqc_fill_parent_data(clk, cells, &parent_data);
444 	if (ret)
445 		return ret;
446 
447 	hw = clk_hw_register_fixed_factor_pdata(dev, np, clk->name, &parent_data,
448 						0, mult, div, 0, 0);
449 
450 	if (IS_ERR(hw))
451 		return PTR_ERR(hw);
452 
453 	cells->hws[clk->index] = hw;
454 	return 0;
455 }
456 
eqc_probe_pll_fracg(struct device * dev,struct device_node * np,const struct eqc_clock * clk,void __iomem * base,struct clk_hw_onecell_data * cells)457 static int eqc_probe_pll_fracg(struct device *dev, struct device_node *np,
458 			       const struct eqc_clock *clk, void __iomem *base,
459 			       struct clk_hw_onecell_data *cells)
460 {
461 	struct clk_parent_data parent_data;
462 	unsigned long mult, div, acc;
463 	struct clk_hw *hw;
464 	int ret;
465 
466 	ret = eqc_pll_parse_fracg(base + clk->pll.reg, &mult, &div, &acc);
467 	if (ret)
468 		return ret;
469 
470 	ret = eqc_fill_parent_data(clk, cells, &parent_data);
471 	if (ret)
472 		return ret;
473 
474 	hw = clk_hw_register_fixed_factor_pdata(dev, np, clk->name, &parent_data, 0, mult,
475 						div, acc, CLK_FIXED_FACTOR_FIXED_ACCURACY);
476 	if (IS_ERR(hw))
477 		return PTR_ERR(hw);
478 
479 	cells->hws[clk->index] = hw;
480 	return 0;
481 }
482 
eqc_probe_pll_jfracr(struct device * dev,struct device_node * np,const struct eqc_clock * clk,void __iomem * base,struct clk_hw_onecell_data * cells)483 static int eqc_probe_pll_jfracr(struct device *dev, struct device_node *np,
484 				const struct eqc_clock *clk, void __iomem *base,
485 				struct clk_hw_onecell_data *cells)
486 {
487 	struct clk_parent_data parent_data = { };
488 	unsigned long mult, div, acc;
489 	struct clk_hw *hw;
490 	int ret;
491 
492 	ret = eqc_pll_parse_jfracr(base + clk->pll.reg, &mult, &div, &acc);
493 	if (ret)
494 		return ret;
495 
496 	ret = eqc_fill_parent_data(clk, cells, &parent_data);
497 	if (ret)
498 		return ret;
499 
500 	hw = clk_hw_register_fixed_factor_pdata(dev, np, clk->name, &parent_data, 0, mult,
501 						div, acc, CLK_FIXED_FACTOR_FIXED_ACCURACY);
502 	if (IS_ERR(hw))
503 		return PTR_ERR(hw);
504 
505 	cells->hws[clk->index] = hw;
506 	return 0;
507 }
508 
eqc_probe(struct platform_device * pdev)509 static int eqc_probe(struct platform_device *pdev)
510 {
511 	struct device *dev = &pdev->dev;
512 	struct device_node *np = dev->of_node;
513 	const struct eqc_match_data *data;
514 	struct clk_hw_onecell_data *cells;
515 	unsigned int i, clk_count;
516 	struct resource *res;
517 	void __iomem *base;
518 	int ret;
519 
520 	data = device_get_match_data(dev);
521 	if (!data)
522 		return 0; /* No clocks nor auxdevs, we are done. */
523 
524 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
525 	if (!res)
526 		return -ENODEV;
527 
528 	base = ioremap(res->start, resource_size(res));
529 	if (!base)
530 		return -ENOMEM;
531 
532 	/* Init optional auxiliary devices. */
533 	eqc_auxdev_create_optional(dev, base, data->reset_auxdev_name);
534 	eqc_auxdev_create_optional(dev, base, data->pinctrl_auxdev_name);
535 	eqc_auxdev_create_optional(dev, base, data->eth_phy_auxdev_name);
536 
537 	if (data->clk_count == 0)
538 		return 0; /* Zero clocks, we are done. */
539 
540 	clk_count = data->clk_count + data->early_clk_count;
541 	cells = kzalloc_flex(*cells, hws, clk_count);
542 	if (!cells)
543 		return -ENOMEM;
544 
545 	cells->num = clk_count;
546 
547 	/* Early PLLs are marked as errors: the early provider will get queried. */
548 	for (i = 0; i < clk_count; i++)
549 		cells->hws[i] = ERR_PTR(-EINVAL);
550 
551 	for (i = 0; i < data->clk_count; i++) {
552 		const struct eqc_clock *clk = &data->clks[i];
553 
554 		if (clk->probe)
555 			ret = clk->probe(dev, NULL, clk, base, cells);
556 		else
557 			ret = -EINVAL;
558 		if (ret)
559 			dev_warn(dev, "failed probing clock %s: %d\n", clk->name, ret);
560 	}
561 
562 	return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, cells);
563 }
564 
565 #define DIV(_index, _parent_idx, _name, _parent_name,			\
566 	    _reg, _shift, _width)					\
567 	{								\
568 		.index = _index,					\
569 		.parent_idx = _parent_idx,				\
570 		.name = _name,						\
571 		.parent_name = _parent_name,				\
572 		.probe = eqc_probe_divider,				\
573 		.unregister = clk_hw_unregister_divider,		\
574 		.div.reg = _reg,					\
575 		.div.shift = _shift,					\
576 		.div.width = _width,					\
577 		.div.flags = CLK_DIVIDER_EVEN_INTEGERS,			\
578 		.div.table = NULL,					\
579 	}
580 
581 #define DIV_TABLE_RO(_index, _parent_idx, _name, _parent_name,		\
582 		     _reg, _shift, _width, _table)			\
583 	{								\
584 		.index = _index,					\
585 		.parent_idx = _parent_idx,				\
586 		.name = _name,						\
587 		.parent_name = _parent_name,				\
588 		.probe = eqc_probe_divider,				\
589 		.unregister = clk_hw_unregister_divider,		\
590 		.div.reg = _reg,					\
591 		.div.shift = _shift,					\
592 		.div.width = _width,					\
593 		.div.flags = CLK_DIVIDER_READ_ONLY,			\
594 		.div.table = _table,					\
595 	}
596 
597 #define FF(_index, _parent_idx, _name, _parent_name, _mult, _div)	\
598 	{								\
599 		.index = _index,					\
600 		.parent_idx = _parent_idx,				\
601 		.name = _name,						\
602 		.parent_name = _parent_name,				\
603 		.probe = eqc_probe_fixed_factor,			\
604 		.unregister = clk_hw_unregister_fixed_factor,		\
605 		.ff.mult = _mult,					\
606 		.ff.div = _div,						\
607 	}
608 
609 #define PLL_AINTP(_index, _parent_idx, _name, _parent_name, _reg)	\
610 	{								\
611 		.index = _index,					\
612 		.parent_idx = _parent_idx,				\
613 		.name = _name,						\
614 		.parent_name = _parent_name,				\
615 		.probe = eqc_probe_pll_aintp,				\
616 		.unregister = clk_hw_unregister_fixed_factor,		\
617 		.pll.reg = _reg,					\
618 	}
619 
620 #define PLL_FRACG(_index, _parent_idx, _name, _parent_name, _reg)	\
621 	{								\
622 		.index = _index,					\
623 		.parent_idx = _parent_idx,				\
624 		.name = _name,						\
625 		.parent_name = _parent_name,				\
626 		.probe = eqc_probe_pll_fracg,				\
627 		.unregister = clk_hw_unregister_fixed_factor,		\
628 		.pll.reg = _reg,					\
629 	}
630 
631 #define PLL_JFRACR(_index, _parent_idx, _name, _parent_name, _reg)	\
632 	{								\
633 		.index = _index,					\
634 		.parent_idx = _parent_idx,				\
635 		.name = _name,						\
636 		.parent_name = _parent_name,				\
637 		.probe = eqc_probe_pll_jfracr,				\
638 		.unregister = clk_hw_unregister_fixed_factor,		\
639 		.pll.reg = _reg,					\
640 	}
641 
642 enum {
643 	/*
644 	 * EQ5C_PLL_CPU children.
645 	 * EQ5C_PER_OCC_PCI is the last clock exposed in dt-bindings.
646 	 */
647 	EQ5C_CPU_OCC = EQ5C_PER_OCC_PCI + 1,
648 	EQ5C_CPU_SI_CSS0,
649 	EQ5C_CPU_CPC,
650 	EQ5C_CPU_CM,
651 	EQ5C_CPU_MEM,
652 	EQ5C_CPU_OCC_ISRAM,
653 	EQ5C_CPU_ISRAM,
654 	EQ5C_CPU_OCC_DBU,
655 	EQ5C_CPU_SI_DBU_TP,
656 
657 	/*
658 	 * EQ5C_PLL_VDI children.
659 	 */
660 	EQ5C_VDI_OCC_VDI,
661 	EQ5C_VDI_VDI,
662 	EQ5C_VDI_OCC_CAN_SER,
663 	EQ5C_VDI_CAN_SER,
664 	EQ5C_VDI_I2C_SER,
665 
666 	/*
667 	 * EQ5C_PLL_PER children.
668 	 */
669 	EQ5C_PER_PERIPH,
670 	EQ5C_PER_CAN,
671 	EQ5C_PER_TIMER,
672 	EQ5C_PER_CCF,
673 	EQ5C_PER_OCC_MJPEG,
674 	EQ5C_PER_HSM,
675 	EQ5C_PER_MJPEG,
676 	EQ5C_PER_FCMU_A,
677 };
678 
679 /* Required early for GIC timer (pll-cpu) and UARTs (pll-per). */
680 static const struct eqc_clock eqc_eyeq5_early_clks[] = {
681 	PLL_FRACG(EQ5C_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu", "ref", 0x02C),
682 	PLL_FRACG(EQ5C_PLL_PER, PARENT_BY_FWNAME, "pll-per", "ref", 0x05C),
683 
684 	FF(EQ5C_CPU_OCC, EQ5C_PLL_CPU, "occ-cpu", NULL, 1, 1),
685 	FF(EQ5C_CPU_SI_CSS0, EQ5C_CPU_OCC, "si-css0", NULL, 1, 1),
686 	FF(EQ5C_CPU_CORE0, EQ5C_CPU_SI_CSS0, "core0", NULL, 1, 1),
687 	FF(EQ5C_CPU_CORE1, EQ5C_CPU_SI_CSS0, "core1", NULL, 1, 1),
688 	FF(EQ5C_CPU_CORE2, EQ5C_CPU_SI_CSS0, "core2", NULL, 1, 1),
689 	FF(EQ5C_CPU_CORE3, EQ5C_CPU_SI_CSS0, "core3", NULL, 1, 1),
690 
691 	FF(EQ5C_PER_OCC, EQ5C_PLL_PER, "occ-periph", NULL, 1, 16),
692 	FF(EQ5C_PER_UART, EQ5C_PER_OCC, "uart", NULL, 1, 1),
693 };
694 
695 static const struct eqc_clock eqc_eyeq5_clks[] = {
696 	PLL_FRACG(EQ5C_PLL_VMP, PARENT_BY_FWNAME, "pll-vmp", "ref", 0x034),
697 	PLL_FRACG(EQ5C_PLL_PMA, PARENT_BY_FWNAME, "pll-pma", "ref", 0x03C),
698 	PLL_FRACG(EQ5C_PLL_VDI, PARENT_BY_FWNAME, "pll-vdi", "ref", 0x044),
699 	PLL_FRACG(EQ5C_PLL_DDR0, PARENT_BY_FWNAME, "pll-ddr0", "ref", 0x04C),
700 	PLL_FRACG(EQ5C_PLL_PCI, PARENT_BY_FWNAME, "pll-pci", "ref", 0x054),
701 	PLL_FRACG(EQ5C_PLL_PMAC, PARENT_BY_FWNAME, "pll-pmac", "ref", 0x064),
702 	PLL_FRACG(EQ5C_PLL_MPC, PARENT_BY_FWNAME, "pll-mpc", "ref", 0x06C),
703 	PLL_FRACG(EQ5C_PLL_DDR1, PARENT_BY_FWNAME, "pll-ddr1", "ref", 0x074),
704 
705 	DIV(EQ5C_DIV_OSPI, PARENT_BY_NAME, "div-ospi", "pll-per", 0x11C, 0, 4),
706 
707 	FF(EQ5C_CPU_CPC, PARENT_BY_NAME, "cpc", "si-css0", 1, 1),
708 	FF(EQ5C_CPU_CM, PARENT_BY_NAME, "cm", "si-css0", 1, 1),
709 	FF(EQ5C_CPU_MEM, PARENT_BY_NAME, "mem", "si-css0", 1, 1),
710 	FF(EQ5C_CPU_OCC_ISRAM, PARENT_BY_NAME, "occ-isram", "pll-cpu", 1, 2),
711 	FF(EQ5C_CPU_ISRAM, EQ5C_CPU_OCC_ISRAM, "isram", NULL, 1, 1),
712 	FF(EQ5C_CPU_OCC_DBU, PARENT_BY_NAME, "occ-dbu", "pll-cpu", 1, 10),
713 	FF(EQ5C_CPU_SI_DBU_TP, EQ5C_CPU_OCC_DBU, "si-dbu-tp", NULL, 1, 1),
714 
715 	FF(EQ5C_VDI_OCC_VDI, PARENT_BY_NAME, "occ-vdi", "pll-vdi", 1, 2),
716 	FF(EQ5C_VDI_VDI, EQ5C_VDI_OCC_VDI, "vdi", NULL, 1, 1),
717 	FF(EQ5C_VDI_OCC_CAN_SER, PARENT_BY_NAME, "occ-can-ser", "pll-vdi", 1, 16),
718 	FF(EQ5C_VDI_CAN_SER, EQ5C_VDI_OCC_CAN_SER, "can-ser", NULL, 1, 1),
719 	FF(EQ5C_VDI_I2C_SER, PARENT_BY_NAME, "i2c-ser", "pll-vdi", 1, 20),
720 
721 	FF(EQ5C_PER_PERIPH, PARENT_BY_NAME, "periph", "occ-periph", 1, 1),
722 	FF(EQ5C_PER_CAN, PARENT_BY_NAME, "can", "occ-periph", 1, 1),
723 	FF(EQ5C_PER_SPI, PARENT_BY_NAME, "spi", "occ-periph", 1, 1),
724 	FF(EQ5C_PER_I2C, PARENT_BY_NAME, "i2c", "occ-periph", 1, 1),
725 	FF(EQ5C_PER_TIMER, PARENT_BY_NAME, "timer", "occ-periph", 1, 1),
726 	FF(EQ5C_PER_GPIO, PARENT_BY_NAME, "gpio", "occ-periph", 1, 1),
727 	FF(EQ5C_PER_EMMC, PARENT_BY_NAME, "emmc-sys", "pll-per", 1, 10),
728 	FF(EQ5C_PER_CCF, PARENT_BY_NAME, "ccf-ctrl", "pll-per", 1, 4),
729 	FF(EQ5C_PER_OCC_MJPEG, PARENT_BY_NAME, "occ-mjpeg", "pll-per", 1, 2),
730 	FF(EQ5C_PER_HSM, EQ5C_PER_OCC_MJPEG, "hsm", NULL, 1, 1),
731 	FF(EQ5C_PER_MJPEG, EQ5C_PER_OCC_MJPEG, "mjpeg", NULL, 1, 1),
732 	FF(EQ5C_PER_FCMU_A, PARENT_BY_NAME, "fcmu-a", "pll-per", 1, 20),
733 	FF(EQ5C_PER_OCC_PCI, PARENT_BY_NAME, "occ-pci-sys", "pll-per", 1, 8),
734 };
735 
736 static const struct eqc_early_match_data eqc_eyeq5_early_match_data __initconst = {
737 	.early_clk_count	= ARRAY_SIZE(eqc_eyeq5_early_clks),
738 	.early_clks		= eqc_eyeq5_early_clks,
739 
740 	.late_clk_count		= ARRAY_SIZE(eqc_eyeq5_clks),
741 };
742 
743 static const struct eqc_match_data eqc_eyeq5_match_data = {
744 	.clk_count	= ARRAY_SIZE(eqc_eyeq5_clks),
745 	.clks		= eqc_eyeq5_clks,
746 
747 	.reset_auxdev_name = "reset",
748 	.pinctrl_auxdev_name = "pinctrl",
749 	.eth_phy_auxdev_name = "phy",
750 
751 	.early_clk_count = ARRAY_SIZE(eqc_eyeq5_early_clks),
752 };
753 
754 static const struct eqc_clock eqc_eyeq6l_clks[] = {
755 	PLL_FRACG(EQ6LC_PLL_DDR, PARENT_BY_FWNAME, "pll-ddr", "ref", 0x02C),
756 	PLL_FRACG(EQ6LC_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu", "ref", 0x034),
757 	PLL_FRACG(EQ6LC_PLL_PER, PARENT_BY_FWNAME, "pll-per", "ref", 0x03C),
758 	PLL_FRACG(EQ6LC_PLL_VDI, PARENT_BY_FWNAME, "pll-vdi", "ref", 0x044),
759 };
760 
761 static const struct eqc_match_data eqc_eyeq6l_match_data = {
762 	.clk_count	= ARRAY_SIZE(eqc_eyeq6l_clks),
763 	.clks		= eqc_eyeq6l_clks,
764 
765 	.reset_auxdev_name = "reset",
766 };
767 
768 static const struct eqc_clock eqc_eyeq6lplus_early_clks[] = {
769 	PLL_FRACG(EQ6LPC_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu", "ref", 0x058),
770 
771 	FF(EQ6LPC_CPU_OCC, EQ6LPC_PLL_CPU, "occ-cpu", NULL, 1, 1),
772 };
773 
774 static const struct eqc_clock eqc_eyeq6lplus_clks[] = {
775 	PLL_FRACG(EQ6LPC_PLL_DDR, PARENT_BY_FWNAME, "pll-ddr", "ref", 0x02C),
776 	PLL_FRACG(EQ6LPC_PLL_ACC, PARENT_BY_FWNAME, "pll-acc", "ref", 0x034),
777 	PLL_FRACG(EQ6LPC_PLL_PER, PARENT_BY_FWNAME, "pll-per", "ref", 0x03C),
778 	PLL_FRACG(EQ6LPC_PLL_VDI, PARENT_BY_FWNAME, "pll-vdi", "ref", 0x044),
779 
780 	FF(EQ6LPC_DDR_OCC, EQ6LPC_PLL_DDR, "occ-ddr", NULL, 1, 1),
781 
782 	FF(EQ6LPC_ACC_VDI, EQ6LPC_PLL_ACC, "vdi-div", NULL, 1, 10),
783 	FF(EQ6LPC_ACC_OCC, EQ6LPC_PLL_ACC, "occ-acc", NULL, 1, 1),
784 	FF(EQ6LPC_ACC_FCMU, EQ6LPC_ACC_OCC, "fcmu-a-clk", NULL, 1, 10),
785 
786 	FF(EQ6LPC_PER_OCC, EQ6LPC_PLL_PER, "occ-per", NULL, 1, 1),
787 	FF(EQ6LPC_PER_I2C_SER, EQ6LPC_PER_OCC, "i2c-ser-clk", NULL, 1, 10),
788 	FF(EQ6LPC_PER_PCLK, EQ6LPC_PER_OCC, "pclk", NULL, 1, 4),
789 	FF(EQ6LPC_PER_TSU, EQ6LPC_PER_OCC, "tsu-clk", NULL, 1, 8),
790 	FF(EQ6LPC_PER_OSPI, EQ6LPC_PER_OCC, "ospi-ref-clk", NULL, 1, 10),
791 	FF(EQ6LPC_PER_GPIO, EQ6LPC_PER_OCC, "gpio-clk", NULL, 1, 4),
792 	FF(EQ6LPC_PER_TIMER, EQ6LPC_PER_OCC, "timer-clk", NULL, 1, 4),
793 	FF(EQ6LPC_PER_I2C, EQ6LPC_PER_OCC, "i2c-clk", NULL, 1, 4),
794 	FF(EQ6LPC_PER_UART, EQ6LPC_PER_OCC, "uart-clk", NULL, 1, 4),
795 	FF(EQ6LPC_PER_SPI, EQ6LPC_PER_OCC, "spi-clk", NULL, 1, 4),
796 	FF(EQ6LPC_PER_PERIPH, EQ6LPC_PER_OCC, "periph-clk", NULL, 1, 1),
797 
798 	FF(EQ6LPC_VDI_OCC, EQ6LPC_PLL_VDI, "occ-vdi", NULL, 1, 1),
799 };
800 
801 static const struct eqc_early_match_data eqc_eyeq6lplus_early_match_data __initconst = {
802 	.early_clk_count	= ARRAY_SIZE(eqc_eyeq6lplus_early_clks),
803 	.early_clks		= eqc_eyeq6lplus_early_clks,
804 
805 	.late_clk_count		= ARRAY_SIZE(eqc_eyeq6lplus_clks),
806 };
807 
808 static const struct eqc_match_data eqc_eyeq6lplus_match_data = {
809 	.clk_count	= ARRAY_SIZE(eqc_eyeq6lplus_clks),
810 	.clks		= eqc_eyeq6lplus_clks,
811 
812 	.reset_auxdev_name = "reset",
813 	.pinctrl_auxdev_name = "pinctrl",
814 
815 	.early_clk_count = ARRAY_SIZE(eqc_eyeq6lplus_early_clks),
816 };
817 
818 static const struct eqc_match_data eqc_eyeq6h_west_match_data = {
819 	.reset_auxdev_name = "reset_west",
820 };
821 
822 static const struct eqc_clock eqc_eyeq6h_east_clks[] = {
823 	PLL_FRACG(0, PARENT_BY_FWNAME, "pll-east", "ref", 0x074),
824 };
825 
826 static const struct eqc_match_data eqc_eyeq6h_east_match_data = {
827 	.clk_count	= ARRAY_SIZE(eqc_eyeq6h_east_clks),
828 	.clks		= eqc_eyeq6h_east_clks,
829 
830 	.reset_auxdev_name = "reset_east",
831 };
832 
833 static const struct eqc_clock eqc_eyeq6h_south_clks[] = {
834 	PLL_FRACG(EQ6HC_SOUTH_PLL_VDI, PARENT_BY_FWNAME, "pll-vdi", "ref", 0x000),
835 	PLL_FRACG(EQ6HC_SOUTH_PLL_PCIE, PARENT_BY_FWNAME, "pll-pcie", "ref", 0x008),
836 	PLL_FRACG(EQ6HC_SOUTH_PLL_PER, PARENT_BY_FWNAME, "pll-per", "ref", 0x010),
837 	PLL_FRACG(EQ6HC_SOUTH_PLL_ISP, PARENT_BY_FWNAME, "pll-isp", "ref", 0x018),
838 
839 	DIV(EQ6HC_SOUTH_DIV_EMMC, EQ6HC_SOUTH_PLL_PER, "div-emmc", NULL, 0x070, 4, 4),
840 	DIV(EQ6HC_SOUTH_DIV_OSPI_REF, EQ6HC_SOUTH_PLL_PER, "div-ospi-ref", NULL, 0x090, 4, 4),
841 	DIV(EQ6HC_SOUTH_DIV_OSPI_SYS, EQ6HC_SOUTH_PLL_PER, "div-ospi-sys", NULL, 0x090, 8, 1),
842 	DIV(EQ6HC_SOUTH_DIV_TSU, EQ6HC_SOUTH_PLL_PCIE, "div-tsu", NULL, 0x098, 4, 8),
843 };
844 
845 static const struct eqc_match_data eqc_eyeq6h_south_match_data = {
846 	.clk_count	= ARRAY_SIZE(eqc_eyeq6h_south_clks),
847 	.clks		= eqc_eyeq6h_south_clks,
848 };
849 
850 static const struct eqc_clock eqc_eyeq6h_ddr0_clks[] = {
851 	PLL_FRACG(0, PARENT_BY_FWNAME, "pll-ddr0", "ref", 0x074),
852 };
853 
854 static const struct eqc_match_data eqc_eyeq6h_ddr0_match_data = {
855 	.clk_count	= ARRAY_SIZE(eqc_eyeq6h_ddr0_clks),
856 	.clks		= eqc_eyeq6h_ddr0_clks,
857 };
858 
859 static const struct eqc_clock eqc_eyeq6h_ddr1_clks[] = {
860 	PLL_FRACG(0, PARENT_BY_FWNAME, "pll-ddr1", "ref", 0x074),
861 };
862 
863 static const struct eqc_match_data eqc_eyeq6h_ddr1_match_data = {
864 	.clk_count	= ARRAY_SIZE(eqc_eyeq6h_ddr1_clks),
865 	.clks		= eqc_eyeq6h_ddr1_clks,
866 };
867 
868 static const struct eqc_clock eqc_eyeq6h_acc_clks[] = {
869 	PLL_FRACG(EQ6HC_ACC_PLL_XNN, PARENT_BY_FWNAME, "pll-xnn", "ref", 0x040),
870 	PLL_FRACG(EQ6HC_ACC_PLL_VMP, PARENT_BY_FWNAME, "pll-vmp", "ref", 0x050),
871 	PLL_FRACG(EQ6HC_ACC_PLL_PMA, PARENT_BY_FWNAME, "pll-pma", "ref", 0x05C),
872 	PLL_FRACG(EQ6HC_ACC_PLL_MPC, PARENT_BY_FWNAME, "pll-mpc", "ref", 0x068),
873 	PLL_FRACG(EQ6HC_ACC_PLL_NOC, PARENT_BY_FWNAME, "pll-noc", "ref", 0x070),
874 };
875 
876 static const struct eqc_match_data eqc_eyeq6h_acc_match_data = {
877 	.clk_count	= ARRAY_SIZE(eqc_eyeq6h_acc_clks),
878 	.clks		= eqc_eyeq6h_acc_clks,
879 
880 	.reset_auxdev_name = "reset_acc",
881 };
882 
883 static const struct eqc_clock eqc_eyeq7h_acc0_clks[] = {
884 	PLL_AINTP(EQ7HC_ACC_PLL_VMP, PARENT_BY_FWNAME, "pll-acc0-vmp", "ref_100p0", 0x400),
885 	PLL_AINTP(EQ7HC_ACC_PLL_MPC, PARENT_BY_FWNAME, "pll-acc0-mpc", "ref_100p0", 0x404),
886 	PLL_AINTP(EQ7HC_ACC_PLL_PMA, PARENT_BY_FWNAME, "pll-acc0-pma", "ref_100p0", 0x408),
887 	PLL_AINTP(EQ7HC_ACC_PLL_NOC, PARENT_BY_FWNAME, "pll-acc0-noc-acc", "ref_106p6", 0x40c),
888 
889 	FF(EQ7HC_ACC_DIV_PMA, EQ7HC_ACC_PLL_PMA, "acc0_pma", NULL, 1, 2),
890 	FF(EQ7HC_ACC_DIV_NCORE, EQ7HC_ACC_PLL_NOC, "acc0_ncore", NULL, 1, 2),
891 	FF(EQ7HC_ACC_DIV_CFG, EQ7HC_ACC_PLL_NOC, "acc0_cfg", NULL, 1, 8),
892 };
893 
894 static const struct eqc_match_data eqc_eyeq7h_acc0_match_data = {
895 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_acc0_clks),
896 	.clks		= eqc_eyeq7h_acc0_clks,
897 
898 	.reset_auxdev_name = "reset_acc0",
899 };
900 
901 static const struct eqc_clock eqc_eyeq7h_acc1_clks[] = {
902 	PLL_AINTP(EQ7HC_ACC_PLL_VMP, PARENT_BY_FWNAME, "pll-acc1-vmp", "ref_100p0", 0x400),
903 	PLL_AINTP(EQ7HC_ACC_PLL_MPC, PARENT_BY_FWNAME, "pll-acc1-mpc", "ref_100p0", 0x404),
904 	PLL_AINTP(EQ7HC_ACC_PLL_PMA, PARENT_BY_FWNAME, "pll-acc1-pma", "ref_100p0", 0x408),
905 	PLL_AINTP(EQ7HC_ACC_PLL_NOC, PARENT_BY_FWNAME, "pll-acc1-noc-acc", "ref_106p6", 0x40c),
906 };
907 
908 static const struct eqc_match_data eqc_eyeq7h_acc1_match_data = {
909 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_acc1_clks),
910 	.clks		= eqc_eyeq7h_acc1_clks,
911 
912 	.reset_auxdev_name = "reset_acc1",
913 };
914 
915 static const struct clk_div_table eqc_eyeq7h_ddr_apb_div_table[] = {
916 	{ .val = 0, .div = 8 },
917 	{ .val = 1, .div = 128 },
918 	{ .val = 0, .div = 0 },
919 };
920 
921 static const struct clk_div_table eqc_eyeq7h_ddr_ref_div_table[] = {
922 	{ .val = 0, .div = 2 },
923 	{ .val = 1, .div = 8 },
924 	{ .val = 0, .div = 0 },
925 };
926 
927 static const struct clk_div_table eqc_eyeq7h_ddr_dfi_div_table[] = {
928 	{ .val = 0, .div = 2 },
929 	{ .val = 1, .div = 32 },
930 	{ .val = 0, .div = 0 },
931 };
932 
933 static const struct eqc_clock eqc_eyeq7h_ddr0_clks[] = {
934 	PLL_AINTP(EQ7HC_DDR_PLL, PARENT_BY_FWNAME, "pll-ddr0", "ref", 0x0),
935 
936 	/* A single bit configures the 3 dividers below */
937 	DIV_TABLE_RO(EQ7HC_DDR_DIV_APB, EQ7HC_DDR_PLL, "div-ddr0_apb", NULL,
938 		     0x08, 10, 1, eqc_eyeq7h_ddr_apb_div_table),
939 	DIV_TABLE_RO(EQ7HC_DDR_DIV_PLLREF, EQ7HC_DDR_PLL, "div-ddr0_pllref", NULL,
940 		     0x08, 10, 1, eqc_eyeq7h_ddr_ref_div_table),
941 	DIV_TABLE_RO(EQ7HC_DDR_DIV_DFI, EQ7HC_DDR_PLL, "div-ddr0-dfi", NULL,
942 		     0x08, 10, 1, eqc_eyeq7h_ddr_dfi_div_table),
943 };
944 
945 static const struct eqc_match_data eqc_eyeq7h_ddr0_match_data = {
946 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_ddr0_clks),
947 	.clks		= eqc_eyeq7h_ddr0_clks,
948 
949 	.reset_auxdev_name = "reset_ddr0",
950 };
951 
952 static const struct eqc_clock eqc_eyeq7h_ddr1_clks[] = {
953 	PLL_AINTP(EQ7HC_DDR_PLL, PARENT_BY_FWNAME, "pll-ddr1", "ref", 0x0),
954 
955 	/* A single bit configures the 3 dividers below */
956 	DIV_TABLE_RO(EQ7HC_DDR_DIV_APB, EQ7HC_DDR_PLL, "div-ddr1_apb", NULL,
957 		     0x08, 10, 1, eqc_eyeq7h_ddr_apb_div_table),
958 	DIV_TABLE_RO(EQ7HC_DDR_DIV_PLLREF, EQ7HC_DDR_PLL, "div-ddr1_pllref", NULL,
959 		     0x08, 10, 1, eqc_eyeq7h_ddr_ref_div_table),
960 	DIV_TABLE_RO(EQ7HC_DDR_DIV_DFI, EQ7HC_DDR_PLL, "div-ddr1-dfi", NULL,
961 		     0x08, 10, 1, eqc_eyeq7h_ddr_dfi_div_table),
962 };
963 
964 static const struct eqc_match_data eqc_eyeq7h_ddr1_match_data = {
965 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_ddr1_clks),
966 	.clks		= eqc_eyeq7h_ddr1_clks,
967 
968 	.reset_auxdev_name = "reset_ddr1",
969 };
970 
971 static const struct eqc_clock eqc_eyeq7h_east_clocks[] = {
972 	PLL_JFRACR(EQ7HC_EAST_PLL_106P6, PARENT_BY_FWNAME, "pll-106p6-e", "ref", 0x00),
973 
974 	FF(EQ7HC_EAST_DIV_REF_106P6, EQ7HC_EAST_PLL_106P6, "ref_106p6_e", NULL, 1, 40),
975 
976 	PLL_AINTP(EQ7HC_EAST_PLL_NOC, EQ7HC_EAST_DIV_REF_106P6, "pll-noc-e", NULL, 0x30),
977 	PLL_AINTP(EQ7HC_EAST_PLL_ISP, PARENT_BY_FWNAME, "pll-isp", "ref_100p0", 0x38),
978 	PLL_AINTP(EQ7HC_EAST_PLL_VEU, PARENT_BY_FWNAME, "pll-veu", "ref_100p0", 0x40),
979 
980 	FF(EQ7HC_EAST_DIV_REF_DDR_PHY, EQ7HC_EAST_PLL_106P6, "ref_ddr_phy_e", NULL, 1, 2),
981 
982 	FF(EQ7HC_EAST_DIV_CORE, EQ7HC_EAST_PLL_NOC, "core_e", NULL, 1, 2),
983 	FF(EQ7HC_EAST_DIV_CORE_MBIST, EQ7HC_EAST_PLL_NOC, "core_mbist_e", NULL, 1, 2),
984 	FF(EQ7HC_EAST_DIV_ISRAM_MBIST, EQ7HC_EAST_PLL_NOC, "isram_mbist_e", NULL, 1, 2),
985 	FF(EQ7HC_EAST_DIV_CFG, EQ7HC_EAST_PLL_NOC, "cfg_e", NULL, 1, 4),
986 
987 	FF(EQ7HC_EAST_DIV_VEU_CORE, EQ7HC_EAST_PLL_VEU, "veu_core", NULL, 1, 4),
988 	FF(EQ7HC_EAST_DIV_VEU_MBIST, EQ7HC_EAST_PLL_VEU, "veu_mbist", NULL, 1, 4),
989 	FF(EQ7HC_EAST_DIV_VEU_OCP, EQ7HC_EAST_PLL_VEU, "veu_ocp", NULL, 1, 16),
990 
991 	FF(EQ7HC_EAST_DIV_LBITS, EQ7HC_EAST_PLL_ISP, "lbits_e", NULL, 1, 48),
992 	FF(EQ7HC_EAST_DIV_ISP0_CORE, EQ7HC_EAST_PLL_ISP, "isp0_core", NULL, 1, 2),
993 };
994 
995 static const struct eqc_match_data eqc_eyeq7h_east_match_data = {
996 	.clk_count = ARRAY_SIZE(eqc_eyeq7h_east_clocks),
997 	.clks = eqc_eyeq7h_east_clocks,
998 
999 	.reset_auxdev_name = "reset_east",
1000 };
1001 
1002 static const struct eqc_clock eqc_eyeq7h_mips0_clks[] = {
1003 	PLL_AINTP(EQ7HC_MIPS_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu0", "ref", 0x0),
1004 
1005 	FF(EQ7HC_MIPS_DIV_CM, EQ7HC_MIPS_PLL_CPU, "mips0_cm", NULL, 1, 2),
1006 };
1007 
1008 static const struct eqc_match_data eqc_eyeq7h_mips0_match_data = {
1009 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_mips0_clks),
1010 	.clks		= eqc_eyeq7h_mips0_clks,
1011 };
1012 
1013 static const struct eqc_clock eqc_eyeq7h_mips1_clks[] = {
1014 	PLL_AINTP(EQ7HC_MIPS_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu1", "ref", 0x0),
1015 
1016 	FF(EQ7HC_MIPS_DIV_CM, EQ7HC_MIPS_PLL_CPU, "mips1_cm", NULL, 1, 2),
1017 };
1018 
1019 static const struct eqc_match_data eqc_eyeq7h_mips1_match_data = {
1020 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_mips1_clks),
1021 	.clks		= eqc_eyeq7h_mips1_clks,
1022 };
1023 
1024 static const struct eqc_clock eqc_eyeq7h_mips2_clks[] = {
1025 	PLL_AINTP(EQ7HC_MIPS_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu2", "ref", 0x0),
1026 
1027 	FF(EQ7HC_MIPS_DIV_CM, EQ7HC_MIPS_PLL_CPU, "mips2_cm", NULL, 1, 2),
1028 };
1029 
1030 static const struct eqc_match_data eqc_eyeq7h_mips2_match_data = {
1031 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_mips2_clks),
1032 	.clks		= eqc_eyeq7h_mips2_clks,
1033 };
1034 
1035 static const struct eqc_clock eqc_eyeq7h_periph_east_clks[] = {
1036 	PLL_AINTP(EQ7HC_PERIPH_EAST_PLL_PER, PARENT_BY_FWNAME, "pll-periph_east_per", "ref", 0x0),
1037 
1038 	FF(EQ7HC_PERIPH_EAST_DIV_PER, EQ7HC_PERIPH_EAST_PLL_PER, "periph_e", NULL, 1, 10),
1039 };
1040 
1041 static const struct eqc_match_data eqc_eyeq7h_periph_east_match_data = {
1042 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_periph_east_clks),
1043 	.clks		= eqc_eyeq7h_periph_east_clks,
1044 
1045 	.reset_auxdev_name = "reset_periph_east",
1046 };
1047 
1048 static const struct eqc_clock eqc_eyeq7h_periph_west_clks[] = {
1049 	PLL_AINTP(EQ7HC_PERIPH_WEST_PLL_PER, PARENT_BY_FWNAME,
1050 		  "pll-periph_west_per", "ref_100p0", 0x0),
1051 	PLL_AINTP(EQ7HC_PERIPH_WEST_PLL_I2S, PARENT_BY_FWNAME,
1052 		  "pll-periph_west_i2s", "ref_106p6", 0x4),
1053 
1054 	FF(EQ7HC_PERIPH_WEST_DIV_PER, EQ7HC_PERIPH_WEST_PLL_PER, "periph_w", NULL, 1, 10),
1055 	FF(EQ7HC_PERIPH_WEST_DIV_I2S, EQ7HC_PERIPH_WEST_PLL_I2S, "periph_i2s_ser_w", NULL, 1, 100),
1056 };
1057 
1058 static const struct eqc_match_data eqc_eyeq7h_periph_west_match_data = {
1059 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_periph_west_clks),
1060 	.clks		= eqc_eyeq7h_periph_west_clks,
1061 
1062 	.reset_auxdev_name = "reset_periph_west",
1063 };
1064 
1065 static const struct eqc_clock eqc_eyeq7h_south_clks[] = {
1066 	PLL_JFRACR(EQ7HC_SOUTH_PLL_100P0, PARENT_BY_FWNAME, "pll-100p0", "ref", 0x40),
1067 
1068 	FF(EQ7HC_SOUTH_DIV_REF_100P0, EQ7HC_SOUTH_PLL_100P0, "ref_100p0", NULL, 1, 48),
1069 
1070 	PLL_AINTP(EQ7HC_SOUTH_PLL_XSPI, EQ7HC_SOUTH_DIV_REF_100P0, "pll-xspi", NULL, 0x10),
1071 	PLL_AINTP(EQ7HC_SOUTH_PLL_VDIO, EQ7HC_SOUTH_DIV_REF_100P0, "pll-vdio", NULL, 0x18),
1072 	PLL_AINTP(EQ7HC_SOUTH_PLL_PER, EQ7HC_SOUTH_DIV_REF_100P0, "pll-per-s", NULL, 0x20),
1073 
1074 	FF(EQ7HC_SOUTH_DIV_VDO_DSI_SYS, EQ7HC_SOUTH_PLL_100P0, "vdo_dsi_sys", NULL, 1, 9),
1075 	FF(EQ7HC_SOUTH_DIV_PMA_CMN_REF, EQ7HC_SOUTH_PLL_100P0, "pma_cmn_ref", NULL, 1, 48),
1076 	FF(EQ7HC_SOUTH_DIV_REF_UFS, EQ7HC_SOUTH_PLL_100P0, "ref_ufs", NULL, 1, 250),
1077 	FF(EQ7HC_SOUTH_DIV_XSPI_SYS, EQ7HC_SOUTH_PLL_XSPI, "xspi_sys", NULL, 1, 8),
1078 	FF(EQ7HC_SOUTH_DIV_XSPI_MBIST, EQ7HC_SOUTH_PLL_XSPI, "xspi_mbist", NULL, 1, 8),
1079 	FF(EQ7HC_SOUTH_DIV_NOC_S, EQ7HC_SOUTH_PLL_PER, "noc_s", NULL, 1, 2),
1080 	FF(EQ7HC_SOUTH_DIV_PCIE_SYS, EQ7HC_SOUTH_PLL_PER, "pcie_sys", NULL, 1, 4),
1081 	FF(EQ7HC_SOUTH_DIV_PCIE_SYS_MBIST, EQ7HC_SOUTH_PLL_PER, "pcie_sys_mbist", NULL, 1, 4),
1082 	FF(EQ7HC_SOUTH_DIV_PCIE_GBE_PHY, EQ7HC_SOUTH_PLL_PER, "pcie_gbe_phy_apb", NULL, 1, 16),
1083 	FF(EQ7HC_SOUTH_DIV_UFS_CORE, EQ7HC_SOUTH_PLL_PER, "ufs_core", NULL, 1, 8),
1084 	FF(EQ7HC_SOUTH_DIV_UFS_SMS, EQ7HC_SOUTH_PLL_PER, "ufs_sms", NULL, 1, 5),
1085 	FF(EQ7HC_SOUTH_DIV_UFS_ROM_SMS, EQ7HC_SOUTH_PLL_PER, "ufs_rom_sms", NULL, 1, 5),
1086 	FF(EQ7HC_SOUTH_DIV_ETH_SYS, EQ7HC_SOUTH_PLL_PER, "eth_sys", NULL, 1, 8),
1087 	FF(EQ7HC_SOUTH_DIV_ETH_MBIST, EQ7HC_SOUTH_PLL_PER, "eth_mbist", NULL, 1, 8),
1088 	FF(EQ7HC_SOUTH_DIV_CFG_S, EQ7HC_SOUTH_PLL_PER, "cfg_s", NULL, 1, 8),
1089 	FF(EQ7HC_SOUTH_DIV_TSU, EQ7HC_SOUTH_PLL_PER, "tsu", NULL, 1, 64),
1090 	FF(EQ7HC_SOUTH_DIV_VDIO, EQ7HC_SOUTH_PLL_VDIO, "vdio", NULL, 1, 4),
1091 	FF(EQ7HC_SOUTH_DIV_VDIO_CORE, EQ7HC_SOUTH_PLL_VDIO, "vdio_core", NULL, 1, 4),
1092 	FF(EQ7HC_SOUTH_DIV_VDIO_CORE_MBIST, EQ7HC_SOUTH_PLL_VDIO, "vdio_core_mbist", NULL, 1, 4),
1093 	FF(EQ7HC_SOUTH_DIV_VDO_CORE_MBIST, EQ7HC_SOUTH_PLL_VDIO, "vdo_core_mbist", NULL, 1, 4),
1094 	FF(EQ7HC_SOUTH_DIV_VDO_P, EQ7HC_SOUTH_PLL_VDIO, "vdo_p", NULL, 1, 40),
1095 	FF(EQ7HC_SOUTH_DIV_VDIO_CFG, EQ7HC_SOUTH_PLL_VDIO, "vdio_cfg", NULL, 1, 150),
1096 	FF(EQ7HC_SOUTH_DIV_VDIO_TXCLKESC, EQ7HC_SOUTH_PLL_VDIO, "vdio_txclkesc", NULL, 1, 8),
1097 };
1098 
1099 static const struct eqc_match_data eqc_eyeq7h_south_match_data = {
1100 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_south_clks),
1101 	.clks		= eqc_eyeq7h_south_clks,
1102 
1103 	.reset_auxdev_name = "reset_south",
1104 };
1105 
1106 static const struct eqc_clock eqc_eyeq7h_west_clks[] = {
1107 	PLL_JFRACR(EQ7HC_WEST_PLL_106P6, PARENT_BY_FWNAME, "pll-106p6-w", "ref", 0x0),
1108 
1109 	FF(EQ7HC_WEST_DIV_REF_106P6, EQ7HC_WEST_PLL_106P6, "ref_106p6_w", NULL, 1, 40),
1110 
1111 	PLL_AINTP(EQ7HC_WEST_PLL_NOC, EQ7HC_WEST_DIV_REF_106P6, "pll-noc-w", NULL, 0x30),
1112 	PLL_AINTP(EQ7HC_WEST_PLL_GPU, PARENT_BY_FWNAME, "pll-gpu", "ref_100p0", 0x38),
1113 	PLL_AINTP(EQ7HC_WEST_PLL_SSI, PARENT_BY_FWNAME, "pll-ssi", "ref_100p0", 0x40),
1114 
1115 	FF(EQ7HC_WEST_DIV_GPU, EQ7HC_WEST_PLL_GPU, "gpu", NULL, 1, 2),
1116 	FF(EQ7HC_WEST_DIV_GPU_MBIST, EQ7HC_WEST_PLL_GPU, "gpu_mbist", NULL, 1, 2),
1117 	FF(EQ7HC_WEST_DIV_LBITS, EQ7HC_WEST_PLL_GPU, "lbits_w", NULL, 1, 40),
1118 	FF(EQ7HC_WEST_DIV_MIPS_TIMER, EQ7HC_WEST_PLL_SSI, "mips_timer", NULL, 1, 24),
1119 	FF(EQ7HC_WEST_DIV_SSI_CORE, EQ7HC_WEST_PLL_SSI, "ssi_core", NULL, 1, 2),
1120 	FF(EQ7HC_WEST_DIV_SSI_CORE_MBIST, EQ7HC_WEST_PLL_SSI, "ssi_core_mbist", NULL, 1, 2),
1121 	FF(EQ7HC_WEST_DIV_SSI_ROM, EQ7HC_WEST_PLL_SSI, "ssi_rom", NULL, 1, 8),
1122 	FF(EQ7HC_WEST_DIV_SSI_ROM_MBIST, EQ7HC_WEST_PLL_SSI, "ssi_rom_mbist", NULL, 1, 8),
1123 	FF(EQ7HC_WEST_DIV_REF_DDR_PHY, EQ7HC_WEST_PLL_106P6, "ref_ddr_phy_w", NULL, 1, 2),
1124 	FF(EQ7HC_WEST_DIV_CORE, EQ7HC_WEST_PLL_NOC, "core_w", NULL, 1, 2),
1125 	FF(EQ7HC_WEST_DIV_CORE_MBIST, EQ7HC_WEST_PLL_NOC, "core_mbist_w", NULL, 1, 2),
1126 	FF(EQ7HC_WEST_DIV_CFG, EQ7HC_WEST_PLL_NOC, "cfg_w", NULL, 1, 4),
1127 	FF(EQ7HC_WEST_DIV_CAU, EQ7HC_WEST_PLL_NOC, "cau_w", NULL, 1, 8),
1128 	FF(EQ7HC_WEST_DIV_CAU_MBIST, EQ7HC_WEST_PLL_NOC, "cau_mbist_w", NULL, 1, 8),
1129 };
1130 
1131 static const struct eqc_match_data eqc_eyeq7h_west_match_data = {
1132 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_west_clks),
1133 	.clks		= eqc_eyeq7h_west_clks,
1134 
1135 	.reset_auxdev_name = "reset_west",
1136 };
1137 
1138 static const struct eqc_clock eqc_eyeq7h_xnn0_clks[] = {
1139 	PLL_AINTP(EQ7HC_XNN_PLL_XNN0, PARENT_BY_FWNAME, "pll-xnn0-0", "ref_100p0", 0x400),
1140 	PLL_AINTP(EQ7HC_XNN_PLL_XNN1, PARENT_BY_FWNAME, "pll-xnn0-1", "ref_100p0", 0x404),
1141 	PLL_AINTP(EQ7HC_XNN_PLL_XNN2, PARENT_BY_FWNAME, "pll-xnn0-2", "ref_100p0", 0x408),
1142 	PLL_AINTP(EQ7HC_XNN_PLL_CLSTR, PARENT_BY_FWNAME, "pll-xnn0-clstr", "ref_106p6", 0x410),
1143 
1144 	FF(EQ7HC_XNN_DIV_XNN0, EQ7HC_XNN_PLL_XNN0, "xnn0", NULL, 1, 2),
1145 	FF(EQ7HC_XNN_DIV_XNN1, EQ7HC_XNN_PLL_XNN1, "xnn1", NULL, 1, 2),
1146 	FF(EQ7HC_XNN_DIV_XNN2, EQ7HC_XNN_PLL_XNN2, "xnn2", NULL, 1, 2),
1147 	FF(EQ7HC_XNN_DIV_CLSTR, EQ7HC_XNN_PLL_CLSTR, "xnn0_clstr", NULL, 1, 2),
1148 	FF(EQ7HC_XNN_DIV_I2, EQ7HC_XNN_PLL_CLSTR, "xnn0_i2", NULL, 1, 4),
1149 	FF(EQ7HC_XNN_DIV_I2_SMS, EQ7HC_XNN_PLL_CLSTR, "xnn0_i2_sms", NULL, 1, 4),
1150 	FF(EQ7HC_XNN_DIV_CFG, EQ7HC_XNN_PLL_CLSTR, "xnn0_cfg", NULL, 1, 8),
1151 };
1152 
1153 static const struct eqc_match_data eqc_eyeq7h_xnn0_match_data = {
1154 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_xnn0_clks),
1155 	.clks		= eqc_eyeq7h_xnn0_clks,
1156 
1157 	.reset_auxdev_name = "reset_xnn0",
1158 };
1159 
1160 static const struct eqc_clock eqc_eyeq7h_xnn1_clks[] = {
1161 	PLL_AINTP(EQ7HC_XNN_PLL_XNN0, PARENT_BY_FWNAME, "pll-xnn1-0", "ref_100p0", 0x400),
1162 	PLL_AINTP(EQ7HC_XNN_PLL_XNN1, PARENT_BY_FWNAME, "pll-xnn1-1", "ref_100p0", 0x404),
1163 	PLL_AINTP(EQ7HC_XNN_PLL_XNN2, PARENT_BY_FWNAME, "pll-xnn1-2", "ref_100p0", 0x408),
1164 	PLL_AINTP(EQ7HC_XNN_PLL_CLSTR, PARENT_BY_FWNAME, "pll-xnn1-clstr", "ref_106p6", 0x410),
1165 };
1166 
1167 static const struct eqc_match_data eqc_eyeq7h_xnn1_match_data = {
1168 	.clk_count	= ARRAY_SIZE(eqc_eyeq7h_xnn1_clks),
1169 	.clks		= eqc_eyeq7h_xnn1_clks,
1170 
1171 	.reset_auxdev_name = "reset_xnn1",
1172 };
1173 
1174 static const struct of_device_id eqc_match_table[] = {
1175 	{ .compatible = "mobileye,eyeq5-olb", .data = &eqc_eyeq5_match_data },
1176 	{ .compatible = "mobileye,eyeq6l-olb", .data = &eqc_eyeq6l_match_data },
1177 	{ .compatible = "mobileye,eyeq6lplus-olb", .data = &eqc_eyeq6lplus_match_data },
1178 	{ .compatible = "mobileye,eyeq6h-west-olb", .data = &eqc_eyeq6h_west_match_data },
1179 	{ .compatible = "mobileye,eyeq6h-east-olb", .data = &eqc_eyeq6h_east_match_data },
1180 	{ .compatible = "mobileye,eyeq6h-south-olb", .data = &eqc_eyeq6h_south_match_data },
1181 	{ .compatible = "mobileye,eyeq6h-ddr0-olb", .data = &eqc_eyeq6h_ddr0_match_data },
1182 	{ .compatible = "mobileye,eyeq6h-ddr1-olb", .data = &eqc_eyeq6h_ddr1_match_data },
1183 	{ .compatible = "mobileye,eyeq6h-acc-olb", .data = &eqc_eyeq6h_acc_match_data },
1184 	{ .compatible = "mobileye,eyeq7h-acc0-olb", .data = &eqc_eyeq7h_acc0_match_data },
1185 	{ .compatible = "mobileye,eyeq7h-acc1-olb", .data = &eqc_eyeq7h_acc1_match_data },
1186 	{ .compatible = "mobileye,eyeq7h-ddr0-olb", .data = &eqc_eyeq7h_ddr0_match_data },
1187 	{ .compatible = "mobileye,eyeq7h-ddr1-olb", .data = &eqc_eyeq7h_ddr1_match_data },
1188 	{ .compatible = "mobileye,eyeq7h-east-olb", .data = &eqc_eyeq7h_east_match_data },
1189 	{ .compatible = "mobileye,eyeq7h-mips0-olb", .data = &eqc_eyeq7h_mips0_match_data },
1190 	{ .compatible = "mobileye,eyeq7h-mips1-olb", .data = &eqc_eyeq7h_mips1_match_data },
1191 	{ .compatible = "mobileye,eyeq7h-mips2-olb", .data = &eqc_eyeq7h_mips2_match_data },
1192 	{ .compatible = "mobileye,eyeq7h-periph-east-olb",
1193 	  .data = &eqc_eyeq7h_periph_east_match_data },
1194 	{ .compatible = "mobileye,eyeq7h-periph-west-olb",
1195 	  .data = &eqc_eyeq7h_periph_west_match_data },
1196 	{ .compatible = "mobileye,eyeq7h-south-olb", .data = &eqc_eyeq7h_south_match_data },
1197 	{ .compatible = "mobileye,eyeq7h-west-olb", .data = &eqc_eyeq7h_west_match_data },
1198 	{ .compatible = "mobileye,eyeq7h-xnn0-olb", .data = &eqc_eyeq7h_xnn0_match_data },
1199 	{ .compatible = "mobileye,eyeq7h-xnn1-olb", .data = &eqc_eyeq7h_xnn1_match_data },
1200 	{}
1201 };
1202 
1203 static struct platform_driver eqc_driver = {
1204 	.probe = eqc_probe,
1205 	.driver = {
1206 		.name = "clk-eyeq",
1207 		.of_match_table = eqc_match_table,
1208 		.suppress_bind_attrs = true,
1209 	},
1210 };
1211 builtin_platform_driver(eqc_driver);
1212 
1213 /* Required early for GIC timer. */
1214 static const struct eqc_clock eqc_eyeq6h_central_early_clks[] = {
1215 	PLL_FRACG(EQ6HC_CENTRAL_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu", "ref", 0x02C),
1216 
1217 	FF(EQ6HC_CENTRAL_CPU_OCC, EQ6HC_CENTRAL_PLL_CPU, "occ-cpu", NULL, 1, 1),
1218 };
1219 
1220 static const struct eqc_early_match_data eqc_eyeq6h_central_early_match_data __initconst = {
1221 	.early_clk_count	= ARRAY_SIZE(eqc_eyeq6h_central_early_clks),
1222 	.early_clks		= eqc_eyeq6h_central_early_clks,
1223 };
1224 
1225 /* Required early for UART. */
1226 static const struct eqc_clock eqc_eyeq6h_west_early_clks[] = {
1227 	PLL_FRACG(EQ6HC_WEST_PLL_PER, PARENT_BY_FWNAME, "pll-west", "ref", 0x074),
1228 
1229 	FF(EQ6HC_WEST_PER_OCC, EQ6HC_WEST_PLL_PER, "west-per-occ", NULL, 1, 10),
1230 	FF(EQ6HC_WEST_PER_UART, EQ6HC_WEST_PER_OCC, "west-per-uart", NULL, 1, 1),
1231 };
1232 
1233 static const struct eqc_early_match_data eqc_eyeq6h_west_early_match_data __initconst = {
1234 	.early_clk_count	= ARRAY_SIZE(eqc_eyeq6h_west_early_clks),
1235 	.early_clks		= eqc_eyeq6h_west_early_clks,
1236 };
1237 
eqc_early_init(struct device_node * np,const struct eqc_early_match_data * early_data)1238 static void __init eqc_early_init(struct device_node *np,
1239 				  const struct eqc_early_match_data *early_data)
1240 {
1241 	struct clk_hw_onecell_data *cells;
1242 	unsigned int i, clk_count;
1243 	void __iomem *base;
1244 	int ret;
1245 
1246 	clk_count = early_data->early_clk_count + early_data->late_clk_count;
1247 	cells = kzalloc_flex(*cells, hws, clk_count);
1248 	if (!cells) {
1249 		ret = -ENOMEM;
1250 		goto err;
1251 	}
1252 
1253 	cells->num = clk_count;
1254 
1255 	/*
1256 	 * Mark all clocks as deferred; some are registered here, the rest at
1257 	 * platform device probe.
1258 	 *
1259 	 * Once the platform device is probed, its provider will take priority
1260 	 * when looking up clocks.
1261 	 */
1262 	for (i = 0; i < clk_count; i++)
1263 		cells->hws[i] = ERR_PTR(-EPROBE_DEFER);
1264 
1265 	/* Offsets (reg64) of early PLLs are relative to OLB block. */
1266 	base = of_iomap(np, 0);
1267 	if (!base) {
1268 		ret = -ENODEV;
1269 		goto err;
1270 	}
1271 
1272 	for (i = 0; i < early_data->early_clk_count; i++) {
1273 		const struct eqc_clock *clk = &early_data->early_clks[i];
1274 
1275 		if (clk->probe)
1276 			ret = clk->probe(NULL, np, clk, base, cells);
1277 		else
1278 			ret = -EINVAL;
1279 		if (ret) {
1280 			pr_err("failed registering %s\n", clk->name);
1281 			goto err;
1282 		}
1283 	}
1284 
1285 	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, cells);
1286 	if (ret) {
1287 		pr_err("failed registering clk provider: %d\n", ret);
1288 		goto err;
1289 	}
1290 
1291 	return;
1292 
1293 err:
1294 	/*
1295 	 * We are doomed. The system will not be able to boot.
1296 	 *
1297 	 * Let's still try to be good citizens by freeing resources and print
1298 	 * a last error message that might help debugging.
1299 	 */
1300 
1301 	pr_err("failed clk init: %d\n", ret);
1302 
1303 	if (cells) {
1304 		of_clk_del_provider(np);
1305 
1306 		for (i = 0; i < early_data->early_clk_count; i++) {
1307 			const struct eqc_clock *clk = &early_data->early_clks[i];
1308 			struct clk_hw *hw = cells->hws[clk->index];
1309 
1310 			if (!IS_ERR_OR_NULL(hw) && clk->unregister)
1311 				clk->unregister(hw);
1312 		}
1313 
1314 		kfree(cells);
1315 	}
1316 }
1317 
eqc_eyeq5_early_init(struct device_node * np)1318 static void __init eqc_eyeq5_early_init(struct device_node *np)
1319 {
1320 	eqc_early_init(np, &eqc_eyeq5_early_match_data);
1321 }
1322 CLK_OF_DECLARE_DRIVER(eqc_eyeq5, "mobileye,eyeq5-olb", eqc_eyeq5_early_init);
1323 
eqc_eyeq6h_central_early_init(struct device_node * np)1324 static void __init eqc_eyeq6h_central_early_init(struct device_node *np)
1325 {
1326 	eqc_early_init(np, &eqc_eyeq6h_central_early_match_data);
1327 }
1328 CLK_OF_DECLARE_DRIVER(eqc_eyeq6h_central, "mobileye,eyeq6h-central-olb",
1329 		      eqc_eyeq6h_central_early_init);
1330 
eqc_eyeq6h_west_early_init(struct device_node * np)1331 static void __init eqc_eyeq6h_west_early_init(struct device_node *np)
1332 {
1333 	eqc_early_init(np, &eqc_eyeq6h_west_early_match_data);
1334 }
1335 CLK_OF_DECLARE_DRIVER(eqc_eyeq6h_west, "mobileye,eyeq6h-west-olb",
1336 		      eqc_eyeq6h_west_early_init);
1337 
eqc_eyeq6lplus_early_init(struct device_node * np)1338 static void __init eqc_eyeq6lplus_early_init(struct device_node *np)
1339 {
1340 	eqc_early_init(np, &eqc_eyeq6lplus_early_match_data);
1341 }
1342 CLK_OF_DECLARE_DRIVER(eqc_eyeq6lplus, "mobileye,eyeq6lplus-olb", eqc_eyeq6lplus_early_init);
1343