diff options
| author | Luc Michel <luc.michel@amd.com> | 2025-09-26 09:07:54 +0200 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2025-10-07 10:35:36 +0100 |
| commit | 00580a9d715138ec1560b91c596dedee07286fee (patch) | |
| tree | 8076140b97959f3ab982b35ffc74adaa4440abd9 /hw/misc/xlnx-versal-crl.c | |
| parent | 4707024bc3362f4b9859214357a687b9154c84cf (diff) | |
| download | focaccia-qemu-00580a9d715138ec1560b91c596dedee07286fee.tar.gz focaccia-qemu-00580a9d715138ec1560b91c596dedee07286fee.zip | |
hw/misc/xlnx-versal-crl: add the versal2 version
Add the versal2 version of the CRL device. For the implemented part, it is similar to the versal version but drives reset line of more devices. Signed-off-by: Luc Michel <luc.michel@amd.com> Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20250926070806.292065-37-luc.michel@amd.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/misc/xlnx-versal-crl.c')
| -rw-r--r-- | hw/misc/xlnx-versal-crl.c | 392 |
1 files changed, 392 insertions, 0 deletions
diff --git a/hw/misc/xlnx-versal-crl.c b/hw/misc/xlnx-versal-crl.c index 6225a92e0b..10e6af002b 100644 --- a/hw/misc/xlnx-versal-crl.c +++ b/hw/misc/xlnx-versal-crl.c @@ -85,6 +85,51 @@ static DeviceState **versal_decode_periph_rst(XlnxVersalCRLBase *s, default: /* invalid or unimplemented */ + g_assert_not_reached(); + } +} + +static DeviceState **versal2_decode_periph_rst(XlnxVersalCRLBase *s, + hwaddr addr, size_t *count) +{ + size_t idx; + XlnxVersal2CRL *xvc = XLNX_VERSAL2_CRL(s); + + *count = 1; + + switch (addr) { + case A_VERSAL2_RST_RPU_A ... A_VERSAL2_RST_RPU_E: + idx = (addr - A_VERSAL2_RST_RPU_A) / sizeof(uint32_t); + idx *= 2; /* two RPUs per RST_RPU_x registers */ + return xvc->cfg.rpu + idx; + + case A_VERSAL2_RST_ADMA: + /* A single register fans out to all DMA reset inputs */ + *count = ARRAY_SIZE(xvc->cfg.adma); + return xvc->cfg.adma; + + case A_VERSAL2_RST_SDMA: + *count = ARRAY_SIZE(xvc->cfg.sdma); + return xvc->cfg.sdma; + + case A_VERSAL2_RST_UART0 ... A_VERSAL2_RST_UART1: + idx = (addr - A_VERSAL2_RST_UART0) / sizeof(uint32_t); + return xvc->cfg.uart + idx; + + case A_VERSAL2_RST_GEM0 ... A_VERSAL2_RST_GEM1: + idx = (addr - A_VERSAL2_RST_GEM0) / sizeof(uint32_t); + return xvc->cfg.gem + idx; + + case A_VERSAL2_RST_USB0 ... A_VERSAL2_RST_USB1: + idx = (addr - A_VERSAL2_RST_USB0) / sizeof(uint32_t); + return xvc->cfg.usb + idx; + + case A_VERSAL2_RST_CAN0 ... A_VERSAL2_RST_CAN3: + idx = (addr - A_VERSAL2_RST_CAN0) / sizeof(uint32_t); + return xvc->cfg.can + idx; + + default: + /* invalid or unimplemented */ return NULL; } } @@ -307,6 +352,246 @@ static const RegisterAccessInfo crl_regs_info[] = { } }; +static const RegisterAccessInfo versal2_crl_regs_info[] = { + { .name = "ERR_CTRL", .addr = A_VERSAL2_ERR_CTRL, + .reset = 0x1, + },{ .name = "WPROT", .addr = A_VERSAL2_WPROT, + },{ .name = "RPLL_CTRL", .addr = A_VERSAL2_RPLL_CTRL, + .reset = 0x24809, + .rsvd = 0xf88c00f6, + },{ .name = "RPLL_CFG", .addr = A_VERSAL2_RPLL_CFG, + .reset = 0x7e5dcc6c, + .rsvd = 0x1801210, + },{ .name = "FLXPLL_CTRL", .addr = A_VERSAL2_FLXPLL_CTRL, + .reset = 0x24809, + .rsvd = 0xf88c00f6, + },{ .name = "FLXPLL_CFG", .addr = A_VERSAL2_FLXPLL_CFG, + .reset = 0x7e5dcc6c, + .rsvd = 0x1801210, + },{ .name = "PLL_STATUS", .addr = A_VERSAL2_PLL_STATUS, + .reset = 0xf, + .rsvd = 0xf0, + .ro = 0xf, + },{ .name = "RPLL_TO_XPD_CTRL", .addr = A_VERSAL2_RPLL_TO_XPD_CTRL, + .reset = 0x2000100, + .rsvd = 0xfdfc00ff, + },{ .name = "LPX_TOP_SWITCH_CTRL", .addr = A_VERSAL2_LPX_TOP_SWITCH_CTRL, + .reset = 0xe000300, + .rsvd = 0xf1fc00f8, + },{ .name = "LPX_LSBUS_CLK_CTRL", .addr = A_VERSAL2_LPX_LSBUS_CLK_CTRL, + .reset = 0x2000800, + .rsvd = 0xfdfc00f8, + },{ .name = "RPU_CLK_CTRL", .addr = A_VERSAL2_RPU_CLK_CTRL, + .reset = 0x3f00300, + .rsvd = 0xfc0c00f8, + },{ .name = "OCM_CLK_CTRL", .addr = A_VERSAL2_OCM_CLK_CTRL, + .reset = 0x1e00000, + .rsvd = 0xfe1fffff, + },{ .name = "IOU_SWITCH_CLK_CTRL", .addr = A_VERSAL2_IOU_SWITCH_CLK_CTRL, + .reset = 0x2000500, + .rsvd = 0xfdfc00f8, + },{ .name = "GEM0_REF_CTRL", .addr = A_VERSAL2_GEM0_REF_CTRL, + .reset = 0xe000a00, + .rsvd = 0xf1fc00f8, + },{ .name = "GEM1_REF_CTRL", .addr = A_VERSAL2_GEM1_REF_CTRL, + .reset = 0xe000a00, + .rsvd = 0xf1fc00f8, + },{ .name = "GEM_TSU_REF_CLK_CTRL", .addr = A_VERSAL2_GEM_TSU_REF_CLK_CTRL, + .reset = 0x300, + .rsvd = 0xfdfc00f8, + },{ .name = "USB0_BUS_REF_CLK_CTRL", + .addr = A_VERSAL2_USB0_BUS_REF_CLK_CTRL, + .reset = 0x2001900, + .rsvd = 0xfdfc00f8, + },{ .name = "USB1_BUS_REF_CLK_CTRL", + .addr = A_VERSAL2_USB1_BUS_REF_CLK_CTRL, + .reset = 0x2001900, + .rsvd = 0xfdfc00f8, + },{ .name = "UART0_REF_CLK_CTRL", .addr = A_VERSAL2_UART0_REF_CLK_CTRL, + .reset = 0xc00, + .rsvd = 0xfdfc00f8, + },{ .name = "UART1_REF_CLK_CTRL", .addr = A_VERSAL2_UART1_REF_CLK_CTRL, + .reset = 0xc00, + .rsvd = 0xfdfc00f8, + },{ .name = "SPI0_REF_CLK_CTRL", .addr = A_VERSAL2_SPI0_REF_CLK_CTRL, + .reset = 0x600, + .rsvd = 0xfdfc00f8, + },{ .name = "SPI1_REF_CLK_CTRL", .addr = A_VERSAL2_SPI1_REF_CLK_CTRL, + .reset = 0x600, + .rsvd = 0xfdfc00f8, + },{ .name = "CAN0_REF_2X_CTRL", .addr = A_VERSAL2_CAN0_REF_2X_CTRL, + .reset = 0xc00, + .rsvd = 0xfdfc00f8, + },{ .name = "CAN1_REF_2X_CTRL", .addr = A_VERSAL2_CAN1_REF_2X_CTRL, + .reset = 0xc00, + .rsvd = 0xfdfc00f8, + },{ .name = "CAN2_REF_2X_CTRL", .addr = A_VERSAL2_CAN2_REF_2X_CTRL, + .reset = 0xc00, + .rsvd = 0xfdfc00f8, + },{ .name = "CAN3_REF_2X_CTRL", .addr = A_VERSAL2_CAN3_REF_2X_CTRL, + .reset = 0xc00, + .rsvd = 0xfdfc00f8, + },{ .name = "I3C0_REF_CTRL", .addr = A_VERSAL2_I3C0_REF_CTRL, + .reset = 0x2000c00, + .rsvd = 0xfdfc00f8, + },{ .name = "I3C1_REF_CTRL", .addr = A_VERSAL2_I3C1_REF_CTRL, + .reset = 0x2000c00, + .rsvd = 0xfdfc00f8, + },{ .name = "I3C2_REF_CTRL", .addr = A_VERSAL2_I3C2_REF_CTRL, + .reset = 0x2000c00, + .rsvd = 0xfdfc00f8, + },{ .name = "I3C3_REF_CTRL", .addr = A_VERSAL2_I3C3_REF_CTRL, + .reset = 0x2000c00, + .rsvd = 0xfdfc00f8, + },{ .name = "I3C4_REF_CTRL", .addr = A_VERSAL2_I3C4_REF_CTRL, + .reset = 0x2000c00, + .rsvd = 0xfdfc00f8, + },{ .name = "I3C5_REF_CTRL", .addr = A_VERSAL2_I3C5_REF_CTRL, + .reset = 0x2000c00, + .rsvd = 0xfdfc00f8, + },{ .name = "I3C6_REF_CTRL", .addr = A_VERSAL2_I3C6_REF_CTRL, + .reset = 0x2000c00, + .rsvd = 0xfdfc00f8, + },{ .name = "I3C7_REF_CTRL", .addr = A_VERSAL2_I3C7_REF_CTRL, + .reset = 0x2000c00, + .rsvd = 0xfdfc00f8, + },{ .name = "DBG_LPX_CTRL", .addr = A_VERSAL2_DBG_LPX_CTRL, + .reset = 0x300, + .rsvd = 0xfdfc00f8, + },{ .name = "TIMESTAMP_REF_CTRL", .addr = A_VERSAL2_TIMESTAMP_REF_CTRL, + .reset = 0x2000c00, + .rsvd = 0xfdfc00f8, + },{ .name = "SAFETY_CHK", .addr = A_VERSAL2_SAFETY_CHK, + },{ .name = "ASU_CLK_CTRL", .addr = A_VERSAL2_ASU_CLK_CTRL, + .reset = 0x2000f04, + .rsvd = 0xfdfc00f8, + },{ .name = "DBG_TSTMP_CLK_CTRL", .addr = A_VERSAL2_DBG_TSTMP_CLK_CTRL, + .reset = 0x300, + .rsvd = 0xfdfc00f8, + },{ .name = "MMI_TOPSW_CLK_CTRL", .addr = A_VERSAL2_MMI_TOPSW_CLK_CTRL, + .reset = 0x2000300, + .rsvd = 0xfdfc00f8, + },{ .name = "WWDT_PLL_CLK_CTRL", .addr = A_VERSAL2_WWDT_PLL_CLK_CTRL, + .reset = 0xc00, + .rsvd = 0xfffc00f8, + },{ .name = "RCLK_CTRL", .addr = A_VERSAL2_RCLK_CTRL, + .rsvd = 0xc040, + },{ .name = "RST_RPU_A", .addr = A_VERSAL2_RST_RPU_A, + .reset = 0x10303, + .rsvd = 0xfffefcfc, + .pre_write = crl_rst_cpu_prew, + },{ .name = "RST_RPU_B", .addr = A_VERSAL2_RST_RPU_B, + .reset = 0x10303, + .rsvd = 0xfffefcfc, + .pre_write = crl_rst_cpu_prew, + },{ .name = "RST_RPU_C", .addr = A_VERSAL2_RST_RPU_C, + .reset = 0x10303, + .rsvd = 0xfffefcfc, + .pre_write = crl_rst_cpu_prew, + },{ .name = "RST_RPU_D", .addr = A_VERSAL2_RST_RPU_D, + .reset = 0x10303, + .rsvd = 0xfffefcfc, + .pre_write = crl_rst_cpu_prew, + },{ .name = "RST_RPU_E", .addr = A_VERSAL2_RST_RPU_E, + .reset = 0x10303, + .rsvd = 0xfffefcfc, + .pre_write = crl_rst_cpu_prew, + },{ .name = "RST_RPU_GD_0", .addr = A_VERSAL2_RST_RPU_GD_0, + .reset = 0x3, + },{ .name = "RST_RPU_GD_1", .addr = A_VERSAL2_RST_RPU_GD_1, + .reset = 0x3, + },{ .name = "RST_ASU_GD", .addr = A_VERSAL2_RST_ASU_GD, + .reset = 0x3, + },{ .name = "RST_ADMA", .addr = A_VERSAL2_RST_ADMA, + .reset = 0x1, + .pre_write = crl_rst_dev_prew, + },{ .name = "RST_SDMA", .addr = A_VERSAL2_RST_SDMA, + .pre_write = crl_rst_dev_prew, + .reset = 0x1, + },{ .name = "RST_GEM0", .addr = A_VERSAL2_RST_GEM0, + .reset = 0x1, + .pre_write = crl_rst_dev_prew, + },{ .name = "RST_GEM1", .addr = A_VERSAL2_RST_GEM1, + .reset = 0x1, + .pre_write = crl_rst_dev_prew, + },{ .name = "RST_USB0", .addr = A_VERSAL2_RST_USB0, + .reset = 0x1, + .pre_write = crl_rst_dev_prew, + },{ .name = "RST_USB1", .addr = A_VERSAL2_RST_USB1, + .reset = 0x1, + .pre_write = crl_rst_dev_prew, + },{ .name = "RST_UART0", .addr = A_VERSAL2_RST_UART0, + .reset = 0x1, + .pre_write = crl_rst_dev_prew, + },{ .name = "RST_UART1", .addr = A_VERSAL2_RST_UART1, + .reset = 0x1, + .pre_write = crl_rst_dev_prew, + },{ .name = "RST_SPI0", .addr = A_VERSAL2_RST_SPI0, + .reset = 0x1, + },{ .name = "RST_SPI1", .addr = A_VERSAL2_RST_SPI1, + .reset = 0x1, + },{ .name = "RST_CAN0", .addr = A_VERSAL2_RST_CAN0, + .reset = 0x1, + .pre_write = crl_rst_dev_prew, + },{ .name = "RST_CAN1", .addr = A_VERSAL2_RST_CAN1, + .reset = 0x1, + .pre_write = crl_rst_dev_prew, + },{ .name = "RST_CAN2", .addr = A_VERSAL2_RST_CAN2, + .reset = 0x1, + .pre_write = crl_rst_dev_prew, + },{ .name = "RST_CAN3", .addr = A_VERSAL2_RST_CAN3, + .reset = 0x1, + .pre_write = crl_rst_dev_prew, + },{ .name = "RST_I3C0", .addr = A_VERSAL2_RST_I3C0, + .reset = 0x1, + },{ .name = "RST_I3C1", .addr = A_VERSAL2_RST_I3C1, + .reset = 0x1, + },{ .name = "RST_I3C2", .addr = A_VERSAL2_RST_I3C2, + .reset = 0x1, + },{ .name = "RST_I3C3", .addr = A_VERSAL2_RST_I3C3, + .reset = 0x1, + },{ .name = "RST_I3C4", .addr = A_VERSAL2_RST_I3C4, + .reset = 0x1, + },{ .name = "RST_I3C5", .addr = A_VERSAL2_RST_I3C5, + .reset = 0x1, + },{ .name = "RST_I3C6", .addr = A_VERSAL2_RST_I3C6, + .reset = 0x1, + },{ .name = "RST_I3C7", .addr = A_VERSAL2_RST_I3C7, + .reset = 0x1, + },{ .name = "RST_DBG_LPX", .addr = A_VERSAL2_RST_DBG_LPX, + .reset = 0x3, + .rsvd = 0xfc, + },{ .name = "RST_GPIO", .addr = A_VERSAL2_RST_GPIO, + .reset = 0x1, + },{ .name = "RST_TTC", .addr = A_VERSAL2_RST_TTC, + .reset = 0xff, + },{ .name = "RST_TIMESTAMP", .addr = A_VERSAL2_RST_TIMESTAMP, + .reset = 0x1, + },{ .name = "RST_SWDT0", .addr = A_VERSAL2_RST_SWDT0, + .reset = 0x1, + },{ .name = "RST_SWDT1", .addr = A_VERSAL2_RST_SWDT1, + .reset = 0x1, + },{ .name = "RST_SWDT2", .addr = A_VERSAL2_RST_SWDT2, + .reset = 0x1, + },{ .name = "RST_SWDT3", .addr = A_VERSAL2_RST_SWDT3, + .reset = 0x1, + },{ .name = "RST_SWDT4", .addr = A_VERSAL2_RST_SWDT4, + .reset = 0x1, + },{ .name = "RST_IPI", .addr = A_VERSAL2_RST_IPI, + },{ .name = "RST_SYSMON", .addr = A_VERSAL2_RST_SYSMON, + },{ .name = "ASU_MB_RST_MODE", .addr = A_VERSAL2_ASU_MB_RST_MODE, + .reset = 0x1, + .rsvd = 0xf8, + },{ .name = "FPX_TOPSW_MUX_CTRL", .addr = A_VERSAL2_FPX_TOPSW_MUX_CTRL, + .reset = 0x1, + },{ .name = "RST_FPX", .addr = A_VERSAL2_RST_FPX, + .reset = 0x3, + },{ .name = "RST_MMI", .addr = A_VERSAL2_RST_MMI, + .reset = 0x1, + },{ .name = "RST_OCM", .addr = A_VERSAL2_RST_OCM, + } +}; + static void versal_crl_reset_enter(Object *obj, ResetType type) { XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj); @@ -317,6 +602,16 @@ static void versal_crl_reset_enter(Object *obj, ResetType type) } } +static void versal2_crl_reset_enter(Object *obj, ResetType type) +{ + XlnxVersal2CRL *s = XLNX_VERSAL2_CRL(obj); + size_t i; + + for (i = 0; i < VERSAL2_CRL_R_MAX; ++i) { + register_reset(&s->regs_info[i]); + } +} + static void versal_crl_reset_hold(Object *obj, ResetType type) { XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj); @@ -388,6 +683,73 @@ static void versal_crl_init(Object *obj) } } +static void versal2_crl_init(Object *obj) +{ + XlnxVersal2CRL *s = XLNX_VERSAL2_CRL(obj); + XlnxVersalCRLBase *xvcb = XLNX_VERSAL_CRL_BASE(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + size_t i; + + xvcb->reg_array = register_init_block32(DEVICE(obj), versal2_crl_regs_info, + ARRAY_SIZE(versal2_crl_regs_info), + s->regs_info, s->regs, + &crl_ops, + XLNX_VERSAL_CRL_ERR_DEBUG, + VERSAL2_CRL_R_MAX * 4); + xvcb->regs = s->regs; + + sysbus_init_mmio(sbd, &xvcb->reg_array->mem); + + for (i = 0; i < ARRAY_SIZE(s->cfg.rpu); ++i) { + object_property_add_link(obj, "rpu[*]", TYPE_ARM_CPU, + (Object **)&s->cfg.rpu[i], + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_STRONG); + } + + for (i = 0; i < ARRAY_SIZE(s->cfg.adma); ++i) { + object_property_add_link(obj, "adma[*]", TYPE_DEVICE, + (Object **)&s->cfg.adma[i], + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_STRONG); + } + + for (i = 0; i < ARRAY_SIZE(s->cfg.sdma); ++i) { + object_property_add_link(obj, "sdma[*]", TYPE_DEVICE, + (Object **)&s->cfg.sdma[i], + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_STRONG); + } + + for (i = 0; i < ARRAY_SIZE(s->cfg.uart); ++i) { + object_property_add_link(obj, "uart[*]", TYPE_DEVICE, + (Object **)&s->cfg.uart[i], + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_STRONG); + } + + for (i = 0; i < ARRAY_SIZE(s->cfg.gem); ++i) { + object_property_add_link(obj, "gem[*]", TYPE_DEVICE, + (Object **)&s->cfg.gem[i], + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_STRONG); + } + + for (i = 0; i < ARRAY_SIZE(s->cfg.usb); ++i) { + object_property_add_link(obj, "usb[*]", TYPE_DEVICE, + (Object **)&s->cfg.usb[i], + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_STRONG); + } + + for (i = 0; i < ARRAY_SIZE(s->cfg.can); ++i) { + object_property_add_link(obj, "can[*]", TYPE_DEVICE, + (Object **)&s->cfg.can[i], + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_STRONG); + } +} + static void crl_finalize(Object *obj) { XlnxVersalCRLBase *s = XLNX_VERSAL_CRL_BASE(obj); @@ -404,6 +766,16 @@ static const VMStateDescription vmstate_versal_crl = { } }; +static const VMStateDescription vmstate_versal2_crl = { + .name = TYPE_XLNX_VERSAL2_CRL, + .version_id = 1, + .minimum_version_id = 1, + .fields = (const VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, XlnxVersal2CRL, VERSAL2_CRL_R_MAX), + VMSTATE_END_OF_LIST(), + } +}; + static void versal_crl_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -416,6 +788,17 @@ static void versal_crl_class_init(ObjectClass *klass, const void *data) xvcc->decode_periph_rst = versal_decode_periph_rst; } +static void versal2_crl_class_init(ObjectClass *klass, const void *data) +{ + XlnxVersalCRLBaseClass *xvcc = XLNX_VERSAL_CRL_BASE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); + + dc->vmsd = &vmstate_versal2_crl; + rc->phases.enter = versal2_crl_reset_enter; + xvcc->decode_periph_rst = versal2_decode_periph_rst; +} + static const TypeInfo crl_base_info = { .name = TYPE_XLNX_VERSAL_CRL_BASE, .parent = TYPE_SYS_BUS_DEVICE, @@ -433,10 +816,19 @@ static const TypeInfo versal_crl_info = { .class_init = versal_crl_class_init, }; +static const TypeInfo versal2_crl_info = { + .name = TYPE_XLNX_VERSAL2_CRL, + .parent = TYPE_XLNX_VERSAL_CRL_BASE, + .instance_size = sizeof(XlnxVersal2CRL), + .instance_init = versal2_crl_init, + .class_init = versal2_crl_class_init, +}; + static void crl_register_types(void) { type_register_static(&crl_base_info); type_register_static(&versal_crl_info); + type_register_static(&versal2_crl_info); } type_init(crl_register_types) |