diff --git a/plat/socionext/synquacer/drivers/scpi/sq_scpi.c b/plat/socionext/synquacer/drivers/scpi/sq_scpi.c index a6924e2..170b7e1 100644 --- a/plat/socionext/synquacer/drivers/scpi/sq_scpi.c +++ b/plat/socionext/synquacer/drivers/scpi/sq_scpi.c @@ -168,3 +168,49 @@ return response.status; } + +uint32_t scpi_get_draminfo(struct draminfo *info) +{ + scpi_cmd_t *cmd; + struct { + scpi_cmd_t cmd; + struct draminfo info; + } response; + uint32_t mhu_status; + + scpi_secure_message_start(); + + /* Populate the command header */ + cmd = SCPI_CMD_HEADER_AP_TO_SCP; + cmd->id = SCPI_CMD_GET_DRAMINFO; + cmd->set = SCPI_SET_EXTENDED; + cmd->sender = 0; + cmd->size = 0; + + scpi_secure_message_send(0); + + mhu_status = mhu_secure_message_wait(); + + /* Expect an SCPI message, reject any other protocol */ + if (mhu_status != (1 << SCPI_MHU_SLOT_ID)) { + ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n", + mhu_status); + panic(); + } + + /* + * Ensure that any read to the SCPI payload area is done after reading + * the MHU register. If these 2 reads were reordered then the CPU would + * read invalid payload data + */ + dmbld(); + + memcpy(&response, (void *)SCPI_SHARED_MEM_SCP_TO_AP, sizeof(response)); + + scpi_secure_message_end(); + + if (response.cmd.status == SCP_OK) + *info = response.info; + + return response.cmd.status; +} diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h index f9bc402..e339d85 100644 --- a/plat/socionext/synquacer/include/platform_def.h +++ b/plat/socionext/synquacer/include/platform_def.h @@ -54,6 +54,8 @@ #define SQ_SYS_TIMCTL_BASE 0x2a810000 #define PLAT_SQ_NSTIMER_FRAME_ID 0 +#define DRAMINFO_BASE 0x2E00FFC0 + #define PLAT_SQ_MHU_BASE 0x45000000 #define PLAT_SQ_SCP_COM_SHARED_MEM_BASE 0x45400000 diff --git a/plat/socionext/synquacer/include/sq_common.h b/plat/socionext/synquacer/include/sq_common.h index 8839a05..58b1e24 100644 --- a/plat/socionext/synquacer/include/sq_common.h +++ b/plat/socionext/synquacer/include/sq_common.h @@ -10,6 +10,19 @@ #include #include +struct draminfo { + uint32_t num_regions; + uint32_t reserved; + uint64_t base1; + uint64_t size1; + uint64_t base2; + uint64_t size2; + uint64_t base3; + uint64_t size3; +}; + +uint32_t scpi_get_draminfo(struct draminfo *info); + void plat_sq_pwrc_setup(void); void plat_sq_interconnect_init(void); diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c index 4d7c851..461c8de 100644 --- a/plat/socionext/synquacer/sq_bl31_setup.c +++ b/plat/socionext/synquacer/sq_bl31_setup.c @@ -132,6 +132,9 @@ void bl31_plat_runtime_setup(void) { + struct draminfo *di = (struct draminfo *)(unsigned long)DRAMINFO_BASE; + + scpi_get_draminfo(di); } void bl31_plat_arch_setup(void)