Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * PLL clock driver for the Mobileye EyeQ5, EyeQ6L and EyeQ6H 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/mod_devicetable.h>
37#include <linux/module.h>
38#include <linux/of.h>
39#include <linux/of_address.h>
40#include <linux/overflow.h>
41#include <linux/platform_device.h>
42#include <linux/printk.h>
43#include <linux/slab.h>
44#include <linux/spinlock.h>
45#include <linux/types.h>
46
47#include <dt-bindings/clock/mobileye,eyeq5-clk.h>
48#include <dt-bindings/clock/mobileye,eyeq6lplus-clk.h>
49
50/* In frac mode, it enables fractional noise canceling DAC. Else, no function. */
51#define PCSR0_DAC_EN BIT(0)
52/* Fractional or integer mode */
53#define PCSR0_DSM_EN BIT(1)
54#define PCSR0_PLL_EN BIT(2)
55/* All clocks output held at 0 */
56#define PCSR0_FOUTPOSTDIV_EN BIT(3)
57#define PCSR0_POST_DIV1 GENMASK(6, 4)
58#define PCSR0_POST_DIV2 GENMASK(9, 7)
59#define PCSR0_REF_DIV GENMASK(15, 10)
60#define PCSR0_INTIN GENMASK(27, 16)
61#define PCSR0_BYPASS BIT(28)
62/* Bits 30..29 are reserved */
63#define PCSR0_PLL_LOCKED BIT(31)
64
65#define PCSR1_RESET BIT(0)
66#define PCSR1_SSGC_DIV GENMASK(4, 1)
67/* Spread amplitude (% = 0.1 * SPREAD[4:0]) */
68#define PCSR1_SPREAD GENMASK(9, 5)
69#define PCSR1_DIS_SSCG BIT(10)
70/* Down-spread or center-spread */
71#define PCSR1_DOWN_SPREAD BIT(11)
72#define PCSR1_FRAC_IN GENMASK(31, 12)
73
74struct eqc_pll {
75 unsigned int index;
76 const char *name;
77 unsigned int reg64;
78};
79
80/*
81 * Divider clock. Divider is 2*(v+1), with v the register value.
82 * Min divider is 2, max is 2*(2^width).
83 */
84struct eqc_div {
85 unsigned int index;
86 const char *name;
87 unsigned int parent;
88 unsigned int reg;
89 u8 shift;
90 u8 width;
91};
92
93struct eqc_fixed_factor {
94 unsigned int index;
95 const char *name;
96 unsigned int mult;
97 unsigned int div;
98 unsigned int parent;
99};
100
101struct eqc_match_data {
102 unsigned int pll_count;
103 const struct eqc_pll *plls;
104
105 unsigned int div_count;
106 const struct eqc_div *divs;
107
108 unsigned int fixed_factor_count;
109 const struct eqc_fixed_factor *fixed_factors;
110
111 const char *reset_auxdev_name;
112 const char *pinctrl_auxdev_name;
113
114 unsigned int early_clk_count;
115};
116
117struct eqc_early_match_data {
118 unsigned int early_pll_count;
119 const struct eqc_pll *early_plls;
120
121 unsigned int early_fixed_factor_count;
122 const struct eqc_fixed_factor *early_fixed_factors;
123
124 /*
125 * We want our of_xlate callback to EPROBE_DEFER instead of dev_err()
126 * and EINVAL. For that, we must know the total clock count.
127 */
128 unsigned int late_clk_count;
129};
130
131/*
132 * Both factors (mult and div) must fit in 32 bits. When an operation overflows,
133 * this function throws away low bits so that factors still fit in 32 bits.
134 *
135 * Precision loss depends on amplitude of mult and div. Worst theoretical
136 * loss is: (UINT_MAX+1) / UINT_MAX - 1 = 2.3e-10.
137 * This is 1Hz every 4.3GHz.
138 */
139static void eqc_pll_downshift_factors(unsigned long *mult, unsigned long *div)
140{
141 unsigned long biggest;
142 unsigned int shift;
143
144 /* This function can be removed if mult/div switch to unsigned long. */
145 static_assert(sizeof_field(struct clk_fixed_factor, mult) == sizeof(unsigned int));
146 static_assert(sizeof_field(struct clk_fixed_factor, div) == sizeof(unsigned int));
147
148 /* No overflow, nothing to be done. */
149 if (*mult <= UINT_MAX && *div <= UINT_MAX)
150 return;
151
152 /*
153 * Compute the shift required to bring the biggest factor into unsigned
154 * int range. That is, shift its highest set bit to the unsigned int
155 * most significant bit.
156 */
157 biggest = max(*mult, *div);
158 shift = __fls(biggest) - (BITS_PER_BYTE * sizeof(unsigned int)) + 1;
159
160 *mult >>= shift;
161 *div >>= shift;
162}
163
164static int eqc_pll_parse_registers(u32 r0, u32 r1, unsigned long *mult,
165 unsigned long *div, unsigned long *acc)
166{
167 unsigned long spread;
168
169 if (r0 & PCSR0_BYPASS) {
170 *mult = 1;
171 *div = 1;
172 *acc = 0;
173 return 0;
174 }
175
176 if (!(r0 & PCSR0_PLL_LOCKED))
177 return -EINVAL;
178
179 *mult = FIELD_GET(PCSR0_INTIN, r0);
180 *div = FIELD_GET(PCSR0_REF_DIV, r0);
181
182 /* Fractional mode, in 2^20 (0x100000) parts. */
183 if (r0 & PCSR0_DSM_EN) {
184 *div *= (1ULL << 20);
185 *mult = *mult * (1ULL << 20) + FIELD_GET(PCSR1_FRAC_IN, r1);
186 }
187
188 if (!*mult || !*div)
189 return -EINVAL;
190
191 if (r1 & (PCSR1_RESET | PCSR1_DIS_SSCG)) {
192 *acc = 0;
193 return 0;
194 }
195
196 /*
197 * Spread spectrum.
198 *
199 * Spread is in 1/1024 parts of frequency. Clock accuracy
200 * is half the spread value expressed in parts per billion.
201 *
202 * accuracy = (spread * 1e9) / (1024 * 2)
203 *
204 * Care is taken to avoid overflowing or losing precision.
205 */
206 spread = FIELD_GET(PCSR1_SPREAD, r1);
207 *acc = DIV_ROUND_CLOSEST(spread * 1000000000, 1024 * 2);
208
209 if (r1 & PCSR1_DOWN_SPREAD) {
210 /*
211 * Downspreading: the central frequency is half a
212 * spread lower.
213 */
214 *mult *= 2048 - spread;
215 *div *= 2048;
216
217 /*
218 * Previous operation might overflow 32 bits. If it
219 * does, throw away the least amount of low bits.
220 */
221 eqc_pll_downshift_factors(mult, div);
222 }
223
224 return 0;
225}
226
227static void eqc_probe_init_plls(struct device *dev, const struct eqc_match_data *data,
228 void __iomem *base, struct clk_hw_onecell_data *cells)
229{
230 unsigned long mult, div, acc;
231 const struct eqc_pll *pll;
232 struct clk_hw *hw;
233 unsigned int i;
234 u32 r0, r1;
235 u64 val;
236 int ret;
237
238 for (i = 0; i < data->pll_count; i++) {
239 pll = &data->plls[i];
240
241 val = readq(base + pll->reg64);
242 r0 = val;
243 r1 = val >> 32;
244
245 ret = eqc_pll_parse_registers(r0, r1, &mult, &div, &acc);
246 if (ret) {
247 dev_warn(dev, "failed parsing state of %s\n", pll->name);
248 cells->hws[pll->index] = ERR_PTR(ret);
249 continue;
250 }
251
252 hw = clk_hw_register_fixed_factor_with_accuracy_fwname(dev,
253 dev->of_node, pll->name, "ref", 0, mult, div, acc);
254 cells->hws[pll->index] = hw;
255 if (IS_ERR(hw))
256 dev_warn(dev, "failed registering %s: %pe\n", pll->name, hw);
257 }
258}
259
260static void eqc_probe_init_divs(struct device *dev, const struct eqc_match_data *data,
261 void __iomem *base, struct clk_hw_onecell_data *cells)
262{
263 struct clk_parent_data parent_data = { };
264 const struct eqc_div *div;
265 struct clk_hw *parent;
266 void __iomem *reg;
267 struct clk_hw *hw;
268 unsigned int i;
269
270 for (i = 0; i < data->div_count; i++) {
271 div = &data->divs[i];
272 reg = base + div->reg;
273 parent = cells->hws[div->parent];
274
275 if (IS_ERR(parent)) {
276 /* Parent is in early clk provider. */
277 parent_data.index = div->parent;
278 parent_data.hw = NULL;
279 } else {
280 /* Avoid clock lookup when we already have the hw reference. */
281 parent_data.index = 0;
282 parent_data.hw = parent;
283 }
284
285 hw = clk_hw_register_divider_table_parent_data(dev, div->name,
286 &parent_data, 0, reg, div->shift, div->width,
287 CLK_DIVIDER_EVEN_INTEGERS, NULL, NULL);
288 cells->hws[div->index] = hw;
289 if (IS_ERR(hw))
290 dev_warn(dev, "failed registering %s: %pe\n",
291 div->name, hw);
292 }
293}
294
295static void eqc_probe_init_fixed_factors(struct device *dev,
296 const struct eqc_match_data *data,
297 struct clk_hw_onecell_data *cells)
298{
299 const struct eqc_fixed_factor *ff;
300 struct clk_hw *hw, *parent_hw;
301 unsigned int i;
302
303 for (i = 0; i < data->fixed_factor_count; i++) {
304 ff = &data->fixed_factors[i];
305 parent_hw = cells->hws[ff->parent];
306
307 if (IS_ERR(parent_hw)) {
308 /* Parent is in early clk provider. */
309 hw = clk_hw_register_fixed_factor_index(dev, ff->name,
310 ff->parent, 0, ff->mult, ff->div);
311 } else {
312 /* Avoid clock lookup when we already have the hw reference. */
313 hw = clk_hw_register_fixed_factor_parent_hw(dev, ff->name,
314 parent_hw, 0, ff->mult, ff->div);
315 }
316
317 cells->hws[ff->index] = hw;
318 if (IS_ERR(hw))
319 dev_warn(dev, "failed registering %s: %pe\n",
320 ff->name, hw);
321 }
322}
323
324static void eqc_auxdev_release(struct device *dev)
325{
326 struct auxiliary_device *adev = to_auxiliary_dev(dev);
327
328 kfree(adev);
329}
330
331static int eqc_auxdev_create(struct device *dev, void __iomem *base,
332 const char *name, u32 id)
333{
334 struct auxiliary_device *adev;
335 int ret;
336
337 adev = kzalloc_obj(*adev);
338 if (!adev)
339 return -ENOMEM;
340
341 adev->name = name;
342 adev->dev.parent = dev;
343 adev->dev.platform_data = (void __force *)base;
344 adev->dev.release = eqc_auxdev_release;
345 adev->id = id;
346
347 ret = auxiliary_device_init(adev);
348 if (ret)
349 return ret;
350
351 ret = auxiliary_device_add(adev);
352 if (ret)
353 auxiliary_device_uninit(adev);
354
355 return ret;
356}
357
358static int eqc_probe(struct platform_device *pdev)
359{
360 struct device *dev = &pdev->dev;
361 struct device_node *np = dev->of_node;
362 const struct eqc_match_data *data;
363 struct clk_hw_onecell_data *cells;
364 unsigned int i, clk_count;
365 struct resource *res;
366 void __iomem *base;
367 int ret;
368
369 data = device_get_match_data(dev);
370 if (!data)
371 return 0; /* No clocks nor auxdevs, we are done. */
372
373 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
374 if (!res)
375 return -ENODEV;
376
377 base = ioremap(res->start, resource_size(res));
378 if (!base)
379 return -ENOMEM;
380
381 /* Init optional reset auxiliary device. */
382 if (data->reset_auxdev_name) {
383 ret = eqc_auxdev_create(dev, base, data->reset_auxdev_name, 0);
384 if (ret)
385 dev_warn(dev, "failed creating auxiliary device %s.%s: %d\n",
386 KBUILD_MODNAME, data->reset_auxdev_name, ret);
387 }
388
389 /* Init optional pinctrl auxiliary device. */
390 if (data->pinctrl_auxdev_name) {
391 ret = eqc_auxdev_create(dev, base, data->pinctrl_auxdev_name, 0);
392 if (ret)
393 dev_warn(dev, "failed creating auxiliary device %s.%s: %d\n",
394 KBUILD_MODNAME, data->pinctrl_auxdev_name, ret);
395 }
396
397 if (data->pll_count + data->div_count + data->fixed_factor_count == 0)
398 return 0; /* Zero clocks, we are done. */
399
400 clk_count = data->pll_count + data->div_count +
401 data->fixed_factor_count + data->early_clk_count;
402 cells = kzalloc_flex(*cells, hws, clk_count);
403 if (!cells)
404 return -ENOMEM;
405
406 cells->num = clk_count;
407
408 /* Early PLLs are marked as errors: the early provider will get queried. */
409 for (i = 0; i < clk_count; i++)
410 cells->hws[i] = ERR_PTR(-EINVAL);
411
412 eqc_probe_init_plls(dev, data, base, cells);
413
414 eqc_probe_init_divs(dev, data, base, cells);
415
416 eqc_probe_init_fixed_factors(dev, data, cells);
417
418 return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, cells);
419}
420
421/* Required early for GIC timer (pll-cpu) and UARTs (pll-per). */
422static const struct eqc_pll eqc_eyeq5_early_plls[] = {
423 { .index = EQ5C_PLL_CPU, .name = "pll-cpu", .reg64 = 0x02C },
424 { .index = EQ5C_PLL_PER, .name = "pll-per", .reg64 = 0x05C },
425};
426
427static const struct eqc_pll eqc_eyeq5_plls[] = {
428 { .index = EQ5C_PLL_VMP, .name = "pll-vmp", .reg64 = 0x034 },
429 { .index = EQ5C_PLL_PMA, .name = "pll-pma", .reg64 = 0x03C },
430 { .index = EQ5C_PLL_VDI, .name = "pll-vdi", .reg64 = 0x044 },
431 { .index = EQ5C_PLL_DDR0, .name = "pll-ddr0", .reg64 = 0x04C },
432 { .index = EQ5C_PLL_PCI, .name = "pll-pci", .reg64 = 0x054 },
433 { .index = EQ5C_PLL_PMAC, .name = "pll-pmac", .reg64 = 0x064 },
434 { .index = EQ5C_PLL_MPC, .name = "pll-mpc", .reg64 = 0x06C },
435 { .index = EQ5C_PLL_DDR1, .name = "pll-ddr1", .reg64 = 0x074 },
436};
437
438enum {
439 /*
440 * EQ5C_PLL_CPU children.
441 * EQ5C_PER_OCC_PCI is the last clock exposed in dt-bindings.
442 */
443 EQ5C_CPU_OCC = EQ5C_PER_OCC_PCI + 1,
444 EQ5C_CPU_SI_CSS0,
445 EQ5C_CPU_CPC,
446 EQ5C_CPU_CM,
447 EQ5C_CPU_MEM,
448 EQ5C_CPU_OCC_ISRAM,
449 EQ5C_CPU_ISRAM,
450 EQ5C_CPU_OCC_DBU,
451 EQ5C_CPU_SI_DBU_TP,
452
453 /*
454 * EQ5C_PLL_VDI children.
455 */
456 EQ5C_VDI_OCC_VDI,
457 EQ5C_VDI_VDI,
458 EQ5C_VDI_OCC_CAN_SER,
459 EQ5C_VDI_CAN_SER,
460 EQ5C_VDI_I2C_SER,
461
462 /*
463 * EQ5C_PLL_PER children.
464 */
465 EQ5C_PER_PERIPH,
466 EQ5C_PER_CAN,
467 EQ5C_PER_TIMER,
468 EQ5C_PER_CCF,
469 EQ5C_PER_OCC_MJPEG,
470 EQ5C_PER_HSM,
471 EQ5C_PER_MJPEG,
472 EQ5C_PER_FCMU_A,
473};
474
475static const struct eqc_fixed_factor eqc_eyeq5_early_fixed_factors[] = {
476 /* EQ5C_PLL_CPU children */
477 { EQ5C_CPU_OCC, "occ-cpu", 1, 1, EQ5C_PLL_CPU },
478 { EQ5C_CPU_SI_CSS0, "si-css0", 1, 1, EQ5C_CPU_OCC },
479 { EQ5C_CPU_CORE0, "core0", 1, 1, EQ5C_CPU_SI_CSS0 },
480 { EQ5C_CPU_CORE1, "core1", 1, 1, EQ5C_CPU_SI_CSS0 },
481 { EQ5C_CPU_CORE2, "core2", 1, 1, EQ5C_CPU_SI_CSS0 },
482 { EQ5C_CPU_CORE3, "core3", 1, 1, EQ5C_CPU_SI_CSS0 },
483
484 /* EQ5C_PLL_PER children */
485 { EQ5C_PER_OCC, "occ-periph", 1, 16, EQ5C_PLL_PER },
486 { EQ5C_PER_UART, "uart", 1, 1, EQ5C_PER_OCC },
487};
488
489static const struct eqc_fixed_factor eqc_eyeq5_fixed_factors[] = {
490 /* EQ5C_PLL_CPU children */
491 { EQ5C_CPU_CPC, "cpc", 1, 1, EQ5C_CPU_SI_CSS0 },
492 { EQ5C_CPU_CM, "cm", 1, 1, EQ5C_CPU_SI_CSS0 },
493 { EQ5C_CPU_MEM, "mem", 1, 1, EQ5C_CPU_SI_CSS0 },
494 { EQ5C_CPU_OCC_ISRAM, "occ-isram", 1, 2, EQ5C_PLL_CPU },
495 { EQ5C_CPU_ISRAM, "isram", 1, 1, EQ5C_CPU_OCC_ISRAM },
496 { EQ5C_CPU_OCC_DBU, "occ-dbu", 1, 10, EQ5C_PLL_CPU },
497 { EQ5C_CPU_SI_DBU_TP, "si-dbu-tp", 1, 1, EQ5C_CPU_OCC_DBU },
498
499 /* EQ5C_PLL_VDI children */
500 { EQ5C_VDI_OCC_VDI, "occ-vdi", 1, 2, EQ5C_PLL_VDI },
501 { EQ5C_VDI_VDI, "vdi", 1, 1, EQ5C_VDI_OCC_VDI },
502 { EQ5C_VDI_OCC_CAN_SER, "occ-can-ser", 1, 16, EQ5C_PLL_VDI },
503 { EQ5C_VDI_CAN_SER, "can-ser", 1, 1, EQ5C_VDI_OCC_CAN_SER },
504 { EQ5C_VDI_I2C_SER, "i2c-ser", 1, 20, EQ5C_PLL_VDI },
505
506 /* EQ5C_PLL_PER children */
507 { EQ5C_PER_PERIPH, "periph", 1, 1, EQ5C_PER_OCC },
508 { EQ5C_PER_CAN, "can", 1, 1, EQ5C_PER_OCC },
509 { EQ5C_PER_SPI, "spi", 1, 1, EQ5C_PER_OCC },
510 { EQ5C_PER_I2C, "i2c", 1, 1, EQ5C_PER_OCC },
511 { EQ5C_PER_TIMER, "timer", 1, 1, EQ5C_PER_OCC },
512 { EQ5C_PER_GPIO, "gpio", 1, 1, EQ5C_PER_OCC },
513 { EQ5C_PER_EMMC, "emmc-sys", 1, 10, EQ5C_PLL_PER },
514 { EQ5C_PER_CCF, "ccf-ctrl", 1, 4, EQ5C_PLL_PER },
515 { EQ5C_PER_OCC_MJPEG, "occ-mjpeg", 1, 2, EQ5C_PLL_PER },
516 { EQ5C_PER_HSM, "hsm", 1, 1, EQ5C_PER_OCC_MJPEG },
517 { EQ5C_PER_MJPEG, "mjpeg", 1, 1, EQ5C_PER_OCC_MJPEG },
518 { EQ5C_PER_FCMU_A, "fcmu-a", 1, 20, EQ5C_PLL_PER },
519 { EQ5C_PER_OCC_PCI, "occ-pci-sys", 1, 8, EQ5C_PLL_PER },
520};
521
522static const struct eqc_div eqc_eyeq5_divs[] = {
523 {
524 .index = EQ5C_DIV_OSPI,
525 .name = "div-ospi",
526 .parent = EQ5C_PLL_PER,
527 .reg = 0x11C,
528 .shift = 0,
529 .width = 4,
530 },
531};
532
533static const struct eqc_early_match_data eqc_eyeq5_early_match_data __initconst = {
534 .early_pll_count = ARRAY_SIZE(eqc_eyeq5_early_plls),
535 .early_plls = eqc_eyeq5_early_plls,
536
537 .early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq5_early_fixed_factors),
538 .early_fixed_factors = eqc_eyeq5_early_fixed_factors,
539
540 .late_clk_count = ARRAY_SIZE(eqc_eyeq5_plls) + ARRAY_SIZE(eqc_eyeq5_divs) +
541 ARRAY_SIZE(eqc_eyeq5_fixed_factors),
542};
543
544static const struct eqc_match_data eqc_eyeq5_match_data = {
545 .pll_count = ARRAY_SIZE(eqc_eyeq5_plls),
546 .plls = eqc_eyeq5_plls,
547
548 .div_count = ARRAY_SIZE(eqc_eyeq5_divs),
549 .divs = eqc_eyeq5_divs,
550
551 .fixed_factor_count = ARRAY_SIZE(eqc_eyeq5_fixed_factors),
552 .fixed_factors = eqc_eyeq5_fixed_factors,
553
554 .reset_auxdev_name = "reset",
555 .pinctrl_auxdev_name = "pinctrl",
556
557 .early_clk_count = ARRAY_SIZE(eqc_eyeq5_early_plls) +
558 ARRAY_SIZE(eqc_eyeq5_early_fixed_factors),
559};
560
561static const struct eqc_pll eqc_eyeq6l_plls[] = {
562 { .index = EQ6LC_PLL_DDR, .name = "pll-ddr", .reg64 = 0x02C },
563 { .index = EQ6LC_PLL_CPU, .name = "pll-cpu", .reg64 = 0x034 }, /* also acc */
564 { .index = EQ6LC_PLL_PER, .name = "pll-per", .reg64 = 0x03C },
565 { .index = EQ6LC_PLL_VDI, .name = "pll-vdi", .reg64 = 0x044 },
566};
567
568static const struct eqc_match_data eqc_eyeq6l_match_data = {
569 .pll_count = ARRAY_SIZE(eqc_eyeq6l_plls),
570 .plls = eqc_eyeq6l_plls,
571
572 .reset_auxdev_name = "reset",
573};
574
575static const struct eqc_pll eqc_eyeq6lplus_early_plls[] = {
576 { .index = EQ6LPC_PLL_CPU, .name = "pll-cpu", .reg64 = 0x058 },
577};
578
579static const struct eqc_pll eqc_eyeq6lplus_plls[] = {
580 { .index = EQ6LPC_PLL_DDR, .name = "pll-ddr", .reg64 = 0x02C },
581 { .index = EQ6LPC_PLL_ACC, .name = "pll-acc", .reg64 = 0x034 },
582 { .index = EQ6LPC_PLL_PER, .name = "pll-per", .reg64 = 0x03C },
583 { .index = EQ6LPC_PLL_VDI, .name = "pll-vdi", .reg64 = 0x044 },
584};
585
586static const struct eqc_fixed_factor eqc_eyeq6lplus_early_fixed_factors[] = {
587 { EQ6LPC_CPU_OCC, "occ-cpu", 1, 1, EQ6LPC_PLL_CPU },
588};
589
590static const struct eqc_fixed_factor eqc_eyeq6lplus_fixed_factors[] = {
591 { EQ6LPC_DDR_OCC, "occ-ddr", 1, 1, EQ6LPC_PLL_DDR },
592
593 { EQ6LPC_ACC_VDI, "vdi-div", 1, 10, EQ6LPC_PLL_ACC },
594 { EQ6LPC_ACC_OCC, "occ-acc", 1, 1, EQ6LPC_PLL_ACC },
595 { EQ6LPC_ACC_FCMU, "fcmu-a-clk", 1, 10, EQ6LPC_ACC_OCC },
596
597 { EQ6LPC_PER_OCC, "occ-per", 1, 1, EQ6LPC_PLL_PER },
598 { EQ6LPC_PER_I2C_SER, "i2c-ser-clk", 1, 10, EQ6LPC_PER_OCC },
599 { EQ6LPC_PER_PCLK, "pclk", 1, 4, EQ6LPC_PER_OCC },
600 { EQ6LPC_PER_TSU, "tsu-clk", 1, 8, EQ6LPC_PER_OCC },
601 { EQ6LPC_PER_OSPI, "ospi-ref-clk", 1, 10, EQ6LPC_PER_OCC },
602 { EQ6LPC_PER_GPIO, "gpio-clk", 1, 4, EQ6LPC_PER_OCC },
603 { EQ6LPC_PER_TIMER, "timer-clk", 1, 4, EQ6LPC_PER_OCC },
604 { EQ6LPC_PER_I2C, "i2c-clk", 1, 4, EQ6LPC_PER_OCC },
605 { EQ6LPC_PER_UART, "uart-clk", 1, 4, EQ6LPC_PER_OCC },
606 { EQ6LPC_PER_SPI, "spi-clk", 1, 4, EQ6LPC_PER_OCC },
607 { EQ6LPC_PER_PERIPH, "periph-clk", 1, 1, EQ6LPC_PER_OCC },
608
609 { EQ6LPC_VDI_OCC, "occ-vdi", 1, 1, EQ6LPC_PLL_VDI },
610};
611
612static const struct eqc_early_match_data eqc_eyeq6lplus_early_match_data __initconst = {
613 .early_pll_count = ARRAY_SIZE(eqc_eyeq6lplus_early_plls),
614 .early_plls = eqc_eyeq6lplus_early_plls,
615
616 .early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq6lplus_early_fixed_factors),
617 .early_fixed_factors = eqc_eyeq6lplus_early_fixed_factors,
618
619 .late_clk_count = ARRAY_SIZE(eqc_eyeq6lplus_plls) +
620 ARRAY_SIZE(eqc_eyeq6lplus_fixed_factors),
621};
622
623static const struct eqc_match_data eqc_eyeq6lplus_match_data = {
624 .pll_count = ARRAY_SIZE(eqc_eyeq6lplus_plls),
625 .plls = eqc_eyeq6lplus_plls,
626
627 .fixed_factor_count = ARRAY_SIZE(eqc_eyeq6lplus_fixed_factors),
628 .fixed_factors = eqc_eyeq6lplus_fixed_factors,
629
630 .reset_auxdev_name = "reset",
631 .pinctrl_auxdev_name = "pinctrl",
632
633 .early_clk_count = ARRAY_SIZE(eqc_eyeq6lplus_early_plls) +
634 ARRAY_SIZE(eqc_eyeq6lplus_early_fixed_factors),
635};
636
637static const struct eqc_match_data eqc_eyeq6h_west_match_data = {
638 .reset_auxdev_name = "reset_west",
639};
640
641static const struct eqc_pll eqc_eyeq6h_east_plls[] = {
642 { .index = 0, .name = "pll-east", .reg64 = 0x074 },
643};
644
645static const struct eqc_match_data eqc_eyeq6h_east_match_data = {
646 .pll_count = ARRAY_SIZE(eqc_eyeq6h_east_plls),
647 .plls = eqc_eyeq6h_east_plls,
648
649 .reset_auxdev_name = "reset_east",
650};
651
652static const struct eqc_pll eqc_eyeq6h_south_plls[] = {
653 { .index = EQ6HC_SOUTH_PLL_VDI, .name = "pll-vdi", .reg64 = 0x000 },
654 { .index = EQ6HC_SOUTH_PLL_PCIE, .name = "pll-pcie", .reg64 = 0x008 },
655 { .index = EQ6HC_SOUTH_PLL_PER, .name = "pll-per", .reg64 = 0x010 },
656 { .index = EQ6HC_SOUTH_PLL_ISP, .name = "pll-isp", .reg64 = 0x018 },
657};
658
659static const struct eqc_div eqc_eyeq6h_south_divs[] = {
660 {
661 .index = EQ6HC_SOUTH_DIV_EMMC,
662 .name = "div-emmc",
663 .parent = EQ6HC_SOUTH_PLL_PER,
664 .reg = 0x070,
665 .shift = 4,
666 .width = 4,
667 },
668 {
669 .index = EQ6HC_SOUTH_DIV_OSPI_REF,
670 .name = "div-ospi-ref",
671 .parent = EQ6HC_SOUTH_PLL_PER,
672 .reg = 0x090,
673 .shift = 4,
674 .width = 4,
675 },
676 {
677 .index = EQ6HC_SOUTH_DIV_OSPI_SYS,
678 .name = "div-ospi-sys",
679 .parent = EQ6HC_SOUTH_PLL_PER,
680 .reg = 0x090,
681 .shift = 8,
682 .width = 1,
683 },
684 {
685 .index = EQ6HC_SOUTH_DIV_TSU,
686 .name = "div-tsu",
687 .parent = EQ6HC_SOUTH_PLL_PCIE,
688 .reg = 0x098,
689 .shift = 4,
690 .width = 8,
691 },
692};
693
694static const struct eqc_match_data eqc_eyeq6h_south_match_data = {
695 .pll_count = ARRAY_SIZE(eqc_eyeq6h_south_plls),
696 .plls = eqc_eyeq6h_south_plls,
697
698 .div_count = ARRAY_SIZE(eqc_eyeq6h_south_divs),
699 .divs = eqc_eyeq6h_south_divs,
700};
701
702static const struct eqc_pll eqc_eyeq6h_ddr0_plls[] = {
703 { .index = 0, .name = "pll-ddr0", .reg64 = 0x074 },
704};
705
706static const struct eqc_match_data eqc_eyeq6h_ddr0_match_data = {
707 .pll_count = ARRAY_SIZE(eqc_eyeq6h_ddr0_plls),
708 .plls = eqc_eyeq6h_ddr0_plls,
709};
710
711static const struct eqc_pll eqc_eyeq6h_ddr1_plls[] = {
712 { .index = 0, .name = "pll-ddr1", .reg64 = 0x074 },
713};
714
715static const struct eqc_match_data eqc_eyeq6h_ddr1_match_data = {
716 .pll_count = ARRAY_SIZE(eqc_eyeq6h_ddr1_plls),
717 .plls = eqc_eyeq6h_ddr1_plls,
718};
719
720static const struct eqc_pll eqc_eyeq6h_acc_plls[] = {
721 { .index = EQ6HC_ACC_PLL_XNN, .name = "pll-xnn", .reg64 = 0x040 },
722 { .index = EQ6HC_ACC_PLL_VMP, .name = "pll-vmp", .reg64 = 0x050 },
723 { .index = EQ6HC_ACC_PLL_PMA, .name = "pll-pma", .reg64 = 0x05C },
724 { .index = EQ6HC_ACC_PLL_MPC, .name = "pll-mpc", .reg64 = 0x068 },
725 { .index = EQ6HC_ACC_PLL_NOC, .name = "pll-noc", .reg64 = 0x070 },
726};
727
728static const struct eqc_match_data eqc_eyeq6h_acc_match_data = {
729 .pll_count = ARRAY_SIZE(eqc_eyeq6h_acc_plls),
730 .plls = eqc_eyeq6h_acc_plls,
731
732 .reset_auxdev_name = "reset_acc",
733};
734
735static const struct of_device_id eqc_match_table[] = {
736 { .compatible = "mobileye,eyeq5-olb", .data = &eqc_eyeq5_match_data },
737 { .compatible = "mobileye,eyeq6l-olb", .data = &eqc_eyeq6l_match_data },
738 { .compatible = "mobileye,eyeq6lplus-olb", .data = &eqc_eyeq6lplus_match_data },
739 { .compatible = "mobileye,eyeq6h-west-olb", .data = &eqc_eyeq6h_west_match_data },
740 { .compatible = "mobileye,eyeq6h-east-olb", .data = &eqc_eyeq6h_east_match_data },
741 { .compatible = "mobileye,eyeq6h-south-olb", .data = &eqc_eyeq6h_south_match_data },
742 { .compatible = "mobileye,eyeq6h-ddr0-olb", .data = &eqc_eyeq6h_ddr0_match_data },
743 { .compatible = "mobileye,eyeq6h-ddr1-olb", .data = &eqc_eyeq6h_ddr1_match_data },
744 { .compatible = "mobileye,eyeq6h-acc-olb", .data = &eqc_eyeq6h_acc_match_data },
745 {}
746};
747
748static struct platform_driver eqc_driver = {
749 .probe = eqc_probe,
750 .driver = {
751 .name = "clk-eyeq",
752 .of_match_table = eqc_match_table,
753 .suppress_bind_attrs = true,
754 },
755};
756builtin_platform_driver(eqc_driver);
757
758/* Required early for GIC timer. */
759static const struct eqc_pll eqc_eyeq6h_central_early_plls[] = {
760 { .index = EQ6HC_CENTRAL_PLL_CPU, .name = "pll-cpu", .reg64 = 0x02C },
761};
762
763static const struct eqc_fixed_factor eqc_eyeq6h_central_early_fixed_factors[] = {
764 { EQ6HC_CENTRAL_CPU_OCC, "occ-cpu", 1, 1, EQ6HC_CENTRAL_PLL_CPU },
765};
766
767static const struct eqc_early_match_data eqc_eyeq6h_central_early_match_data __initconst = {
768 .early_pll_count = ARRAY_SIZE(eqc_eyeq6h_central_early_plls),
769 .early_plls = eqc_eyeq6h_central_early_plls,
770
771 .early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq6h_central_early_fixed_factors),
772 .early_fixed_factors = eqc_eyeq6h_central_early_fixed_factors,
773};
774
775/* Required early for UART. */
776static const struct eqc_pll eqc_eyeq6h_west_early_plls[] = {
777 { .index = EQ6HC_WEST_PLL_PER, .name = "pll-west", .reg64 = 0x074 },
778};
779
780static const struct eqc_fixed_factor eqc_eyeq6h_west_early_fixed_factors[] = {
781 { EQ6HC_WEST_PER_OCC, "west-per-occ", 1, 10, EQ6HC_WEST_PLL_PER },
782 { EQ6HC_WEST_PER_UART, "west-per-uart", 1, 1, EQ6HC_WEST_PER_OCC },
783};
784
785static const struct eqc_early_match_data eqc_eyeq6h_west_early_match_data __initconst = {
786 .early_pll_count = ARRAY_SIZE(eqc_eyeq6h_west_early_plls),
787 .early_plls = eqc_eyeq6h_west_early_plls,
788
789 .early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq6h_west_early_fixed_factors),
790 .early_fixed_factors = eqc_eyeq6h_west_early_fixed_factors,
791};
792
793static void __init eqc_early_init(struct device_node *np,
794 const struct eqc_early_match_data *early_data)
795{
796 struct clk_hw_onecell_data *cells;
797 unsigned int i, clk_count;
798 void __iomem *base;
799 int ret;
800
801 clk_count = early_data->early_pll_count + early_data->early_fixed_factor_count +
802 early_data->late_clk_count;
803 cells = kzalloc_flex(*cells, hws, clk_count);
804 if (!cells) {
805 ret = -ENOMEM;
806 goto err;
807 }
808
809 cells->num = clk_count;
810
811 /*
812 * Mark all clocks as deferred; some are registered here, the rest at
813 * platform device probe.
814 *
815 * Once the platform device is probed, its provider will take priority
816 * when looking up clocks.
817 */
818 for (i = 0; i < clk_count; i++)
819 cells->hws[i] = ERR_PTR(-EPROBE_DEFER);
820
821 /* Offsets (reg64) of early PLLs are relative to OLB block. */
822 base = of_iomap(np, 0);
823 if (!base) {
824 ret = -ENODEV;
825 goto err;
826 }
827
828 for (i = 0; i < early_data->early_pll_count; i++) {
829 const struct eqc_pll *pll = &early_data->early_plls[i];
830 unsigned long mult, div, acc;
831 struct clk_hw *hw;
832 u32 r0, r1;
833 u64 val;
834
835 val = readq(base + pll->reg64);
836 r0 = val;
837 r1 = val >> 32;
838
839 ret = eqc_pll_parse_registers(r0, r1, &mult, &div, &acc);
840 if (ret) {
841 pr_err("failed parsing state of %s\n", pll->name);
842 goto err;
843 }
844
845 hw = clk_hw_register_fixed_factor_with_accuracy_fwname(NULL,
846 np, pll->name, "ref", 0, mult, div, acc);
847 cells->hws[pll->index] = hw;
848 if (IS_ERR(hw)) {
849 pr_err("failed registering %s: %pe\n", pll->name, hw);
850 ret = PTR_ERR(hw);
851 goto err;
852 }
853 }
854
855 for (i = 0; i < early_data->early_fixed_factor_count; i++) {
856 const struct eqc_fixed_factor *ff = &early_data->early_fixed_factors[i];
857 struct clk_hw *parent_hw = cells->hws[ff->parent];
858 struct clk_hw *hw;
859
860 hw = clk_hw_register_fixed_factor_parent_hw(NULL, ff->name,
861 parent_hw, 0, ff->mult, ff->div);
862 cells->hws[ff->index] = hw;
863 if (IS_ERR(hw)) {
864 pr_err("failed registering %s: %pe\n", ff->name, hw);
865 ret = PTR_ERR(hw);
866 goto err;
867 }
868 }
869
870 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, cells);
871 if (ret) {
872 pr_err("failed registering clk provider: %d\n", ret);
873 goto err;
874 }
875
876 return;
877
878err:
879 /*
880 * We are doomed. The system will not be able to boot.
881 *
882 * Let's still try to be good citizens by freeing resources and print
883 * a last error message that might help debugging.
884 */
885
886 pr_err("failed clk init: %d\n", ret);
887
888 if (cells) {
889 of_clk_del_provider(np);
890
891 for (i = 0; i < early_data->early_pll_count; i++) {
892 const struct eqc_pll *pll = &early_data->early_plls[i];
893 struct clk_hw *hw = cells->hws[pll->index];
894
895 if (!IS_ERR_OR_NULL(hw))
896 clk_hw_unregister_fixed_factor(hw);
897 }
898
899 kfree(cells);
900 }
901}
902
903static void __init eqc_eyeq5_early_init(struct device_node *np)
904{
905 eqc_early_init(np, &eqc_eyeq5_early_match_data);
906}
907CLK_OF_DECLARE_DRIVER(eqc_eyeq5, "mobileye,eyeq5-olb", eqc_eyeq5_early_init);
908
909static void __init eqc_eyeq6h_central_early_init(struct device_node *np)
910{
911 eqc_early_init(np, &eqc_eyeq6h_central_early_match_data);
912}
913CLK_OF_DECLARE_DRIVER(eqc_eyeq6h_central, "mobileye,eyeq6h-central-olb",
914 eqc_eyeq6h_central_early_init);
915
916static void __init eqc_eyeq6h_west_early_init(struct device_node *np)
917{
918 eqc_early_init(np, &eqc_eyeq6h_west_early_match_data);
919}
920CLK_OF_DECLARE_DRIVER(eqc_eyeq6h_west, "mobileye,eyeq6h-west-olb",
921 eqc_eyeq6h_west_early_init);
922
923static void __init eqc_eyeq6lplus_early_init(struct device_node *np)
924{
925 eqc_early_init(np, &eqc_eyeq6lplus_early_match_data);
926}
927CLK_OF_DECLARE_DRIVER(eqc_eyeq6lplus, "mobileye,eyeq6lplus-olb", eqc_eyeq6lplus_early_init);