diff options
author | Kinsey Moore <kinsey.moore@oarcorp.com> | 2023-06-16 09:38:03 -0500 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2024-10-01 13:55:38 +0100 |
commit | 604b72dd3c393bf6a7cac59c3a74a2bec4673a80 (patch) | |
tree | f5305421e1226dd793379126c63a66609ff77109 | |
parent | e569d959336004be8e50547be381886ba8a6e3d0 (diff) | |
download | qemu-604b72dd3c393bf6a7cac59c3a74a2bec4673a80.zip qemu-604b72dd3c393bf6a7cac59c3a74a2bec4673a80.tar.gz qemu-604b72dd3c393bf6a7cac59c3a74a2bec4673a80.tar.bz2 |
hw/arm/xlnx: Connect secondary CGEM IRQs
The Cadence GEM peripherals as configured for Zynq MPSoC and Versal
platforms have two priority queues with separate interrupt sources for
each. If the interrupt source for the second priority queue is not
connected, they work in polling mode only. This change connects the
second interrupt source for platforms where it is available. This patch
has been tested using the lwIP stack with a Xilinx-supplied driver from
their embeddedsw repository.
Signed-off-by: Kinsey Moore <kinsey.moore@oarcorp.com>
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/arm/xlnx-versal.c | 12 | ||||
-rw-r--r-- | hw/arm/xlnx-zynqmp.c | 11 | ||||
-rw-r--r-- | include/hw/arm/xlnx-versal.h | 1 | ||||
-rw-r--r-- | include/hw/arm/xlnx-zynqmp.h | 1 |
4 files changed, 23 insertions, 2 deletions
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c index 50cb060..3a1e2e2 100644 --- a/hw/arm/xlnx-versal.c +++ b/hw/arm/xlnx-versal.c @@ -258,14 +258,23 @@ static void versal_create_gems(Versal *s, qemu_irq *pic) char *name = g_strdup_printf("gem%d", i); DeviceState *dev; MemoryRegion *mr; + OrIRQState *or_irq; object_initialize_child(OBJECT(s), name, &s->lpd.iou.gem[i], TYPE_CADENCE_GEM); + or_irq = &s->lpd.iou.gem_irq_orgate[i]; + object_initialize_child(OBJECT(s), "gem-irq-orgate[*]", + or_irq, TYPE_OR_IRQ); dev = DEVICE(&s->lpd.iou.gem[i]); qemu_configure_nic_device(dev, true, NULL); object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort); object_property_set_int(OBJECT(dev), "num-priority-queues", 2, &error_abort); + object_property_set_int(OBJECT(or_irq), + "num-lines", 2, &error_fatal); + qdev_realize(DEVICE(or_irq), NULL, &error_fatal); + qdev_connect_gpio_out(DEVICE(or_irq), 0, pic[irqs[i]]); + object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps), &error_abort); sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); @@ -273,7 +282,8 @@ static void versal_create_gems(Versal *s, qemu_irq *pic) mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); memory_region_add_subregion(&s->mr_ps, addrs[i], mr); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(DEVICE(or_irq), 0)); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, qdev_get_gpio_in(DEVICE(or_irq), 1)); g_free(name); } } diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index afeb3f8..ab2d50e 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -394,6 +394,8 @@ static void xlnx_zynqmp_init(Object *obj) for (i = 0; i < XLNX_ZYNQMP_NUM_GEMS; i++) { object_initialize_child(obj, "gem[*]", &s->gem[i], TYPE_CADENCE_GEM); + object_initialize_child(obj, "gem-irq-orgate[*]", + &s->gem_irq_orgate[i], TYPE_OR_IRQ); } for (i = 0; i < XLNX_ZYNQMP_NUM_UARTS; i++) { @@ -625,12 +627,19 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) &error_abort); object_property_set_int(OBJECT(&s->gem[i]), "num-priority-queues", 2, &error_abort); + object_property_set_int(OBJECT(&s->gem_irq_orgate[i]), + "num-lines", 2, &error_fatal); + qdev_realize(DEVICE(&s->gem_irq_orgate[i]), NULL, &error_fatal); + qdev_connect_gpio_out(DEVICE(&s->gem_irq_orgate[i]), 0, gic_spi[gem_intr[i]]); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->gem[i]), errp)) { return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem[i]), 0, gem_addr[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem[i]), 0, - gic_spi[gem_intr[i]]); + qdev_get_gpio_in(DEVICE(&s->gem_irq_orgate[i]), 0)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem[i]), 1, + qdev_get_gpio_in(DEVICE(&s->gem_irq_orgate[i]), 1)); } for (i = 0; i < XLNX_ZYNQMP_NUM_UARTS; i++) { diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h index 025beb5..05ed641 100644 --- a/include/hw/arm/xlnx-versal.h +++ b/include/hw/arm/xlnx-versal.h @@ -78,6 +78,7 @@ struct Versal { struct { PL011State uart[XLNX_VERSAL_NR_UARTS]; CadenceGEMState gem[XLNX_VERSAL_NR_GEMS]; + OrIRQState gem_irq_orgate[XLNX_VERSAL_NR_GEMS]; XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS]; VersalUsb2 usb; CanBusState *canbus[XLNX_VERSAL_NR_CANFD]; diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 48f7948..c137ac5 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -116,6 +116,7 @@ struct XlnxZynqMPState { MemoryRegion mr_unimp[XLNX_ZYNQMP_NUM_UNIMP_AREAS]; CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS]; + OrIRQState gem_irq_orgate[XLNX_ZYNQMP_NUM_GEMS]; CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS]; XlnxZynqMPCANState can[XLNX_ZYNQMP_NUM_CAN]; SysbusAHCIState sata; |