This commit adds SCU register support for SSP SDRAM remap control and runtime activation. It introduces logic for the PSP to dynamically configure the mapping of its own DRAM windows into SSP-visible SDRAM space, enabling shared memory communication via memory region aliases.
Two MemoryRegion aliases are attached to the SCU via QOM property links: - ssp-sdram-remap1: maps PSP DRAM at 0x400000000 (size: 32MB) to SSP SDRAM offset 0x2000000 - ssp-sdram-remap2: maps PSP DRAM at 0x42c000000 (size: 32MB) to SSP SDRAM offset 0x0 The SCU registers AST2700_SCU_SSP_CTRL_1/2 and AST2700_SCU_SSP_REMAP_ADDR_{1,2} / REMAP_SIZE_{1,2} allow runtime reconfiguration of alias offset, base, and size. Bumps the SCU VMState version to 3. |------------------------------------------| |----------------------------| | PSP DRAM | | SSP SDRAM | |------------------------------------------| |----------------------------| | 0x4_0000_0000 (SCU_124 << 4) | --> | 0x0000_0000 | | remap1 base |---| | | - SCU_150: target addr | | size: 32MB (SCU_14C) | | | | remap2 | |------------------------------------------| | | |----------------------------| | | | | | | | 0x4_2C00_0000 (SCU_128 << 4) |-----| | 0x0200_0000 | | remap2 base | | | - SCU_148: target addr | | size: 32MB (SCU_154) | |---> | remap1 | |------------------------------------------| |----------------------------| Signed-off-by: Jamin Lin <jamin_...@aspeedtech.com> --- include/hw/misc/aspeed_scu.h | 3 ++ hw/arm/aspeed_ast27x0.c | 6 ++++ hw/misc/aspeed_scu.c | 53 ++++++++++++++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h index 684b48b722..408f821379 100644 --- a/include/hw/misc/aspeed_scu.h +++ b/include/hw/misc/aspeed_scu.h @@ -39,6 +39,9 @@ struct AspeedSCUState { uint32_t hw_strap1; uint32_t hw_strap2; uint32_t hw_prot_key; + + MemoryRegion *ssp_sdram_remap1; + MemoryRegion *ssp_sdram_remap2; }; #define AST2400_A0_SILICON_REV 0x02000303U diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index 0f988eaa4d..587c042c30 100644 --- a/hw/arm/aspeed_ast27x0.c +++ b/hw/arm/aspeed_ast27x0.c @@ -833,6 +833,12 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp) memory_region_init_alias(&a->tsp.sdram_remap_alias, OBJECT(a), "tsp.sdram.remap", s->memory, 0x42e000000, 32 * MiB); + object_property_set_link(OBJECT(&s->scu), "ssp-sdram-remap1", + OBJECT(&a->ssp.sdram_remap1_alias), + &error_abort); + object_property_set_link(OBJECT(&s->scu), "ssp-sdram-remap2", + OBJECT(&a->ssp.sdram_remap2_alias), + &error_abort); } if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { return; diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index a0ab5eed8f..df379cafbe 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -143,6 +143,14 @@ #define AST2700_HW_STRAP1_SEC2 TO_REG(0x28) #define AST2700_HW_STRAP1_SEC3 TO_REG(0x2C) +/* SSP */ +#define AST2700_SCU_SSP_CTRL_1 TO_REG(0x124) +#define AST2700_SCU_SSP_CTRL_2 TO_REG(0x128) +#define AST2700_SCU_SSP_REMAP_ADDR_1 TO_REG(0x148) +#define AST2700_SCU_SSP_REMAP_SIZE_1 TO_REG(0x14c) +#define AST2700_SCU_SSP_REMAP_ADDR_2 TO_REG(0x150) +#define AST2700_SCU_SSP_REMAP_SIZE_2 TO_REG(0x154) + #define AST2700_SCU_CLK_SEL_1 TO_REG(0x280) #define AST2700_SCU_HPLL_PARAM TO_REG(0x300) #define AST2700_SCU_HPLL_EXT_PARAM TO_REG(0x304) @@ -605,8 +613,8 @@ static void aspeed_scu_realize(DeviceState *dev, Error **errp) static const VMStateDescription vmstate_aspeed_scu = { .name = "aspeed.scu", - .version_id = 2, - .minimum_version_id = 2, + .version_id = 3, + .minimum_version_id = 3, .fields = (const VMStateField[]) { VMSTATE_UINT32_ARRAY(regs, AspeedSCUState, ASPEED_AST2600_SCU_NR_REGS), VMSTATE_END_OF_LIST() @@ -618,6 +626,10 @@ static const Property aspeed_scu_properties[] = { DEFINE_PROP_UINT32("hw-strap1", AspeedSCUState, hw_strap1, 0), DEFINE_PROP_UINT32("hw-strap2", AspeedSCUState, hw_strap2, 0), DEFINE_PROP_UINT32("hw-prot-key", AspeedSCUState, hw_prot_key, 0), + DEFINE_PROP_LINK("ssp-sdram-remap1", AspeedSCUState, ssp_sdram_remap1, + TYPE_MEMORY_REGION, MemoryRegion *), + DEFINE_PROP_LINK("ssp-sdram-remap2", AspeedSCUState, ssp_sdram_remap2, + TYPE_MEMORY_REGION, MemoryRegion *), }; static void aspeed_scu_class_init(ObjectClass *klass, const void *data) @@ -902,6 +914,7 @@ static void aspeed_ast2700_scu_write(void *opaque, hwaddr offset, int reg = TO_REG(offset); /* Truncate here so bitwise operations below behave as expected */ uint32_t data = data64; + MemoryRegion *mr; if (reg >= ASPEED_AST2700_SCU_NR_REGS) { qemu_log_mask(LOG_GUEST_ERROR, @@ -913,6 +926,36 @@ static void aspeed_ast2700_scu_write(void *opaque, hwaddr offset, trace_aspeed_ast2700_scu_write(offset, size, data); switch (reg) { + case AST2700_SCU_SSP_CTRL_1: + case AST2700_SCU_SSP_CTRL_2: + mr = (reg == AST2700_SCU_SSP_CTRL_1) ? + s->ssp_sdram_remap1 : s->ssp_sdram_remap2; + if (mr == NULL) { + return; + } + data &= 0x7fffffff; + memory_region_set_alias_offset(mr, (uint64_t) data << 4); + break; + case AST2700_SCU_SSP_REMAP_ADDR_1: + case AST2700_SCU_SSP_REMAP_ADDR_2: + mr = (reg == AST2700_SCU_SSP_REMAP_ADDR_1) ? + s->ssp_sdram_remap1 : s->ssp_sdram_remap2; + if (mr == NULL) { + return; + } + data &= 0x3fffffff; + memory_region_set_address(mr, data); + break; + case AST2700_SCU_SSP_REMAP_SIZE_1: + case AST2700_SCU_SSP_REMAP_SIZE_2: + mr = (reg == AST2700_SCU_SSP_REMAP_SIZE_1) ? + s->ssp_sdram_remap1 : s->ssp_sdram_remap2; + if (mr == NULL) { + return; + } + data &= 0x3fffffff; + memory_region_set_size(mr, data); + break; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Unhandled write at offset 0x%" HWADDR_PRIx "\n", @@ -940,6 +983,12 @@ static const uint32_t ast2700_a0_resets[ASPEED_AST2700_SCU_NR_REGS] = { [AST2700_HW_STRAP1_SEC1] = 0x000000FF, [AST2700_HW_STRAP1_SEC2] = 0x00000000, [AST2700_HW_STRAP1_SEC3] = 0x1000408F, + [AST2700_SCU_SSP_CTRL_1] = 0x40000000, + [AST2700_SCU_SSP_CTRL_2] = 0x42C00000, + [AST2700_SCU_SSP_REMAP_ADDR_1] = 0x02000000, + [AST2700_SCU_SSP_REMAP_SIZE_1] = 0x02000000, + [AST2700_SCU_SSP_REMAP_ADDR_2] = 0x00000000, + [AST2700_SCU_SSP_REMAP_SIZE_2] = 0x02000000, [AST2700_SCU_HPLL_PARAM] = 0x0000009f, [AST2700_SCU_HPLL_EXT_PARAM] = 0x8000004f, [AST2700_SCU_DPLL_PARAM] = 0x0080009f, -- 2.43.0