Lines Matching +full:gic +full:- +full:v5 +full:- +full:irs

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2024-2025 ARM Limited, All Rights Reserved.
6 #define pr_fmt(fmt) "GICv5 IRS: " fmt
14 #include <linux/irqchip/arm-gic-v5.h>
17 * Hardcoded ID_BITS limit for systems supporting only a 1-level IST
18 * table. Systems supporting only a 1-level IST table aren't expected
31 return readl_relaxed(irs_data->irs_base + reg_offset); in irs_readl_relaxed()
37 writel_relaxed(val, irs_data->irs_base + reg_offset); in irs_writel_relaxed()
43 return readq_relaxed(irs_data->irs_base + reg_offset); in irs_readq_relaxed()
49 writeq_relaxed(val, irs_data->irs_base + reg_offset); in irs_writeq_relaxed()
53 * The polling wait (in gicv5_wait_for_op_s_atomic()) on a GIC register
55 * required to synchronize CPU and GIC access to IST memory.
59 return gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_IST_STATUSR, in gicv5_irs_ist_synchronise()
84 u8 lpi_id_cap = ilog2(KMALLOC_MAX_SIZE) - 2 + istsz; in gicv5_irs_init_ist_linear()
94 return -ENOMEM; in gicv5_irs_init_ist_linear()
96 if (irs_data->flags & IRS_FLAGS_NON_COHERENT) in gicv5_irs_init_ist_linear()
138 n = max(5, lpi_id_bits - ((10 - istsz) + (2 * l2sz)) + 2); in gicv5_irs_init_ist_two_level()
144 return -ENOMEM; in gicv5_irs_init_ist_two_level()
146 if (irs_data->flags & IRS_FLAGS_NON_COHERENT) in gicv5_irs_init_ist_two_level()
161 * required by metadata is reported through istsz - the number of bits in gicv5_irs_init_ist_two_level()
165 gicv5_global_data.ist.l2_bits = (10 - istsz) + (2 * l2sz); in gicv5_irs_init_ist_two_level()
186 * taking the hierarchical domain struct irq_domain.root->mutex.
203 return -ENOENT; in gicv5_irs_iste_alloc()
215 return -ENOMEM; in gicv5_irs_iste_alloc()
219 if (irs_data->flags & IRS_FLAGS_NON_COHERENT) { in gicv5_irs_iste_alloc()
240 * Make sure we invalidate the cache line pulled before the IRS in gicv5_irs_iste_alloc()
243 if (irs_data->flags & IRS_FLAGS_NON_COHERENT) { in gicv5_irs_iste_alloc()
260 * physically contiguous blocks of memory as page-sized allocations are
302 return -EPERM; in gicv5_irs_init_ist()
315 * For 1-level tables, we should support a number of bits that in gicv5_irs_init_ist()
317 * the level 1-table gets too large and its memory allocation in gicv5_irs_init_ist()
352 if (two_levels && (lpi_id_bits > ((10 - l2_iste_sz) + (2 * l2sz)))) { in gicv5_irs_init_ist()
378 return -ENODEV; in gicv5_irs_cpu_to_iaffid()
392 if (!irs_data->spi_range) in gicv5_irs_lookup_by_spi_id()
395 min = irs_data->spi_min; in gicv5_irs_lookup_by_spi_id()
396 max = irs_data->spi_min + irs_data->spi_range - 1; in gicv5_irs_lookup_by_spi_id()
409 ret = gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_SPI_STATUSR, in gicv5_irs_wait_for_spi_op()
414 return !!FIELD_GET(GICV5_IRS_SPI_STATUSR_V, statusr) ? 0 : -EIO; in gicv5_irs_wait_for_spi_op()
424 ret = gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_PE_STATUSR, in gicv5_irs_wait_for_irs_pe()
432 return valid ? 0 : -EIO; in gicv5_irs_wait_for_irs_pe()
447 struct gicv5_irs_chip_data *irs_data = d->chip_data; in gicv5_spi_irq_set_type()
467 return -EINVAL; in gicv5_spi_irq_set_type()
470 guard(raw_spinlock)(&irs_data->spi_config_lock); in gicv5_spi_irq_set_type()
472 selr = FIELD_PREP(GICV5_IRS_SPI_SELR_ID, d->hwirq); in gicv5_spi_irq_set_type()
486 return gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_CR0, in gicv5_irs_wait_for_idle()
502 gicv5_wait_for_op(irs_data->irs_base, GICV5_IRS_SYNC_STATUSR, in gicv5_irs_syncr()
521 pr_err("No IRS associated with CPU %u\n", cpuid); in gicv5_irs_register_cpu()
522 return -ENXIO; in gicv5_irs_register_cpu()
531 return -ENXIO; in gicv5_irs_register_cpu()
553 irs_data->fwnode = handle; in gicv5_irs_init_bases()
554 irs_data->irs_base = irs_base; in gicv5_irs_init_bases()
556 if (of_property_read_bool(np, "dma-noncoherent")) { in gicv5_irs_init_bases()
558 * A non-coherent IRS implies that some cache levels cannot be in gicv5_irs_init_bases()
559 * used coherently by the cores and GIC. Our only option is to mark in gicv5_irs_init_bases()
560 * memory attributes for the GIC as non-cacheable; by default, in gicv5_irs_init_bases()
561 * non-cacheable memory attributes imply outer-shareable in gicv5_irs_init_bases()
574 irs_data->flags |= IRS_FLAGS_NON_COHERENT; in gicv5_irs_init_bases()
601 * Detect IAFFID<->CPU mappings from the device tree and in gicv5_irs_of_init_affinity()
602 * record IRS<->CPU topology information. in gicv5_irs_of_init_affinity()
604 u16 iaffid_mask = GENMASK(iaffid_bits - 1, 0); in gicv5_irs_of_init_affinity()
609 return -EINVAL; in gicv5_irs_of_init_affinity()
614 return -EINVAL; in gicv5_irs_of_init_affinity()
618 return -ENOMEM; in gicv5_irs_of_init_affinity()
640 pr_warn("CPU %d iaffid 0x%x exceeds IRS iaffid bits\n", in gicv5_irs_of_init_affinity()
648 /* We also know that the CPU is connected to this IRS */ in gicv5_irs_of_init_affinity()
691 return -ENOMEM; in gicv5_irs_init()
693 raw_spin_lock_init(&irs_data->spi_config_lock); in gicv5_irs_init()
695 ret = of_property_match_string(node, "reg-names", "ns-config"); in gicv5_irs_init()
697 pr_err("%pOF: ns-config reg-name not present\n", node); in gicv5_irs_init()
703 pr_err("%pOF: unable to map GICv5 IRS registers\n", node); in gicv5_irs_init()
708 gicv5_irs_init_bases(irs_data, irs_base, &node->fwnode); in gicv5_irs_init()
721 "LPI support not available - no IPIs, can't proceed\n")) { in gicv5_irs_init()
722 ret = -ENODEV; in gicv5_irs_init()
727 irs_data->spi_min = FIELD_GET(GICV5_IRS_IDR7_SPI_BASE, idr); in gicv5_irs_init()
730 irs_data->spi_range = FIELD_GET(GICV5_IRS_IDR6_SPI_IRS_RANGE, idr); in gicv5_irs_init()
732 if (irs_data->spi_range) { in gicv5_irs_init()
733 pr_info("%s detected SPI range [%u-%u]\n", in gicv5_irs_init()
735 irs_data->spi_min, in gicv5_irs_init()
736 irs_data->spi_min + in gicv5_irs_init()
737 irs_data->spi_range - 1); in gicv5_irs_init()
741 * Do the global setting only on the first IRS. in gicv5_irs_init()
760 list_add_tail(&irs_data->entry, &irs_nodes); in gicv5_irs_init()
779 iounmap(irs_data->irs_base); in gicv5_irs_remove()
780 list_del(&irs_data->entry); in gicv5_irs_remove()
793 return -ENODEV; in gicv5_irs_enable()
809 gicv5_its_of_probe(to_of_node(irs_data->fwnode)); in gicv5_irs_its_probe()
818 if (!of_device_is_compatible(np, "arm,gic-v5-irs")) in gicv5_irs_of_probe()
823 pr_err("Failed to init IRS %s\n", np->full_name); in gicv5_irs_of_probe()
826 return list_empty(&irs_nodes) ? -ENODEV : 0; in gicv5_irs_of_probe()