Lines Matching +full:u54 +full:- +full:mc +full:- +full:rvcoreip

1 // SPDX-License-Identifier: GPL-2.0
24 * This driver implements a version of the RISC-V PLIC with the actual layout
27 * https://static.dev.sifive.com/U54-MC-RVCoreIP.pdf
29 * The largest number supported by devices marked as 'sifive,plic-1.0.0', is
30 * 1024, of which device 0 is defined as non-existent by the RISC-V Privileged
106 raw_spin_lock(&handler->enable_lock); in plic_toggle()
107 __plic_toggle(handler->enable_base, hwirq, enable); in plic_toggle()
108 raw_spin_unlock(&handler->enable_lock); in plic_toggle()
119 plic_toggle(handler, d->hwirq, enable); in plic_irq_toggle()
137 writel(1, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); in plic_irq_unmask()
144 writel(0, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); in plic_irq_mask()
152 plic_toggle(handler, d->hwirq, 1); in plic_irq_eoi()
153 writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); in plic_irq_eoi()
154 plic_toggle(handler, d->hwirq, 0); in plic_irq_eoi()
156 writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); in plic_irq_eoi()
168 cpumask_and(&amask, &priv->lmask, mask_val); in plic_set_affinity()
176 return -EINVAL; in plic_set_affinity()
223 if (!test_bit(PLIC_QUIRK_EDGE_INTERRUPT, &priv->plic_quirks)) in plic_irq_set_type()
236 return -EINVAL; in plic_irq_set_type()
248 priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv; in plic_irq_suspend()
250 for (i = 0; i < priv->nr_irqs; i++) in plic_irq_suspend()
251 if (readl(priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID)) in plic_irq_suspend()
252 __set_bit(i, priv->prio_save); in plic_irq_suspend()
254 __clear_bit(i, priv->prio_save); in plic_irq_suspend()
259 if (!handler->present) in plic_irq_suspend()
262 raw_spin_lock(&handler->enable_lock); in plic_irq_suspend()
263 for (i = 0; i < DIV_ROUND_UP(priv->nr_irqs, 32); i++) { in plic_irq_suspend()
264 reg = handler->enable_base + i * sizeof(u32); in plic_irq_suspend()
265 handler->enable_save[i] = readl(reg); in plic_irq_suspend()
267 raw_spin_unlock(&handler->enable_lock); in plic_irq_suspend()
279 priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv; in plic_irq_resume()
281 for (i = 0; i < priv->nr_irqs; i++) { in plic_irq_resume()
283 writel((priv->prio_save[index] & BIT_MASK(i)) ? 1 : 0, in plic_irq_resume()
284 priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID); in plic_irq_resume()
290 if (!handler->present) in plic_irq_resume()
293 raw_spin_lock(&handler->enable_lock); in plic_irq_resume()
294 for (i = 0; i < DIV_ROUND_UP(priv->nr_irqs, 32); i++) { in plic_irq_resume()
295 reg = handler->enable_base + i * sizeof(u32); in plic_irq_resume()
296 writel(handler->enable_save[i], reg); in plic_irq_resume()
298 raw_spin_unlock(&handler->enable_lock); in plic_irq_resume()
310 struct plic_priv *priv = d->host_data; in plic_irqdomain_map()
312 irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data, in plic_irqdomain_map()
315 irq_set_affinity(irq, &priv->lmask); in plic_irqdomain_map()
324 struct plic_priv *priv = d->host_data; in plic_irq_domain_translate()
326 if (test_bit(PLIC_QUIRK_EDGE_INTERRUPT, &priv->plic_quirks)) in plic_irq_domain_translate()
360 * Handling an interrupt is a two-step process: first you claim the interrupt
369 void __iomem *claim = handler->hart_base + CONTEXT_CLAIM; in plic_handle_irq()
372 WARN_ON_ONCE(!handler->present); in plic_handle_irq()
377 int err = generic_handle_domain_irq(handler->priv->irqdomain, in plic_handle_irq()
390 writel(threshold, handler->hart_base + CONTEXT_THRESHOLD); in plic_set_threshold()
427 return -ENOMEM; in __plic_init()
429 priv->plic_quirks = plic_quirks; in __plic_init()
431 priv->regs = of_iomap(node, 0); in __plic_init()
432 if (WARN_ON(!priv->regs)) { in __plic_init()
433 error = -EIO; in __plic_init()
437 error = -EINVAL; in __plic_init()
442 priv->nr_irqs = nr_irqs; in __plic_init()
444 priv->prio_save = bitmap_alloc(nr_irqs, GFP_KERNEL); in __plic_init()
445 if (!priv->prio_save) in __plic_init()
452 error = -ENOMEM; in __plic_init()
453 priv->irqdomain = irq_domain_add_linear(node, nr_irqs + 1, in __plic_init()
455 if (WARN_ON(!priv->irqdomain)) in __plic_init()
474 /* Disable S-mode enable bits if running in M-mode. */ in __plic_init()
476 void __iomem *enable_base = priv->regs + in __plic_init()
507 * When running in M-mode we need to ignore the S-mode handler. in __plic_init()
512 if (handler->present) { in __plic_init()
518 cpumask_set_cpu(cpu, &priv->lmask); in __plic_init()
519 handler->present = true; in __plic_init()
520 handler->hart_base = priv->regs + CONTEXT_BASE + in __plic_init()
522 raw_spin_lock_init(&handler->enable_lock); in __plic_init()
523 handler->enable_base = priv->regs + CONTEXT_ENABLE_BASE + in __plic_init()
525 handler->priv = priv; in __plic_init()
527 handler->enable_save = kcalloc(DIV_ROUND_UP(nr_irqs, 32), in __plic_init()
528 sizeof(*handler->enable_save), GFP_KERNEL); in __plic_init()
529 if (!handler->enable_save) in __plic_init()
534 writel(1, priv->regs + PRIORITY_BASE + in __plic_init()
546 if (handler->present && !plic_cpuhp_setup_done) { in __plic_init()
561 kfree(handler->enable_save); in __plic_init()
564 kfree(priv->prio_save); in __plic_init()
566 iounmap(priv->regs); in __plic_init()
578 IRQCHIP_DECLARE(sifive_plic, "sifive,plic-1.0.0", plic_init);
588 IRQCHIP_DECLARE(thead_c900_plic, "thead,c900-plic", plic_edge_init);