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


Reply via email to