diff mbox series

[PULL,02/54] hw/arm/xlnx: Connect secondary CGEM IRQs

Message ID 20241001163918.1275441-3-peter.maydell@linaro.org (mailing list archive)
State New, archived
Headers show
Series [PULL,01/54] MAINTAINERS: Update STM32L4x5 and B-L475E-IOT01A maintainers | expand

Commit Message

Peter Maydell Oct. 1, 2024, 4:38 p.m. UTC
From: Kinsey Moore <kinsey.moore@oarcorp.com>

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>
---
 include/hw/arm/xlnx-versal.h |  1 +
 include/hw/arm/xlnx-zynqmp.h |  1 +
 hw/arm/xlnx-versal.c         | 12 +++++++++++-
 hw/arm/xlnx-zynqmp.c         | 11 ++++++++++-
 4 files changed, 23 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index 025beb5532d..05ed641b6b6 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 48f79480921..c137ac59e85 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;
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index 50cb0606cbf..3a1e2e29f1c 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 afeb3f88f81..ab2d50e31bc 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++) {