1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Reset driver for the Mobileye EyeQ5, EyeQ6L, EyeQ6H and EyeQ7H platforms.
4 *
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. EyeQ7H has fourteen OLB instances;
8 * eleven host reset controllers.
9 *
10 * Each reset controller has one or more domain. Domains are of a given type
11 * (see enum eqr_domain_type), with a valid offset mask (up to 32 resets per
12 * domain).
13 *
14 * Domain types define expected behavior: one-register-per-reset,
15 * one-bit-per-reset, status detection method, busywait duration, etc.
16 *
17 * We use eqr_ as prefix, as-in "EyeQ Reset", but way shorter.
18 *
19 * Known resets in EyeQ5 domain 0 (type EQR_EYEQ5_SARCR):
20 * 3. CAN0 4. CAN1 5. CAN2 6. SPI0
21 * 7. SPI1 8. SPI2 9. SPI3 10. UART0
22 * 11. UART1 12. UART2 13. I2C0 14. I2C1
23 * 15. I2C2 16. I2C3 17. I2C4 18. TIMER0
24 * 19. TIMER1 20. TIMER2 21. TIMER3 22. TIMER4
25 * 23. WD0 24. EXT0 25. EXT1 26. GPIO
26 * 27. WD1
27 *
28 * Known resets in EyeQ5 domain 1 (type EQR_EYEQ5_ACRP):
29 * 0. VMP0 1. VMP1 2. VMP2 3. VMP3
30 * 4. PMA0 5. PMA1 6. PMAC0 7. PMAC1
31 * 8. MPC0 9. MPC1 10. MPC2 11. MPC3
32 * 12. MPC4
33 *
34 * Known resets in EyeQ5 domain 2 (type EQR_EYEQ5_PCIE):
35 * 0. PCIE0_CORE 1. PCIE0_APB 2. PCIE0_LINK_AXI 3. PCIE0_LINK_MGMT
36 * 4. PCIE0_LINK_HOT 5. PCIE0_LINK_PIPE 6. PCIE1_CORE 7. PCIE1_APB
37 * 8. PCIE1_LINK_AXI 9. PCIE1_LINK_MGMT 10. PCIE1_LINK_HOT 11. PCIE1_LINK_PIPE
38 * 12. MULTIPHY 13. MULTIPHY_APB 15. PCIE0_LINK_MGMT 16. PCIE1_LINK_MGMT
39 * 17. PCIE0_LINK_PM 18. PCIE1_LINK_PM
40 *
41 * Known resets in EyeQ6L domain 0 (type EQR_EYEQ5_SARCR):
42 * 0. SPI0 1. SPI1 2. UART0 3. I2C0
43 * 4. I2C1 5. TIMER0 6. TIMER1 7. TIMER2
44 * 8. TIMER3 9. WD0 10. WD1 11. EXT0
45 * 12. EXT1 13. GPIO
46 *
47 * Known resets in EyeQ6L domain 1 (type EQR_EYEQ5_ACRP):
48 * 0. VMP0 1. VMP1 2. VMP2 3. VMP3
49 * 4. PMA0 5. PMA1 6. PMAC0 7. PMAC1
50 * 8. MPC0 9. MPC1 10. MPC2 11. MPC3
51 * 12. MPC4
52 *
53 * Known resets in EyeQ6Lplus domain 0 (type EQR_EYEQ5_PCIE):
54 * 0. SPI0 1. SPI1 2. UART0 3. I2C0
55 * 4. I2C1 5. TIMER0 6. TIMER1 7. TIMER2
56 * 8. TIMER3 9. WD0 10. WD1 11. EXT0
57 * 12. EXT1 13. GPIO
58 *
59 * Known resets in EyeQ6Lplus domain 1 (type EQR_EYEQ5_ACRP):
60 * 0. VMP0 1. VMP1 2. VMP2 3. VMP3
61 * 4. PMA0 5. PMA1 6. PMAC0 7. PMAC1
62 * 8. MPC0 9. MPC1 10. MPC2 11. MPC3
63 * 12. MPC4
64 *
65 * Known resets in EyeQ6H west/east (type EQR_EYEQ6H_SARCR):
66 * 0. CAN 1. SPI0 2. SPI1 3. UART0
67 * 4. UART1 5. I2C0 6. I2C1 7. -hole-
68 * 8. TIMER0 9. TIMER1 10. WD 11. EXT TIMER
69 * 12. GPIO
70 *
71 * Known resets in EyeQ6H acc (type EQR_EYEQ5_ACRP):
72 * 1. XNN0 2. XNN1 3. XNN2 4. XNN3
73 * 5. VMP0 6. VMP1 7. VMP2 8. VMP3
74 * 9. PMA0 10. PMA1 11. MPC0 12. MPC1
75 * 13. MPC2 14. MPC3 15. PERIPH
76 *
77 * Known resets in EyeQ7H acc domain 0 (type EQR_EYEQ7H_ACRP)
78 * 0. VMP0 1. XVMP1 2. VMP2 3. VMP3
79 * 4. MPC0 5. MPC1 6. PMA0 7. PMA1
80 *
81 * Known resets in EyeQ7H acc domain 1 (type EQR_EYEQ7H_ACC)
82 * 0. NCORE0 1. NCORE1 2. NCORE0_M 3. NCORE1_M
83 * 4. NCORE_NOC 5. VMP_NOC 6. MPC_NOC 7. PMA_NOC
84 *
85 * Known resets in EyeQ7H ddr (type EQR_EYEQ7H_CFG)
86 * 0. APB 1. DMI 2. DFI 3. PHY_SMS
87 * 4. CTL_SMS
88 *
89 * Known resets in EyeQ7H east (type EQR_EYEQ7H_CFG)
90 * 0. ISP 1. VEU 2. LBIST
91 *
92 * Known resets in EyeQ7H periph (type EQR_EYEQ6H_SARCR)
93 * 0. gpio 1.EXT TIMER 2.UART 3. SPI
94 * 4. I2C0 5. I2C1 6.I2C2 7. I2S
95 *
96 * Known resets in EyeQ7H south domain 0 (type EQR_EYEQ7H_CFG)
97 * 0. PCI_PHY 1. PCI_CTL 2. S_NOC 3. GBE_PHY
98 * 4. GBE_CTL
99 *
100 * Known resets in EyeQ7H south domain 1 (type EQR_EYEQ7H_CFG)
101 * 0. XSPI 1. UFS 2. VDIO
102 *
103 * Known resets in EyeQ7H west (type EQR_EYEQ7H_CFG)
104 * 0. GPU 1. CAU 2. LBIST 3. GPU_LBIST
105 *
106 * Known resets in EyeQ7H xnn domain 0 (type EQR_EYEQ7H_ACRP)
107 * 0. XNN0 1. XNN1 2.XNN2
108 *
109 * Known resets in EyeQ7H xnn domain 1 (type EQR_EYEQ7H_ACC)
110 * 0. XNN0 1. XNN1 2. XNN2 3. XNN3
111 * 4. NCORE 5. L2_0 6. L2_1 7. SMS_0
112 * 8. SMS_1
113 *
114 * Abbreviations:
115 * - PMA: Programmable Macro Array
116 * - MPC: Multi-threaded Processing Clusters
117 * - VMP: Vector Microcode Processors
118 *
119 * Copyright (C) 2024 Mobileye Vision Technologies Ltd.
120 */
121
122 #include <linux/array_size.h>
123 #include <linux/auxiliary_bus.h>
124 #include <linux/bitfield.h>
125 #include <linux/bits.h>
126 #include <linux/bug.h>
127 #include <linux/cleanup.h>
128 #include <linux/container_of.h>
129 #include <linux/device.h>
130 #include <linux/err.h>
131 #include <linux/errno.h>
132 #include <linux/init.h>
133 #include <linux/io.h>
134 #include <linux/iopoll.h>
135 #include <linux/lockdep.h>
136 #include <linux/mutex.h>
137 #include <linux/of.h>
138 #include <linux/reset-controller.h>
139 #include <linux/slab.h>
140 #include <linux/types.h>
141
142 /*
143 * A reset ID, as returned by eqr_of_xlate_*(), is a (domain, offset) pair.
144 * Low byte is domain, rest is offset.
145 */
146 #define ID_DOMAIN_MASK GENMASK(7, 0)
147 #define ID_OFFSET_MASK GENMASK(31, 8)
148
149 enum eqr_domain_type {
150 EQR_EYEQ5_SARCR,
151 EQR_EYEQ5_ACRP,
152 EQR_EYEQ5_PCIE,
153 EQR_EYEQ6H_SARCR,
154 EQR_EYEQ7H_ACC,
155 EQR_EYEQ7H_ACRP,
156 EQR_EYEQ7H_CFG,
157
158 EQR_NB_DOM_TYPES /* number of domain types, keep at the end */
159 };
160
161 /*
162 * Domain type EQR_EYEQ5_SARCR register offsets.
163 */
164 #define EQR_EYEQ5_SARCR_REQUEST (0x000)
165 #define EQR_EYEQ5_SARCR_STATUS (0x004)
166
167 /*
168 * Domain type EQR_EYEQ5_ACRP register masks.
169 * Registers are: base + 4 * offset.
170 */
171 #define EQR_EYEQ5_ACRP_PD_REQ BIT(0)
172 #define EQR_EYEQ5_ACRP_ST_POWER_DOWN BIT(27)
173 #define EQR_EYEQ5_ACRP_ST_ACTIVE BIT(29)
174
175 /*
176 * Domain type EQR_EYEQ6H_SARCR register offsets.
177 */
178 #define EQR_EYEQ6H_SARCR_RST_REQUEST (0x000)
179 #define EQR_EYEQ6H_SARCR_CLK_STATUS (0x004)
180 #define EQR_EYEQ6H_SARCR_RST_STATUS (0x008)
181 #define EQR_EYEQ6H_SARCR_CLK_REQUEST (0x00C)
182
183 /*
184 * Domain type EQR_EYEQ7H_ACC register offsets.
185 */
186 #define EQR_EYEQ7H_ACC_CLK_EN (0x000)
187 #define EQR_EYEQ7H_ACC_RST_EN (0x004)
188
189 /*
190 * Domain type EQR_EYEQ7H_ACRP register masks.
191 * Registers are: base + 4 * offset.
192 */
193 #define EQR_EYEQ7H_ACRP_PD_REQ BIT(0)
194 #define EQR_EYEQ7H_ACRP_MBIST_CFG GENMASK(3, 1)
195 #define EQR_EYEQ7H_ACRP_ST_POWER_DOWN BIT(13)
196 #define EQR_EYEQ7H_ACRP_ST_ACTIVE BIT(14)
197
198 struct eqr_busy_wait_timings {
199 unsigned long sleep_us;
200 unsigned long timeout_us;
201 };
202
203 static const struct eqr_busy_wait_timings eqr_timings[EQR_NB_DOM_TYPES] = {
204 [EQR_EYEQ5_SARCR] = {1, 10},
205 [EQR_EYEQ5_ACRP] = {1, 40 * USEC_PER_MSEC}, /* LBIST implies long timeout. */
206 /* EQR_EYEQ5_PCIE does no busy waiting. */
207 [EQR_EYEQ6H_SARCR] = {1, 400},
208 /* EQR_EYEQ7H_ACC does no busy waiting. */
209 [EQR_EYEQ7H_ACRP] = {1, 40 * USEC_PER_MSEC},
210 /* EQR_EYEQ7H_CFG does no busy waiting. */
211 };
212
213 #define EQR_MAX_DOMAIN_COUNT 3
214
215 struct eqr_domain_descriptor {
216 enum eqr_domain_type type;
217 u32 valid_mask;
218 unsigned int offset;
219 };
220
221 struct eqr_match_data {
222 unsigned int domain_count;
223 const struct eqr_domain_descriptor *domains;
224 };
225
226 struct eqr_private {
227 /*
228 * One mutex per domain for read-modify-write operations on registers.
229 * Some domains can be involved in LBIST which implies long critical
230 * sections; we wouldn't want other domains to be impacted by that.
231 */
232 struct mutex mutexes[EQR_MAX_DOMAIN_COUNT];
233 void __iomem *base;
234 const struct eqr_match_data *data;
235 struct reset_controller_dev rcdev;
236 };
237
eqr_rcdev_to_priv(struct reset_controller_dev * x)238 static inline struct eqr_private *eqr_rcdev_to_priv(struct reset_controller_dev *x)
239 {
240 return container_of(x, struct eqr_private, rcdev);
241 }
242
eqr_double_readl(void __iomem * addr_a,void __iomem * addr_b,u32 * dest_a,u32 * dest_b)243 static u32 eqr_double_readl(void __iomem *addr_a, void __iomem *addr_b,
244 u32 *dest_a, u32 *dest_b)
245 {
246 *dest_a = readl(addr_a);
247 *dest_b = readl(addr_b);
248 return 0; /* read_poll_timeout() op argument must return something. */
249 }
250
eqr_busy_wait_locked(struct eqr_private * priv,struct device * dev,u32 domain,u32 offset,bool assert)251 static int eqr_busy_wait_locked(struct eqr_private *priv, struct device *dev,
252 u32 domain, u32 offset, bool assert)
253 {
254 void __iomem *base = priv->base + priv->data->domains[domain].offset;
255 enum eqr_domain_type domain_type = priv->data->domains[domain].type;
256 unsigned long timeout_us = eqr_timings[domain_type].timeout_us;
257 unsigned long sleep_us = eqr_timings[domain_type].sleep_us;
258 u32 val, mask, rst_status, clk_status;
259 void __iomem *reg;
260 int ret;
261
262 lockdep_assert_held(&priv->mutexes[domain]);
263
264 switch (domain_type) {
265 case EQR_EYEQ5_SARCR:
266 reg = base + EQR_EYEQ5_SARCR_STATUS;
267 mask = BIT(offset);
268
269 ret = readl_poll_timeout(reg, val, !(val & mask) == assert,
270 sleep_us, timeout_us);
271 break;
272
273 case EQR_EYEQ5_ACRP:
274 reg = base + 4 * offset;
275 if (assert)
276 mask = EQR_EYEQ5_ACRP_ST_POWER_DOWN;
277 else
278 mask = EQR_EYEQ5_ACRP_ST_ACTIVE;
279
280 ret = readl_poll_timeout(reg, val, !!(val & mask),
281 sleep_us, timeout_us);
282 break;
283
284 case EQR_EYEQ6H_SARCR:
285 /*
286 * Wait until both bits change:
287 * readl(base + EQR_EYEQ6H_SARCR_RST_STATUS) & BIT(offset)
288 * readl(base + EQR_EYEQ6H_SARCR_CLK_STATUS) & BIT(offset)
289 */
290 mask = BIT(offset);
291 ret = read_poll_timeout(eqr_double_readl, val,
292 (!(rst_status & mask) == assert) &&
293 (!(clk_status & mask) == assert),
294 sleep_us, timeout_us, false,
295 base + EQR_EYEQ6H_SARCR_RST_STATUS,
296 base + EQR_EYEQ6H_SARCR_CLK_STATUS,
297 &rst_status, &clk_status);
298 break;
299
300 case EQR_EYEQ7H_ACRP:
301 reg = base + 4 * offset;
302 if (assert)
303 mask = EQR_EYEQ7H_ACRP_ST_POWER_DOWN;
304 else
305 mask = EQR_EYEQ7H_ACRP_ST_ACTIVE;
306
307 ret = readl_poll_timeout(reg, val, !!(val & mask),
308 sleep_us, timeout_us);
309 break;
310
311 case EQR_EYEQ5_PCIE:
312 case EQR_EYEQ7H_ACC:
313 case EQR_EYEQ7H_CFG:
314 ret = 0; /* No busy waiting. */
315 break;
316
317 default:
318 WARN_ON(1);
319 ret = -EINVAL;
320 break;
321 }
322
323 if (ret == -ETIMEDOUT)
324 dev_dbg(dev, "%u-%u: timeout\n", domain, offset);
325 return ret;
326 }
327
eqr_assert_locked(struct eqr_private * priv,u32 domain,u32 offset)328 static void eqr_assert_locked(struct eqr_private *priv, u32 domain, u32 offset)
329 {
330 enum eqr_domain_type domain_type = priv->data->domains[domain].type;
331 void __iomem *base, *reg;
332 u32 val;
333
334 lockdep_assert_held(&priv->mutexes[domain]);
335
336 base = priv->base + priv->data->domains[domain].offset;
337
338 switch (domain_type) {
339 case EQR_EYEQ5_SARCR:
340 reg = base + EQR_EYEQ5_SARCR_REQUEST;
341 writel(readl(reg) & ~BIT(offset), reg);
342 break;
343
344 case EQR_EYEQ5_ACRP:
345 reg = base + 4 * offset;
346 writel(readl(reg) | EQR_EYEQ5_ACRP_PD_REQ, reg);
347 break;
348
349 case EQR_EYEQ5_PCIE:
350 writel(readl(base) & ~BIT(offset), base);
351 break;
352
353 case EQR_EYEQ6H_SARCR:
354 /* RST_REQUEST and CLK_REQUEST must be kept in sync. */
355 val = readl(base + EQR_EYEQ6H_SARCR_RST_REQUEST);
356 val &= ~BIT(offset);
357 writel(val, base + EQR_EYEQ6H_SARCR_RST_REQUEST);
358 writel(val, base + EQR_EYEQ6H_SARCR_CLK_REQUEST);
359 break;
360
361 case EQR_EYEQ7H_ACC:
362 /* RST_REQUEST and CLK_REQUEST must be kept in sync. */
363 val = readl(base + EQR_EYEQ7H_ACC_RST_EN);
364 val &= ~BIT(offset);
365 writel(val, base + EQR_EYEQ7H_ACC_RST_EN);
366 writel(val, base + EQR_EYEQ7H_ACC_CLK_EN);
367 break;
368
369 case EQR_EYEQ7H_ACRP:
370 /* set powerdown and leave MBIST bits at zero */
371 reg = base + 4 * offset;
372 val = readl(reg) & ~EQR_EYEQ7H_ACRP_MBIST_CFG;
373 writel(val | EQR_EYEQ7H_ACRP_PD_REQ, reg);
374 break;
375
376 case EQR_EYEQ7H_CFG:
377 /* clear clock enable and NRESET bits */
378 val = readl(base);
379 val &= ~GENMASK(2 * offset + 1, 2 * offset);
380 writel(val, base);
381 break;
382
383 default:
384 WARN_ON(1);
385 break;
386 }
387 }
388
eqr_assert(struct reset_controller_dev * rcdev,unsigned long id)389 static int eqr_assert(struct reset_controller_dev *rcdev, unsigned long id)
390 {
391 struct eqr_private *priv = eqr_rcdev_to_priv(rcdev);
392 u32 domain = FIELD_GET(ID_DOMAIN_MASK, id);
393 u32 offset = FIELD_GET(ID_OFFSET_MASK, id);
394
395 dev_dbg(rcdev->dev, "%u-%u: assert request\n", domain, offset);
396
397 guard(mutex)(&priv->mutexes[domain]);
398
399 eqr_assert_locked(priv, domain, offset);
400 return eqr_busy_wait_locked(priv, rcdev->dev, domain, offset, true);
401 }
402
eqr_deassert_locked(struct eqr_private * priv,u32 domain,u32 offset)403 static void eqr_deassert_locked(struct eqr_private *priv, u32 domain,
404 u32 offset)
405 {
406 enum eqr_domain_type domain_type = priv->data->domains[domain].type;
407 void __iomem *base, *reg;
408 u32 val;
409
410 lockdep_assert_held(&priv->mutexes[domain]);
411
412 base = priv->base + priv->data->domains[domain].offset;
413
414 switch (domain_type) {
415 case EQR_EYEQ5_SARCR:
416 reg = base + EQR_EYEQ5_SARCR_REQUEST;
417 writel(readl(reg) | BIT(offset), reg);
418 break;
419
420 case EQR_EYEQ5_ACRP:
421 reg = base + 4 * offset;
422 writel(readl(reg) & ~EQR_EYEQ5_ACRP_PD_REQ, reg);
423 break;
424
425 case EQR_EYEQ5_PCIE:
426 writel(readl(base) | BIT(offset), base);
427 break;
428
429 case EQR_EYEQ6H_SARCR:
430 /* RST_REQUEST and CLK_REQUEST must be kept in sync. */
431 val = readl(base + EQR_EYEQ6H_SARCR_RST_REQUEST);
432 val |= BIT(offset);
433 writel(val, base + EQR_EYEQ6H_SARCR_RST_REQUEST);
434 writel(val, base + EQR_EYEQ6H_SARCR_CLK_REQUEST);
435 break;
436
437 case EQR_EYEQ7H_ACC:
438 /* RST_REQUEST and CLK_REQUEST must be kept in sync. */
439 val = readl(base + EQR_EYEQ7H_ACC_RST_EN);
440 val |= BIT(offset);
441 writel(val, base + EQR_EYEQ7H_ACC_RST_EN);
442 writel(val, base + EQR_EYEQ7H_ACC_CLK_EN);
443 break;
444
445 case EQR_EYEQ7H_ACRP:
446 /* clear powerdown and leave MBIST bits at zero */
447 reg = base + 4 * offset;
448 val = readl(reg) & ~EQR_EYEQ7H_ACRP_MBIST_CFG;
449 writel(val & ~EQR_EYEQ7H_ACRP_PD_REQ, reg);
450 break;
451
452 case EQR_EYEQ7H_CFG:
453 /* set clock enable and NRESET bits */
454 val = readl(base);
455 val |= GENMASK(2 * offset + 1, 2 * offset);
456 writel(val, base);
457 break;
458
459 default:
460 WARN_ON(1);
461 break;
462 }
463 }
464
eqr_deassert(struct reset_controller_dev * rcdev,unsigned long id)465 static int eqr_deassert(struct reset_controller_dev *rcdev, unsigned long id)
466 {
467 struct eqr_private *priv = eqr_rcdev_to_priv(rcdev);
468 u32 domain = FIELD_GET(ID_DOMAIN_MASK, id);
469 u32 offset = FIELD_GET(ID_OFFSET_MASK, id);
470
471 dev_dbg(rcdev->dev, "%u-%u: deassert request\n", domain, offset);
472
473 guard(mutex)(&priv->mutexes[domain]);
474
475 eqr_deassert_locked(priv, domain, offset);
476 return eqr_busy_wait_locked(priv, rcdev->dev, domain, offset, false);
477 }
478
eqr_status(struct reset_controller_dev * rcdev,unsigned long id)479 static int eqr_status(struct reset_controller_dev *rcdev, unsigned long id)
480 {
481 u32 domain = FIELD_GET(ID_DOMAIN_MASK, id);
482 u32 offset = FIELD_GET(ID_OFFSET_MASK, id);
483 struct eqr_private *priv = eqr_rcdev_to_priv(rcdev);
484 enum eqr_domain_type domain_type = priv->data->domains[domain].type;
485 void __iomem *base, *reg;
486
487 dev_dbg(rcdev->dev, "%u-%u: status request\n", domain, offset);
488
489 guard(mutex)(&priv->mutexes[domain]);
490
491 base = priv->base + priv->data->domains[domain].offset;
492
493 switch (domain_type) {
494 case EQR_EYEQ5_SARCR:
495 reg = base + EQR_EYEQ5_SARCR_STATUS;
496 return !(readl(reg) & BIT(offset));
497 case EQR_EYEQ5_ACRP:
498 reg = base + 4 * offset;
499 return !(readl(reg) & EQR_EYEQ5_ACRP_ST_ACTIVE);
500 case EQR_EYEQ5_PCIE:
501 return !(readl(base) & BIT(offset));
502 case EQR_EYEQ6H_SARCR:
503 reg = base + EQR_EYEQ6H_SARCR_RST_STATUS;
504 return !(readl(reg) & BIT(offset));
505 case EQR_EYEQ7H_ACC:
506 reg = base + EQR_EYEQ7H_ACC_RST_EN;
507 return !(readl(reg) & BIT(offset));
508 case EQR_EYEQ7H_ACRP:
509 reg = base + 4 * offset;
510 return !(readl(reg) & EQR_EYEQ7H_ACRP_ST_ACTIVE);
511 case EQR_EYEQ7H_CFG:
512 return !(readl(base) & BIT(2 * offset));
513 default:
514 return -EINVAL;
515 }
516 }
517
518 static const struct reset_control_ops eqr_ops = {
519 .assert = eqr_assert,
520 .deassert = eqr_deassert,
521 .status = eqr_status,
522 };
523
eqr_of_xlate_internal(struct reset_controller_dev * rcdev,u32 domain,u32 offset)524 static int eqr_of_xlate_internal(struct reset_controller_dev *rcdev,
525 u32 domain, u32 offset)
526 {
527 struct eqr_private *priv = eqr_rcdev_to_priv(rcdev);
528
529 if (domain >= priv->data->domain_count || offset > 31 ||
530 !(priv->data->domains[domain].valid_mask & BIT(offset))) {
531 dev_err(rcdev->dev, "%u-%u: invalid reset\n", domain, offset);
532 return -EINVAL;
533 }
534
535 return FIELD_PREP(ID_DOMAIN_MASK, domain) | FIELD_PREP(ID_OFFSET_MASK, offset);
536 }
537
eqr_of_xlate_onecell(struct reset_controller_dev * rcdev,const struct of_phandle_args * reset_spec)538 static int eqr_of_xlate_onecell(struct reset_controller_dev *rcdev,
539 const struct of_phandle_args *reset_spec)
540 {
541 return eqr_of_xlate_internal(rcdev, 0, reset_spec->args[0]);
542 }
543
eqr_of_xlate_twocells(struct reset_controller_dev * rcdev,const struct of_phandle_args * reset_spec)544 static int eqr_of_xlate_twocells(struct reset_controller_dev *rcdev,
545 const struct of_phandle_args *reset_spec)
546 {
547 return eqr_of_xlate_internal(rcdev, reset_spec->args[0], reset_spec->args[1]);
548 }
549
eqr_probe(struct auxiliary_device * adev,const struct auxiliary_device_id * id)550 static int eqr_probe(struct auxiliary_device *adev,
551 const struct auxiliary_device_id *id)
552 {
553 const struct of_device_id *match;
554 struct device *dev = &adev->dev;
555 struct eqr_private *priv;
556 unsigned int i;
557 int ret;
558
559 /*
560 * Get match data. We cannot use device_get_match_data() because it does
561 * not accept reused OF nodes; see device_set_of_node_from_dev().
562 */
563 match = of_match_node(dev->driver->of_match_table, dev->of_node);
564 if (!match || !match->data)
565 return -ENODEV;
566
567 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
568 if (!priv)
569 return -ENOMEM;
570
571 priv->data = match->data;
572 priv->base = (void __iomem *)dev_get_platdata(dev);
573 priv->rcdev.ops = &eqr_ops;
574 priv->rcdev.owner = THIS_MODULE;
575 priv->rcdev.dev = dev;
576 priv->rcdev.of_node = dev->of_node;
577
578 if (priv->data->domain_count == 1) {
579 priv->rcdev.of_reset_n_cells = 1;
580 priv->rcdev.of_xlate = eqr_of_xlate_onecell;
581 } else {
582 priv->rcdev.of_reset_n_cells = 2;
583 priv->rcdev.of_xlate = eqr_of_xlate_twocells;
584 }
585
586 for (i = 0; i < priv->data->domain_count; i++)
587 mutex_init(&priv->mutexes[i]);
588
589 priv->rcdev.nr_resets = 0;
590 for (i = 0; i < priv->data->domain_count; i++)
591 priv->rcdev.nr_resets += hweight32(priv->data->domains[i].valid_mask);
592
593 ret = devm_reset_controller_register(dev, &priv->rcdev);
594 if (ret)
595 return dev_err_probe(dev, ret, "failed registering reset controller\n");
596
597 return 0;
598 }
599
600 static const struct eqr_domain_descriptor eqr_eyeq5_domains[] = {
601 {
602 .type = EQR_EYEQ5_SARCR,
603 .valid_mask = 0xFFFFFF8,
604 .offset = 0x004,
605 },
606 {
607 .type = EQR_EYEQ5_ACRP,
608 .valid_mask = 0x0001FFF,
609 .offset = 0x200,
610 },
611 {
612 .type = EQR_EYEQ5_PCIE,
613 .valid_mask = 0x007BFFF,
614 .offset = 0x120,
615 },
616 };
617
618 static const struct eqr_match_data eqr_eyeq5_data = {
619 .domain_count = ARRAY_SIZE(eqr_eyeq5_domains),
620 .domains = eqr_eyeq5_domains,
621 };
622
623 static const struct eqr_domain_descriptor eqr_eyeq6l_domains[] = {
624 {
625 .type = EQR_EYEQ5_SARCR,
626 .valid_mask = 0x3FFF,
627 .offset = 0x004,
628 },
629 {
630 .type = EQR_EYEQ5_ACRP,
631 .valid_mask = 0x00FF,
632 .offset = 0x200,
633 },
634 };
635
636 static const struct eqr_match_data eqr_eyeq6l_data = {
637 .domain_count = ARRAY_SIZE(eqr_eyeq6l_domains),
638 .domains = eqr_eyeq6l_domains,
639 };
640
641 static const struct eqr_domain_descriptor eqr_eyeq6lplus_domains[] = {
642 {
643 .type = EQR_EYEQ5_PCIE,
644 .valid_mask = 0x3FFF,
645 .offset = 0x004,
646 },
647 {
648 .type = EQR_EYEQ5_ACRP,
649 .valid_mask = 0x00FF,
650 .offset = 0x200,
651 },
652 };
653
654 static const struct eqr_match_data eqr_eyeq6lplus_data = {
655 .domain_count = ARRAY_SIZE(eqr_eyeq6lplus_domains),
656 .domains = eqr_eyeq6lplus_domains,
657 };
658
659 /* West and east OLBs each have an instance. */
660 static const struct eqr_domain_descriptor eqr_eyeq6h_we_domains[] = {
661 {
662 .type = EQR_EYEQ6H_SARCR,
663 .valid_mask = 0x1F7F,
664 .offset = 0x004,
665 },
666 };
667
668 static const struct eqr_match_data eqr_eyeq6h_we_data = {
669 .domain_count = ARRAY_SIZE(eqr_eyeq6h_we_domains),
670 .domains = eqr_eyeq6h_we_domains,
671 };
672
673 static const struct eqr_domain_descriptor eqr_eyeq6h_acc_domains[] = {
674 {
675 .type = EQR_EYEQ5_ACRP,
676 .valid_mask = 0x7FFF,
677 .offset = 0x000,
678 },
679 };
680
681 static const struct eqr_match_data eqr_eyeq6h_acc_data = {
682 .domain_count = ARRAY_SIZE(eqr_eyeq6h_acc_domains),
683 .domains = eqr_eyeq6h_acc_domains,
684 };
685
686 static const struct eqr_domain_descriptor eqr_eyeq7h_acc_domains[] = {
687 {
688 .type = EQR_EYEQ7H_ACRP,
689 .valid_mask = 0xFF,
690 .offset = 0x000,
691 },
692 {
693 .type = EQR_EYEQ7H_ACC,
694 .valid_mask = 0xFF,
695 .offset = 0x060,
696 },
697 };
698
699 static const struct eqr_match_data eqr_eyeq7h_acc_data = {
700 .domain_count = ARRAY_SIZE(eqr_eyeq7h_acc_domains),
701 .domains = eqr_eyeq7h_acc_domains,
702 };
703
704 static const struct eqr_domain_descriptor eqr_eyeq7h_ddr_domains[] = {
705 {
706 .type = EQR_EYEQ7H_CFG,
707 .valid_mask = 0x1F,
708 .offset = 0x008,
709 },
710 };
711
712 static const struct eqr_match_data eqr_eyeq7h_ddr_data = {
713 .domain_count = ARRAY_SIZE(eqr_eyeq7h_ddr_domains),
714 .domains = eqr_eyeq7h_ddr_domains,
715 };
716
717 static const struct eqr_domain_descriptor eqr_eyeq7h_east_domains[] = {
718 {
719 .type = EQR_EYEQ7H_CFG,
720 .valid_mask = 0x7,
721 .offset = 0x060,
722 },
723 };
724
725 static const struct eqr_match_data eqr_eyeq7h_east_data = {
726 .domain_count = ARRAY_SIZE(eqr_eyeq7h_east_domains),
727 .domains = eqr_eyeq7h_east_domains,
728 };
729
730 /* Periph OLBs each have an instance. */
731 static const struct eqr_domain_descriptor eqr_eyeq7h_per_domains[] = {
732 {
733 .type = EQR_EYEQ6H_SARCR,
734 .valid_mask = 0xFF,
735 .offset = 0x030,
736 },
737 };
738
739 static const struct eqr_match_data eqr_eyeq7h_per_data = {
740 .domain_count = ARRAY_SIZE(eqr_eyeq7h_per_domains),
741 .domains = eqr_eyeq7h_per_domains,
742 };
743
744 static const struct eqr_domain_descriptor eqr_eyeq7h_south_domains[] = {
745 {
746 .type = EQR_EYEQ7H_CFG,
747 .valid_mask = 0x1F,
748 .offset = 0x070,
749 },
750 {
751 .type = EQR_EYEQ7H_CFG,
752 .valid_mask = 0x7,
753 .offset = 0x074,
754 },
755 };
756
757 static const struct eqr_match_data eqr_eyeq7h_south_data = {
758 .domain_count = ARRAY_SIZE(eqr_eyeq7h_south_domains),
759 .domains = eqr_eyeq7h_south_domains,
760 };
761
762 static const struct eqr_domain_descriptor eqr_eyeq7h_west_domains[] = {
763 {
764 .type = EQR_EYEQ7H_CFG,
765 .valid_mask = 0xf,
766 .offset = 0x068,
767 },
768 };
769
770 static const struct eqr_match_data eqr_eyeq7h_west_data = {
771 .domain_count = ARRAY_SIZE(eqr_eyeq7h_west_domains),
772 .domains = eqr_eyeq7h_west_domains,
773 };
774
775 static const struct eqr_domain_descriptor eqr_eyeq7h_xnn_domains[] = {
776 {
777 .type = EQR_EYEQ7H_ACRP,
778 .valid_mask = 0x7,
779 .offset = 0x000,
780 },
781 {
782 .type = EQR_EYEQ7H_ACC,
783 .valid_mask = 0x1FF,
784 .offset = 0x060,
785 },
786 };
787
788 static const struct eqr_match_data eqr_eyeq7h_xnn_data = {
789 .domain_count = ARRAY_SIZE(eqr_eyeq7h_xnn_domains),
790 .domains = eqr_eyeq7h_xnn_domains,
791 };
792
793 /*
794 * Table describes OLB system-controller compatibles.
795 * It does not get used to match against devicetree node.
796 */
797 static const struct of_device_id eqr_match_table[] = {
798 { .compatible = "mobileye,eyeq5-olb", .data = &eqr_eyeq5_data },
799 { .compatible = "mobileye,eyeq6l-olb", .data = &eqr_eyeq6l_data },
800 { .compatible = "mobileye,eyeq6lplus-olb", .data = &eqr_eyeq6lplus_data },
801 { .compatible = "mobileye,eyeq6h-west-olb", .data = &eqr_eyeq6h_we_data },
802 { .compatible = "mobileye,eyeq6h-east-olb", .data = &eqr_eyeq6h_we_data },
803 { .compatible = "mobileye,eyeq6h-acc-olb", .data = &eqr_eyeq6h_acc_data },
804 { .compatible = "mobileye,eyeq7h-acc0-olb", .data = &eqr_eyeq7h_acc_data },
805 { .compatible = "mobileye,eyeq7h-acc1-olb", .data = &eqr_eyeq7h_acc_data },
806 { .compatible = "mobileye,eyeq7h-ddr0-olb", .data = &eqr_eyeq7h_ddr_data },
807 { .compatible = "mobileye,eyeq7h-ddr1-olb", .data = &eqr_eyeq7h_ddr_data },
808 { .compatible = "mobileye,eyeq7h-east-olb", .data = &eqr_eyeq7h_east_data },
809 { .compatible = "mobileye,eyeq7h-periph-east-olb", .data = &eqr_eyeq7h_per_data },
810 { .compatible = "mobileye,eyeq7h-periph-west-olb", .data = &eqr_eyeq7h_per_data },
811 { .compatible = "mobileye,eyeq7h-south-olb", .data = &eqr_eyeq7h_south_data },
812 { .compatible = "mobileye,eyeq7h-west-olb", .data = &eqr_eyeq7h_west_data },
813 { .compatible = "mobileye,eyeq7h-xnn0-olb", .data = &eqr_eyeq7h_xnn_data },
814 { .compatible = "mobileye,eyeq7h-xnn1-olb", .data = &eqr_eyeq7h_xnn_data },
815 {}
816 };
817 MODULE_DEVICE_TABLE(of, eqr_match_table);
818
819 static const struct auxiliary_device_id eqr_id_table[] = {
820 { .name = "clk_eyeq.reset" },
821 { .name = "clk_eyeq.reset_acc" },
822 { .name = "clk_eyeq.reset_acc0" },
823 { .name = "clk_eyeq.reset_acc1" },
824 { .name = "clk_eyeq.reset_ddr0" },
825 { .name = "clk_eyeq.reset_ddr1" },
826 { .name = "clk_eyeq.reset_east" },
827 { .name = "clk_eyeq.reset_periph_east" },
828 { .name = "clk_eyeq.reset_periph_west" },
829 { .name = "clk_eyeq.reset_south" },
830 { .name = "clk_eyeq.reset_west" },
831 { .name = "clk_eyeq.reset_xnn0" },
832 { .name = "clk_eyeq.reset_xnn1" },
833 {}
834 };
835 MODULE_DEVICE_TABLE(auxiliary, eqr_id_table);
836
837 static struct auxiliary_driver eqr_driver = {
838 .probe = eqr_probe,
839 .id_table = eqr_id_table,
840 .driver = {
841 .of_match_table = eqr_match_table,
842 }
843 };
844 module_auxiliary_driver(eqr_driver);
845