@samitouri / QOSamiQemu / commits / ab480be728

hw/arm/ast27x0: Share FMC controller with SSP and TSP

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 <jamin_lin@aspeedtech.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Tested-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Link: https://lore.kernel.org/qemu-devel/20260717084559.3477061-8-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com>

Jamin Lin committed Jul 17, 2026 at 08:46 UTC ab480be728c2fea79121d1448bda25f1bdbd759c
4 files changed +43
hw/arm/aspeed_ast27x0-fc.c
+4
@@ -159,6 +159,8 @@ static bool ast2700fc_ssp_init(Ast2700FCState *s, AspeedSoCState *psp,
159 OBJECT(&s->ca35.scu), &error_abort);
160 object_property_set_link(OBJECT(&s->ssp), "scuio",
161 OBJECT(&psp->scuio), &error_abort);
162 + object_property_set_link(OBJECT(&s->ssp), "fmc",
163 + OBJECT(&psp->fmc), &error_abort);
164 if (!qdev_realize(DEVICE(&s->ssp), NULL, errp)) {
165 return false;
166 }
@@ -191,6 +193,8 @@ static bool ast2700fc_tsp_init(Ast2700FCState *s, AspeedSoCState *psp,
193 OBJECT(&s->ca35.scu), &error_abort);
194 object_property_set_link(OBJECT(&s->tsp), "scuio",
195 OBJECT(&psp->scuio), &error_abort);
196 + object_property_set_link(OBJECT(&s->tsp), "fmc",
197 + OBJECT(&psp->fmc), &error_abort);
198 if (!qdev_realize(DEVICE(&s->tsp), NULL, errp)) {
199 return false;
200 }
hw/arm/aspeed_ast27x0-ssp.c
+16
@@ -27,6 +27,7 @@ static const hwaddr aspeed_soc_ast27x0ssp_memmap[] = {
27 [ASPEED_DEV_TIMER1] = 0x72C10000,
28 [ASPEED_DEV_UART4] = 0x72C1A000,
29 [ASPEED_DEV_IPC0] = 0x72C1C000,
30 + [ASPEED_DEV_FMC] = 0x74000000,
31 [ASPEED_DEV_PRIC1] = 0x74100000,
32 [ASPEED_DEV_SCUIO] = 0x74C02000,
33 [ASPEED_DEV_OTP] = 0x74C07000,
@@ -177,6 +178,12 @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp)
178 return;
179 }
180
181 + if (!a->fmc) {
182 + error_setg(errp, TYPE_ASPEED27X0SSP_COPROCESSOR
183 + ": 'fmc' link is not set");
184 + return;
185 + }
186 +
187 /* AST27X0 SSP Core */
188 armv7m = DEVICE(&a->armv7m);
189 qdev_prop_set_uint32(armv7m, "num-irq", 256);
@@ -269,6 +276,13 @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp)
276 sysbus_connect_irq(SYS_BUS_DEVICE(s->uart), 0,
277 aspeed_soc_ast27x0ssp_get_irq(s, s->uart_dev));
278
279 + /* FMC */
280 + memory_region_init_alias(&a->fmc_alias, OBJECT(a), "fmc.alias",
281 + &a->fmc->mmio, 0,
282 + memory_region_size(&a->fmc->mmio));
283 + memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_FMC],
284 + &a->fmc_alias);
285 +
286 aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->timerctrl),
287 "aspeed.timerctrl",
288 sc->memmap[ASPEED_DEV_TIMER1], 0x200);
@@ -294,6 +308,8 @@ static const Property aspeed_27x0_coprocessor_properties[] = {
308 TYPE_ASPEED_2700_SCU, Aspeed2700SCUState *),
309 DEFINE_PROP_LINK("scuio", Aspeed27x0CoprocessorState, scuio,
310 TYPE_ASPEED_SCU, AspeedSCUState *),
311 + DEFINE_PROP_LINK("fmc", Aspeed27x0CoprocessorState, fmc, TYPE_ASPEED_SMC,
312 + AspeedSMCState *),
313 };
314
315 static void aspeed_soc_ast27x0ssp_class_init(ObjectClass *klass,
hw/arm/aspeed_ast27x0-tsp.c
+16
@@ -27,6 +27,7 @@ static const hwaddr aspeed_soc_ast27x0tsp_memmap[] = {
27 [ASPEED_DEV_TIMER1] = 0x72C10000,
28 [ASPEED_DEV_UART4] = 0x72C1A000,
29 [ASPEED_DEV_IPC0] = 0x72C1C000,
30 + [ASPEED_DEV_FMC] = 0x74000000,
31 [ASPEED_DEV_PRIC1] = 0x74100000,
32 [ASPEED_DEV_SCUIO] = 0x74C02000,
33 [ASPEED_DEV_OTP] = 0x74C07000,
@@ -177,6 +178,12 @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp)
178 return;
179 }
180
181 + if (!a->fmc) {
182 + error_setg(errp, TYPE_ASPEED27X0TSP_COPROCESSOR
183 + ": 'fmc' link is not set");
184 + return;
185 + }
186 +
187 /* AST27X0 TSP Core */
188 armv7m = DEVICE(&a->armv7m);
189 qdev_prop_set_uint32(armv7m, "num-irq", 256);
@@ -269,6 +276,13 @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp)
276 sysbus_connect_irq(SYS_BUS_DEVICE(s->uart), 0,
277 aspeed_soc_ast27x0tsp_get_irq(s, s->uart_dev));
278
279 + /* FMC */
280 + memory_region_init_alias(&a->fmc_alias, OBJECT(a), "fmc.alias",
281 + &a->fmc->mmio, 0,
282 + memory_region_size(&a->fmc->mmio));
283 + memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_FMC],
284 + &a->fmc_alias);
285 +
286 aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->timerctrl),
287 "aspeed.timerctrl",
288 sc->memmap[ASPEED_DEV_TIMER1], 0x200);
@@ -294,6 +308,8 @@ static const Property aspeed_27x0_coprocessor_properties[] = {
308 TYPE_ASPEED_2700_SCU, Aspeed2700SCUState *),
309 DEFINE_PROP_LINK("scuio", Aspeed27x0CoprocessorState, scuio,
310 TYPE_ASPEED_SCU, AspeedSCUState *),
311 + DEFINE_PROP_LINK("fmc", Aspeed27x0CoprocessorState, fmc, TYPE_ASPEED_SMC,
312 + AspeedSMCState *),
313 };
314
315 static void aspeed_soc_ast27x0tsp_class_init(ObjectClass *klass,
include/hw/arm/aspeed_coprocessor.h
+7
@@ -49,10 +49,17 @@ struct Aspeed27x0CoprocessorState {
49
50 ARMv7MState armv7m;
51
52 + /*
53 + * SCU, SCUIO and FMC are not owned by this coprocessor: they are
54 + * shared with the main PSP SoC, and only aliased into this
55 + * coprocessor's own address space here.
56 + */
57 MemoryRegion scu_alias;
58 MemoryRegion scuio_alias;
59 + MemoryRegion fmc_alias;
60 Aspeed2700SCUState *scu;
61 AspeedSCUState *scuio;
62 + AspeedSMCState *fmc;
63 };
64
65 #define TYPE_ASPEED27X0SSP_COPROCESSOR "aspeed27x0ssp-coprocessor"