diff options
| author | Luc Michel <luc.michel@amd.com> | 2025-09-26 09:07:29 +0200 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2025-10-07 10:35:36 +0100 |
| commit | 6532bc7cc7f5560b7782a2799d9d5f0ac2719c42 (patch) | |
| tree | 4fe7d884e397a39783e5649dd2f8cf9f241f4a5c /hw/arm/xlnx-versal.c | |
| parent | 98cb650c5cd73e28ec389373dcc7a656bf70368a (diff) | |
| download | focaccia-qemu-6532bc7cc7f5560b7782a2799d9d5f0ac2719c42.tar.gz focaccia-qemu-6532bc7cc7f5560b7782a2799d9d5f0ac2719c42.zip | |
hw/arm/xlnx-versal: ospi: refactor creation
Refactor the OSPI controller creation using the VersalMap structure. Note that the connection to the PMC IOU SLCR is removed for now and will be re-added by next commits. Signed-off-by: Luc Michel <luc.michel@amd.com> Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20250926070806.292065-12-luc.michel@amd.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/arm/xlnx-versal.c')
| -rw-r--r-- | hw/arm/xlnx-versal.c | 142 |
1 files changed, 81 insertions, 61 deletions
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c index f8291ac614..964250bf15 100644 --- a/hw/arm/xlnx-versal.c +++ b/hw/arm/xlnx-versal.c @@ -34,6 +34,7 @@ #include "hw/misc/xlnx-versal-xramc.h" #include "hw/usb/xlnx-usb-subsystem.h" #include "hw/nvram/xlnx-versal-efuse.h" +#include "hw/ssi/xlnx-versal-ospi.h" #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72") #define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f") @@ -95,6 +96,15 @@ typedef struct VersalMap { uint64_t cache; int irq; } efuse; + + struct VersalOspiMap { + uint64_t ctrl; + uint64_t dac; + uint64_t dac_sz; + uint64_t dma_src; + uint64_t dma_dst; + int irq; + } ospi; } VersalMap; static const VersalMap VERSAL_MAP = { @@ -128,6 +138,13 @@ static const VersalMap VERSAL_MAP = { .num_usb = 1, .efuse = { .ctrl = 0xf1240000, .cache = 0xf1250000, .irq = 139 }, + + .ospi = { + .ctrl = 0xf1010000, + .dac = 0xc0000000, .dac_sz = 0x20000000, + .dma_src = 0xf1011000, .dma_dst = 0xf1011800, + .irq = 124, + }, }; static const VersalMap *VERSION_TO_MAP[] = { @@ -815,95 +832,74 @@ static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic) qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2)); } -static void versal_create_ospi(Versal *s, qemu_irq *pic) +static DeviceState *versal_create_ospi(Versal *s, + const struct VersalOspiMap *map) { SysBusDevice *sbd; MemoryRegion *mr_dac; - qemu_irq ospi_mux_sel; - DeviceState *orgate; + DeviceState *dev, *dma_dst, *dma_src, *orgate; + MemoryRegion *linear_mr = g_new(MemoryRegion, 1); - memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s), - "versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE); + dev = qdev_new(TYPE_XILINX_VERSAL_OSPI); + object_property_add_child(OBJECT(s), "ospi", OBJECT(dev)); - object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi, - TYPE_XILINX_VERSAL_OSPI); + memory_region_init(linear_mr, OBJECT(dev), "linear-mr", map->dac_sz); - mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1); - memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac); + mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); + memory_region_add_subregion(linear_mr, 0x0, mr_dac); /* Create the OSPI destination DMA */ - object_initialize_child(OBJECT(s), "versal-ospi-dma-dst", - &s->pmc.iou.ospi.dma_dst, - TYPE_XLNX_CSU_DMA); - - object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst), - "dma", OBJECT(get_system_memory()), - &error_abort); + dma_dst = qdev_new(TYPE_XLNX_CSU_DMA); + object_property_add_child(OBJECT(dev), "dma-dst-dev", OBJECT(dma_dst)); + object_property_set_link(OBJECT(dma_dst), "dma", + OBJECT(get_system_memory()), &error_abort); - sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst); - sysbus_realize(sbd, &error_fatal); + sbd = SYS_BUS_DEVICE(dma_dst); + sysbus_realize_and_unref(sbd, &error_fatal); - memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST, + memory_region_add_subregion(&s->mr_ps, map->dma_dst, sysbus_mmio_get_region(sbd, 0)); /* Create the OSPI source DMA */ - object_initialize_child(OBJECT(s), "versal-ospi-dma-src", - &s->pmc.iou.ospi.dma_src, - TYPE_XLNX_CSU_DMA); + dma_src = qdev_new(TYPE_XLNX_CSU_DMA); + object_property_add_child(OBJECT(dev), "dma-src-dev", OBJECT(dma_src)); - object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst", - false, &error_abort); + object_property_set_bool(OBJECT(dma_src), "is-dst", false, &error_abort); - object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src), - "dma", OBJECT(mr_dac), &error_abort); - - object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src), - "stream-connected-dma", - OBJECT(&s->pmc.iou.ospi.dma_dst), + object_property_set_link(OBJECT(dma_src), "dma", OBJECT(mr_dac), &error_abort); - sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src); - sysbus_realize(sbd, &error_fatal); + object_property_set_link(OBJECT(dma_src), "stream-connected-dma", + OBJECT(dma_dst), &error_abort); - memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC, + sbd = SYS_BUS_DEVICE(dma_src); + sysbus_realize_and_unref(sbd, &error_fatal); + + memory_region_add_subregion(&s->mr_ps, map->dma_src, sysbus_mmio_get_region(sbd, 0)); /* Realize the OSPI */ - object_property_set_link(OBJECT(&s->pmc.iou.ospi.ospi), "dma-src", - OBJECT(&s->pmc.iou.ospi.dma_src), &error_abort); + object_property_set_link(OBJECT(dev), "dma-src", + OBJECT(dma_src), &error_abort); - sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi); - sysbus_realize(sbd, &error_fatal); + sbd = SYS_BUS_DEVICE(dev); + sysbus_realize_and_unref(sbd, &error_fatal); - memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI, + memory_region_add_subregion(&s->mr_ps, map->ctrl, sysbus_mmio_get_region(sbd, 0)); - memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC, - &s->pmc.iou.ospi.linear_mr); - - /* ospi_mux_sel */ - ospi_mux_sel = qdev_get_gpio_in_named(DEVICE(&s->pmc.iou.ospi.ospi), - "ospi-mux-sel", 0); - qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "ospi-mux-sel", 0, - ospi_mux_sel); + memory_region_add_subregion(&s->mr_ps, map->dac, + linear_mr); /* OSPI irq */ - object_initialize_child(OBJECT(s), "ospi-irq-orgate", - &s->pmc.iou.ospi.irq_orgate, TYPE_OR_IRQ); - object_property_set_int(OBJECT(&s->pmc.iou.ospi.irq_orgate), - "num-lines", NUM_OSPI_IRQ_LINES, &error_fatal); + orgate = create_or_gate(s, OBJECT(dev), "irq-orgate", NUM_OSPI_IRQ_LINES, + map->irq); - orgate = DEVICE(&s->pmc.iou.ospi.irq_orgate); - qdev_realize(orgate, NULL, &error_fatal); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(orgate, 0)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma_src), 0, qdev_get_gpio_in(orgate, 1)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma_dst), 0, qdev_get_gpio_in(orgate, 2)); - sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 0, - qdev_get_gpio_in(orgate, 0)); - sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src), 0, - qdev_get_gpio_in(orgate, 1)); - sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst), 0, - qdev_get_gpio_in(orgate, 2)); - - qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]); + return dev; } static void versal_create_cfu(Versal *s, qemu_irq *pic) @@ -1266,13 +1262,13 @@ static void versal_realize(DeviceState *dev, Error **errp) } versal_create_efuse(s, &map->efuse); + versal_create_ospi(s, &map->ospi); versal_create_pmc_apb_irq_orgate(s, pic); versal_create_rtc(s, pic); versal_create_trng(s, pic); versal_create_bbram(s, pic); versal_create_pmc_iou_slcr(s, pic); - versal_create_ospi(s, pic); versal_create_crl(s, pic); versal_create_cfu(s, pic); versal_map_ddr(s); @@ -1318,6 +1314,30 @@ void versal_efuse_attach_drive(Versal *s, BlockBackend *blk) qdev_prop_set_drive(efuse, "drive", blk); } +void versal_ospi_create_flash(Versal *s, int flash_idx, const char *flash_mdl, + BlockBackend *blk) +{ + BusState *spi_bus; + DeviceState *flash, *ospi; + qemu_irq cs_line; + + ospi = DEVICE(versal_get_child(s, "ospi")); + spi_bus = qdev_get_child_bus(ospi, "spi0"); + + flash = qdev_new(flash_mdl); + + if (blk) { + qdev_prop_set_drive_err(flash, "drive", blk, &error_fatal); + } + qdev_prop_set_uint8(flash, "cs", flash_idx); + qdev_realize_and_unref(flash, spi_bus, &error_fatal); + + cs_line = qdev_get_gpio_in_named(flash, SSI_GPIO_CS, 0); + + sysbus_connect_irq(SYS_BUS_DEVICE(ospi), + flash_idx + 1, cs_line); +} + int versal_get_num_can(VersalVersion version) { const VersalMap *map = VERSION_TO_MAP[version]; |