Lines Matching +full:reg +full:- +full:offset

1 // SPDX-License-Identifier: GPL-2.0-only
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.
54 * 4. UART1 5. I2C0 6. I2C1 7. -hole-
65 * - PMA: Programmable Macro Array
66 * - MPC: Multi-threaded Processing Clusters
67 * - VMP: Vector Microcode Processors
89 #include <linux/reset-controller.h>
94 * A reset ID, as returned by eqr_of_xlate_*(), is a (domain, offset) pair.
95 * Low byte is domain, rest is offset.
115 * Registers are: base + 4 * offset.
146 unsigned int offset; member
156 * One mutex per domain for read-modify-write operations on registers.
180 u32 domain, u32 offset, bool assert) in eqr_busy_wait_locked() argument
182 void __iomem *base = priv->base + priv->data->domains[domain].offset; in eqr_busy_wait_locked()
183 enum eqr_domain_type domain_type = priv->data->domains[domain].type; in eqr_busy_wait_locked()
187 void __iomem *reg; in eqr_busy_wait_locked() local
190 lockdep_assert_held(&priv->mutexes[domain]); in eqr_busy_wait_locked()
194 reg = base + EQR_EYEQ5_SARCR_STATUS; in eqr_busy_wait_locked()
195 mask = BIT(offset); in eqr_busy_wait_locked()
197 ret = readl_poll_timeout(reg, val, !(val & mask) == assert, in eqr_busy_wait_locked()
202 reg = base + 4 * offset; in eqr_busy_wait_locked()
208 ret = readl_poll_timeout(reg, val, !!(val & mask), in eqr_busy_wait_locked()
219 * readl(base + EQR_EYEQ6H_SARCR_RST_STATUS) & BIT(offset) in eqr_busy_wait_locked()
220 * readl(base + EQR_EYEQ6H_SARCR_CLK_STATUS) & BIT(offset) in eqr_busy_wait_locked()
222 mask = BIT(offset); in eqr_busy_wait_locked()
234 ret = -EINVAL; in eqr_busy_wait_locked()
238 if (ret == -ETIMEDOUT) in eqr_busy_wait_locked()
239 dev_dbg(dev, "%u-%u: timeout\n", domain, offset); in eqr_busy_wait_locked()
243 static void eqr_assert_locked(struct eqr_private *priv, u32 domain, u32 offset) in eqr_assert_locked() argument
245 enum eqr_domain_type domain_type = priv->data->domains[domain].type; in eqr_assert_locked()
246 void __iomem *base, *reg; in eqr_assert_locked() local
249 lockdep_assert_held(&priv->mutexes[domain]); in eqr_assert_locked()
251 base = priv->base + priv->data->domains[domain].offset; in eqr_assert_locked()
255 reg = base + EQR_EYEQ5_SARCR_REQUEST; in eqr_assert_locked()
256 writel(readl(reg) & ~BIT(offset), reg); in eqr_assert_locked()
260 reg = base + 4 * offset; in eqr_assert_locked()
261 writel(readl(reg) | EQR_EYEQ5_ACRP_PD_REQ, reg); in eqr_assert_locked()
265 writel(readl(base) & ~BIT(offset), base); in eqr_assert_locked()
271 val &= ~BIT(offset); in eqr_assert_locked()
286 u32 offset = FIELD_GET(ID_OFFSET_MASK, id); in eqr_assert() local
288 dev_dbg(rcdev->dev, "%u-%u: assert request\n", domain, offset); in eqr_assert()
290 guard(mutex)(&priv->mutexes[domain]); in eqr_assert()
292 eqr_assert_locked(priv, domain, offset); in eqr_assert()
293 return eqr_busy_wait_locked(priv, rcdev->dev, domain, offset, true); in eqr_assert()
297 u32 offset) in eqr_deassert_locked() argument
299 enum eqr_domain_type domain_type = priv->data->domains[domain].type; in eqr_deassert_locked()
300 void __iomem *base, *reg; in eqr_deassert_locked() local
303 lockdep_assert_held(&priv->mutexes[domain]); in eqr_deassert_locked()
305 base = priv->base + priv->data->domains[domain].offset; in eqr_deassert_locked()
309 reg = base + EQR_EYEQ5_SARCR_REQUEST; in eqr_deassert_locked()
310 writel(readl(reg) | BIT(offset), reg); in eqr_deassert_locked()
314 reg = base + 4 * offset; in eqr_deassert_locked()
315 writel(readl(reg) & ~EQR_EYEQ5_ACRP_PD_REQ, reg); in eqr_deassert_locked()
319 writel(readl(base) | BIT(offset), base); in eqr_deassert_locked()
325 val |= BIT(offset); in eqr_deassert_locked()
340 u32 offset = FIELD_GET(ID_OFFSET_MASK, id); in eqr_deassert() local
342 dev_dbg(rcdev->dev, "%u-%u: deassert request\n", domain, offset); in eqr_deassert()
344 guard(mutex)(&priv->mutexes[domain]); in eqr_deassert()
346 eqr_deassert_locked(priv, domain, offset); in eqr_deassert()
347 return eqr_busy_wait_locked(priv, rcdev->dev, domain, offset, false); in eqr_deassert()
353 u32 offset = FIELD_GET(ID_OFFSET_MASK, id); in eqr_status() local
355 enum eqr_domain_type domain_type = priv->data->domains[domain].type; in eqr_status()
356 void __iomem *base, *reg; in eqr_status() local
358 dev_dbg(rcdev->dev, "%u-%u: status request\n", domain, offset); in eqr_status()
360 guard(mutex)(&priv->mutexes[domain]); in eqr_status()
362 base = priv->base + priv->data->domains[domain].offset; in eqr_status()
366 reg = base + EQR_EYEQ5_SARCR_STATUS; in eqr_status()
367 return !(readl(reg) & BIT(offset)); in eqr_status()
369 reg = base + 4 * offset; in eqr_status()
370 return !(readl(reg) & EQR_EYEQ5_ACRP_ST_ACTIVE); in eqr_status()
372 return !(readl(base) & BIT(offset)); in eqr_status()
374 reg = base + EQR_EYEQ6H_SARCR_RST_STATUS; in eqr_status()
375 return !(readl(reg) & BIT(offset)); in eqr_status()
377 return -EINVAL; in eqr_status()
388 u32 domain, u32 offset) in eqr_of_xlate_internal() argument
392 if (domain >= priv->data->domain_count || offset > 31 || in eqr_of_xlate_internal()
393 !(priv->data->domains[domain].valid_mask & BIT(offset))) { in eqr_of_xlate_internal()
394 dev_err(rcdev->dev, "%u-%u: invalid reset\n", domain, offset); in eqr_of_xlate_internal()
395 return -EINVAL; in eqr_of_xlate_internal()
398 return FIELD_PREP(ID_DOMAIN_MASK, domain) | FIELD_PREP(ID_OFFSET_MASK, offset); in eqr_of_xlate_internal()
404 return eqr_of_xlate_internal(rcdev, 0, reset_spec->args[0]); in eqr_of_xlate_onecell()
410 return eqr_of_xlate_internal(rcdev, reset_spec->args[0], reset_spec->args[1]); in eqr_of_xlate_twocells()
417 struct device *dev = &adev->dev; in eqr_probe()
423 * We are an auxiliary device of clk-eyeq. We do not have an OF node by in eqr_probe()
426 WARN_ON(dev->of_node); in eqr_probe()
427 device_set_of_node_from_dev(dev, dev->parent); in eqr_probe()
428 if (!dev->of_node) in eqr_probe()
429 return -ENODEV; in eqr_probe()
435 match = of_match_node(dev->driver->of_match_table, dev->of_node); in eqr_probe()
436 if (!match || !match->data) in eqr_probe()
437 return -ENODEV; in eqr_probe()
441 return -ENOMEM; in eqr_probe()
443 priv->data = match->data; in eqr_probe()
444 priv->base = (void __iomem *)dev_get_platdata(dev); in eqr_probe()
445 priv->rcdev.ops = &eqr_ops; in eqr_probe()
446 priv->rcdev.owner = THIS_MODULE; in eqr_probe()
447 priv->rcdev.dev = dev; in eqr_probe()
448 priv->rcdev.of_node = dev->of_node; in eqr_probe()
450 if (priv->data->domain_count == 1) { in eqr_probe()
451 priv->rcdev.of_reset_n_cells = 1; in eqr_probe()
452 priv->rcdev.of_xlate = eqr_of_xlate_onecell; in eqr_probe()
454 priv->rcdev.of_reset_n_cells = 2; in eqr_probe()
455 priv->rcdev.of_xlate = eqr_of_xlate_twocells; in eqr_probe()
458 for (i = 0; i < priv->data->domain_count; i++) in eqr_probe()
459 mutex_init(&priv->mutexes[i]); in eqr_probe()
461 priv->rcdev.nr_resets = 0; in eqr_probe()
462 for (i = 0; i < priv->data->domain_count; i++) in eqr_probe()
463 priv->rcdev.nr_resets += hweight32(priv->data->domains[i].valid_mask); in eqr_probe()
465 ret = devm_reset_controller_register(dev, &priv->rcdev); in eqr_probe()
476 .offset = 0x004,
481 .offset = 0x200,
486 .offset = 0x120,
499 .offset = 0x004,
504 .offset = 0x200,
518 .offset = 0x004,
531 .offset = 0x000,
541 * Table describes OLB system-controller compatibles.
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 },