1 // SPDX-License-Identifier: GPL-2.0-only
3 * PLL clock driver for the Mobileye EyeQ5, EyeQ6L and EyeQ6H platforms.
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.
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.
14 * We use eqc_ as prefix, as-in "EyeQ Clock", but way shorter.
16 * Copyright (C) 2024 Mobileye Vision Technologies Ltd.
20 * Set pr_fmt() for printing from eqc_early_init().
21 * It is called at of_clk_init() stage (read: really early).
23 #define pr_fmt(fmt) "clk-eyeq: " fmt
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>
36 #include <linux/mod_devicetable.h>
37 #include <linux/module.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>
47 #include <dt-bindings/clock/mobileye,eyeq5-clk.h>
49 /* In frac mode, it enables fractional noise canceling DAC. Else, no function. */
50 #define PCSR0_DAC_EN BIT(0)
51 /* Fractional or integer mode */
52 #define PCSR0_DSM_EN BIT(1)
53 #define PCSR0_PLL_EN BIT(2)
54 /* All clocks output held at 0 */
55 #define PCSR0_FOUTPOSTDIV_EN BIT(3)
56 #define PCSR0_POST_DIV1 GENMASK(6, 4)
57 #define PCSR0_POST_DIV2 GENMASK(9, 7)
58 #define PCSR0_REF_DIV GENMASK(15, 10)
59 #define PCSR0_INTIN GENMASK(27, 16)
60 #define PCSR0_BYPASS BIT(28)
61 /* Bits 30..29 are reserved */
62 #define PCSR0_PLL_LOCKED BIT(31)
64 #define PCSR1_RESET BIT(0)
65 #define PCSR1_SSGC_DIV GENMASK(4, 1)
66 /* Spread amplitude (% = 0.1 * SPREAD[4:0]) */
67 #define PCSR1_SPREAD GENMASK(9, 5)
68 #define PCSR1_DIS_SSCG BIT(10)
69 /* Down-spread or center-spread */
70 #define PCSR1_DOWN_SPREAD BIT(11)
71 #define PCSR1_FRAC_IN GENMASK(31, 12)
80 * Divider clock. Divider is 2*(v+1), with v the register value.
81 * Min divider is 2, max is 2*(2^width).
92 struct eqc_fixed_factor
{
100 struct eqc_match_data
{
101 unsigned int pll_count
;
102 const struct eqc_pll
*plls
;
104 unsigned int div_count
;
105 const struct eqc_div
*divs
;
107 unsigned int fixed_factor_count
;
108 const struct eqc_fixed_factor
*fixed_factors
;
110 const char *reset_auxdev_name
;
111 const char *pinctrl_auxdev_name
;
113 unsigned int early_clk_count
;
116 struct eqc_early_match_data
{
117 unsigned int early_pll_count
;
118 const struct eqc_pll
*early_plls
;
120 unsigned int early_fixed_factor_count
;
121 const struct eqc_fixed_factor
*early_fixed_factors
;
124 * We want our of_xlate callback to EPROBE_DEFER instead of dev_err()
125 * and EINVAL. For that, we must know the total clock count.
127 unsigned int late_clk_count
;
131 * Both factors (mult and div) must fit in 32 bits. When an operation overflows,
132 * this function throws away low bits so that factors still fit in 32 bits.
134 * Precision loss depends on amplitude of mult and div. Worst theorical
135 * loss is: (UINT_MAX+1) / UINT_MAX - 1 = 2.3e-10.
136 * This is 1Hz every 4.3GHz.
138 static void eqc_pll_downshift_factors(unsigned long *mult
, unsigned long *div
)
140 unsigned long biggest
;
143 /* This function can be removed if mult/div switch to unsigned long. */
144 static_assert(sizeof_field(struct clk_fixed_factor
, mult
) == sizeof(unsigned int));
145 static_assert(sizeof_field(struct clk_fixed_factor
, div
) == sizeof(unsigned int));
147 /* No overflow, nothing to be done. */
148 if (*mult
<= UINT_MAX
&& *div
<= UINT_MAX
)
152 * Compute the shift required to bring the biggest factor into unsigned
153 * int range. That is, shift its highest set bit to the unsigned int
154 * most significant bit.
156 biggest
= max(*mult
, *div
);
157 shift
= __fls(biggest
) - (BITS_PER_BYTE
* sizeof(unsigned int)) + 1;
163 static int eqc_pll_parse_registers(u32 r0
, u32 r1
, unsigned long *mult
,
164 unsigned long *div
, unsigned long *acc
)
168 if (r0
& PCSR0_BYPASS
) {
175 if (!(r0
& PCSR0_PLL_LOCKED
))
178 *mult
= FIELD_GET(PCSR0_INTIN
, r0
);
179 *div
= FIELD_GET(PCSR0_REF_DIV
, r0
);
180 if (r0
& PCSR0_FOUTPOSTDIV_EN
)
181 *div
*= FIELD_GET(PCSR0_POST_DIV1
, r0
) * FIELD_GET(PCSR0_POST_DIV2
, r0
);
183 /* Fractional mode, in 2^20 (0x100000) parts. */
184 if (r0
& PCSR0_DSM_EN
) {
185 *div
*= (1ULL << 20);
186 *mult
= *mult
* (1ULL << 20) + FIELD_GET(PCSR1_FRAC_IN
, r1
);
192 if (r1
& (PCSR1_RESET
| PCSR1_DIS_SSCG
)) {
200 * Spread is 1/1000 parts of frequency, accuracy is half of
201 * that. To get accuracy, convert to ppb (parts per billion).
203 * acc = spread * 1e6 / 2
204 * with acc in parts per billion and,
205 * spread in parts per thousand.
207 spread
= FIELD_GET(PCSR1_SPREAD
, r1
);
208 *acc
= spread
* 500000;
210 if (r1
& PCSR1_DOWN_SPREAD
) {
212 * Downspreading: the central frequency is half a
215 *mult
*= 2000 - spread
;
219 * Previous operation might overflow 32 bits. If it
220 * does, throw away the least amount of low bits.
222 eqc_pll_downshift_factors(mult
, div
);
228 static void eqc_probe_init_plls(struct device
*dev
, const struct eqc_match_data
*data
,
229 void __iomem
*base
, struct clk_hw_onecell_data
*cells
)
231 unsigned long mult
, div
, acc
;
232 const struct eqc_pll
*pll
;
239 for (i
= 0; i
< data
->pll_count
; i
++) {
240 pll
= &data
->plls
[i
];
242 val
= readq(base
+ pll
->reg64
);
246 ret
= eqc_pll_parse_registers(r0
, r1
, &mult
, &div
, &acc
);
248 dev_warn(dev
, "failed parsing state of %s\n", pll
->name
);
249 cells
->hws
[pll
->index
] = ERR_PTR(ret
);
253 hw
= clk_hw_register_fixed_factor_with_accuracy_fwname(dev
,
254 dev
->of_node
, pll
->name
, "ref", 0, mult
, div
, acc
);
255 cells
->hws
[pll
->index
] = hw
;
257 dev_warn(dev
, "failed registering %s: %pe\n", pll
->name
, hw
);
261 static void eqc_probe_init_divs(struct device
*dev
, const struct eqc_match_data
*data
,
262 void __iomem
*base
, struct clk_hw_onecell_data
*cells
)
264 struct clk_parent_data parent_data
= { };
265 const struct eqc_div
*div
;
266 struct clk_hw
*parent
;
271 for (i
= 0; i
< data
->div_count
; i
++) {
272 div
= &data
->divs
[i
];
273 reg
= base
+ div
->reg
;
274 parent
= cells
->hws
[div
->parent
];
276 if (IS_ERR(parent
)) {
277 /* Parent is in early clk provider. */
278 parent_data
.index
= div
->parent
;
279 parent_data
.hw
= NULL
;
281 /* Avoid clock lookup when we already have the hw reference. */
282 parent_data
.index
= 0;
283 parent_data
.hw
= parent
;
286 hw
= clk_hw_register_divider_table_parent_data(dev
, div
->name
,
287 &parent_data
, 0, reg
, div
->shift
, div
->width
,
288 CLK_DIVIDER_EVEN_INTEGERS
, NULL
, NULL
);
289 cells
->hws
[div
->index
] = hw
;
291 dev_warn(dev
, "failed registering %s: %pe\n",
296 static void eqc_probe_init_fixed_factors(struct device
*dev
,
297 const struct eqc_match_data
*data
,
298 struct clk_hw_onecell_data
*cells
)
300 const struct eqc_fixed_factor
*ff
;
301 struct clk_hw
*hw
, *parent_hw
;
304 for (i
= 0; i
< data
->fixed_factor_count
; i
++) {
305 ff
= &data
->fixed_factors
[i
];
306 parent_hw
= cells
->hws
[ff
->parent
];
308 if (IS_ERR(parent_hw
)) {
309 /* Parent is in early clk provider. */
310 hw
= clk_hw_register_fixed_factor_index(dev
, ff
->name
,
311 ff
->parent
, 0, ff
->mult
, ff
->div
);
313 /* Avoid clock lookup when we already have the hw reference. */
314 hw
= clk_hw_register_fixed_factor_parent_hw(dev
, ff
->name
,
315 parent_hw
, 0, ff
->mult
, ff
->div
);
318 cells
->hws
[ff
->index
] = hw
;
320 dev_warn(dev
, "failed registering %s: %pe\n",
325 static void eqc_auxdev_release(struct device
*dev
)
327 struct auxiliary_device
*adev
= to_auxiliary_dev(dev
);
332 static int eqc_auxdev_create(struct device
*dev
, void __iomem
*base
,
333 const char *name
, u32 id
)
335 struct auxiliary_device
*adev
;
338 adev
= kzalloc(sizeof(*adev
), GFP_KERNEL
);
343 adev
->dev
.parent
= dev
;
344 adev
->dev
.platform_data
= (void __force
*)base
;
345 adev
->dev
.release
= eqc_auxdev_release
;
348 ret
= auxiliary_device_init(adev
);
352 ret
= auxiliary_device_add(adev
);
354 auxiliary_device_uninit(adev
);
359 static int eqc_probe(struct platform_device
*pdev
)
361 struct device
*dev
= &pdev
->dev
;
362 struct device_node
*np
= dev
->of_node
;
363 const struct eqc_match_data
*data
;
364 struct clk_hw_onecell_data
*cells
;
365 unsigned int i
, clk_count
;
366 struct resource
*res
;
370 data
= device_get_match_data(dev
);
372 return 0; /* No clocks nor auxdevs, we are done. */
374 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
378 base
= ioremap(res
->start
, resource_size(res
));
382 /* Init optional reset auxiliary device. */
383 if (data
->reset_auxdev_name
) {
384 ret
= eqc_auxdev_create(dev
, base
, data
->reset_auxdev_name
, 0);
386 dev_warn(dev
, "failed creating auxiliary device %s.%s: %d\n",
387 KBUILD_MODNAME
, data
->reset_auxdev_name
, ret
);
390 /* Init optional pinctrl auxiliary device. */
391 if (data
->pinctrl_auxdev_name
) {
392 ret
= eqc_auxdev_create(dev
, base
, data
->pinctrl_auxdev_name
, 0);
394 dev_warn(dev
, "failed creating auxiliary device %s.%s: %d\n",
395 KBUILD_MODNAME
, data
->pinctrl_auxdev_name
, ret
);
398 if (data
->pll_count
+ data
->div_count
+ data
->fixed_factor_count
== 0)
399 return 0; /* Zero clocks, we are done. */
401 clk_count
= data
->pll_count
+ data
->div_count
+
402 data
->fixed_factor_count
+ data
->early_clk_count
;
403 cells
= kzalloc(struct_size(cells
, hws
, clk_count
), GFP_KERNEL
);
407 cells
->num
= clk_count
;
409 /* Early PLLs are marked as errors: the early provider will get queried. */
410 for (i
= 0; i
< clk_count
; i
++)
411 cells
->hws
[i
] = ERR_PTR(-EINVAL
);
413 eqc_probe_init_plls(dev
, data
, base
, cells
);
415 eqc_probe_init_divs(dev
, data
, base
, cells
);
417 eqc_probe_init_fixed_factors(dev
, data
, cells
);
419 return of_clk_add_hw_provider(np
, of_clk_hw_onecell_get
, cells
);
422 /* Required early for GIC timer (pll-cpu) and UARTs (pll-per). */
423 static const struct eqc_pll eqc_eyeq5_early_plls
[] = {
424 { .index
= EQ5C_PLL_CPU
, .name
= "pll-cpu", .reg64
= 0x02C },
425 { .index
= EQ5C_PLL_PER
, .name
= "pll-per", .reg64
= 0x05C },
428 static const struct eqc_pll eqc_eyeq5_plls
[] = {
429 { .index
= EQ5C_PLL_VMP
, .name
= "pll-vmp", .reg64
= 0x034 },
430 { .index
= EQ5C_PLL_PMA
, .name
= "pll-pma", .reg64
= 0x03C },
431 { .index
= EQ5C_PLL_VDI
, .name
= "pll-vdi", .reg64
= 0x044 },
432 { .index
= EQ5C_PLL_DDR0
, .name
= "pll-ddr0", .reg64
= 0x04C },
433 { .index
= EQ5C_PLL_PCI
, .name
= "pll-pci", .reg64
= 0x054 },
434 { .index
= EQ5C_PLL_PMAC
, .name
= "pll-pmac", .reg64
= 0x064 },
435 { .index
= EQ5C_PLL_MPC
, .name
= "pll-mpc", .reg64
= 0x06C },
436 { .index
= EQ5C_PLL_DDR1
, .name
= "pll-ddr1", .reg64
= 0x074 },
441 * EQ5C_PLL_CPU children.
442 * EQ5C_PER_OCC_PCI is the last clock exposed in dt-bindings.
444 EQ5C_CPU_OCC
= EQ5C_PER_OCC_PCI
+ 1,
455 * EQ5C_PLL_VDI children.
459 EQ5C_VDI_OCC_CAN_SER
,
464 * EQ5C_PLL_PER children.
476 static const struct eqc_fixed_factor eqc_eyeq5_early_fixed_factors
[] = {
477 /* EQ5C_PLL_CPU children */
478 { EQ5C_CPU_OCC
, "occ-cpu", 1, 1, EQ5C_PLL_CPU
},
479 { EQ5C_CPU_SI_CSS0
, "si-css0", 1, 1, EQ5C_CPU_OCC
},
480 { EQ5C_CPU_CORE0
, "core0", 1, 1, EQ5C_CPU_SI_CSS0
},
481 { EQ5C_CPU_CORE1
, "core1", 1, 1, EQ5C_CPU_SI_CSS0
},
482 { EQ5C_CPU_CORE2
, "core2", 1, 1, EQ5C_CPU_SI_CSS0
},
483 { EQ5C_CPU_CORE3
, "core3", 1, 1, EQ5C_CPU_SI_CSS0
},
485 /* EQ5C_PLL_PER children */
486 { EQ5C_PER_OCC
, "occ-periph", 1, 16, EQ5C_PLL_PER
},
487 { EQ5C_PER_UART
, "uart", 1, 1, EQ5C_PER_OCC
},
490 static const struct eqc_fixed_factor eqc_eyeq5_fixed_factors
[] = {
491 /* EQ5C_PLL_CPU children */
492 { EQ5C_CPU_CPC
, "cpc", 1, 1, EQ5C_CPU_SI_CSS0
},
493 { EQ5C_CPU_CM
, "cm", 1, 1, EQ5C_CPU_SI_CSS0
},
494 { EQ5C_CPU_MEM
, "mem", 1, 1, EQ5C_CPU_SI_CSS0
},
495 { EQ5C_CPU_OCC_ISRAM
, "occ-isram", 1, 2, EQ5C_PLL_CPU
},
496 { EQ5C_CPU_ISRAM
, "isram", 1, 1, EQ5C_CPU_OCC_ISRAM
},
497 { EQ5C_CPU_OCC_DBU
, "occ-dbu", 1, 10, EQ5C_PLL_CPU
},
498 { EQ5C_CPU_SI_DBU_TP
, "si-dbu-tp", 1, 1, EQ5C_CPU_OCC_DBU
},
500 /* EQ5C_PLL_VDI children */
501 { EQ5C_VDI_OCC_VDI
, "occ-vdi", 1, 2, EQ5C_PLL_VDI
},
502 { EQ5C_VDI_VDI
, "vdi", 1, 1, EQ5C_VDI_OCC_VDI
},
503 { EQ5C_VDI_OCC_CAN_SER
, "occ-can-ser", 1, 16, EQ5C_PLL_VDI
},
504 { EQ5C_VDI_CAN_SER
, "can-ser", 1, 1, EQ5C_VDI_OCC_CAN_SER
},
505 { EQ5C_VDI_I2C_SER
, "i2c-ser", 1, 20, EQ5C_PLL_VDI
},
507 /* EQ5C_PLL_PER children */
508 { EQ5C_PER_PERIPH
, "periph", 1, 1, EQ5C_PER_OCC
},
509 { EQ5C_PER_CAN
, "can", 1, 1, EQ5C_PER_OCC
},
510 { EQ5C_PER_SPI
, "spi", 1, 1, EQ5C_PER_OCC
},
511 { EQ5C_PER_I2C
, "i2c", 1, 1, EQ5C_PER_OCC
},
512 { EQ5C_PER_TIMER
, "timer", 1, 1, EQ5C_PER_OCC
},
513 { EQ5C_PER_GPIO
, "gpio", 1, 1, EQ5C_PER_OCC
},
514 { EQ5C_PER_EMMC
, "emmc-sys", 1, 10, EQ5C_PLL_PER
},
515 { EQ5C_PER_CCF
, "ccf-ctrl", 1, 4, EQ5C_PLL_PER
},
516 { EQ5C_PER_OCC_MJPEG
, "occ-mjpeg", 1, 2, EQ5C_PLL_PER
},
517 { EQ5C_PER_HSM
, "hsm", 1, 1, EQ5C_PER_OCC_MJPEG
},
518 { EQ5C_PER_MJPEG
, "mjpeg", 1, 1, EQ5C_PER_OCC_MJPEG
},
519 { EQ5C_PER_FCMU_A
, "fcmu-a", 1, 20, EQ5C_PLL_PER
},
520 { EQ5C_PER_OCC_PCI
, "occ-pci-sys", 1, 8, EQ5C_PLL_PER
},
523 static const struct eqc_div eqc_eyeq5_divs
[] = {
525 .index
= EQ5C_DIV_OSPI
,
527 .parent
= EQ5C_PLL_PER
,
534 static const struct eqc_early_match_data eqc_eyeq5_early_match_data __initconst
= {
535 .early_pll_count
= ARRAY_SIZE(eqc_eyeq5_early_plls
),
536 .early_plls
= eqc_eyeq5_early_plls
,
538 .early_fixed_factor_count
= ARRAY_SIZE(eqc_eyeq5_early_fixed_factors
),
539 .early_fixed_factors
= eqc_eyeq5_early_fixed_factors
,
541 .late_clk_count
= ARRAY_SIZE(eqc_eyeq5_plls
) + ARRAY_SIZE(eqc_eyeq5_divs
) +
542 ARRAY_SIZE(eqc_eyeq5_fixed_factors
),
545 static const struct eqc_match_data eqc_eyeq5_match_data
= {
546 .pll_count
= ARRAY_SIZE(eqc_eyeq5_plls
),
547 .plls
= eqc_eyeq5_plls
,
549 .div_count
= ARRAY_SIZE(eqc_eyeq5_divs
),
550 .divs
= eqc_eyeq5_divs
,
552 .fixed_factor_count
= ARRAY_SIZE(eqc_eyeq5_fixed_factors
),
553 .fixed_factors
= eqc_eyeq5_fixed_factors
,
555 .reset_auxdev_name
= "reset",
556 .pinctrl_auxdev_name
= "pinctrl",
558 .early_clk_count
= ARRAY_SIZE(eqc_eyeq5_early_plls
) +
559 ARRAY_SIZE(eqc_eyeq5_early_fixed_factors
),
562 static const struct eqc_pll eqc_eyeq6l_plls
[] = {
563 { .index
= EQ6LC_PLL_DDR
, .name
= "pll-ddr", .reg64
= 0x02C },
564 { .index
= EQ6LC_PLL_CPU
, .name
= "pll-cpu", .reg64
= 0x034 }, /* also acc */
565 { .index
= EQ6LC_PLL_PER
, .name
= "pll-per", .reg64
= 0x03C },
566 { .index
= EQ6LC_PLL_VDI
, .name
= "pll-vdi", .reg64
= 0x044 },
569 static const struct eqc_match_data eqc_eyeq6l_match_data
= {
570 .pll_count
= ARRAY_SIZE(eqc_eyeq6l_plls
),
571 .plls
= eqc_eyeq6l_plls
,
573 .reset_auxdev_name
= "reset",
576 static const struct eqc_match_data eqc_eyeq6h_west_match_data
= {
577 .reset_auxdev_name
= "reset_west",
580 static const struct eqc_pll eqc_eyeq6h_east_plls
[] = {
581 { .index
= 0, .name
= "pll-east", .reg64
= 0x074 },
584 static const struct eqc_match_data eqc_eyeq6h_east_match_data
= {
585 .pll_count
= ARRAY_SIZE(eqc_eyeq6h_east_plls
),
586 .plls
= eqc_eyeq6h_east_plls
,
588 .reset_auxdev_name
= "reset_east",
591 static const struct eqc_pll eqc_eyeq6h_south_plls
[] = {
592 { .index
= EQ6HC_SOUTH_PLL_VDI
, .name
= "pll-vdi", .reg64
= 0x000 },
593 { .index
= EQ6HC_SOUTH_PLL_PCIE
, .name
= "pll-pcie", .reg64
= 0x008 },
594 { .index
= EQ6HC_SOUTH_PLL_PER
, .name
= "pll-per", .reg64
= 0x010 },
595 { .index
= EQ6HC_SOUTH_PLL_ISP
, .name
= "pll-isp", .reg64
= 0x018 },
598 static const struct eqc_div eqc_eyeq6h_south_divs
[] = {
600 .index
= EQ6HC_SOUTH_DIV_EMMC
,
602 .parent
= EQ6HC_SOUTH_PLL_PER
,
608 .index
= EQ6HC_SOUTH_DIV_OSPI_REF
,
609 .name
= "div-ospi-ref",
610 .parent
= EQ6HC_SOUTH_PLL_PER
,
616 .index
= EQ6HC_SOUTH_DIV_OSPI_SYS
,
617 .name
= "div-ospi-sys",
618 .parent
= EQ6HC_SOUTH_PLL_PER
,
624 .index
= EQ6HC_SOUTH_DIV_TSU
,
626 .parent
= EQ6HC_SOUTH_PLL_PCIE
,
633 static const struct eqc_match_data eqc_eyeq6h_south_match_data
= {
634 .pll_count
= ARRAY_SIZE(eqc_eyeq6h_south_plls
),
635 .plls
= eqc_eyeq6h_south_plls
,
637 .div_count
= ARRAY_SIZE(eqc_eyeq6h_south_divs
),
638 .divs
= eqc_eyeq6h_south_divs
,
641 static const struct eqc_pll eqc_eyeq6h_ddr0_plls
[] = {
642 { .index
= 0, .name
= "pll-ddr0", .reg64
= 0x074 },
645 static const struct eqc_match_data eqc_eyeq6h_ddr0_match_data
= {
646 .pll_count
= ARRAY_SIZE(eqc_eyeq6h_ddr0_plls
),
647 .plls
= eqc_eyeq6h_ddr0_plls
,
650 static const struct eqc_pll eqc_eyeq6h_ddr1_plls
[] = {
651 { .index
= 0, .name
= "pll-ddr1", .reg64
= 0x074 },
654 static const struct eqc_match_data eqc_eyeq6h_ddr1_match_data
= {
655 .pll_count
= ARRAY_SIZE(eqc_eyeq6h_ddr1_plls
),
656 .plls
= eqc_eyeq6h_ddr1_plls
,
659 static const struct eqc_pll eqc_eyeq6h_acc_plls
[] = {
660 { .index
= EQ6HC_ACC_PLL_XNN
, .name
= "pll-xnn", .reg64
= 0x040 },
661 { .index
= EQ6HC_ACC_PLL_VMP
, .name
= "pll-vmp", .reg64
= 0x050 },
662 { .index
= EQ6HC_ACC_PLL_PMA
, .name
= "pll-pma", .reg64
= 0x05C },
663 { .index
= EQ6HC_ACC_PLL_MPC
, .name
= "pll-mpc", .reg64
= 0x068 },
664 { .index
= EQ6HC_ACC_PLL_NOC
, .name
= "pll-noc", .reg64
= 0x070 },
667 static const struct eqc_match_data eqc_eyeq6h_acc_match_data
= {
668 .pll_count
= ARRAY_SIZE(eqc_eyeq6h_acc_plls
),
669 .plls
= eqc_eyeq6h_acc_plls
,
671 .reset_auxdev_name
= "reset_acc",
674 static const struct of_device_id eqc_match_table
[] = {
675 { .compatible
= "mobileye,eyeq5-olb", .data
= &eqc_eyeq5_match_data
},
676 { .compatible
= "mobileye,eyeq6l-olb", .data
= &eqc_eyeq6l_match_data
},
677 { .compatible
= "mobileye,eyeq6h-west-olb", .data
= &eqc_eyeq6h_west_match_data
},
678 { .compatible
= "mobileye,eyeq6h-east-olb", .data
= &eqc_eyeq6h_east_match_data
},
679 { .compatible
= "mobileye,eyeq6h-south-olb", .data
= &eqc_eyeq6h_south_match_data
},
680 { .compatible
= "mobileye,eyeq6h-ddr0-olb", .data
= &eqc_eyeq6h_ddr0_match_data
},
681 { .compatible
= "mobileye,eyeq6h-ddr1-olb", .data
= &eqc_eyeq6h_ddr1_match_data
},
682 { .compatible
= "mobileye,eyeq6h-acc-olb", .data
= &eqc_eyeq6h_acc_match_data
},
686 static struct platform_driver eqc_driver
= {
690 .of_match_table
= eqc_match_table
,
691 .suppress_bind_attrs
= true,
694 builtin_platform_driver(eqc_driver
);
696 /* Required early for GIC timer. */
697 static const struct eqc_pll eqc_eyeq6h_central_early_plls
[] = {
698 { .index
= EQ6HC_CENTRAL_PLL_CPU
, .name
= "pll-cpu", .reg64
= 0x02C },
701 static const struct eqc_fixed_factor eqc_eyeq6h_central_early_fixed_factors
[] = {
702 { EQ6HC_CENTRAL_CPU_OCC
, "occ-cpu", 1, 1, EQ6HC_CENTRAL_PLL_CPU
},
705 static const struct eqc_early_match_data eqc_eyeq6h_central_early_match_data __initconst
= {
706 .early_pll_count
= ARRAY_SIZE(eqc_eyeq6h_central_early_plls
),
707 .early_plls
= eqc_eyeq6h_central_early_plls
,
709 .early_fixed_factor_count
= ARRAY_SIZE(eqc_eyeq6h_central_early_fixed_factors
),
710 .early_fixed_factors
= eqc_eyeq6h_central_early_fixed_factors
,
713 /* Required early for UART. */
714 static const struct eqc_pll eqc_eyeq6h_west_early_plls
[] = {
715 { .index
= EQ6HC_WEST_PLL_PER
, .name
= "pll-west", .reg64
= 0x074 },
718 static const struct eqc_fixed_factor eqc_eyeq6h_west_early_fixed_factors
[] = {
719 { EQ6HC_WEST_PER_OCC
, "west-per-occ", 1, 10, EQ6HC_WEST_PLL_PER
},
720 { EQ6HC_WEST_PER_UART
, "west-per-uart", 1, 1, EQ6HC_WEST_PER_OCC
},
723 static const struct eqc_early_match_data eqc_eyeq6h_west_early_match_data __initconst
= {
724 .early_pll_count
= ARRAY_SIZE(eqc_eyeq6h_west_early_plls
),
725 .early_plls
= eqc_eyeq6h_west_early_plls
,
727 .early_fixed_factor_count
= ARRAY_SIZE(eqc_eyeq6h_west_early_fixed_factors
),
728 .early_fixed_factors
= eqc_eyeq6h_west_early_fixed_factors
,
731 static void __init
eqc_early_init(struct device_node
*np
,
732 const struct eqc_early_match_data
*early_data
)
734 struct clk_hw_onecell_data
*cells
;
735 unsigned int i
, clk_count
;
739 clk_count
= early_data
->early_pll_count
+ early_data
->early_fixed_factor_count
+
740 early_data
->late_clk_count
;
741 cells
= kzalloc(struct_size(cells
, hws
, clk_count
), GFP_KERNEL
);
747 cells
->num
= clk_count
;
750 * Mark all clocks as deferred; some are registered here, the rest at
751 * platform device probe.
753 * Once the platform device is probed, its provider will take priority
754 * when looking up clocks.
756 for (i
= 0; i
< clk_count
; i
++)
757 cells
->hws
[i
] = ERR_PTR(-EPROBE_DEFER
);
759 /* Offsets (reg64) of early PLLs are relative to OLB block. */
760 base
= of_iomap(np
, 0);
766 for (i
= 0; i
< early_data
->early_pll_count
; i
++) {
767 const struct eqc_pll
*pll
= &early_data
->early_plls
[i
];
768 unsigned long mult
, div
, acc
;
773 val
= readq(base
+ pll
->reg64
);
777 ret
= eqc_pll_parse_registers(r0
, r1
, &mult
, &div
, &acc
);
779 pr_err("failed parsing state of %s\n", pll
->name
);
783 hw
= clk_hw_register_fixed_factor_with_accuracy_fwname(NULL
,
784 np
, pll
->name
, "ref", 0, mult
, div
, acc
);
785 cells
->hws
[pll
->index
] = hw
;
787 pr_err("failed registering %s: %pe\n", pll
->name
, hw
);
793 for (i
= 0; i
< early_data
->early_fixed_factor_count
; i
++) {
794 const struct eqc_fixed_factor
*ff
= &early_data
->early_fixed_factors
[i
];
795 struct clk_hw
*parent_hw
= cells
->hws
[ff
->parent
];
798 hw
= clk_hw_register_fixed_factor_parent_hw(NULL
, ff
->name
,
799 parent_hw
, 0, ff
->mult
, ff
->div
);
800 cells
->hws
[ff
->index
] = hw
;
802 pr_err("failed registering %s: %pe\n", ff
->name
, hw
);
808 ret
= of_clk_add_hw_provider(np
, of_clk_hw_onecell_get
, cells
);
810 pr_err("failed registering clk provider: %d\n", ret
);
818 * We are doomed. The system will not be able to boot.
820 * Let's still try to be good citizens by freeing resources and print
821 * a last error message that might help debugging.
824 pr_err("failed clk init: %d\n", ret
);
827 of_clk_del_provider(np
);
829 for (i
= 0; i
< early_data
->early_pll_count
; i
++) {
830 const struct eqc_pll
*pll
= &early_data
->early_plls
[i
];
831 struct clk_hw
*hw
= cells
->hws
[pll
->index
];
833 if (!IS_ERR_OR_NULL(hw
))
834 clk_hw_unregister_fixed_factor(hw
);
841 static void __init
eqc_eyeq5_early_init(struct device_node
*np
)
843 eqc_early_init(np
, &eqc_eyeq5_early_match_data
);
845 CLK_OF_DECLARE_DRIVER(eqc_eyeq5
, "mobileye,eyeq5-olb", eqc_eyeq5_early_init
);
847 static void __init
eqc_eyeq6h_central_early_init(struct device_node
*np
)
849 eqc_early_init(np
, &eqc_eyeq6h_central_early_match_data
);
851 CLK_OF_DECLARE_DRIVER(eqc_eyeq6h_central
, "mobileye,eyeq6h-central-olb",
852 eqc_eyeq6h_central_early_init
);
854 static void __init
eqc_eyeq6h_west_early_init(struct device_node
*np
)
856 eqc_early_init(np
, &eqc_eyeq6h_west_early_match_data
);
858 CLK_OF_DECLARE_DRIVER(eqc_eyeq6h_west
, "mobileye,eyeq6h-west-olb",
859 eqc_eyeq6h_west_early_init
);