diff --git a/module/scmi/include/mod_scmi.h b/module/scmi/include/mod_scmi.h index 78322b101845d50066b47a08897eccfbc8462904..4968f2463b4e19a8121c01d580b1f62c3429142c 100644 --- a/module/scmi/include/mod_scmi.h +++ b/module/scmi/include/mod_scmi.h @@ -117,6 +117,12 @@ struct mod_scmi_service_config { */ fwk_id_t transport_api_id; + /*! + * \brief Identifier of the notification indicating the transport has been + * initialized. + */ + fwk_id_t transport_notification_init_id; + /*! * \brief Identifier of the agent. * @@ -415,6 +421,26 @@ static inline bool mod_scmi_is_slave(enum scmi_channel_type type, return (int)type != (int)role; } +/*! + * \brief SCMI notification indices. + */ +enum mod_scmi_notification_idx { + /*! The SCMI service has been initialized */ + MOD_SCMI_NOTIFICATION_IDX_INITIALIZED, + + /*! Number of defined notifications */ + MOD_SCMI_NOTIFICATION_IDX_COUNT +}; + +/*! + * \brief Identifier for the MOD_SCMI_NOTIFICATION_IDX_INITIALIZED + * notification. + */ +static const fwk_id_t mod_scmi_notification_id_initialized = + FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SCMI, + MOD_SCMI_NOTIFICATION_IDX_INITIALIZED); + /*! * @} */ diff --git a/module/scmi/src/mod_scmi.c b/module/scmi/src/mod_scmi.c index 583c57374f671d0ab69b4059622d3b73c0212fdf..ea61e03ab4eb8485e624678488771f694e3250e4 100644 --- a/module/scmi/src/mod_scmi.c +++ b/module/scmi/src/mod_scmi.c @@ -18,10 +18,12 @@ #include #include #include +#include #include #include #include #include +#include struct scmi_protocol { /* SCMI protocol message handler */ @@ -782,15 +784,68 @@ static int scmi_process_event(const struct fwk_event *event, return FWK_SUCCESS; } +static int scmi_start(fwk_id_t id) +{ + const struct mod_scmi_service_config *config; + unsigned int notifications_sent; + + if (fwk_id_is_type(id, FWK_ID_TYPE_MODULE)) + return FWK_SUCCESS; + + config = fwk_module_get_data(id); + + if (fwk_id_is_equal(config->transport_notification_init_id, FWK_ID_NONE)) { + /* Notify that the service is immediately ready */ + struct fwk_event scmi_services_initialized_notification = { + .id = mod_scmi_notification_id_initialized, + .source_id = id, + }; + + return fwk_notification_notify(&scmi_services_initialized_notification, + ¬ifications_sent); + } + + return fwk_notification_subscribe(config->transport_notification_init_id, + config->transport_id, + id); +} + +static int scmi_process_notification(const struct fwk_event *event, + struct fwk_event *resp_event) +{ + const struct mod_scmi_service_config *config; + unsigned int notifications_sent; + + fwk_assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_ELEMENT)); + + config = fwk_module_get_data(event->target_id); + if (config == NULL) + return FWK_E_PARAM; + + fwk_assert(fwk_id_is_equal(event->id, + config->transport_notification_init_id)); + + /* Notify that this service is ready */ + struct fwk_event scmi_services_initialized_notification = { + .id = mod_scmi_notification_id_initialized, + }; + + return fwk_notification_notify(&scmi_services_initialized_notification, + ¬ifications_sent); +} + /* SCMI module definition */ const struct fwk_module module_scmi = { .name = "SCMI", .api_count = MOD_SCMI_API_IDX_COUNT, .event_count = 1, + .notification_count = MOD_SCMI_NOTIFICATION_IDX_COUNT, .type = FWK_MODULE_TYPE_SERVICE, .init = scmi_init, .element_init = scmi_service_init, .bind = scmi_bind, + .start = scmi_start, .process_bind_request = scmi_process_bind_request, - .process_event = scmi_process_event + .process_event = scmi_process_event, + .process_notification = scmi_process_notification, }; diff --git a/module/smt/include/mod_smt.h b/module/smt/include/mod_smt.h index 2291b5f6996deb4733baf8bcf2f0ae6720f884fb..6c8a0c40f1dc96968d21ce8414eda402d1b576be 100644 --- a/module/smt/include/mod_smt.h +++ b/module/smt/include/mod_smt.h @@ -120,4 +120,24 @@ enum mod_smt_api_idx { MOD_SMT_API_IDX_COUNT, }; +/*! + * \brief SMT notification indices. + */ +enum mod_smt_notification_idx { + /*! The SMT channel has been initialized */ + MOD_SMT_NOTIFICATION_IDX_INITIALIZED, + + /*! Number of defined notifications */ + MOD_SMT_NOTIFICATION_IDX_COUNT +}; + +/*! + * \brief Identifier for the MOD_SMT_NOTIFICATION_IDX_INITIALIZED + * notification. + */ +static const fwk_id_t mod_smt_notification_id_initialized = + FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_NOTIFICATION_IDX_INITIALIZED); + #endif /* MOD_SMT_H */ diff --git a/module/smt/src/mod_smt.c b/module/smt/src/mod_smt.c index a1682b7c08c3d21f488651d70fddbd689f0aa21a..253271192c6fb2cc7ed4f83c00a78419a41d70fc 100644 --- a/module/smt/src/mod_smt.c +++ b/module/smt/src/mod_smt.c @@ -47,6 +47,9 @@ struct smt_channel_ctx { /* SCMI service API */ struct mod_scmi_from_transport_api *scmi_api; + + /* Flag indicating the mailbox is ready */ + bool smt_mailbox_ready; }; struct smt_ctx { @@ -343,6 +346,13 @@ static int smt_signal_message(fwk_id_t channel_id) channel_ctx = &smt_ctx.channel_ctx_table[fwk_id_get_element_idx(channel_id)]; + if (!channel_ctx->smt_mailbox_ready) { + /* Discard any message in the mailbox when not ready */ + smt_ctx.log_api->log(MOD_LOG_GROUP_ERROR, "[SMT] Message not valid\n"); + + return FWK_SUCCESS; + } + switch (channel_ctx->config->type) { case MOD_SMT_CHANNEL_TYPE_MASTER: /* Not supported yet */ @@ -531,6 +541,8 @@ static int smt_process_notification( { struct mod_pd_power_state_transition_notification_params *params; struct smt_channel_ctx *channel_ctx; + unsigned int notifications_sent; + int status; assert(fwk_id_is_equal(event->id, mod_pd_notification_id_power_state_transition)); @@ -539,18 +551,34 @@ static int smt_process_notification( params = (struct mod_pd_power_state_transition_notification_params *) event->params; - if (params->state != MOD_PD_STATE_ON) - return FWK_SUCCESS; - channel_ctx = &smt_ctx.channel_ctx_table[fwk_id_get_element_idx(event->target_id)]; + if (params->state != MOD_PD_STATE_ON) { + if (params->state == MOD_PD_STATE_OFF) + channel_ctx->smt_mailbox_ready = false; + + return FWK_SUCCESS; + } + if (channel_ctx->config->policies & MOD_SMT_POLICY_INIT_MAILBOX) { /* Initialize mailbox */ *((struct mod_smt_memory *)channel_ctx->config->mailbox_address) = (struct mod_smt_memory) { .status = (1 << MOD_SMT_MAILBOX_STATUS_FREE_POS) }; + + /* Notify that this mailbox is initialized */ + struct fwk_event smt_channels_initialized_notification = { + .id = mod_smt_notification_id_initialized, + }; + + channel_ctx->smt_mailbox_ready = true; + + status = fwk_notification_notify(&smt_channels_initialized_notification, + ¬ifications_sent); + if (status != FWK_SUCCESS) + return status; } return FWK_SUCCESS; @@ -560,6 +588,7 @@ const struct fwk_module module_smt = { .name = "smt", .type = FWK_MODULE_TYPE_SERVICE, .api_count = MOD_SMT_API_IDX_COUNT, + .notification_count = MOD_SMT_NOTIFICATION_IDX_COUNT, .init = smt_init, .element_init = smt_channel_init, .bind = smt_bind, diff --git a/product/n1sdp/module/n1sdp_system/src/mod_n1sdp_system.c b/product/n1sdp/module/n1sdp_system/src/mod_n1sdp_system.c index 61ba9f18786c29b60721c55597ba5707f5bee847..d735e33a15e63ff6b5f0777fb1c85770b97d6a57 100644 --- a/product/n1sdp/module/n1sdp_system/src/mod_n1sdp_system.c +++ b/product/n1sdp/module/n1sdp_system/src/mod_n1sdp_system.c @@ -25,11 +25,15 @@ #include #include #include +#include +#include #include #include #include #include #include +#include +#include #include #include @@ -43,6 +47,19 @@ struct cs_cnt_ctrl_reg { #define CS_CNTCONTROL ((struct cs_cnt_ctrl_reg *)SCP_CS_CNTCONTROL_BASE) +/* SCMI Services used by software on the AP cores */ +static unsigned int scmi_notification_table[] = { + SCP_N1SDP_SCMI_SERVICE_IDX_PSCI, + SCP_N1SDP_SCMI_SERVICE_IDX_OSPM, +}; + +/* SDS Feature flags */ +static const uint32_t feature_flags = (N1SDP_SDS_FEATURE_FIRMWARE_MASK | + N1SDP_SDS_FEATURE_DMC_MASK | + N1SDP_SDS_FEATURE_MESSAGING_MASK); +static fwk_id_t sds_feature_availability_id = + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SDS, 3); + /* Module context */ struct n1sdp_system_ctx { @@ -57,6 +74,9 @@ struct n1sdp_system_ctx { /* Pointer to N1SDP Flash APIs */ const struct mod_n1sdp_flash_api *flash_api; + + /* Pointer to SDS */ + const struct mod_sds_api *sds_api; }; struct n1sdp_system_isr { @@ -273,6 +293,126 @@ void csys_pwrupreq_handler(void) fwk_interrupt_disable(CSYS_PWR_UP_REQ_IRQ); } +/* + * Initialize primary core during system initialization + */ +static int n1sdp_system_init_primary_core(void) +{ + int status; + struct mod_pd_restricted_api *mod_pd_restricted_api = NULL; + struct mod_n1sdp_fip_descriptor *fip_desc_table = NULL; + unsigned int fip_count; + unsigned int i; + unsigned int core_idx; + unsigned int cluster_idx; + unsigned int cluster_count; + int fip_index_bl31 = -1; + int fip_index_bl33 = -1; + + n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, + "[N1SDP SYSTEM] Looking for AP firmware in flash memory...\n"); + + status = n1sdp_system_ctx.flash_api->get_n1sdp_fip_descriptor_count( + FWK_ID_MODULE(FWK_MODULE_IDX_N1SDP_SYSTEM), &fip_count); + if (status != FWK_SUCCESS) + return status; + + status = n1sdp_system_ctx.flash_api->get_n1sdp_fip_descriptor_table( + FWK_ID_MODULE(FWK_MODULE_IDX_N1SDP_SYSTEM), &fip_desc_table); + if (status != FWK_SUCCESS) + return status; + + for (i = 0; i < fip_count; i++) { + if (fip_desc_table[i].type == MOD_N1SDP_FIP_TYPE_TF_BL31) { + n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, + "[N1SDP SYSTEM] Found BL31 at address: 0x%08x," + " size: %u, flags: 0x%x\n", + fip_desc_table[i].address, fip_desc_table[i].size, + fip_desc_table[i].flags); + fip_index_bl31 = i; + } else if (fip_desc_table[i].type == MOD_N1SDP_FIP_TYPE_NS_BL33) { + n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, + "[N1SDP SYSTEM] Found BL33 at address: 0x%08x," + " size: %u, flags: 0x%x\n", + fip_desc_table[i].address, fip_desc_table[i].size, + fip_desc_table[i].flags); + fip_index_bl33 = i; + } + } + + if ((fip_index_bl31 < 0) || (fip_index_bl33 < 0)) { + n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, + "[N1SDP SYSTEM] Error! " + "FIP does not have all required binaries\n"); + return FWK_E_PANIC; + } + + n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, + "[N1SDP SYSTEM] Copying AP BL31 to address 0x%x...\n", + AP_CORE_RESET_ADDR); + + status = n1sdp_system_copy_to_ap_sram(AP_CORE_RESET_ADDR, + fip_desc_table[fip_index_bl31].address, + fip_desc_table[fip_index_bl31].size); + if (status != FWK_SUCCESS) + return FWK_E_PANIC; + + n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, + "[N1SDP SYSTEM] Copying AP BL33 to address 0x%x...\n", + AP_BL33_BASE_ADDR); + + status = n1sdp_system_copy_to_ap_ddr(AP_BL33_BASE_ADDR, + fip_desc_table[fip_index_bl33].address, + fip_desc_table[fip_index_bl33].size); + if (status != FWK_SUCCESS) + return FWK_E_PANIC; + + mod_pd_restricted_api = n1sdp_system_ctx.mod_pd_restricted_api; + + n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, + "[N1SDP SYSTEM] Setting AP Reset Address to 0x%x\n", + AP_CORE_RESET_ADDR); + + cluster_count = n1sdp_core_get_cluster_count(); + for (cluster_idx = 0; cluster_idx < cluster_count; cluster_idx++) { + for (core_idx = 0; + core_idx < n1sdp_core_get_core_per_cluster_count(cluster_idx); + core_idx++) { + PIK_CLUSTER(cluster_idx)->STATIC_CONFIG[core_idx].RVBARADDR_LW + = (uint32_t)(AP_CORE_RESET_ADDR - AP_SCP_SRAM_OFFSET); + PIK_CLUSTER(cluster_idx)->STATIC_CONFIG[core_idx].RVBARADDR_UP + = (uint32_t) + ((AP_CORE_RESET_ADDR - AP_SCP_SRAM_OFFSET) >> 32); + } + } + + n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_DEBUG, + "[N1SDP SYSTEM] Switching ON primary core...\n"); + + status = mod_pd_restricted_api->set_composite_state_async( + FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, 0), + false, + MOD_PD_COMPOSITE_STATE(MOD_PD_LEVEL_2, 0, MOD_PD_STATE_ON, + MOD_PD_STATE_ON, MOD_PD_STATE_ON)); + if (status != FWK_SUCCESS) + return status; + + return FWK_SUCCESS; +} + +static int messaging_stack_ready(void) +{ + const struct mod_sds_structure_desc *sds_structure_desc = + fwk_module_get_data(sds_feature_availability_id); + + /* + * Write SDS Feature Availability to signal the completion of the messaging + * stack + */ + return n1sdp_system_ctx.sds_api->struct_write(sds_structure_desc->id, + 0, (void *)(&feature_flags), sds_structure_desc->size); +} + /* * Functions fulfilling the framework's module interface */ @@ -298,16 +438,17 @@ static int n1sdp_system_bind(fwk_id_t id, unsigned int round) { int status; - if (round == 0) { - status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), - FWK_ID_API(FWK_MODULE_IDX_LOG, 0), &n1sdp_system_ctx.log_api); - if (status != FWK_SUCCESS) - return status; - } + if (round > 0) + return FWK_SUCCESS; + + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), + FWK_ID_API(FWK_MODULE_IDX_LOG, 0), &n1sdp_system_ctx.log_api); + if (status != FWK_SUCCESS) + return status; status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_N1SDP_FLASH), - FWK_ID_API(FWK_MODULE_IDX_N1SDP_FLASH, 0), - &n1sdp_system_ctx.flash_api); + FWK_ID_API(FWK_MODULE_IDX_N1SDP_FLASH, 0), + &n1sdp_system_ctx.flash_api); if (status != FWK_SUCCESS) return status; @@ -317,9 +458,15 @@ static int n1sdp_system_bind(fwk_id_t id, unsigned int round) if (status != FWK_SUCCESS) return status; - return fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_PPU_V1), + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_PPU_V1), FWK_ID_API(FWK_MODULE_IDX_PPU_V1, MOD_PPU_V1_API_IDX_ISR), &n1sdp_system_ctx.ppu_v1_isr_api); + if (status != FWK_SUCCESS) + return status; + + return fwk_module_bind(fwk_module_id_sds, + FWK_ID_API(FWK_MODULE_IDX_SDS, 0), + &n1sdp_system_ctx.sds_api); } static int n1sdp_system_process_bind_request(fwk_id_t requester_id, @@ -342,6 +489,7 @@ static int n1sdp_system_process_bind_request(fwk_id_t requester_id, static int n1sdp_system_start(fwk_id_t id) { int status; + unsigned int i; status = fwk_notification_subscribe( mod_clock_notification_id_state_changed, @@ -379,6 +527,33 @@ static int n1sdp_system_start(fwk_id_t id) n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_DEBUG, "[N1SDP SYSTEM] Requesting SYSTOP initialization...\n"); + /* + * Subscribe to these SCMI channels in order to know when they have all + * initialized. + * At that point we can consider the SCMI stack to be initialized from + * the point of view of the PSCI agent. + */ + for (i = 0; i < FWK_ARRAY_SIZE(scmi_notification_table); i++) { + status = fwk_notification_subscribe( + mod_scmi_notification_id_initialized, + fwk_id_build_element_id(fwk_module_id_scmi, + scmi_notification_table[i]), + id); + if (status != FWK_SUCCESS) + return status; + } + + /* + * Subscribe to the SDS initialized notification so we can correctly let the + * PSCI agent know that the SCMI stack is initialized. + */ + status = fwk_notification_subscribe( + mod_sds_notification_id_initialized, + fwk_module_id_sds, + id); + if (status != FWK_SUCCESS) + return status; + return n1sdp_system_ctx.mod_pd_restricted_api->set_composite_state_async( FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, 0), false, MOD_PD_COMPOSITE_STATE(MOD_PD_LEVEL_2, 0, MOD_PD_STATE_ON, @@ -389,124 +564,50 @@ static int n1sdp_system_process_notification(const struct fwk_event *event, struct fwk_event *resp_event) { struct clock_notification_params *params = NULL; - struct mod_pd_restricted_api *mod_pd_restricted_api = NULL; - struct mod_n1sdp_fip_descriptor *fip_desc_table = NULL; - unsigned int fip_count; - unsigned int i; - unsigned int core_idx; - unsigned int cluster_idx; - unsigned int cluster_count; - int fip_index_bl31 = -1; - int fip_index_bl33 = -1; + static unsigned int scmi_notification_count = 0; + static bool sds_notification_received = false; int status; - assert(fwk_id_is_equal(event->id, - mod_clock_notification_id_state_changed)); assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_MODULE)); params = (struct clock_notification_params *)event->params; - /* - * Initialize primary core when the system is initialized for the - * first time only. - */ - if (params->new_state == MOD_CLOCK_STATE_RUNNING) { - - n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, - "[N1SDP SYSTEM] Looking for AP firmware in flash memory...\n"); + if (fwk_id_is_equal(event->id, mod_clock_notification_id_state_changed)) { - status = n1sdp_system_ctx.flash_api->get_n1sdp_fip_descriptor_count( - FWK_ID_MODULE(FWK_MODULE_IDX_N1SDP_SYSTEM), &fip_count); - if (status != FWK_SUCCESS) - return status; - - status = n1sdp_system_ctx.flash_api->get_n1sdp_fip_descriptor_table( - FWK_ID_MODULE(FWK_MODULE_IDX_N1SDP_SYSTEM), &fip_desc_table); - if (status != FWK_SUCCESS) - return status; - - for (i = 0; i < fip_count; i++) { - if (fip_desc_table[i].type == MOD_N1SDP_FIP_TYPE_TF_BL31) { - n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, - "[N1SDP SYSTEM] Found BL31 at address: 0x%08x," - " size: %u, flags: 0x%x\n", - fip_desc_table[i].address, fip_desc_table[i].size, - fip_desc_table[i].flags); - fip_index_bl31 = i; - } else if (fip_desc_table[i].type == MOD_N1SDP_FIP_TYPE_NS_BL33) { - n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, - "[N1SDP SYSTEM] Found BL33 at address: 0x%08x," - " size: %u, flags: 0x%x\n", - fip_desc_table[i].address, fip_desc_table[i].size, - fip_desc_table[i].flags); - fip_index_bl33 = i; - } - } - - if ((fip_index_bl31 < 0) || (fip_index_bl33 < 0)) { - n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, - "[N1SDP SYSTEM] Error! " - "FIP does not have all required binaries\n"); - return FWK_E_PANIC; - } - - n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, - "[N1SDP SYSTEM] Copying AP BL31 to address 0x%x...\n", - AP_CORE_RESET_ADDR); - - status = n1sdp_system_copy_to_ap_sram(AP_CORE_RESET_ADDR, - fip_desc_table[fip_index_bl31].address, - fip_desc_table[fip_index_bl31].size); - if (status != FWK_SUCCESS) - return FWK_E_PANIC; - - n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, - "[N1SDP SYSTEM] Copying AP BL33 to address 0x%x...\n", - AP_BL33_BASE_ADDR); - - status = n1sdp_system_copy_to_ap_ddr(AP_BL33_BASE_ADDR, - fip_desc_table[fip_index_bl33].address, - fip_desc_table[fip_index_bl33].size); - if (status != FWK_SUCCESS) - return FWK_E_PANIC; - - mod_pd_restricted_api = n1sdp_system_ctx.mod_pd_restricted_api; + /* + * Initialize primary core when the system is initialized for the + * first time only. + */ + if (params->new_state == MOD_CLOCK_STATE_RUNNING) { + status = n1sdp_system_init_primary_core(); + if (status != FWK_SUCCESS) + return status; - n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_INFO, - "[N1SDP SYSTEM] Setting AP Reset Address to 0x%x\n", - AP_CORE_RESET_ADDR); - - cluster_count = n1sdp_core_get_cluster_count(); - for (cluster_idx = 0; cluster_idx < cluster_count; cluster_idx++) { - for (core_idx = 0; - core_idx < n1sdp_core_get_core_per_cluster_count(cluster_idx); - core_idx++) { - PIK_CLUSTER(cluster_idx)->STATIC_CONFIG[core_idx].RVBARADDR_LW - = (uint32_t)(AP_CORE_RESET_ADDR - AP_SCP_SRAM_OFFSET); - PIK_CLUSTER(cluster_idx)->STATIC_CONFIG[core_idx].RVBARADDR_UP - = (uint32_t) - ((AP_CORE_RESET_ADDR - AP_SCP_SRAM_OFFSET) >> 32); - } + /* + * Unsubscribe to interconnect clock state change notification as + * it has to be processed only once during system startup. + */ + return fwk_notification_unsubscribe(event->id, event->source_id, + event->target_id); } - n1sdp_system_ctx.log_api->log(MOD_LOG_GROUP_DEBUG, - "[N1SDP SYSTEM] Switching ON primary core...\n"); + return FWK_SUCCESS; + } else if (fwk_id_is_equal(event->id, + mod_scmi_notification_id_initialized)) { + scmi_notification_count++; + } else if (fwk_id_is_equal(event->id, + mod_sds_notification_id_initialized)) { + sds_notification_received = true; + } else + return FWK_E_PARAM; - status = mod_pd_restricted_api->set_composite_state_async( - FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, 0), - false, - MOD_PD_COMPOSITE_STATE(MOD_PD_LEVEL_2, 0, MOD_PD_STATE_ON, - MOD_PD_STATE_ON, MOD_PD_STATE_ON)); - if (status != FWK_SUCCESS) - return status; + if ((scmi_notification_count == FWK_ARRAY_SIZE(scmi_notification_table)) && + sds_notification_received) { + messaging_stack_ready(); - /* - * Unsubscribe to interconnect clock state change notification as - * it has to be processed only once during system startup. - */ - return fwk_notification_unsubscribe(event->id, event->source_id, - event->target_id); - } + scmi_notification_count = 0; + sds_notification_received = false; + } return FWK_SUCCESS; } diff --git a/product/n1sdp/scp_ramfw/config_scmi.c b/product/n1sdp/scp_ramfw/config_scmi.c index d68e1da4fdf56c6e644a76b1ca0ab6bd02ce4a86..c395c9d3e8d40144a0efaa46a8dea904a58f70e9 100644 --- a/product/n1sdp/scp_ramfw/config_scmi.c +++ b/product/n1sdp/scp_ramfw/config_scmi.c @@ -25,6 +25,9 @@ static const struct fwk_element service_table[] = { .transport_api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), + .transport_notification_init_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_NOTIFICATION_IDX_INITIALIZED), .scmi_agent_id = SCP_SCMI_AGENT_ID_PSCI, }), }, @@ -37,6 +40,9 @@ static const struct fwk_element service_table[] = { .transport_api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), + .transport_notification_init_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_NOTIFICATION_IDX_INITIALIZED), .scmi_agent_id = SCP_SCMI_AGENT_ID_OSPM, }), }, @@ -49,6 +55,7 @@ static const struct fwk_element service_table[] = { .transport_api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), + .transport_notification_init_id = FWK_ID_NONE_INIT, .scmi_agent_id = SCP_SCMI_AGENT_ID_MCP, }), }, diff --git a/product/n1sdp/scp_ramfw/config_sds.c b/product/n1sdp/scp_ramfw/config_sds.c index 765043c3e239d019ccc7f5a82f547b7ec8dd4305..53f022a34cbf256748bd979e6d648d8306ed9177 100644 --- a/product/n1sdp/scp_ramfw/config_sds.c +++ b/product/n1sdp/scp_ramfw/config_sds.c @@ -19,9 +19,7 @@ #include static const uint32_t version_packed = FWK_BUILD_VERSION; -static const uint32_t feature_flags = (N1SDP_SDS_FEATURE_FIRMWARE_MASK | - N1SDP_SDS_FEATURE_DMC_MASK | - N1SDP_SDS_FEATURE_MESSAGING_MASK); +static const uint32_t feature_flags = 0x00000000; const struct mod_sds_config sds_module_config = { .region_base_address = SCP_SDS_MEM_BASE, diff --git a/product/rdn1e1/module/rdn1e1_system/src/mod_rdn1e1_system.c b/product/rdn1e1/module/rdn1e1_system/src/mod_rdn1e1_system.c index 225810327311b72818338566befe519d7433ed66..419d34944707a3901f9b9123443eef73353075b1 100644 --- a/product/rdn1e1/module/rdn1e1_system/src/mod_rdn1e1_system.c +++ b/product/rdn1e1/module/rdn1e1_system/src/mod_rdn1e1_system.c @@ -20,15 +20,25 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #include #include +#include #include +/* SCMI services required to enable the messaging stack */ +static unsigned int scmi_notification_table[] = { + SCP_RDN1E1_SCMI_SERVICE_IDX_PSCI, + SCP_RDN1E1_SCMI_SERVICE_IDX_OSPM, +}; + /* Module context */ struct rdn1e1_system_ctx { /* Pointer to the SCP PIK registers */ @@ -42,6 +52,9 @@ struct rdn1e1_system_ctx { /* Power domain module restricted API pointer */ struct mod_pd_restricted_api *mod_pd_restricted_api; + + /* SDS API pointer */ + const struct mod_sds_api *sds_api; }; struct rdn1e1_system_isr { @@ -52,6 +65,30 @@ struct rdn1e1_system_isr { static struct rdn1e1_system_ctx rdn1e1_system_ctx; const struct fwk_module_config config_rdn1e1_system = { 0 }; +static const uint32_t feature_flags = (RDN1E1_SDS_FEATURE_FIRMWARE_MASK | + RDN1E1_SDS_FEATURE_DMC_MASK | + RDN1E1_SDS_FEATURE_MESSAGING_MASK); + +static fwk_id_t sds_feature_availability_id = + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SDS, 3); + +/* + * SCMI Messaging stack + */ + +static int messaging_stack_ready(void) +{ + const struct mod_sds_structure_desc *sds_structure_desc = + fwk_module_get_data(sds_feature_availability_id); + + /* + * Write SDS Feature Availability to signal the completion of the messaging + * stack + */ + return rdn1e1_system_ctx.sds_api->struct_write(sds_structure_desc->id, + 0, (void *)(&feature_flags), sds_structure_desc->size); +} + /* * PPU Interrupt Service Routines for cluster and core power domains */ @@ -173,12 +210,13 @@ static int rdn1e1_system_bind(fwk_id_t id, unsigned int round) { int status; - if (round == 0) { - status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), - FWK_ID_API(FWK_MODULE_IDX_LOG, 0), &rdn1e1_system_ctx.log_api); - if (status != FWK_SUCCESS) - return status; - } + if (round > 0) + return FWK_SUCCESS; + + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), + FWK_ID_API(FWK_MODULE_IDX_LOG, 0), &rdn1e1_system_ctx.log_api); + if (status != FWK_SUCCESS) + return status; status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_POWER_DOMAIN), FWK_ID_API(FWK_MODULE_IDX_POWER_DOMAIN, MOD_PD_API_IDX_RESTRICTED), @@ -186,9 +224,15 @@ static int rdn1e1_system_bind(fwk_id_t id, unsigned int round) if (status != FWK_SUCCESS) return status; - return fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_PPU_V1), + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_PPU_V1), FWK_ID_API(FWK_MODULE_IDX_PPU_V1, MOD_PPU_V1_API_IDX_ISR), &rdn1e1_system_ctx.ppu_v1_isr_api); + if (status != FWK_SUCCESS) + return status; + + return fwk_module_bind(fwk_module_id_sds, + FWK_ID_API(FWK_MODULE_IDX_SDS, 0), + &rdn1e1_system_ctx.sds_api); } static int rdn1e1_system_process_bind_request(fwk_id_t requester_id, @@ -201,6 +245,7 @@ static int rdn1e1_system_process_bind_request(fwk_id_t requester_id, static int rdn1e1_system_start(fwk_id_t id) { int status; + unsigned int i; status = fwk_notification_subscribe( mod_clock_notification_id_state_changed, @@ -212,6 +257,33 @@ static int rdn1e1_system_start(fwk_id_t id) rdn1e1_system_ctx.log_api->log(MOD_LOG_GROUP_DEBUG, "[RDN1E1 SYSTEM] Requesting SYSTOP initialization...\n"); + /* + * Subscribe to these SCMI channels in order to know when they have all + * initialized. + * At that point we can consider the SCMI stack to be initialized from + * the point of view of the PSCI agent. + */ + for (i = 0; i < FWK_ARRAY_SIZE(scmi_notification_table); i++) { + status = fwk_notification_subscribe( + mod_scmi_notification_id_initialized, + fwk_id_build_element_id(fwk_module_id_scmi, + scmi_notification_table[i]), + id); + if (status != FWK_SUCCESS) + return status; + } + + /* + * Subscribe to the SDS initialized notification so we can correctly let the + * PSCI agent know that the SCMI stack is initialized. + */ + status = fwk_notification_subscribe( + mod_sds_notification_id_initialized, + fwk_module_id_sds, + id); + if (status != FWK_SUCCESS) + return status; + return rdn1e1_system_ctx.mod_pd_restricted_api->set_composite_state_async( FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, 0), false, @@ -225,33 +297,53 @@ int rdn1e1_system_process_notification(const struct fwk_event *event, int status; struct clock_notification_params *params; struct mod_pd_restricted_api *mod_pd_restricted_api; + static unsigned int scmi_notification_count = 0; + static bool sds_notification_received = false; - assert(fwk_id_is_equal(event->id, mod_clock_notification_id_state_changed)); assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_MODULE)); - params = (struct clock_notification_params *)event->params; - - /* - * Initialize primary core when the system is initialized for the first time - * only - */ - if (params->new_state == MOD_CLOCK_STATE_RUNNING) { - rdn1e1_system_ctx.log_api->log(MOD_LOG_GROUP_DEBUG, - "[RDN1E1 SYSTEM] Initializing the primary core...\n"); - - mod_pd_restricted_api = rdn1e1_system_ctx.mod_pd_restricted_api; - - status = mod_pd_restricted_api->set_composite_state_async( - FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, 0), - false, - MOD_PD_COMPOSITE_STATE(MOD_PD_LEVEL_2, 0, MOD_PD_STATE_ON, - MOD_PD_STATE_ON, MOD_PD_STATE_ON)); - if (status != FWK_SUCCESS) - return status; - - /* Unsubscribe to the notification */ - return fwk_notification_unsubscribe(event->id, event->source_id, - event->target_id); + if (fwk_id_is_equal(event->id, mod_clock_notification_id_state_changed)) { + params = (struct clock_notification_params *)event->params; + + /* + * Initialize primary core when the system is initialized for the first + * time only + */ + if (params->new_state == MOD_CLOCK_STATE_RUNNING) { + rdn1e1_system_ctx.log_api->log(MOD_LOG_GROUP_DEBUG, + "[RDN1E1 SYSTEM] Initializing the primary core...\n"); + + mod_pd_restricted_api = rdn1e1_system_ctx.mod_pd_restricted_api; + + status = mod_pd_restricted_api->set_composite_state_async( + FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, 0), + false, + MOD_PD_COMPOSITE_STATE(MOD_PD_LEVEL_2, 0, MOD_PD_STATE_ON, + MOD_PD_STATE_ON, MOD_PD_STATE_ON)); + if (status != FWK_SUCCESS) + return status; + + /* Unsubscribe to the notification */ + return fwk_notification_unsubscribe(event->id, event->source_id, + event->target_id); + } + + return FWK_SUCCESS; + } else if (fwk_id_is_equal(event->id, + mod_scmi_notification_id_initialized)) { + scmi_notification_count++; + } else if (fwk_id_is_equal(event->id, + mod_sds_notification_id_initialized)) { + sds_notification_received = true; + } else + return FWK_E_PARAM; + + if ((scmi_notification_count == FWK_ARRAY_SIZE(scmi_notification_table)) && + sds_notification_received) { + messaging_stack_ready(); + + scmi_notification_count = 0; + sds_notification_received = false; } return FWK_SUCCESS; diff --git a/product/rdn1e1/scp_ramfw/config_scmi.c b/product/rdn1e1/scp_ramfw/config_scmi.c index 0da2fee190c4167e88296dd57e515c9d781a360b..1ec6057fe476cfc1e0e53a469102a60d2c064ef7 100644 --- a/product/rdn1e1/scp_ramfw/config_scmi.c +++ b/product/rdn1e1/scp_ramfw/config_scmi.c @@ -25,6 +25,9 @@ static const struct fwk_element service_table[] = { .transport_api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), + .transport_notification_init_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_NOTIFICATION_IDX_INITIALIZED), .scmi_agent_id = SCP_SCMI_AGENT_ID_PSCI, }), }, @@ -37,6 +40,9 @@ static const struct fwk_element service_table[] = { .transport_api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), + .transport_notification_init_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_NOTIFICATION_IDX_INITIALIZED), .scmi_agent_id = SCP_SCMI_AGENT_ID_OSPM, }), }, diff --git a/product/rdn1e1/scp_ramfw/config_sds.c b/product/rdn1e1/scp_ramfw/config_sds.c index db795fba2cabdad71f226a052db7913b03576a89..766823e531d3eac13aea3fee5a433b2b9df6848e 100644 --- a/product/rdn1e1/scp_ramfw/config_sds.c +++ b/product/rdn1e1/scp_ramfw/config_sds.c @@ -21,9 +21,7 @@ #include static const uint32_t version_packed = FWK_BUILD_VERSION; -static const uint32_t feature_flags = (RDN1E1_SDS_FEATURE_FIRMWARE_MASK | - RDN1E1_SDS_FEATURE_DMC_MASK | - RDN1E1_SDS_FEATURE_MESSAGING_MASK); +static const uint32_t feature_flags = 0x00000000; const struct mod_sds_config sds_module_config = { .region_base_address = SCP_SDS_MEM_BASE, diff --git a/product/sgi575/module/sgi575_system/src/mod_sgi575_system.c b/product/sgi575/module/sgi575_system/src/mod_sgi575_system.c index 861f529cee2e2687b1ef491c79e8da8615d92fac..be6ab8567bd922f77c71a2f98c74c2a3a5fba8fe 100644 --- a/product/sgi575/module/sgi575_system/src/mod_sgi575_system.c +++ b/product/sgi575/module/sgi575_system/src/mod_sgi575_system.c @@ -21,14 +21,24 @@ #include #include #include +#include +#include #include #include #include #include +#include #include #include +#include #include +/* SCMI services required to enable the messaging stack */ +static unsigned int scmi_notification_table[] = { + SCP_SGI575_SCMI_SERVICE_IDX_PSCI, + SCP_SGI575_SCMI_SERVICE_IDX_OSPM, +}; + /* Module context */ struct sgi575_system_ctx { /* Pointer to the SCP PIK registers */ @@ -42,6 +52,9 @@ struct sgi575_system_ctx { /* Power domain module restricted API pointer */ struct mod_pd_restricted_api *mod_pd_restricted_api; + + /* SDS API pointer */ + const struct mod_sds_api *sds_api; }; struct sgi575_system_isr { @@ -52,6 +65,30 @@ struct sgi575_system_isr { static struct sgi575_system_ctx sgi575_system_ctx; const struct fwk_module_config config_sgi575_system = { 0 }; +static const uint32_t feature_flags = (SGI575_SDS_FEATURE_FIRMWARE_MASK | + SGI575_SDS_FEATURE_DMC_MASK | + SGI575_SDS_FEATURE_MESSAGING_MASK); + +static fwk_id_t sds_feature_availability_id = + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SDS, 4); + +/* + * SCMI Messaging stack + */ + +static int messaging_stack_ready(void) +{ + const struct mod_sds_structure_desc *sds_structure_desc = + fwk_module_get_data(sds_feature_availability_id); + + /* + * Write SDS Feature Availability to signal the completion of the messaging + * stack + */ + return sgi575_system_ctx.sds_api->struct_write(sds_structure_desc->id, + 0, (void *)(&feature_flags), sds_structure_desc->size); +} + /* * PPU Interrupt Service Routines for cluster and core power domains */ @@ -173,12 +210,13 @@ static int sgi575_system_bind(fwk_id_t id, unsigned int round) { int status; - if (round == 0) { - status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), - FWK_ID_API(FWK_MODULE_IDX_LOG, 0), &sgi575_system_ctx.log_api); - if (status != FWK_SUCCESS) - return status; - } + if (round > 0) + return FWK_SUCCESS; + + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), + FWK_ID_API(FWK_MODULE_IDX_LOG, 0), &sgi575_system_ctx.log_api); + if (status != FWK_SUCCESS) + return status; status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_POWER_DOMAIN), FWK_ID_API(FWK_MODULE_IDX_POWER_DOMAIN, MOD_PD_API_IDX_RESTRICTED), @@ -186,9 +224,15 @@ static int sgi575_system_bind(fwk_id_t id, unsigned int round) if (status != FWK_SUCCESS) return status; - return fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_PPU_V1), + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_PPU_V1), FWK_ID_API(FWK_MODULE_IDX_PPU_V1, MOD_PPU_V1_API_IDX_ISR), &sgi575_system_ctx.ppu_v1_isr_api); + if (status != FWK_SUCCESS) + return status; + + return fwk_module_bind(fwk_module_id_sds, + FWK_ID_API(FWK_MODULE_IDX_SDS, 0), + &sgi575_system_ctx.sds_api); } static int sgi575_system_process_bind_request(fwk_id_t requester_id, @@ -201,6 +245,7 @@ static int sgi575_system_process_bind_request(fwk_id_t requester_id, static int sgi575_system_start(fwk_id_t id) { int status; + unsigned int i; status = fwk_notification_subscribe( mod_clock_notification_id_state_changed, @@ -212,6 +257,33 @@ static int sgi575_system_start(fwk_id_t id) sgi575_system_ctx.log_api->log(MOD_LOG_GROUP_DEBUG, "[SGI575 SYSTEM] Requesting SYSTOP initialization...\n"); + /* + * Subscribe to these SCMI channels in order to know when they have all + * initialized. + * At that point we can consider the SCMI stack to be initialized from + * the point of view of the PSCI agent. + */ + for (i = 0; i < FWK_ARRAY_SIZE(scmi_notification_table); i++) { + status = fwk_notification_subscribe( + mod_scmi_notification_id_initialized, + fwk_id_build_element_id(fwk_module_id_scmi, + scmi_notification_table[i]), + id); + if (status != FWK_SUCCESS) + return status; + } + + /* + * Subscribe to the SDS initialized notification so we can correctly let the + * PSCI agent know that the SCMI stack is initialized. + */ + status = fwk_notification_subscribe( + mod_sds_notification_id_initialized, + fwk_module_id_sds, + id); + if (status != FWK_SUCCESS) + return status; + return sgi575_system_ctx.mod_pd_restricted_api->set_composite_state_async( FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, 0), false, @@ -225,33 +297,53 @@ int sgi575_system_process_notification(const struct fwk_event *event, int status; struct clock_notification_params *params; struct mod_pd_restricted_api *mod_pd_restricted_api; + static unsigned int scmi_notification_count = 0; + static bool sds_notification_received = false; - assert(fwk_id_is_equal(event->id, mod_clock_notification_id_state_changed)); assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_MODULE)); - params = (struct clock_notification_params *)event->params; - - /* - * Initialize primary core when the system is initialized for the first time - * only - */ - if (params->new_state == MOD_CLOCK_STATE_RUNNING) { - sgi575_system_ctx.log_api->log(MOD_LOG_GROUP_DEBUG, - "[SGI575 SYSTEM] Initializing the primary core...\n"); - - mod_pd_restricted_api = sgi575_system_ctx.mod_pd_restricted_api; - - status = mod_pd_restricted_api->set_composite_state_async( - FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, 0), - false, - MOD_PD_COMPOSITE_STATE(MOD_PD_LEVEL_2, 0, MOD_PD_STATE_ON, - MOD_PD_STATE_ON, MOD_PD_STATE_ON)); - if (status != FWK_SUCCESS) - return status; - - /* Unsubscribe to the notification */ - return fwk_notification_unsubscribe(event->id, event->source_id, - event->target_id); + if (fwk_id_is_equal(event->id, mod_clock_notification_id_state_changed)) { + params = (struct clock_notification_params *)event->params; + + /* + * Initialize primary core when the system is initialized for the first + * time only + */ + if (params->new_state == MOD_CLOCK_STATE_RUNNING) { + sgi575_system_ctx.log_api->log(MOD_LOG_GROUP_DEBUG, + "[SGI575 SYSTEM] Initializing the primary core...\n"); + + mod_pd_restricted_api = sgi575_system_ctx.mod_pd_restricted_api; + + status = mod_pd_restricted_api->set_composite_state_async( + FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, 0), + false, + MOD_PD_COMPOSITE_STATE(MOD_PD_LEVEL_2, 0, MOD_PD_STATE_ON, + MOD_PD_STATE_ON, MOD_PD_STATE_ON)); + if (status != FWK_SUCCESS) + return status; + + /* Unsubscribe to the notification */ + return fwk_notification_unsubscribe(event->id, event->source_id, + event->target_id); + } + + return FWK_SUCCESS; + } else if (fwk_id_is_equal(event->id, + mod_scmi_notification_id_initialized)) { + scmi_notification_count++; + } else if (fwk_id_is_equal(event->id, + mod_sds_notification_id_initialized)) { + sds_notification_received = true; + } else + return FWK_E_PARAM; + + if ((scmi_notification_count == FWK_ARRAY_SIZE(scmi_notification_table)) && + sds_notification_received) { + messaging_stack_ready(); + + scmi_notification_count = 0; + sds_notification_received = false; } return FWK_SUCCESS; diff --git a/product/sgi575/scp_ramfw/config_scmi.c b/product/sgi575/scp_ramfw/config_scmi.c index 3ceb793006958f119876ac4825f572caa697bbec..72b73f67907e9cff4277a16ae1b0fa784d7ee4b6 100644 --- a/product/sgi575/scp_ramfw/config_scmi.c +++ b/product/sgi575/scp_ramfw/config_scmi.c @@ -25,6 +25,9 @@ static const struct fwk_element service_table[] = { .transport_api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), + .transport_notification_init_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_NOTIFICATION_IDX_INITIALIZED), .scmi_agent_id = SCP_SCMI_AGENT_ID_PSCI, }), }, @@ -37,6 +40,9 @@ static const struct fwk_element service_table[] = { .transport_api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), + .transport_notification_init_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_NOTIFICATION_IDX_INITIALIZED), .scmi_agent_id = SCP_SCMI_AGENT_ID_OSPM, }), }, diff --git a/product/sgi575/scp_ramfw/config_sds.c b/product/sgi575/scp_ramfw/config_sds.c index f6d0152a87a60d7960d1b3c91560c8a74ad73879..98265fb4455b9aa46a2bacfcb8a975bfeda8b467 100644 --- a/product/sgi575/scp_ramfw/config_sds.c +++ b/product/sgi575/scp_ramfw/config_sds.c @@ -21,9 +21,7 @@ #include static const uint32_t version_packed = FWK_BUILD_VERSION; -static const uint32_t feature_flags = (SGI575_SDS_FEATURE_FIRMWARE_MASK | - SGI575_SDS_FEATURE_DMC_MASK | - SGI575_SDS_FEATURE_MESSAGING_MASK); +static const uint32_t feature_flags = 0x00000000; const struct mod_sds_config sds_module_config = { .region_base_address = SCP_SDS_MEM_BASE, diff --git a/product/sgm775/module/sgm775_system/src/mod_sgm775_system.c b/product/sgm775/module/sgm775_system/src/mod_sgm775_system.c index 10d6bbe6d1b8ff4c2e1ddf7bbf2dd402ed3b6071..94c3977006bc2f64a856d82357bb56a99a77ef3c 100644 --- a/product/sgm775/module/sgm775_system/src/mod_sgm775_system.c +++ b/product/sgm775/module/sgm775_system/src/mod_sgm775_system.c @@ -9,9 +9,47 @@ */ #include +#include +#include #include +#include +#include +#include +#include #include #include +#include +#include + +static const uint32_t feature_flags = SGM775_SDS_FEATURE_FIRMWARE_MASK; +static fwk_id_t sds_feature_availability_id = + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SDS, 1); + +/* SCMI services required to enable the messaging stack */ +static unsigned int scmi_notification_table[] = { + SGM775_SCMI_SERVICE_IDX_PSCI, + SGM775_SCMI_SERVICE_IDX_OSPM_0, + SGM775_SCMI_SERVICE_IDX_OSPM_1, +}; + +static struct mod_sds_api *sds_api; + +/* + * Static helpers + */ + +static int messaging_stack_ready(void) +{ + const struct mod_sds_structure_desc *sds_structure_desc = + fwk_module_get_data(sds_feature_availability_id); + + /* + * Write SDS Feature Availability to signal the completion of the messaging + * stack + */ + return sds_api->struct_write(sds_structure_desc->id, + 0, (void *)(&feature_flags), sds_structure_desc->size); +} /* * Functions fulfilling the framework's module interface @@ -39,6 +77,16 @@ static int sgm775_system_init(fwk_id_t module_id, unsigned int unused, return FWK_SUCCESS; } +static int sgm775_system_bind(fwk_id_t id, unsigned int round) +{ + if (round > 0) + return FWK_SUCCESS; + + return fwk_module_bind(fwk_module_id_sds, + FWK_ID_API(FWK_MODULE_IDX_SDS, 0), + &sds_api); +} + static int sgm775_system_process_bind_request(fwk_id_t source_id, fwk_id_t target_id, fwk_id_t api_id, const void **api) { @@ -47,12 +95,75 @@ static int sgm775_system_process_bind_request(fwk_id_t source_id, return FWK_SUCCESS; } +static int sgm775_system_start(fwk_id_t id) +{ + int status; + unsigned int i; + + /* + * Subscribe to these SCMI channels in order to know when they have all + * initialized. + * At that point we can consider the SCMI stack to be initialized from + * the point of view of the PSCI agent. + */ + for (i = 0; i < FWK_ARRAY_SIZE(scmi_notification_table); i++) { + status = fwk_notification_subscribe( + mod_scmi_notification_id_initialized, + fwk_id_build_element_id(fwk_module_id_scmi, + scmi_notification_table[i]), + id); + if (status != FWK_SUCCESS) + return status; + } + + /* + * Subscribe to the SDS initialized notification so we can correctly let the + * PSCI agent know that the SCMI stack is initialized. + */ + return fwk_notification_subscribe( + mod_sds_notification_id_initialized, + fwk_module_id_sds, + id); +} + +static int sgm775_system_process_notification(const struct fwk_event *event, + struct fwk_event *resp_event) +{ + static unsigned int scmi_notification_count = 0; + static bool sds_notification_received = false; + + if (!fwk_expect(fwk_id_is_type(event->target_id, FWK_ID_TYPE_MODULE))) + return FWK_E_PARAM; + + if (fwk_id_is_equal(event->id, + mod_scmi_notification_id_initialized)) { + scmi_notification_count++; + } else if (fwk_id_is_equal(event->id, + mod_sds_notification_id_initialized)) { + sds_notification_received = true; + } else + return FWK_E_PARAM; + + if ((scmi_notification_count == FWK_ARRAY_SIZE(scmi_notification_table)) && + sds_notification_received) { + messaging_stack_ready(); + + scmi_notification_count = 0; + sds_notification_received = false; + } + + return FWK_SUCCESS; +} + const struct fwk_module module_sgm775_system = { .name = "SGM775_SYSTEM", .api_count = MOD_SGM775_SYSTEM_API_COUNT, .type = FWK_MODULE_TYPE_DRIVER, .init = sgm775_system_init, + .bind = sgm775_system_bind, .process_bind_request = sgm775_system_process_bind_request, + .start = sgm775_system_start, + .process_notification = sgm775_system_process_notification, }; /* No elements, no module configuration data */ diff --git a/product/sgm775/scp_ramfw/config_scmi.c b/product/sgm775/scp_ramfw/config_scmi.c index 4269586dfe924c0fd4899c4afe75925980b187de..e0aadc705f05284186c424a725468ded0c99b16a 100644 --- a/product/sgm775/scp_ramfw/config_scmi.c +++ b/product/sgm775/scp_ramfw/config_scmi.c @@ -23,6 +23,9 @@ static const struct fwk_element service_table[] = { SGM775_SCMI_SERVICE_IDX_PSCI), .transport_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), + .transport_notification_init_id = + FWK_ID_NOTIFICATION_INIT(FWK_MODULE_IDX_SMT, + MOD_SMT_NOTIFICATION_IDX_INITIALIZED), .scmi_agent_id = SCMI_AGENT_ID_PSCI, }), }, @@ -33,6 +36,9 @@ static const struct fwk_element service_table[] = { SGM775_SCMI_SERVICE_IDX_OSPM_0), .transport_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), + .transport_notification_init_id = + FWK_ID_NOTIFICATION_INIT(FWK_MODULE_IDX_SMT, + MOD_SMT_NOTIFICATION_IDX_INITIALIZED), .scmi_agent_id = SCMI_AGENT_ID_OSPM, }), }, @@ -43,6 +49,9 @@ static const struct fwk_element service_table[] = { SGM775_SCMI_SERVICE_IDX_OSPM_1), .transport_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), + .transport_notification_init_id = + FWK_ID_NOTIFICATION_INIT(FWK_MODULE_IDX_SMT, + MOD_SMT_NOTIFICATION_IDX_INITIALIZED), .scmi_agent_id = SCMI_AGENT_ID_OSPM, }), }, diff --git a/product/sgm775/scp_ramfw/config_sds.c b/product/sgm775/scp_ramfw/config_sds.c index fff3734d90015b19deb14418b4145bf18dd7b86a..9d60183bdccba3e06284f9b71268a096e065d6d7 100644 --- a/product/sgm775/scp_ramfw/config_sds.c +++ b/product/sgm775/scp_ramfw/config_sds.c @@ -16,7 +16,7 @@ #include #include -static const uint32_t feature_flags = SGM775_SDS_FEATURE_FIRMWARE_MASK; +static const uint32_t feature_flags = 0x00000000; static const uint32_t version_packed = FWK_BUILD_VERSION; const struct mod_sds_config sds_module_config = {