On Wed, Jul 16, 2025 at 11:53:53AM +0200, Luc Michel wrote:
> Refactore the eFuse devices creation using the VersalMap structure.
> 
> Note that the corresponding FDT nodes are removed. They do not
> correspond to any real node in standard Versal DTBs. No matching drivers
> exist for them.
> 
> Signed-off-by: Luc Michel <luc.mic...@amd.com>

Reviewed-by: Francisco Iglesias <francisco.igles...@amd.com>

> ---
>  include/hw/arm/xlnx-versal.h |  5 +--
>  hw/arm/xlnx-versal-virt.c    | 43 ++------------------
>  hw/arm/xlnx-versal.c         | 78 +++++++++++++++++++++++-------------
>  3 files changed, 54 insertions(+), 72 deletions(-)
> 
> diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
> index 5d4b30f0ff9..79ca9b13321 100644
> --- a/include/hw/arm/xlnx-versal.h
> +++ b/include/hw/arm/xlnx-versal.h
> @@ -18,11 +18,10 @@
>  #include "hw/or-irq.h"
>  #include "hw/intc/arm_gicv3.h"
>  #include "hw/rtc/xlnx-zynqmp-rtc.h"
>  #include "qom/object.h"
>  #include "hw/nvram/xlnx-bbram.h"
> -#include "hw/nvram/xlnx-versal-efuse.h"
>  #include "hw/ssi/xlnx-versal-ospi.h"
>  #include "hw/dma/xlnx_csu_dma.h"
>  #include "hw/misc/xlnx-versal-crl.h"
>  #include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
>  #include "hw/misc/xlnx-versal-trng.h"
> @@ -100,13 +99,10 @@ struct Versal {
>          } iou;
>  
>          XlnxZynqMPRTC rtc;
>          XlnxVersalTRng trng;
>          XlnxBBRam bbram;
> -        XlnxEFuse efuse;
> -        XlnxVersalEFuseCtrl efuse_ctrl;
> -        XlnxVersalEFuseCache efuse_cache;
>          XlnxVersalCFUAPB cfu_apb;
>          XlnxVersalCFUFDRO cfu_fdro;
>          XlnxVersalCFUSFR cfu_sfr;
>          XlnxVersalCFrameReg cframe[XLNX_VERSAL_NR_CFRAME];
>          XlnxVersalCFrameBcastReg cframe_bcast;
> @@ -137,10 +133,11 @@ static inline void versal_set_fdt(Versal *s, void *fdt)
>      g_assert(!qdev_is_realized(DEVICE(s)));
>      s->cfg.fdt = fdt;
>  }
>  
>  void versal_sdhci_plug_card(Versal *s, int sd_idx, BlockBackend *blk);
> +void versal_efuse_attach_drive(Versal *s, BlockBackend *blk);
>  
>  int versal_get_num_can(VersalVersion version);
>  int versal_get_num_sdhci(VersalVersion version);
>  
>  /* Memory-map and IRQ definitions. Copied a subset from
> diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
> index 36341b825eb..d3c84d1955a 100644
> --- a/hw/arm/xlnx-versal-virt.c
> +++ b/hw/arm/xlnx-versal-virt.c
> @@ -190,45 +190,10 @@ static void fdt_add_bbram_node(VersalVirt *s)
>                                   2, MM_PMC_BBRAM_CTRL_SIZE);
>      qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
>      g_free(name);
>  }
>  
> -static void fdt_add_efuse_ctrl_node(VersalVirt *s)
> -{
> -    const char compat[] = TYPE_XLNX_VERSAL_EFUSE_CTRL;
> -    const char interrupt_names[] = "pmc_efuse";
> -    char *name = g_strdup_printf("/pmc_efuse@%x", MM_PMC_EFUSE_CTRL);
> -
> -    qemu_fdt_add_subnode(s->fdt, name);
> -
> -    qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
> -                           GIC_FDT_IRQ_TYPE_SPI, VERSAL_EFUSE_IRQ,
> -                           GIC_FDT_IRQ_FLAGS_LEVEL_HI);
> -    qemu_fdt_setprop(s->fdt, name, "interrupt-names",
> -                     interrupt_names, sizeof(interrupt_names));
> -    qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
> -                                 2, MM_PMC_EFUSE_CTRL,
> -                                 2, MM_PMC_EFUSE_CTRL_SIZE);
> -    qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
> -    g_free(name);
> -}
> -
> -static void fdt_add_efuse_cache_node(VersalVirt *s)
> -{
> -    const char compat[] = TYPE_XLNX_VERSAL_EFUSE_CACHE;
> -    char *name = g_strdup_printf("/xlnx_pmc_efuse_cache@%x",
> -                                 MM_PMC_EFUSE_CACHE);
> -
> -    qemu_fdt_add_subnode(s->fdt, name);
> -
> -    qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
> -                                 2, MM_PMC_EFUSE_CACHE,
> -                                 2, MM_PMC_EFUSE_CACHE_SIZE);
> -    qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
> -    g_free(name);
> -}
> -
>  static void fdt_nop_memory_nodes(void *fdt, Error **errp)
>  {
>      Error *err = NULL;
>      char **node_path;
>      int n = 0;
> @@ -391,19 +356,19 @@ static void bbram_attach_drive(XlnxBBRam *dev)
>      if (blk) {
>          qdev_prop_set_drive(DEVICE(dev), "drive", blk);
>      }
>  }
>  
> -static void efuse_attach_drive(XlnxEFuse *dev)
> +static void efuse_attach_drive(VersalVirt *s)
>  {
>      DriveInfo *dinfo;
>      BlockBackend *blk;
>  
>      dinfo = drive_get_by_index(IF_PFLASH, 1);
>      blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
>      if (blk) {
> -        qdev_prop_set_drive(DEVICE(dev), "drive", blk);
> +        versal_efuse_attach_drive(&s->soc, blk);
>      }
>  }
>  
>  static void sd_plug_card(VersalVirt *s, int idx, DriveInfo *di)
>  {
> @@ -478,12 +443,10 @@ static void versal_virt_init(MachineState *machine)
>      versal_set_fdt(&s->soc, s->fdt);
>      fdt_add_gic_nodes(s);
>      fdt_add_timer_nodes(s);
>      fdt_add_rtc_node(s);
>      fdt_add_bbram_node(s);
> -    fdt_add_efuse_ctrl_node(s);
> -    fdt_add_efuse_cache_node(s);
>      fdt_add_cpu_nodes(s, psci_conduit);
>      fdt_add_clk_node(s, "/old-clk125", 125000000, s->phandle.clk_125Mhz);
>      fdt_add_clk_node(s, "/old-clk25", 25000000, s->phandle.clk_25Mhz);
>  
>      sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal);
> @@ -496,11 +459,11 @@ static void versal_virt_init(MachineState *machine)
>  
>      /* Attach bbram backend, if given */
>      bbram_attach_drive(&s->soc.pmc.bbram);
>  
>      /* Attach efuse backend, if given */
> -    efuse_attach_drive(&s->soc.pmc.efuse);
> +    efuse_attach_drive(s);
>  
>      /* Plug SD cards */
>      for (i = 0; i < versal_get_num_sdhci(VERSAL_VER_VERSAL); i++) {
>          sd_plug_card(s, i, drive_get(IF_SD, 0, i));
>      }
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> index 4e4df0851e8..ed202b0fcda 100644
> --- a/hw/arm/xlnx-versal.c
> +++ b/hw/arm/xlnx-versal.c
> @@ -31,10 +31,11 @@
>  #include "hw/sd/sdhci.h"
>  #include "hw/net/cadence_gem.h"
>  #include "hw/dma/xlnx-zdma.h"
>  #include "hw/misc/xlnx-versal-xramc.h"
>  #include "hw/usb/xlnx-usb-subsystem.h"
> +#include "hw/nvram/xlnx-versal-efuse.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
>  
> @@ -86,10 +87,16 @@ typedef struct VersalMap {
>          uint64_t xhci;
>          uint64_t ctrl;
>          int irq;
>      } usb[2];
>      size_t num_usb;
> +
> +    struct VersalEfuseMap {
> +        uint64_t ctrl;
> +        uint64_t cache;
> +        int irq;
> +    } efuse;
>  } VersalMap;
>  
>  static const VersalMap VERSAL_MAP = {
>      .uart[0] = { 0xff000000, 18 },
>      .uart[1] = { 0xff010000, 19 },
> @@ -117,10 +124,12 @@ static const VersalMap VERSAL_MAP = {
>          .irq = 79,
>      },
>  
>      .usb[0] = { .xhci = 0xfe200000, .ctrl = 0xff9d0000, .irq = 22 },
>      .num_usb = 1,
> +
> +    .efuse = { .ctrl = 0xf1240000, .cache = 0xf1250000, .irq = 139 },
>  };
>  
>  static const VersalMap *VERSION_TO_MAP[] = {
>      [VERSAL_VER_VERSAL] = &VERSAL_MAP,
>  };
> @@ -744,46 +753,45 @@ static void versal_create_bbram(Versal *s, qemu_irq 
> *pic)
>                                  sysbus_mmio_get_region(sbd, 0));
>      sysbus_connect_irq(sbd, 0,
>                         qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1));
>  }
>  
> -static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base)
> +static void versal_create_efuse(Versal *s,
> +                                const struct VersalEfuseMap *map)
>  {
> -    SysBusDevice *part = SYS_BUS_DEVICE(dev);
> +    DeviceState *bits;
> +    DeviceState *ctrl;
> +    DeviceState *cache;
>  
> -    object_property_set_link(OBJECT(part), "efuse",
> -                             OBJECT(&s->pmc.efuse), &error_abort);
> +    ctrl = qdev_new(TYPE_XLNX_VERSAL_EFUSE_CTRL);
> +    cache = qdev_new(TYPE_XLNX_VERSAL_EFUSE_CACHE);
> +    bits = qdev_new(TYPE_XLNX_EFUSE);
>  
> -    sysbus_realize(part, &error_abort);
> -    memory_region_add_subregion(&s->mr_ps, base,
> -                                sysbus_mmio_get_region(part, 0));
> -}
> +    qdev_prop_set_uint32(bits, "efuse-nr", 3);
> +    qdev_prop_set_uint32(bits, "efuse-size", 8192);
>  
> -static void versal_create_efuse(Versal *s, qemu_irq *pic)
> -{
> -    Object *bits = OBJECT(&s->pmc.efuse);
> -    Object *ctrl = OBJECT(&s->pmc.efuse_ctrl);
> -    Object *cache = OBJECT(&s->pmc.efuse_cache);
> +    object_property_add_child(OBJECT(s), "efuse", OBJECT(bits));
> +    qdev_realize_and_unref(bits, NULL, &error_abort);
>  
> -    object_initialize_child(OBJECT(s), "efuse-ctrl", &s->pmc.efuse_ctrl,
> -                            TYPE_XLNX_VERSAL_EFUSE_CTRL);
> +    object_property_set_link(OBJECT(ctrl), "efuse", OBJECT(bits), 
> &error_abort);
>  
> -    object_initialize_child(OBJECT(s), "efuse-cache", &s->pmc.efuse_cache,
> -                            TYPE_XLNX_VERSAL_EFUSE_CACHE);
> +    object_property_set_link(OBJECT(cache), "efuse", OBJECT(bits),
> +                             &error_abort);
>  
> -    object_initialize_child_with_props(ctrl, "xlnx-efuse@0", bits,
> -                                       sizeof(s->pmc.efuse),
> -                                       TYPE_XLNX_EFUSE, &error_abort,
> -                                       "efuse-nr", "3",
> -                                       "efuse-size", "8192",
> -                                       NULL);
> +    object_property_add_child(OBJECT(s), "efuse-cache", OBJECT(cache));
> +    sysbus_realize_and_unref(SYS_BUS_DEVICE(cache), &error_abort);
>  
> -    qdev_realize(DEVICE(bits), NULL, &error_abort);
> -    versal_realize_efuse_part(s, ctrl, MM_PMC_EFUSE_CTRL);
> -    versal_realize_efuse_part(s, cache, MM_PMC_EFUSE_CACHE);
> +    object_property_add_child(OBJECT(s), "efuse-ctrl", OBJECT(ctrl));
> +    sysbus_realize_and_unref(SYS_BUS_DEVICE(ctrl), &error_abort);
>  
> -    sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
> +    memory_region_add_subregion(&s->mr_ps, map->ctrl,
> +                                sysbus_mmio_get_region(SYS_BUS_DEVICE(ctrl),
> +                                                       0));
> +    memory_region_add_subregion(&s->mr_ps, map->cache,
> +                                sysbus_mmio_get_region(SYS_BUS_DEVICE(cache),
> +                                                       0));
> +    versal_sysbus_connect_irq(s, SYS_BUS_DEVICE(ctrl), 0, map->irq);
>  }
>  
>  static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
>  {
>      SysBusDevice *sbd;
> @@ -1247,15 +1255,16 @@ static void versal_realize(DeviceState *dev, Error 
> **errp)
>  
>      for (i = 0; i < map->num_usb; i++) {
>          versal_create_usb(s, &map->usb[i]);
>      }
>  
> +    versal_create_efuse(s, &map->efuse);
> +
>      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_efuse(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);
> @@ -1286,10 +1295,23 @@ void versal_sdhci_plug_card(Versal *s, int sd_idx, 
> BlockBackend *blk)
>      qdev_prop_set_drive_err(card, "drive", blk, &error_fatal);
>      qdev_realize_and_unref(card, qdev_get_child_bus(DEVICE(sdhci), "sd-bus"),
>                             &error_fatal);
>  }
>  
> +void versal_efuse_attach_drive(Versal *s, BlockBackend *blk)
> +{
> +    DeviceState *efuse;
> +
> +    efuse = DEVICE(versal_get_child(s, "efuse"));
> +
> +    if (efuse == NULL) {
> +        return;
> +    }
> +
> +    qdev_prop_set_drive(efuse, "drive", blk);
> +}
> +
>  int versal_get_num_can(VersalVersion version)
>  {
>      const VersalMap *map = VERSION_TO_MAP[version];
>  
>      return map->num_canfd;
> -- 
> 2.50.0
> 

Reply via email to