Route the i.MX8MP peripheral interrupt sources through two-output SplitIRQ devices. Connect the first splitter output to the Cortex-A53 GIC. The second output will be connected to the Cortex-M7 NVIC when CM7 support is added.
Signed-off-by: Gaurav Sharma <[email protected]> --- hw/arm/fsl-imx8mp.c | 56 ++++++++++++++++++++++++------------- include/hw/arm/fsl-imx8mp.h | 2 ++ 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c index 18d2b17ca8..395356bc13 100644 --- a/hw/arm/fsl-imx8mp.c +++ b/hw/arm/fsl-imx8mp.c @@ -196,6 +196,12 @@ static void fsl_imx8mp_init(Object *obj) FslImx8mpState *s = FSL_IMX8MP(obj); int i; + for (i = 0; i < FSL_IMX8MP_NUM_IRQS; i++) { + g_autofree char *name = g_strdup_printf("irq-splitter%d", i); + object_initialize_child(obj, name, &s->cpu_irq_splitter[i], + TYPE_SPLIT_IRQ); + } + object_initialize_child(obj, "gic", &s->gic, gicv3_class_name()); object_initialize_child(obj, "ccm", &s->ccm, TYPE_IMX8MP_CCM); @@ -280,6 +286,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) FslImx8mpState *s = FSL_IMX8MP(dev); DeviceState *gicdev = DEVICE(&s->gic); const char *cpu_type = ms->cpu_type ?: ARM_CPU_TYPE_NAME("cortex-a53"); + qemu_irq spi_irq[FSL_IMX8MP_NUM_IRQS]; int i; if (ms->smp.cpus > FSL_IMX8MP_NUM_A53) { @@ -407,6 +414,15 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) } } + for (i = 0; i < FSL_IMX8MP_NUM_IRQS; i++) { + DeviceState *splitter = DEVICE(&s->cpu_irq_splitter[i]); + qdev_prop_set_uint16(splitter, "num-lines", 2); + qdev_realize(splitter, NULL, &error_abort); + spi_irq[i] = qdev_get_gpio_in(splitter, 0); + qdev_connect_gpio_out(splitter, 0, + qdev_get_gpio_in(gicdev, i)); + } + /* CCM */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->ccm), errp)) { return; @@ -440,7 +456,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, - qdev_get_gpio_in(gicdev, serial_table[i].irq)); + spi_irq[serial_table[i].irq]); } /* SRC */ @@ -472,7 +488,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) } qdev_connect_gpio_out(DEVICE(&s->gpt5_gpt6_irq), 0, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_GPT5_GPT6_IRQ)); + spi_irq[FSL_IMX8MP_GPT5_GPT6_IRQ]); for (i = 0; i < FSL_IMX8MP_NUM_GPTS; i++) { hwaddr gpt_addrs[FSL_IMX8MP_NUM_GPTS] = { @@ -501,7 +517,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) }; sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0, - qdev_get_gpio_in(gicdev, gpt_irqs[i])); + spi_irq[gpt_irqs[i]]); } else { int irq = i - FSL_IMX8MP_NUM_GPTS + 2; @@ -536,9 +552,9 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) } sysbus_connect_irq(SYS_BUS_DEVICE(&s->mu[0].a), 0, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_MU1_A_IRQ)); + spi_irq[FSL_IMX8MP_MU1_A_IRQ]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->mu[0].b), 0, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_MU1_B_IRQ)); + spi_irq[FSL_IMX8MP_MU1_B_IRQ]); /* I2Cs */ for (i = 0; i < FSL_IMX8MP_NUM_I2CS; i++) { @@ -560,7 +576,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0, - qdev_get_gpio_in(gicdev, i2c_table[i].irq)); + spi_irq[i2c_table[i].irq]); } /* GPIOs */ @@ -607,9 +623,9 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0, - qdev_get_gpio_in(gicdev, gpio_table[i].irq_low)); + spi_irq[gpio_table[i].irq_low]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1, - qdev_get_gpio_in(gicdev, gpio_table[i].irq_high)); + spi_irq[gpio_table[i].irq_high]); } /* USDHCs */ @@ -629,7 +645,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0, usdhc_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0, - qdev_get_gpio_in(gicdev, usdhc_table[i].irq)); + spi_irq[usdhc_table[i].irq]); } /* USBs */ @@ -650,7 +666,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) } sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0, usb_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i].sysbus_xhci), 0, - qdev_get_gpio_in(gicdev, usb_table[i].irq)); + spi_irq[usb_table[i].irq]); } /* ECSPIs */ @@ -670,7 +686,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0, - qdev_get_gpio_in(gicdev, spi_table[i].irq)); + spi_irq[spi_table[i].irq]); } /* ENET1 */ @@ -684,9 +700,9 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->enet), 0, fsl_imx8mp_memmap[FSL_IMX8MP_ENET1].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->enet), 0, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_ENET1_MAC_IRQ)); + spi_irq[FSL_IMX8MP_ENET1_MAC_IRQ]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->enet), 1, - qdev_get_gpio_in(gicdev, FSL_IMX6_ENET1_MAC_1588_IRQ)); + spi_irq[FSL_IMX6_ENET1_MAC_1588_IRQ]); /* SNVS */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->snvs), errp)) { @@ -714,7 +730,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, wdog_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0, - qdev_get_gpio_in(gicdev, wdog_table[i].irq)); + spi_irq[wdog_table[i].irq]); } /* PCIe */ @@ -725,15 +741,15 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) fsl_imx8mp_memmap[FSL_IMX8MP_PCIE1].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_INTA_IRQ)); + spi_irq[FSL_IMX8MP_PCI_INTA_IRQ]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_INTB_IRQ)); + spi_irq[FSL_IMX8MP_PCI_INTB_IRQ]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_INTC_IRQ)); + spi_irq[FSL_IMX8MP_PCI_INTC_IRQ]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_INTD_IRQ)); + spi_irq[FSL_IMX8MP_PCI_INTD_IRQ]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_MSI_IRQ)); + spi_irq[FSL_IMX8MP_PCI_MSI_IRQ]); if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie_phy), errp)) { return; @@ -766,7 +782,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->flexcan[i]), 0, flexcan_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->flexcan[i]), 0, - qdev_get_gpio_in(gicdev, flexcan_table[i].irq)); + spi_irq[flexcan_table[i].irq]); } /* On-Chip RAM */ diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h index f547cbae42..2824f38355 100644 --- a/include/hw/arm/fsl-imx8mp.h +++ b/include/hw/arm/fsl-imx8mp.h @@ -24,6 +24,7 @@ #include "hw/net/flexcan.h" #include "hw/net/imx_fec.h" #include "hw/core/or-irq.h" +#include "hw/core/split-irq.h" #include "hw/pci-host/designware.h" #include "hw/pci-host/fsl_imx8m_phy.h" #include "hw/sd/sdhci.h" @@ -89,6 +90,7 @@ struct FslImx8mpState { FslImx8mPciePhyState pcie_phy; FlexcanState flexcan[FSL_IMX8MP_NUM_CANS]; OrIRQState gpt5_gpt6_irq; + SplitIRQ cpu_irq_splitter[FSL_IMX8MP_NUM_IRQS]; MemoryRegion ocram; MemoryRegion itcm; MemoryRegion dtcm; -- 2.34.1
