AST2700 provides a single FMC controller shared by the main CA35 processor (PSP) and the SSP/TSP coprocessors.
>From the PSP perspective, the FMC controller is memory-mapped at 0x14000000–0x140000FF. The SSP and TSP access the same controller through a different address window at 0x74000000–0x740000FF. This change allows the SSP and TSP SoC models to reference the existing PSP FMC instance instead of creating independent controllers. An MMIO alias is added in the SSP and TSP address spaces to map their FMC access window to the shared FMC device. This ensures consistent FMC state across PSP, SSP, and TSP and matches the AST2700 hardware design. Signed-off-by: Jamin Lin <[email protected]> --- include/hw/arm/aspeed_coprocessor.h | 2 ++ hw/arm/aspeed_ast27x0-fc.c | 4 ++++ hw/arm/aspeed_ast27x0-ssp.c | 16 ++++++++++++++++ hw/arm/aspeed_ast27x0-tsp.c | 16 ++++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/include/hw/arm/aspeed_coprocessor.h b/include/hw/arm/aspeed_coprocessor.h index b77ea06e7f..23c3b97f06 100644 --- a/include/hw/arm/aspeed_coprocessor.h +++ b/include/hw/arm/aspeed_coprocessor.h @@ -51,8 +51,10 @@ struct Aspeed27x0CoprocessorState { MemoryRegion scu_alias; MemoryRegion scuio_alias; + MemoryRegion fmc_alias; Aspeed2700SCUState *scu; AspeedSCUState *scuio; + AspeedSMCState *fmc; }; #define TYPE_ASPEED27X0SSP_COPROCESSOR "aspeed27x0ssp-coprocessor" diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c index d14a42ebca..058cea42ed 100644 --- a/hw/arm/aspeed_ast27x0-fc.c +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -159,6 +159,8 @@ static bool ast2700fc_ssp_init(Ast2700FCState *s, AspeedSoCState *psp, OBJECT(&s->ca35.scu), &error_abort); object_property_set_link(OBJECT(&s->ssp), "scuio", OBJECT(&psp->scuio), &error_abort); + object_property_set_link(OBJECT(&s->ssp), "fmc", + OBJECT(&psp->fmc), &error_abort); if (!qdev_realize(DEVICE(&s->ssp), NULL, errp)) { return false; } @@ -191,6 +193,8 @@ static bool ast2700fc_tsp_init(Ast2700FCState *s, AspeedSoCState *psp, OBJECT(&s->ca35.scu), &error_abort); object_property_set_link(OBJECT(&s->tsp), "scuio", OBJECT(&psp->scuio), &error_abort); + object_property_set_link(OBJECT(&s->tsp), "fmc", + OBJECT(&psp->fmc), &error_abort); if (!qdev_realize(DEVICE(&s->tsp), NULL, errp)) { return false; } diff --git a/hw/arm/aspeed_ast27x0-ssp.c b/hw/arm/aspeed_ast27x0-ssp.c index fa492f1797..e03653086c 100644 --- a/hw/arm/aspeed_ast27x0-ssp.c +++ b/hw/arm/aspeed_ast27x0-ssp.c @@ -27,6 +27,7 @@ static const hwaddr aspeed_soc_ast27x0ssp_memmap[] = { [ASPEED_DEV_TIMER1] = 0x72C10000, [ASPEED_DEV_UART4] = 0x72C1A000, [ASPEED_DEV_IPC0] = 0x72C1C000, + [ASPEED_DEV_FMC] = 0x74000000, [ASPEED_DEV_PRIC1] = 0x74100000, [ASPEED_DEV_SCUIO] = 0x74C02000, [ASPEED_DEV_OTP] = 0x74C07000, @@ -177,6 +178,12 @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp) return; } + if (!a->fmc) { + error_setg(errp, TYPE_ASPEED27X0SSP_COPROCESSOR + ": 'fmc' link is not set"); + return; + } + /* AST27X0 SSP Core */ armv7m = DEVICE(&a->armv7m); qdev_prop_set_uint32(armv7m, "num-irq", 256); @@ -269,6 +276,13 @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(s->uart), 0, aspeed_soc_ast27x0ssp_get_irq(s, s->uart_dev)); + /* FMC */ + memory_region_init_alias(&a->fmc_alias, OBJECT(a), "fmc.alias", + &a->fmc->mmio, 0, + memory_region_size(&a->fmc->mmio)); + memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_FMC], + &a->fmc_alias); + aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->timerctrl), "aspeed.timerctrl", sc->memmap[ASPEED_DEV_TIMER1], 0x200); @@ -294,6 +308,8 @@ static const Property aspeed_27x0_coprocessor_properties[] = { TYPE_ASPEED_2700_SCU, Aspeed2700SCUState *), DEFINE_PROP_LINK("scuio", Aspeed27x0CoprocessorState, scuio, TYPE_ASPEED_SCU, AspeedSCUState *), + DEFINE_PROP_LINK("fmc", Aspeed27x0CoprocessorState, fmc, TYPE_ASPEED_SMC, + AspeedSMCState *), }; static void aspeed_soc_ast27x0ssp_class_init(ObjectClass *klass, diff --git a/hw/arm/aspeed_ast27x0-tsp.c b/hw/arm/aspeed_ast27x0-tsp.c index 3a98bd232c..39ba062a20 100644 --- a/hw/arm/aspeed_ast27x0-tsp.c +++ b/hw/arm/aspeed_ast27x0-tsp.c @@ -27,6 +27,7 @@ static const hwaddr aspeed_soc_ast27x0tsp_memmap[] = { [ASPEED_DEV_TIMER1] = 0x72C10000, [ASPEED_DEV_UART4] = 0x72C1A000, [ASPEED_DEV_IPC0] = 0x72C1C000, + [ASPEED_DEV_FMC] = 0x74000000, [ASPEED_DEV_PRIC1] = 0x74100000, [ASPEED_DEV_SCUIO] = 0x74C02000, [ASPEED_DEV_OTP] = 0x74C07000, @@ -177,6 +178,12 @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp) return; } + if (!a->fmc) { + error_setg(errp, TYPE_ASPEED27X0TSP_COPROCESSOR + ": 'fmc' link is not set"); + return; + } + /* AST27X0 TSP Core */ armv7m = DEVICE(&a->armv7m); qdev_prop_set_uint32(armv7m, "num-irq", 256); @@ -269,6 +276,13 @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(s->uart), 0, aspeed_soc_ast27x0tsp_get_irq(s, s->uart_dev)); + /* FMC */ + memory_region_init_alias(&a->fmc_alias, OBJECT(a), "fmc.alias", + &a->fmc->mmio, 0, + memory_region_size(&a->fmc->mmio)); + memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_FMC], + &a->fmc_alias); + aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->timerctrl), "aspeed.timerctrl", sc->memmap[ASPEED_DEV_TIMER1], 0x200); @@ -294,6 +308,8 @@ static const Property aspeed_27x0_coprocessor_properties[] = { TYPE_ASPEED_2700_SCU, Aspeed2700SCUState *), DEFINE_PROP_LINK("scuio", Aspeed27x0CoprocessorState, scuio, TYPE_ASPEED_SCU, AspeedSCUState *), + DEFINE_PROP_LINK("fmc", Aspeed27x0CoprocessorState, fmc, TYPE_ASPEED_SMC, + AspeedSMCState *), }; static void aspeed_soc_ast27x0tsp_class_init(ObjectClass *klass, -- 2.43.0
