Refactor the CFU device creation using the VersalMap structure. All users of the APB IRQ OR gate have now been converted. The OR gate device can be dropped.
Signed-off-by: Luc Michel <luc.mic...@amd.com> --- include/hw/arm/xlnx-versal.h | 14 -- hw/arm/xlnx-versal.c | 258 ++++++++++++++++------------------- 2 files changed, 115 insertions(+), 157 deletions(-) diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h index abdbed15689..5a685aea6d4 100644 --- a/include/hw/arm/xlnx-versal.h +++ b/include/hw/arm/xlnx-versal.h @@ -13,17 +13,14 @@ #ifndef XLNX_VERSAL_H #define XLNX_VERSAL_H #include "hw/sysbus.h" #include "hw/cpu/cluster.h" -#include "hw/or-irq.h" #include "hw/intc/arm_gicv3.h" #include "qom/object.h" #include "hw/misc/xlnx-versal-crl.h" #include "net/can_emu.h" -#include "hw/misc/xlnx-versal-cfu.h" -#include "hw/misc/xlnx-versal-cframe-reg.h" #include "target/arm/cpu.h" #include "hw/arm/xlnx-versal-version.h" #define TYPE_XLNX_VERSAL_BASE "xlnx-versal-base" OBJECT_DECLARE_TYPE(Versal, VersalClass, XLNX_VERSAL_BASE) @@ -76,21 +73,10 @@ struct Versal { } rpu; XlnxVersalCRL crl; } lpd; - /* The Platform Management Controller subsystem. */ - struct { - XlnxVersalCFUAPB cfu_apb; - XlnxVersalCFUFDRO cfu_fdro; - XlnxVersalCFUSFR cfu_sfr; - XlnxVersalCFrameReg cframe[XLNX_VERSAL_NR_CFRAME]; - XlnxVersalCFrameBcastReg cframe_bcast; - - OrIRQState apb_irq_orgate; - } pmc; - struct { uint32_t clk_25mhz; uint32_t clk_125mhz; } phandle; diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c index 41965531f8d..2128dbbad92 100644 --- a/hw/arm/xlnx-versal.c +++ b/hw/arm/xlnx-versal.c @@ -37,10 +37,13 @@ #include "hw/ssi/xlnx-versal-ospi.h" #include "hw/misc/xlnx-versal-pmc-iou-slcr.h" #include "hw/nvram/xlnx-bbram.h" #include "hw/misc/xlnx-versal-trng.h" #include "hw/rtc/xlnx-zynqmp-rtc.h" +#include "hw/misc/xlnx-versal-cfu.h" +#include "hw/misc/xlnx-versal-cframe-reg.h" +#include "hw/or-irq.h" #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72") #define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f") #define GEM_REVISION 0x40070106 @@ -128,10 +131,28 @@ typedef struct VersalMap { struct VersalRtcMap { VersalSimplePeriphMap map; int alarm_irq; int second_irq; } rtc; + + struct VersalCfuMap { + uint64_t cframe_base; + uint64_t cframe_stride; + uint64_t cfu_fdro; + uint64_t cframe_bcast_reg; + uint64_t cframe_bcast_fdri; + uint64_t cfu_apb; + uint64_t cfu_stream; + uint64_t cfu_stream_2; + uint64_t cfu_sfr; + int cfu_apb_irq; + int cframe_irq; + size_t num_cframe; + struct VersalCfuCframeCfg { + uint32_t blktype_frames[7]; + } cframe_cfg[15]; + } cfu; } VersalMap; static const VersalMap VERSAL_MAP = { .uart[0] = { 0xff000000, 18 }, .uart[1] = { 0xff010000, 19 }, @@ -176,10 +197,26 @@ static const VersalMap VERSAL_MAP = { .trng = { 0xf1230000, 141 }, .rtc = { { 0xf12a0000, OR_IRQ(121, 2) }, .alarm_irq = 142, .second_irq = 143 }, + + .cfu = { + .cframe_base = 0xf12d0000, .cframe_stride = 0x1000, + .cframe_bcast_reg = 0xf12ee000, .cframe_bcast_fdri = 0xf12ef000, + .cfu_apb = 0xf12b0000, .cfu_sfr = 0xf12c1000, + .cfu_stream = 0xf12c0000, .cfu_stream_2 = 0xf1f80000, + .cfu_fdro = 0xf12c2000, + .cfu_apb_irq = 120, .cframe_irq = OR_IRQ(121, 3), + .num_cframe = 15, + .cframe_cfg = { + { { 34111, 3528, 12800, 11, 5, 1, 1 } }, + { { 38498, 3841, 15361, 13, 7, 3, 1 } }, + { { 38498, 3841, 15361, 13, 7, 3, 1 } }, + { { 38498, 3841, 15361, 13, 7, 3, 1 } }, + }, + }, }; static const VersalMap *VERSION_TO_MAP[] = { [VERSAL_VER_VERSAL] = &VERSAL_MAP, }; @@ -743,31 +780,10 @@ static void versal_create_sdhci(Versal *s, qemu_fdt_setprop_cells(s->cfg.fdt, node, "interrupts", GIC_FDT_IRQ_TYPE_SPI, map->irq, GIC_FDT_IRQ_FLAGS_LEVEL_HI); } -static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic) -{ - DeviceState *orgate; - - /* - * The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following - * models: - * - RTC - * - BBRAM - * - PMC SLCR - * - CFRAME regs (input 3 - 17 to the orgate) - */ - object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate", - &s->pmc.apb_irq_orgate, TYPE_OR_IRQ); - orgate = DEVICE(&s->pmc.apb_irq_orgate); - object_property_set_int(OBJECT(orgate), - "num-lines", VERSAL_NUM_PMC_APB_IRQS, &error_fatal); - qdev_realize(orgate, NULL, &error_fatal); - qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]); -} - static void versal_create_rtc(Versal *s, const struct VersalRtcMap *map) { SysBusDevice *sbd; MemoryRegion *mr; g_autofree char *node; @@ -982,158 +998,115 @@ static DeviceState *versal_create_ospi(Versal *s, sysbus_connect_irq(SYS_BUS_DEVICE(dma_dst), 0, qdev_get_gpio_in(orgate, 2)); return dev; } -static void versal_create_cfu(Versal *s, qemu_irq *pic) +static void versal_create_cfu(Versal *s, const struct VersalCfuMap *map) { SysBusDevice *sbd; - DeviceState *dev; + Object *container; + DeviceState *cfu_fdro, *cfu_apb, *cfu_sfr, *cframe_bcast; + DeviceState *cframe_irq_or; int i; - const struct { + + container = object_new(TYPE_CONTAINER); + object_property_add_child(OBJECT(s), "cfu", container); + object_unref(container); + + /* CFU FDRO */ + cfu_fdro = qdev_new(TYPE_XLNX_VERSAL_CFU_FDRO); + object_property_add_child(container, "cfu-fdro", OBJECT(cfu_fdro)); + sbd = SYS_BUS_DEVICE(cfu_fdro); + + sysbus_realize_and_unref(sbd, &error_fatal); + memory_region_add_subregion(&s->mr_ps, map->cfu_fdro, + sysbus_mmio_get_region(sbd, 0)); + + /* cframe bcast */ + cframe_bcast = qdev_new(TYPE_XLNX_VERSAL_CFRAME_BCAST_REG); + object_property_add_child(container, "cframe-bcast", OBJECT(cframe_bcast)); + + /* CFU APB */ + cfu_apb = qdev_new(TYPE_XLNX_VERSAL_CFU_APB); + object_property_add_child(container, "cfu-apb", OBJECT(cfu_apb)); + + /* IRQ or gate for cframes */ + cframe_irq_or = qdev_new(TYPE_OR_IRQ); + object_property_add_child(container, "cframe-irq-or-gate", + OBJECT(cframe_irq_or)); + qdev_prop_set_uint16(cframe_irq_or, "num-lines", map->num_cframe); + qdev_realize_and_unref(cframe_irq_or, NULL, &error_abort); + versal_qdev_connect_gpio_out(s, cframe_irq_or, 0, map->cframe_irq); + + /* cframe reg */ + for (i = 0; i < map->num_cframe; i++) { uint64_t reg_base; uint64_t fdri_base; - } cframe_addr[] = { - { MM_PMC_CFRAME0_REG, MM_PMC_CFRAME0_FDRI }, - { MM_PMC_CFRAME1_REG, MM_PMC_CFRAME1_FDRI }, - { MM_PMC_CFRAME2_REG, MM_PMC_CFRAME2_FDRI }, - { MM_PMC_CFRAME3_REG, MM_PMC_CFRAME3_FDRI }, - { MM_PMC_CFRAME4_REG, MM_PMC_CFRAME4_FDRI }, - { MM_PMC_CFRAME5_REG, MM_PMC_CFRAME5_FDRI }, - { MM_PMC_CFRAME6_REG, MM_PMC_CFRAME6_FDRI }, - { MM_PMC_CFRAME7_REG, MM_PMC_CFRAME7_FDRI }, - { MM_PMC_CFRAME8_REG, MM_PMC_CFRAME8_FDRI }, - { MM_PMC_CFRAME9_REG, MM_PMC_CFRAME9_FDRI }, - { MM_PMC_CFRAME10_REG, MM_PMC_CFRAME10_FDRI }, - { MM_PMC_CFRAME11_REG, MM_PMC_CFRAME11_FDRI }, - { MM_PMC_CFRAME12_REG, MM_PMC_CFRAME12_FDRI }, - { MM_PMC_CFRAME13_REG, MM_PMC_CFRAME13_FDRI }, - { MM_PMC_CFRAME14_REG, MM_PMC_CFRAME14_FDRI }, - }; - const struct { - uint32_t blktype0_frames; - uint32_t blktype1_frames; - uint32_t blktype2_frames; - uint32_t blktype3_frames; - uint32_t blktype4_frames; - uint32_t blktype5_frames; - uint32_t blktype6_frames; - } cframe_cfg[] = { - [0] = { 34111, 3528, 12800, 11, 5, 1, 1 }, - [1] = { 38498, 3841, 15361, 13, 7, 3, 1 }, - [2] = { 38498, 3841, 15361, 13, 7, 3, 1 }, - [3] = { 38498, 3841, 15361, 13, 7, 3, 1 }, - }; + DeviceState *dev; + g_autofree char *prop_name; + size_t j; - /* CFU FDRO */ - object_initialize_child(OBJECT(s), "cfu-fdro", &s->pmc.cfu_fdro, - TYPE_XLNX_VERSAL_CFU_FDRO); - sbd = SYS_BUS_DEVICE(&s->pmc.cfu_fdro); + dev = qdev_new(TYPE_XLNX_VERSAL_CFRAME_REG); + object_property_add_child(container, "cframe[*]", OBJECT(dev)); - sysbus_realize(sbd, &error_fatal); - memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_FDRO, - sysbus_mmio_get_region(sbd, 0)); + sbd = SYS_BUS_DEVICE(dev); - /* CFRAME REG */ - for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) { - g_autofree char *name = g_strdup_printf("cframe%d", i); + for (j = 0; j < ARRAY_SIZE(map->cframe_cfg[i].blktype_frames); j++) { + g_autofree char *blktype_prop_name; - object_initialize_child(OBJECT(s), name, &s->pmc.cframe[i], - TYPE_XLNX_VERSAL_CFRAME_REG); - - sbd = SYS_BUS_DEVICE(&s->pmc.cframe[i]); - dev = DEVICE(&s->pmc.cframe[i]); - - if (i < ARRAY_SIZE(cframe_cfg)) { - object_property_set_int(OBJECT(dev), "blktype0-frames", - cframe_cfg[i].blktype0_frames, - &error_abort); - object_property_set_int(OBJECT(dev), "blktype1-frames", - cframe_cfg[i].blktype1_frames, - &error_abort); - object_property_set_int(OBJECT(dev), "blktype2-frames", - cframe_cfg[i].blktype2_frames, - &error_abort); - object_property_set_int(OBJECT(dev), "blktype3-frames", - cframe_cfg[i].blktype3_frames, - &error_abort); - object_property_set_int(OBJECT(dev), "blktype4-frames", - cframe_cfg[i].blktype4_frames, - &error_abort); - object_property_set_int(OBJECT(dev), "blktype5-frames", - cframe_cfg[i].blktype5_frames, - &error_abort); - object_property_set_int(OBJECT(dev), "blktype6-frames", - cframe_cfg[i].blktype6_frames, + blktype_prop_name = g_strdup_printf("blktype%zu-frames", j); + object_property_set_int(OBJECT(dev), blktype_prop_name, + map->cframe_cfg[i].blktype_frames[j], &error_abort); } + object_property_set_link(OBJECT(dev), "cfu-fdro", - OBJECT(&s->pmc.cfu_fdro), &error_fatal); + OBJECT(cfu_fdro), &error_abort); - sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_abort); - memory_region_add_subregion(&s->mr_ps, cframe_addr[i].reg_base, + reg_base = map->cframe_base + i * map->cframe_stride * 2; + fdri_base = reg_base + map->cframe_stride; + memory_region_add_subregion(&s->mr_ps, reg_base, sysbus_mmio_get_region(sbd, 0)); - memory_region_add_subregion(&s->mr_ps, cframe_addr[i].fdri_base, + memory_region_add_subregion(&s->mr_ps, fdri_base, sysbus_mmio_get_region(sbd, 1)); - sysbus_connect_irq(sbd, 0, - qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), - 3 + i)); - } - - /* CFRAME BCAST */ - object_initialize_child(OBJECT(s), "cframe_bcast", &s->pmc.cframe_bcast, - TYPE_XLNX_VERSAL_CFRAME_BCAST_REG); + sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(cframe_irq_or, i)); - sbd = SYS_BUS_DEVICE(&s->pmc.cframe_bcast); - dev = DEVICE(&s->pmc.cframe_bcast); - - for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) { - g_autofree char *propname = g_strdup_printf("cframe%d", i); - object_property_set_link(OBJECT(dev), propname, - OBJECT(&s->pmc.cframe[i]), &error_fatal); + prop_name = g_strdup_printf("cframe%d", i); + object_property_set_link(OBJECT(cframe_bcast), prop_name, + OBJECT(dev), &error_abort); + object_property_set_link(OBJECT(cfu_apb), prop_name, + OBJECT(dev), &error_abort); } - sysbus_realize(sbd, &error_fatal); - - memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_REG, + sbd = SYS_BUS_DEVICE(cframe_bcast); + sysbus_realize_and_unref(sbd, &error_abort); + memory_region_add_subregion(&s->mr_ps, map->cframe_bcast_reg, sysbus_mmio_get_region(sbd, 0)); - memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_FDRI, + memory_region_add_subregion(&s->mr_ps, map->cframe_bcast_fdri, sysbus_mmio_get_region(sbd, 1)); - /* CFU APB */ - object_initialize_child(OBJECT(s), "cfu-apb", &s->pmc.cfu_apb, - TYPE_XLNX_VERSAL_CFU_APB); - sbd = SYS_BUS_DEVICE(&s->pmc.cfu_apb); - dev = DEVICE(&s->pmc.cfu_apb); - - for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) { - g_autofree char *propname = g_strdup_printf("cframe%d", i); - object_property_set_link(OBJECT(dev), propname, - OBJECT(&s->pmc.cframe[i]), &error_fatal); - } - - sysbus_realize(sbd, &error_fatal); - memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_APB, + sbd = SYS_BUS_DEVICE(cfu_apb); + sysbus_realize_and_unref(sbd, &error_fatal); + memory_region_add_subregion(&s->mr_ps, map->cfu_apb, sysbus_mmio_get_region(sbd, 0)); - memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM, + memory_region_add_subregion(&s->mr_ps, map->cfu_stream, sysbus_mmio_get_region(sbd, 1)); - memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM_2, + memory_region_add_subregion(&s->mr_ps, map->cfu_stream_2, sysbus_mmio_get_region(sbd, 2)); - sysbus_connect_irq(sbd, 0, pic[VERSAL_CFU_IRQ_0]); + versal_sysbus_connect_irq(s, sbd, 0, map->cfu_apb_irq); /* CFU SFR */ - object_initialize_child(OBJECT(s), "cfu-sfr", &s->pmc.cfu_sfr, - TYPE_XLNX_VERSAL_CFU_SFR); + cfu_sfr = qdev_new(TYPE_XLNX_VERSAL_CFU_SFR); + object_property_add_child(container, "cfu-sfr", OBJECT(cfu_sfr)); + sbd = SYS_BUS_DEVICE(cfu_sfr); - sbd = SYS_BUS_DEVICE(&s->pmc.cfu_sfr); - - object_property_set_link(OBJECT(&s->pmc.cfu_sfr), - "cfu", OBJECT(&s->pmc.cfu_apb), &error_abort); - - sysbus_realize(sbd, &error_fatal); - memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_SFR, + object_property_set_link(OBJECT(cfu_sfr), + "cfu", OBJECT(cfu_apb), &error_abort); + sysbus_realize_and_unref(sbd, &error_fatal); + memory_region_add_subregion(&s->mr_ps, map->cfu_sfr, sysbus_mmio_get_region(sbd, 0)); } static void versal_create_crl(Versal *s, qemu_irq *pic) { @@ -1353,14 +1326,13 @@ static void versal_realize(DeviceState *dev, Error **errp) "ospi-mux-sel", 0)); versal_create_bbram(s, &map->bbram); versal_create_trng(s, &map->trng); versal_create_rtc(s, &map->rtc); + versal_create_cfu(s, &map->cfu); - versal_create_pmc_apb_irq_orgate(s, pic); versal_create_crl(s, pic); - versal_create_cfu(s, pic); versal_map_ddr(s); versal_unimp(s); /* Create the On Chip Memory (OCM). */ memory_region_init_ram(&s->lpd.mr_ocm, OBJECT(s), "ocm", -- 2.50.0