hw/pci-host/designware: Expose MSI IRQ
Fixes INTD and MSI interrupts poking the same IRQ line without keeping track of each other's IRQ level. Furthermore, SoCs such as the i.MX 8M Plus don't share the MSI IRQ with the INTx lines, so expose it as a dedicated pin. Signed-off-by: Bernhard Beschow <shentey@gmail.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
a451cc11c4
commit
1b326f278d
@ -516,6 +516,7 @@ config FSL_IMX6
|
|||||||
select PL310 # cache controller
|
select PL310 # cache controller
|
||||||
select PCI_EXPRESS_DESIGNWARE
|
select PCI_EXPRESS_DESIGNWARE
|
||||||
select SDHCI
|
select SDHCI
|
||||||
|
select OR_IRQ
|
||||||
|
|
||||||
config ASPEED_SOC
|
config ASPEED_SOC
|
||||||
bool
|
bool
|
||||||
@ -573,6 +574,7 @@ config FSL_IMX7
|
|||||||
select WDT_IMX2
|
select WDT_IMX2
|
||||||
select PCI_EXPRESS_DESIGNWARE
|
select PCI_EXPRESS_DESIGNWARE
|
||||||
select SDHCI
|
select SDHCI
|
||||||
|
select OR_IRQ
|
||||||
select UNIMP
|
select UNIMP
|
||||||
|
|
||||||
config ARM_SMMUV3
|
config ARM_SMMUV3
|
||||||
|
@ -106,6 +106,8 @@ static void fsl_imx6_init(Object *obj)
|
|||||||
object_initialize_child(obj, "eth", &s->eth, TYPE_IMX_ENET);
|
object_initialize_child(obj, "eth", &s->eth, TYPE_IMX_ENET);
|
||||||
|
|
||||||
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
|
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
|
||||||
|
object_initialize_child(obj, "pcie4-msi-irq", &s->pcie4_msi_irq,
|
||||||
|
TYPE_OR_IRQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fsl_imx6_realize(DeviceState *dev, Error **errp)
|
static void fsl_imx6_realize(DeviceState *dev, Error **errp)
|
||||||
@ -435,14 +437,23 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
|
|||||||
sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort);
|
sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort);
|
||||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX6_PCIe_REG_ADDR);
|
sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX6_PCIe_REG_ADDR);
|
||||||
|
|
||||||
|
object_property_set_int(OBJECT(&s->pcie4_msi_irq), "num-lines", 2,
|
||||||
|
&error_abort);
|
||||||
|
qdev_realize(DEVICE(&s->pcie4_msi_irq), NULL, &error_abort);
|
||||||
|
|
||||||
|
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE4_MSI_IRQ);
|
||||||
|
qdev_connect_gpio_out(DEVICE(&s->pcie4_msi_irq), 0, irq);
|
||||||
|
|
||||||
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE1_IRQ);
|
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE1_IRQ);
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq);
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq);
|
||||||
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE2_IRQ);
|
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE2_IRQ);
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq);
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq);
|
||||||
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE3_IRQ);
|
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE3_IRQ);
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq);
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq);
|
||||||
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE4_IRQ);
|
irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 0);
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
|
||||||
|
irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 1);
|
||||||
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4, irq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PCIe PHY
|
* PCIe PHY
|
||||||
|
@ -150,6 +150,8 @@ static void fsl_imx7_init(Object *obj)
|
|||||||
* PCIE
|
* PCIE
|
||||||
*/
|
*/
|
||||||
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
|
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
|
||||||
|
object_initialize_child(obj, "pcie4-msi-irq", &s->pcie4_msi_irq,
|
||||||
|
TYPE_OR_IRQ);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* USBs
|
* USBs
|
||||||
@ -597,14 +599,23 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
|||||||
sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort);
|
sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort);
|
||||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR);
|
sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR);
|
||||||
|
|
||||||
|
object_property_set_int(OBJECT(&s->pcie4_msi_irq), "num-lines", 2,
|
||||||
|
&error_abort);
|
||||||
|
qdev_realize(DEVICE(&s->pcie4_msi_irq), NULL, &error_abort);
|
||||||
|
|
||||||
|
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_MSI_IRQ);
|
||||||
|
qdev_connect_gpio_out(DEVICE(&s->pcie4_msi_irq), 0, irq);
|
||||||
|
|
||||||
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTA_IRQ);
|
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTA_IRQ);
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq);
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq);
|
||||||
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTB_IRQ);
|
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTB_IRQ);
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq);
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq);
|
||||||
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTC_IRQ);
|
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTC_IRQ);
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq);
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq);
|
||||||
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_IRQ);
|
irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 0);
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
|
||||||
|
irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 1);
|
||||||
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4, irq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* USBs
|
* USBs
|
||||||
|
@ -55,8 +55,6 @@
|
|||||||
#define DESIGNWARE_PCIE_ATU_DEVFN(x) (((x) >> 16) & 0xff)
|
#define DESIGNWARE_PCIE_ATU_DEVFN(x) (((x) >> 16) & 0xff)
|
||||||
#define DESIGNWARE_PCIE_ATU_UPPER_TARGET 0x91C
|
#define DESIGNWARE_PCIE_ATU_UPPER_TARGET 0x91C
|
||||||
|
|
||||||
#define DESIGNWARE_PCIE_IRQ_MSI 3
|
|
||||||
|
|
||||||
static DesignwarePCIEHost *
|
static DesignwarePCIEHost *
|
||||||
designware_pcie_root_to_host(DesignwarePCIERoot *root)
|
designware_pcie_root_to_host(DesignwarePCIERoot *root)
|
||||||
{
|
{
|
||||||
@ -90,7 +88,7 @@ static void designware_pcie_root_msi_write(void *opaque, hwaddr addr,
|
|||||||
root->msi.intr[0].status |= BIT(val) & root->msi.intr[0].enable;
|
root->msi.intr[0].status |= BIT(val) & root->msi.intr[0].enable;
|
||||||
|
|
||||||
if (root->msi.intr[0].status & ~root->msi.intr[0].mask) {
|
if (root->msi.intr[0].status & ~root->msi.intr[0].mask) {
|
||||||
qemu_set_irq(host->pci.irqs[DESIGNWARE_PCIE_IRQ_MSI], 1);
|
qemu_set_irq(host->pci.msi, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +333,7 @@ static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address,
|
|||||||
case DESIGNWARE_PCIE_MSI_INTR0_STATUS:
|
case DESIGNWARE_PCIE_MSI_INTR0_STATUS:
|
||||||
root->msi.intr[0].status ^= val;
|
root->msi.intr[0].status ^= val;
|
||||||
if (!root->msi.intr[0].status) {
|
if (!root->msi.intr[0].status) {
|
||||||
qemu_set_irq(host->pci.irqs[DESIGNWARE_PCIE_IRQ_MSI], 0);
|
qemu_set_irq(host->pci.msi, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -680,6 +678,7 @@ static void designware_pcie_host_realize(DeviceState *dev, Error **errp)
|
|||||||
for (i = 0; i < ARRAY_SIZE(s->pci.irqs); i++) {
|
for (i = 0; i < ARRAY_SIZE(s->pci.irqs); i++) {
|
||||||
sysbus_init_irq(sbd, &s->pci.irqs[i]);
|
sysbus_init_irq(sbd, &s->pci.irqs[i]);
|
||||||
}
|
}
|
||||||
|
sysbus_init_irq(sbd, &s->pci.msi);
|
||||||
|
|
||||||
memory_region_init_io(&s->mmio,
|
memory_region_init_io(&s->mmio,
|
||||||
OBJECT(s),
|
OBJECT(s),
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "hw/usb/chipidea.h"
|
#include "hw/usb/chipidea.h"
|
||||||
#include "hw/usb/imx-usb-phy.h"
|
#include "hw/usb/imx-usb-phy.h"
|
||||||
#include "hw/pci-host/designware.h"
|
#include "hw/pci-host/designware.h"
|
||||||
|
#include "hw/or-irq.h"
|
||||||
#include "exec/memory.h"
|
#include "exec/memory.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
@ -73,6 +74,7 @@ struct FslIMX6State {
|
|||||||
ChipideaState usb[FSL_IMX6_NUM_USBS];
|
ChipideaState usb[FSL_IMX6_NUM_USBS];
|
||||||
IMXFECState eth;
|
IMXFECState eth;
|
||||||
DesignwarePCIEHost pcie;
|
DesignwarePCIEHost pcie;
|
||||||
|
OrIRQState pcie4_msi_irq;
|
||||||
MemoryRegion rom;
|
MemoryRegion rom;
|
||||||
MemoryRegion caam;
|
MemoryRegion caam;
|
||||||
MemoryRegion ocram;
|
MemoryRegion ocram;
|
||||||
@ -457,7 +459,7 @@ struct FslIMX6State {
|
|||||||
#define FSL_IMX6_PCIE1_IRQ 120
|
#define FSL_IMX6_PCIE1_IRQ 120
|
||||||
#define FSL_IMX6_PCIE2_IRQ 121
|
#define FSL_IMX6_PCIE2_IRQ 121
|
||||||
#define FSL_IMX6_PCIE3_IRQ 122
|
#define FSL_IMX6_PCIE3_IRQ 122
|
||||||
#define FSL_IMX6_PCIE4_IRQ 123
|
#define FSL_IMX6_PCIE4_MSI_IRQ 123
|
||||||
#define FSL_IMX6_DCIC1_IRQ 124
|
#define FSL_IMX6_DCIC1_IRQ 124
|
||||||
#define FSL_IMX6_DCIC2_IRQ 125
|
#define FSL_IMX6_DCIC2_IRQ 125
|
||||||
#define FSL_IMX6_MLB150_HIGH_IRQ 126
|
#define FSL_IMX6_MLB150_HIGH_IRQ 126
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "hw/net/imx_fec.h"
|
#include "hw/net/imx_fec.h"
|
||||||
#include "hw/pci-host/designware.h"
|
#include "hw/pci-host/designware.h"
|
||||||
#include "hw/usb/chipidea.h"
|
#include "hw/usb/chipidea.h"
|
||||||
|
#include "hw/or-irq.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
#include "qemu/units.h"
|
#include "qemu/units.h"
|
||||||
@ -85,6 +86,7 @@ struct FslIMX7State {
|
|||||||
IMX7GPRState gpr;
|
IMX7GPRState gpr;
|
||||||
ChipideaState usb[FSL_IMX7_NUM_USBS];
|
ChipideaState usb[FSL_IMX7_NUM_USBS];
|
||||||
DesignwarePCIEHost pcie;
|
DesignwarePCIEHost pcie;
|
||||||
|
OrIRQState pcie4_msi_irq;
|
||||||
MemoryRegion rom;
|
MemoryRegion rom;
|
||||||
MemoryRegion caam;
|
MemoryRegion caam;
|
||||||
MemoryRegion ocram;
|
MemoryRegion ocram;
|
||||||
@ -428,7 +430,7 @@ enum FslIMX7IRQs {
|
|||||||
FSL_IMX7_PCI_INTA_IRQ = 125,
|
FSL_IMX7_PCI_INTA_IRQ = 125,
|
||||||
FSL_IMX7_PCI_INTB_IRQ = 124,
|
FSL_IMX7_PCI_INTB_IRQ = 124,
|
||||||
FSL_IMX7_PCI_INTC_IRQ = 123,
|
FSL_IMX7_PCI_INTC_IRQ = 123,
|
||||||
FSL_IMX7_PCI_INTD_IRQ = 122,
|
FSL_IMX7_PCI_INTD_MSI_IRQ = 122,
|
||||||
|
|
||||||
FSL_IMX7_UART7_IRQ = 126,
|
FSL_IMX7_UART7_IRQ = 126,
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ struct DesignwarePCIEHost {
|
|||||||
MemoryRegion io;
|
MemoryRegion io;
|
||||||
|
|
||||||
qemu_irq irqs[4];
|
qemu_irq irqs[4];
|
||||||
|
qemu_irq msi;
|
||||||
} pci;
|
} pci;
|
||||||
|
|
||||||
MemoryRegion mmio;
|
MemoryRegion mmio;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user