1 // SPDX-License-Identifier: GPL-2.0-only
3 * Reset driver for the Mobileye EyeQ5, EyeQ6L and EyeQ6H platforms.
5 * Controllers live in a shared register region called OLB. EyeQ5 and EyeQ6L
6 * have a single OLB instance for a single reset controller. EyeQ6H has seven
7 * OLB instances; three host reset controllers.
9 * Each reset controller has one or more domain. Domains are of a given type
10 * (see enum eqr_domain_type), with a valid offset mask (up to 32 resets per
13 * Domain types define expected behavior: one-register-per-reset,
14 * one-bit-per-reset, status detection method, busywait duration, etc.
16 * We use eqr_ as prefix, as-in "EyeQ Reset", but way shorter.
18 * Known resets in EyeQ5 domain 0 (type EQR_EYEQ5_SARCR):
19 * 3. CAN0 4. CAN1 5. CAN2 6. SPI0
20 * 7. SPI1 8. SPI2 9. SPI3 10. UART0
21 * 11. UART1 12. UART2 13. I2C0 14. I2C1
22 * 15. I2C2 16. I2C3 17. I2C4 18. TIMER0
23 * 19. TIMER1 20. TIMER2 21. TIMER3 22. TIMER4
24 * 23. WD0 24. EXT0 25. EXT1 26. GPIO
27 * Known resets in EyeQ5 domain 1 (type EQR_EYEQ5_ACRP):
28 * 0. VMP0 1. VMP1 2. VMP2 3. VMP3
29 * 4. PMA0 5. PMA1 6. PMAC0 7. PMAC1
30 * 8. MPC0 9. MPC1 10. MPC2 11. MPC3
33 * Known resets in EyeQ5 domain 2 (type EQR_EYEQ5_PCIE):
34 * 0. PCIE0_CORE 1. PCIE0_APB 2. PCIE0_LINK_AXI 3. PCIE0_LINK_MGMT
35 * 4. PCIE0_LINK_HOT 5. PCIE0_LINK_PIPE 6. PCIE1_CORE 7. PCIE1_APB
36 * 8. PCIE1_LINK_AXI 9. PCIE1_LINK_MGMT 10. PCIE1_LINK_HOT 11. PCIE1_LINK_PIPE
37 * 12. MULTIPHY 13. MULTIPHY_APB 15. PCIE0_LINK_MGMT 16. PCIE1_LINK_MGMT
38 * 17. PCIE0_LINK_PM 18. PCIE1_LINK_PM
40 * Known resets in EyeQ6L domain 0 (type EQR_EYEQ5_SARCR):
41 * 0. SPI0 1. SPI1 2. UART0 3. I2C0
42 * 4. I2C1 5. TIMER0 6. TIMER1 7. TIMER2
43 * 8. TIMER3 9. WD0 10. WD1 11. EXT0
46 * Known resets in EyeQ6L domain 1 (type EQR_EYEQ5_ACRP):
47 * 0. VMP0 1. VMP1 2. VMP2 3. VMP3
48 * 4. PMA0 5. PMA1 6. PMAC0 7. PMAC1
49 * 8. MPC0 9. MPC1 10. MPC2 11. MPC3
52 * Known resets in EyeQ6H west/east (type EQR_EYEQ6H_SARCR):
53 * 0. CAN 1. SPI0 2. SPI1 3. UART0
54 * 4. UART1 5. I2C0 6. I2C1 7. -hole-
55 * 8. TIMER0 9. TIMER1 10. WD 11. EXT TIMER
58 * Known resets in EyeQ6H acc (type EQR_EYEQ5_ACRP):
59 * 1. XNN0 2. XNN1 3. XNN2 4. XNN3
60 * 5. VMP0 6. VMP1 7. VMP2 8. VMP3
61 * 9. PMA0 10. PMA1 11. MPC0 12. MPC1
62 * 13. MPC2 14. MPC3 15. PERIPH
65 * - PMA: Programmable Macro Array
66 * - MPC: Multi-threaded Processing Clusters
67 * - VMP: Vector Microcode Processors
69 * Copyright (C) 2024 Mobileye Vision Technologies Ltd.
72 #include <linux/array_size.h>
73 #include <linux/auxiliary_bus.h>
74 #include <linux/bitfield.h>
75 #include <linux/bits.h>
76 #include <linux/bug.h>
77 #include <linux/cleanup.h>
78 #include <linux/container_of.h>
79 #include <linux/device.h>
80 #include <linux/err.h>
81 #include <linux/errno.h>
82 #include <linux/init.h>
84 #include <linux/iopoll.h>
85 #include <linux/lockdep.h>
86 #include <linux/mod_devicetable.h>
87 #include <linux/mutex.h>
89 #include <linux/reset-controller.h>
90 #include <linux/slab.h>
91 #include <linux/types.h>
94 * A reset ID, as returned by eqr_of_xlate_*(), is a (domain, offset) pair.
95 * Low byte is domain, rest is offset.
97 #define ID_DOMAIN_MASK GENMASK(7, 0)
98 #define ID_OFFSET_MASK GENMASK(31, 8)
100 enum eqr_domain_type
{
108 * Domain type EQR_EYEQ5_SARCR register offsets.
110 #define EQR_EYEQ5_SARCR_REQUEST (0x000)
111 #define EQR_EYEQ5_SARCR_STATUS (0x004)
114 * Domain type EQR_EYEQ5_ACRP register masks.
115 * Registers are: base + 4 * offset.
117 #define EQR_EYEQ5_ACRP_PD_REQ BIT(0)
118 #define EQR_EYEQ5_ACRP_ST_POWER_DOWN BIT(27)
119 #define EQR_EYEQ5_ACRP_ST_ACTIVE BIT(29)
122 * Domain type EQR_EYEQ6H_SARCR register offsets.
124 #define EQR_EYEQ6H_SARCR_RST_REQUEST (0x000)
125 #define EQR_EYEQ6H_SARCR_CLK_STATUS (0x004)
126 #define EQR_EYEQ6H_SARCR_RST_STATUS (0x008)
127 #define EQR_EYEQ6H_SARCR_CLK_REQUEST (0x00C)
129 struct eqr_busy_wait_timings
{
130 unsigned long sleep_us
;
131 unsigned long timeout_us
;
134 static const struct eqr_busy_wait_timings eqr_timings
[] = {
135 [EQR_EYEQ5_SARCR
] = {1, 10},
136 [EQR_EYEQ5_ACRP
] = {1, 40 * USEC_PER_MSEC
}, /* LBIST implies long timeout. */
137 /* EQR_EYEQ5_PCIE does no busy waiting. */
138 [EQR_EYEQ6H_SARCR
] = {1, 400},
141 #define EQR_MAX_DOMAIN_COUNT 3
143 struct eqr_domain_descriptor
{
144 enum eqr_domain_type type
;
149 struct eqr_match_data
{
150 unsigned int domain_count
;
151 const struct eqr_domain_descriptor
*domains
;
156 * One mutex per domain for read-modify-write operations on registers.
157 * Some domains can be involved in LBIST which implies long critical
158 * sections; we wouldn't want other domains to be impacted by that.
160 struct mutex mutexes
[EQR_MAX_DOMAIN_COUNT
];
162 const struct eqr_match_data
*data
;
163 struct reset_controller_dev rcdev
;
166 static inline struct eqr_private
*eqr_rcdev_to_priv(struct reset_controller_dev
*x
)
168 return container_of(x
, struct eqr_private
, rcdev
);
171 static u32
eqr_double_readl(void __iomem
*addr_a
, void __iomem
*addr_b
,
172 u32
*dest_a
, u32
*dest_b
)
174 *dest_a
= readl(addr_a
);
175 *dest_b
= readl(addr_b
);
176 return 0; /* read_poll_timeout() op argument must return something. */
179 static int eqr_busy_wait_locked(struct eqr_private
*priv
, struct device
*dev
,
180 u32 domain
, u32 offset
, bool assert)
182 void __iomem
*base
= priv
->base
+ priv
->data
->domains
[domain
].offset
;
183 enum eqr_domain_type domain_type
= priv
->data
->domains
[domain
].type
;
184 unsigned long timeout_us
= eqr_timings
[domain_type
].timeout_us
;
185 unsigned long sleep_us
= eqr_timings
[domain_type
].sleep_us
;
186 u32 val
, mask
, rst_status
, clk_status
;
190 lockdep_assert_held(&priv
->mutexes
[domain
]);
192 switch (domain_type
) {
193 case EQR_EYEQ5_SARCR
:
194 reg
= base
+ EQR_EYEQ5_SARCR_STATUS
;
197 ret
= readl_poll_timeout(reg
, val
, !(val
& mask
) == assert,
198 sleep_us
, timeout_us
);
202 reg
= base
+ 4 * offset
;
204 mask
= EQR_EYEQ5_ACRP_ST_POWER_DOWN
;
206 mask
= EQR_EYEQ5_ACRP_ST_ACTIVE
;
208 ret
= readl_poll_timeout(reg
, val
, !!(val
& mask
),
209 sleep_us
, timeout_us
);
213 ret
= 0; /* No busy waiting. */
216 case EQR_EYEQ6H_SARCR
:
218 * Wait until both bits change:
219 * readl(base + EQR_EYEQ6H_SARCR_RST_STATUS) & BIT(offset)
220 * readl(base + EQR_EYEQ6H_SARCR_CLK_STATUS) & BIT(offset)
223 ret
= read_poll_timeout(eqr_double_readl
, val
,
224 (!(rst_status
& mask
) == assert) &&
225 (!(clk_status
& mask
) == assert),
226 sleep_us
, timeout_us
, false,
227 base
+ EQR_EYEQ6H_SARCR_RST_STATUS
,
228 base
+ EQR_EYEQ6H_SARCR_CLK_STATUS
,
229 &rst_status
, &clk_status
);
238 if (ret
== -ETIMEDOUT
)
239 dev_dbg(dev
, "%u-%u: timeout\n", domain
, offset
);
243 static void eqr_assert_locked(struct eqr_private
*priv
, u32 domain
, u32 offset
)
245 enum eqr_domain_type domain_type
= priv
->data
->domains
[domain
].type
;
246 void __iomem
*base
, *reg
;
249 lockdep_assert_held(&priv
->mutexes
[domain
]);
251 base
= priv
->base
+ priv
->data
->domains
[domain
].offset
;
253 switch (domain_type
) {
254 case EQR_EYEQ5_SARCR
:
255 reg
= base
+ EQR_EYEQ5_SARCR_REQUEST
;
256 writel(readl(reg
) & ~BIT(offset
), reg
);
260 reg
= base
+ 4 * offset
;
261 writel(readl(reg
) | EQR_EYEQ5_ACRP_PD_REQ
, reg
);
265 writel(readl(base
) & ~BIT(offset
), base
);
268 case EQR_EYEQ6H_SARCR
:
269 /* RST_REQUEST and CLK_REQUEST must be kept in sync. */
270 val
= readl(base
+ EQR_EYEQ6H_SARCR_RST_REQUEST
);
272 writel(val
, base
+ EQR_EYEQ6H_SARCR_RST_REQUEST
);
273 writel(val
, base
+ EQR_EYEQ6H_SARCR_CLK_REQUEST
);
282 static int eqr_assert(struct reset_controller_dev
*rcdev
, unsigned long id
)
284 struct eqr_private
*priv
= eqr_rcdev_to_priv(rcdev
);
285 u32 domain
= FIELD_GET(ID_DOMAIN_MASK
, id
);
286 u32 offset
= FIELD_GET(ID_OFFSET_MASK
, id
);
288 dev_dbg(rcdev
->dev
, "%u-%u: assert request\n", domain
, offset
);
290 guard(mutex
)(&priv
->mutexes
[domain
]);
292 eqr_assert_locked(priv
, domain
, offset
);
293 return eqr_busy_wait_locked(priv
, rcdev
->dev
, domain
, offset
, true);
296 static void eqr_deassert_locked(struct eqr_private
*priv
, u32 domain
,
299 enum eqr_domain_type domain_type
= priv
->data
->domains
[domain
].type
;
300 void __iomem
*base
, *reg
;
303 lockdep_assert_held(&priv
->mutexes
[domain
]);
305 base
= priv
->base
+ priv
->data
->domains
[domain
].offset
;
307 switch (domain_type
) {
308 case EQR_EYEQ5_SARCR
:
309 reg
= base
+ EQR_EYEQ5_SARCR_REQUEST
;
310 writel(readl(reg
) | BIT(offset
), reg
);
314 reg
= base
+ 4 * offset
;
315 writel(readl(reg
) & ~EQR_EYEQ5_ACRP_PD_REQ
, reg
);
319 writel(readl(base
) | BIT(offset
), base
);
322 case EQR_EYEQ6H_SARCR
:
323 /* RST_REQUEST and CLK_REQUEST must be kept in sync. */
324 val
= readl(base
+ EQR_EYEQ6H_SARCR_RST_REQUEST
);
326 writel(val
, base
+ EQR_EYEQ6H_SARCR_RST_REQUEST
);
327 writel(val
, base
+ EQR_EYEQ6H_SARCR_CLK_REQUEST
);
336 static int eqr_deassert(struct reset_controller_dev
*rcdev
, unsigned long id
)
338 struct eqr_private
*priv
= eqr_rcdev_to_priv(rcdev
);
339 u32 domain
= FIELD_GET(ID_DOMAIN_MASK
, id
);
340 u32 offset
= FIELD_GET(ID_OFFSET_MASK
, id
);
342 dev_dbg(rcdev
->dev
, "%u-%u: deassert request\n", domain
, offset
);
344 guard(mutex
)(&priv
->mutexes
[domain
]);
346 eqr_deassert_locked(priv
, domain
, offset
);
347 return eqr_busy_wait_locked(priv
, rcdev
->dev
, domain
, offset
, false);
350 static int eqr_status(struct reset_controller_dev
*rcdev
, unsigned long id
)
352 u32 domain
= FIELD_GET(ID_DOMAIN_MASK
, id
);
353 u32 offset
= FIELD_GET(ID_OFFSET_MASK
, id
);
354 struct eqr_private
*priv
= eqr_rcdev_to_priv(rcdev
);
355 enum eqr_domain_type domain_type
= priv
->data
->domains
[domain
].type
;
356 void __iomem
*base
, *reg
;
358 dev_dbg(rcdev
->dev
, "%u-%u: status request\n", domain
, offset
);
360 guard(mutex
)(&priv
->mutexes
[domain
]);
362 base
= priv
->base
+ priv
->data
->domains
[domain
].offset
;
364 switch (domain_type
) {
365 case EQR_EYEQ5_SARCR
:
366 reg
= base
+ EQR_EYEQ5_SARCR_STATUS
;
367 return !(readl(reg
) & BIT(offset
));
369 reg
= base
+ 4 * offset
;
370 return !(readl(reg
) & EQR_EYEQ5_ACRP_ST_ACTIVE
);
372 return !(readl(base
) & BIT(offset
));
373 case EQR_EYEQ6H_SARCR
:
374 reg
= base
+ EQR_EYEQ6H_SARCR_RST_STATUS
;
375 return !(readl(reg
) & BIT(offset
));
381 static const struct reset_control_ops eqr_ops
= {
382 .assert = eqr_assert
,
383 .deassert
= eqr_deassert
,
384 .status
= eqr_status
,
387 static int eqr_of_xlate_internal(struct reset_controller_dev
*rcdev
,
388 u32 domain
, u32 offset
)
390 struct eqr_private
*priv
= eqr_rcdev_to_priv(rcdev
);
392 if (domain
>= priv
->data
->domain_count
|| offset
> 31 ||
393 !(priv
->data
->domains
[domain
].valid_mask
& BIT(offset
))) {
394 dev_err(rcdev
->dev
, "%u-%u: invalid reset\n", domain
, offset
);
398 return FIELD_PREP(ID_DOMAIN_MASK
, domain
) | FIELD_PREP(ID_OFFSET_MASK
, offset
);
401 static int eqr_of_xlate_onecell(struct reset_controller_dev
*rcdev
,
402 const struct of_phandle_args
*reset_spec
)
404 return eqr_of_xlate_internal(rcdev
, 0, reset_spec
->args
[0]);
407 static int eqr_of_xlate_twocells(struct reset_controller_dev
*rcdev
,
408 const struct of_phandle_args
*reset_spec
)
410 return eqr_of_xlate_internal(rcdev
, reset_spec
->args
[0], reset_spec
->args
[1]);
413 static int eqr_probe(struct auxiliary_device
*adev
,
414 const struct auxiliary_device_id
*id
)
416 const struct of_device_id
*match
;
417 struct device
*dev
= &adev
->dev
;
418 struct eqr_private
*priv
;
423 * We are an auxiliary device of clk-eyeq. We do not have an OF node by
424 * default; let's reuse our parent's OF node.
426 WARN_ON(dev
->of_node
);
427 device_set_of_node_from_dev(dev
, dev
->parent
);
432 * Using our newfound OF node, we can get match data. We cannot use
433 * device_get_match_data() because it does not match reused OF nodes.
435 match
= of_match_node(dev
->driver
->of_match_table
, dev
->of_node
);
436 if (!match
|| !match
->data
)
439 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
443 priv
->data
= match
->data
;
444 priv
->base
= (void __iomem
*)dev_get_platdata(dev
);
445 priv
->rcdev
.ops
= &eqr_ops
;
446 priv
->rcdev
.owner
= THIS_MODULE
;
447 priv
->rcdev
.dev
= dev
;
448 priv
->rcdev
.of_node
= dev
->of_node
;
450 if (priv
->data
->domain_count
== 1) {
451 priv
->rcdev
.of_reset_n_cells
= 1;
452 priv
->rcdev
.of_xlate
= eqr_of_xlate_onecell
;
454 priv
->rcdev
.of_reset_n_cells
= 2;
455 priv
->rcdev
.of_xlate
= eqr_of_xlate_twocells
;
458 for (i
= 0; i
< priv
->data
->domain_count
; i
++)
459 mutex_init(&priv
->mutexes
[i
]);
461 priv
->rcdev
.nr_resets
= 0;
462 for (i
= 0; i
< priv
->data
->domain_count
; i
++)
463 priv
->rcdev
.nr_resets
+= hweight32(priv
->data
->domains
[i
].valid_mask
);
465 ret
= devm_reset_controller_register(dev
, &priv
->rcdev
);
467 return dev_err_probe(dev
, ret
, "failed registering reset controller\n");
472 static const struct eqr_domain_descriptor eqr_eyeq5_domains
[] = {
474 .type
= EQR_EYEQ5_SARCR
,
475 .valid_mask
= 0xFFFFFF8,
479 .type
= EQR_EYEQ5_ACRP
,
480 .valid_mask
= 0x0001FFF,
484 .type
= EQR_EYEQ5_PCIE
,
485 .valid_mask
= 0x007BFFF,
490 static const struct eqr_match_data eqr_eyeq5_data
= {
491 .domain_count
= ARRAY_SIZE(eqr_eyeq5_domains
),
492 .domains
= eqr_eyeq5_domains
,
495 static const struct eqr_domain_descriptor eqr_eyeq6l_domains
[] = {
497 .type
= EQR_EYEQ5_SARCR
,
498 .valid_mask
= 0x3FFF,
502 .type
= EQR_EYEQ5_ACRP
,
503 .valid_mask
= 0x00FF,
508 static const struct eqr_match_data eqr_eyeq6l_data
= {
509 .domain_count
= ARRAY_SIZE(eqr_eyeq6l_domains
),
510 .domains
= eqr_eyeq6l_domains
,
513 /* West and east OLBs each have an instance. */
514 static const struct eqr_domain_descriptor eqr_eyeq6h_we_domains
[] = {
516 .type
= EQR_EYEQ6H_SARCR
,
517 .valid_mask
= 0x1F7F,
522 static const struct eqr_match_data eqr_eyeq6h_we_data
= {
523 .domain_count
= ARRAY_SIZE(eqr_eyeq6h_we_domains
),
524 .domains
= eqr_eyeq6h_we_domains
,
527 static const struct eqr_domain_descriptor eqr_eyeq6h_acc_domains
[] = {
529 .type
= EQR_EYEQ5_ACRP
,
530 .valid_mask
= 0x7FFF,
535 static const struct eqr_match_data eqr_eyeq6h_acc_data
= {
536 .domain_count
= ARRAY_SIZE(eqr_eyeq6h_acc_domains
),
537 .domains
= eqr_eyeq6h_acc_domains
,
541 * Table describes OLB system-controller compatibles.
542 * It does not get used to match against devicetree node.
544 static const struct of_device_id eqr_match_table
[] = {
545 { .compatible
= "mobileye,eyeq5-olb", .data
= &eqr_eyeq5_data
},
546 { .compatible
= "mobileye,eyeq6l-olb", .data
= &eqr_eyeq6l_data
},
547 { .compatible
= "mobileye,eyeq6h-west-olb", .data
= &eqr_eyeq6h_we_data
},
548 { .compatible
= "mobileye,eyeq6h-east-olb", .data
= &eqr_eyeq6h_we_data
},
549 { .compatible
= "mobileye,eyeq6h-acc-olb", .data
= &eqr_eyeq6h_acc_data
},
552 MODULE_DEVICE_TABLE(of
, eqr_match_table
);
554 static const struct auxiliary_device_id eqr_id_table
[] = {
555 { .name
= "clk_eyeq.reset" },
556 { .name
= "clk_eyeq.reset_west" },
557 { .name
= "clk_eyeq.reset_east" },
558 { .name
= "clk_eyeq.reset_acc" },
561 MODULE_DEVICE_TABLE(auxiliary
, eqr_id_table
);
563 static struct auxiliary_driver eqr_driver
= {
565 .id_table
= eqr_id_table
,
567 .of_match_table
= eqr_match_table
,
570 module_auxiliary_driver(eqr_driver
);