Connect the Xilinx SPI devices to the ZynqMP model. Signed-off-by: Alistair Francis <alistair.fran...@xilinx.com> --- V4: - Rename the SPI busses so that they can all be accessed from the SoC - Don't set the num-busses property V3: - Expose the SPI Bus as part of the SoC device V2: - Don't connect the SPI flash to the SoC
hw/arm/xlnx-zynqmp.c | 38 ++++++++++++++++++++++++++++++++++++++ include/hw/arm/xlnx-zynqmp.h | 3 +++ 2 files changed, 41 insertions(+) diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index 87553bb..6c82f83 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -56,6 +56,14 @@ static const int sdhci_intr[XLNX_ZYNQMP_NUM_SDHCI] = { 48, 49, }; +static const uint64_t spi_addr[XLNX_ZYNQMP_NUM_SPIS] = { + 0xFF040000, 0xFF050000, +}; + +static const int spi_intr[XLNX_ZYNQMP_NUM_SPIS] = { + 19, 20, +}; + typedef struct XlnxZynqMPGICRegion { int region_index; uint32_t address; @@ -112,6 +120,12 @@ static void xlnx_zynqmp_init(Object *obj) qdev_set_parent_bus(DEVICE(&s->sdhci[i]), sysbus_get_default()); } + + for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) { + object_initialize(&s->spi[i], sizeof(s->spi[i]), + TYPE_XILINX_SPIPS); + qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default()); + } } static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) @@ -286,6 +300,30 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci[i]), 0, gic_spi[sdhci_intr[i]]); } + + for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) { + BusState *spi_bus; + char bus_name[6]; + + object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", &err); + + sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_addr[i]); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0, + gic_spi[spi_intr[i]]); + + /* Rename each SPI bus after the SPI device to allow the board + * to access all of the busses from the SoC. + */ + spi_bus = qdev_get_child_bus(DEVICE(&s->spi[i]), "spi0"); + snprintf(bus_name, 6, "spi%d", i); + memcpy((char *) spi_bus->name, bus_name, 6 * sizeof(char)); + + /* Add the SPI buses to the SoC child bus */ + /* FIXME: This causes the later buses to be duplicated in + * the SPI devices printout when running qtree. + */ + QLIST_INSERT_HEAD(&dev->child_bus, spi_bus, sibling); + } } static Property xlnx_zynqmp_props[] = { diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index d116092..f598a43 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -25,6 +25,7 @@ #include "hw/ide/pci.h" #include "hw/ide/ahci.h" #include "hw/sd/sdhci.h" +#include "hw/ssi/xilinx_spips.h" #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp" #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \ @@ -35,6 +36,7 @@ #define XLNX_ZYNQMP_NUM_GEMS 4 #define XLNX_ZYNQMP_NUM_UARTS 2 #define XLNX_ZYNQMP_NUM_SDHCI 2 +#define XLNX_ZYNQMP_NUM_SPIS 2 #define XLNX_ZYNQMP_NUM_OCM_BANKS 4 #define XLNX_ZYNQMP_OCM_RAM_0_ADDRESS 0xFFFC0000 @@ -66,6 +68,7 @@ typedef struct XlnxZynqMPState { CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS]; SysbusAHCIState sata; SDHCIState sdhci[XLNX_ZYNQMP_NUM_SDHCI]; + XilinxSPIPS spi[XLNX_ZYNQMP_NUM_SPIS]; char *boot_cpu; ARMCPU *boot_cpu_ptr; -- 2.5.0