diff --git a/module/dvfs/include/mod_dvfs.h b/module/dvfs/include/mod_dvfs.h index 584e171528e60315a04ddf8541c932bec8aec920..9e262aa134a2af4adac5f7c8a89c15434644e468 100644 --- a/module/dvfs/include/mod_dvfs.h +++ b/module/dvfs/include/mod_dvfs.h @@ -9,6 +9,7 @@ #define MOD_DVFS_H #include +#include #include #include @@ -76,6 +77,16 @@ struct mod_dvfs_domain_config { */ fwk_id_t alarm_id; + /*! + * \brief Notifications identifier. + */ + fwk_id_t notification_id; + + /*! + * \brief Notifications API identifier. + */ + fwk_id_t notification_api_id; + /*! Delay in milliseconds before retrying a request */ uint16_t retry_ms; @@ -157,9 +168,11 @@ struct mod_dvfs_domain_api { * \brief Set the frequency of a domain. * * \param domain_id Element identifier of the domain. - * \param idx Index of the operating point to transition to. + * \param cookie Context-specific value. + * \param frequency Requested frequency. */ - int (*set_frequency)(fwk_id_t domain_id, uint64_t frequency); + int (*set_frequency)(fwk_id_t domain_id, uintptr_t cookie, + uint64_t frequency); /*! * \brief Get the frequency of a domain. @@ -175,13 +188,42 @@ struct mod_dvfs_domain_api { * \brief Set the frequency of a domain. * * \param domain_id Element identifier of the domain. + * \param cookie Context-specific value. * \param limits Pointer to the new limits. */ int (*set_frequency_limits)( - fwk_id_t domain_id, + fwk_id_t domain_id, uintptr_t cookie, const struct mod_dvfs_frequency_limits *limits); }; +/*! + * \brief DVFS notification API. + * + * \details API used by the domain when a notification is required. + */ +struct mod_dvfs_notification_api { + /*! + * \brief Send a limitschanged notification for the domain. + * + * \param domain_id Domain identifier. + * \param cookie Context-specific value. + * \param range_min Min allowed performance level. + * \param range_max Max allowed performance level. + */ + void (*notify_limits)(fwk_id_t domain_id, uintptr_t cookie, + uint32_t range_min, uint32_t range_max); + + /*! + * \brief Send a level changed notification for the domain. + * + * \param domain_id Domain identifier. + * \param cookie Context-specific value. + * \param level The new performance level of the domain. + */ + void (*notify_level)(fwk_id_t domain_id, uintptr_t cookie, + uint32_t level); +}; + /*! * \} */ diff --git a/module/dvfs/src/mod_dvfs.c b/module/dvfs/src/mod_dvfs.c index 2e2173b4ea89a020bec0200395b5fde1c7c121c8..fc974df591611ac11f68d39ec23b0a83dc063e46 100644 --- a/module/dvfs/src/mod_dvfs.c +++ b/module/dvfs/src/mod_dvfs.c @@ -69,6 +69,9 @@ struct mod_dvfs_request { /* New operating point data for the request */ struct mod_dvfs_opp new_opp; + /* Context-specific value */ + uintptr_t cookie; + /* Response expected for this request */ bool response_required; @@ -102,6 +105,8 @@ struct mod_dvfs_domain_ctx { /* Alarm API for pending requests */ const struct mod_timer_alarm_api *alarm_api; + /* DVFS perf notification API */ + struct mod_dvfs_notification_api *notification_api; } apis; /* Number of operating points */ @@ -133,6 +138,9 @@ struct mod_dvfs_ctx { /* Number of DVFS domains */ uint32_t dvfs_domain_element_count; + /* DVFS config data */ + struct mod_dvfs_config *config; + /* DVFS device context table */ struct mod_dvfs_domain_ctx (*domain_ctx)[]; } dvfs_ctx; @@ -256,10 +264,12 @@ static int put_event_request(struct mod_dvfs_domain_ctx *ctx, } static int dvfs_set_frequency_start(struct mod_dvfs_domain_ctx *ctx, + uintptr_t cookie, const struct mod_dvfs_opp *new_opp, bool retry_request, uint8_t num_retries) { + ctx->request.cookie = cookie, ctx->request.new_opp = *new_opp; ctx->request.retry_request = retry_request; ctx->request.response_required = false; @@ -276,7 +286,9 @@ static void dvfs_flush_pending_request(struct mod_dvfs_domain_ctx *ctx) { if (ctx->request_pending) { ctx->request_pending = false; - dvfs_set_frequency_start(ctx, &ctx->pending_request.new_opp, + dvfs_set_frequency_start(ctx, + ctx->pending_request.cookie, + &ctx->pending_request.new_opp, ctx->pending_request.retry_request, ctx->pending_request.num_retries); } @@ -323,7 +335,8 @@ static int dvfs_handle_pending_request(struct mod_dvfs_domain_ctx *ctx) } static int dvfs_create_pending_level_request(struct mod_dvfs_domain_ctx *ctx, - const struct mod_dvfs_opp *new_opp, bool retry_request) + uintptr_t cookie, const struct mod_dvfs_opp *new_opp, + bool retry_request) { if (ctx->request_pending) { @@ -349,7 +362,7 @@ static int dvfs_create_pending_level_request(struct mod_dvfs_domain_ctx *ctx, */ if (retry_request) ctx->pending_request.retry_request = retry_request; - + ctx->pending_request.cookie = cookie; return FWK_SUCCESS; } @@ -483,7 +496,12 @@ static int dvfs_get_current_opp(fwk_id_t domain_id, struct mod_dvfs_opp *opp) /* * DVFS module asynchronous API functions */ -static int dvfs_set_frequency(fwk_id_t domain_id, uint64_t frequency) + +/* + * DVFS module asynchronous API functions + */ +static int dvfs_set_frequency(fwk_id_t domain_id, uintptr_t cookie, + uint64_t frequency) { struct mod_dvfs_domain_ctx *ctx; const struct mod_dvfs_opp *new_opp; @@ -501,17 +519,18 @@ static int dvfs_set_frequency(fwk_id_t domain_id, uint64_t frequency) return FWK_E_RANGE; if (ctx->state != DVFS_DOMAIN_STATE_IDLE) - return dvfs_create_pending_level_request(ctx, new_opp, false); + return dvfs_create_pending_level_request(ctx, cookie, + new_opp, false); if ((new_opp->frequency == ctx->current_opp.frequency) && (new_opp->voltage == ctx->current_opp.voltage)) return FWK_SUCCESS; - return dvfs_set_frequency_start(ctx, new_opp, false, 0); + return dvfs_set_frequency_start(ctx, cookie, new_opp, false, 0); } static int dvfs_set_frequency_limits(fwk_id_t domain_id, - const struct mod_dvfs_frequency_limits *limits) + uintptr_t cookie, const struct mod_dvfs_frequency_limits *limits) { struct mod_dvfs_domain_ctx *ctx; const struct mod_dvfs_opp *new_opp; @@ -534,10 +553,18 @@ static int dvfs_set_frequency_limits(fwk_id_t domain_id, return FWK_SUCCESS; } - if (ctx->state != DVFS_DOMAIN_STATE_IDLE) - return dvfs_create_pending_level_request(ctx, new_opp, true); + if (ctx->apis.notification_api) { + ctx->apis.notification_api->notify_limits( + ctx->domain_id, cookie, + limits->minimum, limits->maximum); + } + + if (ctx->state != DVFS_DOMAIN_STATE_IDLE) { + return dvfs_create_pending_level_request(ctx, cookie, + new_opp, true); + } - return dvfs_set_frequency_start(ctx, new_opp, true, 0); + return dvfs_set_frequency_start(ctx, cookie, new_opp, true, 0); } static const struct mod_dvfs_domain_api mod_dvfs_domain_api = { @@ -623,12 +650,21 @@ static int dvfs_complete(struct mod_dvfs_domain_ctx *ctx, ctx->pending_request.retry_request = ctx->request.retry_request; ctx->pending_request.num_retries = ctx->request.num_retries; if (!ctx->request_pending) { + ctx->pending_request.cookie = ctx->request.cookie; ctx->pending_request.new_opp = ctx->request.new_opp; ctx->request_pending = true; } } } + if ((req_status == FWK_SUCCESS) && (ctx->state != DVFS_DOMAIN_GET_OPP)) { + if (ctx->apis.notification_api) { + ctx->apis.notification_api->notify_level( + ctx->domain_id, ctx->request.cookie, + ctx->current_opp.frequency); + } + } + /* * Now we need to start processing the pending request if any, * note that we do not set the state to DOMAIN_STATE_IDLE @@ -922,7 +958,9 @@ static int mod_dvfs_process_event(const struct fwk_event *event, if (fwk_id_is_equal(event->id, mod_dvfs_event_id_retry)) { ctx->request.set_source_id = false; ctx->request_pending = false; - status = dvfs_set_frequency_start(ctx, &ctx->pending_request.new_opp, + status = dvfs_set_frequency_start(ctx, + ctx->pending_request.cookie, + &ctx->pending_request.new_opp, ctx->pending_request.retry_request, ctx->pending_request.num_retries); ctx->pending_request = (struct mod_dvfs_request){ 0 }; @@ -997,7 +1035,7 @@ static int dvfs_start(fwk_id_t id) if (status == FWK_SUCCESS) { ctx = get_domain_ctx(id); ctx->request.set_source_id = true; - dvfs_set_frequency_start(ctx, &sustained_opp, true, 0); + dvfs_set_frequency_start(ctx, 0, &sustained_opp, true, 0); } return status; @@ -1009,6 +1047,7 @@ static int dvfs_init(fwk_id_t module_id, unsigned int element_count, dvfs_ctx.domain_ctx = fwk_mm_calloc(element_count, sizeof((*dvfs_ctx.domain_ctx)[0])); + dvfs_ctx.config = (struct mod_dvfs_config *)data; dvfs_ctx.dvfs_domain_element_count = element_count; return FWK_SUCCESS; @@ -1048,10 +1087,6 @@ dvfs_bind_element(fwk_id_t domain_id, unsigned int round) int status; const struct mod_dvfs_domain_ctx *ctx = get_domain_ctx(domain_id); - /* Only handle the first round */ - if (round > 0) - return FWK_SUCCESS; - /* Bind to the power supply module */ status = fwk_module_bind(ctx->config->psu_id, mod_psu_api_id_device, &ctx->apis.psu); @@ -1064,6 +1099,15 @@ dvfs_bind_element(fwk_id_t domain_id, unsigned int round) if (status != FWK_SUCCESS) return FWK_E_PANIC; + /* Bind to a notification module if required */ + if (!(fwk_id_is_equal(ctx->config->notification_id, FWK_ID_NONE))) { + status = fwk_module_bind(ctx->config->notification_id, + ctx->config->notification_api_id, + &ctx->apis.notification_api); + if (status != FWK_SUCCESS) + return FWK_E_PANIC; + } + /* Bind to the alarm HAL if required */ if (ctx->config->retry_ms > 0) { status = fwk_module_bind(ctx->config->alarm_id, MOD_TIMER_API_ID_ALARM, @@ -1078,6 +1122,10 @@ dvfs_bind_element(fwk_id_t domain_id, unsigned int round) static int dvfs_bind(fwk_id_t id, unsigned int round) { + /* Only handle the first round */ + if (round > 0) + return FWK_SUCCESS; + /* Bind our elements */ if (fwk_id_is_type(id, FWK_ID_TYPE_ELEMENT)) return dvfs_bind_element(id, round); @@ -1085,21 +1133,6 @@ dvfs_bind(fwk_id_t id, unsigned int round) return FWK_SUCCESS; } -static int -dvfs_process_bind_request_module(fwk_id_t source_id, - fwk_id_t api_id, - const void **api) -{ - /* Only expose the module API */ - if (!fwk_id_is_equal(api_id, mod_dvfs_api_id_dvfs)) - return FWK_E_PARAM; - - /* We don't do any permissions management */ - *api = &mod_dvfs_domain_api; - - return FWK_SUCCESS; -} - static int dvfs_process_bind_request(fwk_id_t source_id, fwk_id_t target_id, @@ -1110,7 +1143,10 @@ dvfs_process_bind_request(fwk_id_t source_id, if (!fwk_id_is_equal(target_id, fwk_module_id_dvfs)) return FWK_E_PARAM; - return dvfs_process_bind_request_module(source_id, api_id, api); + /* We don't do any permissions management */ + *api = &mod_dvfs_domain_api; + + return FWK_SUCCESS; } /* Module description */ diff --git a/module/scmi/include/internal/mod_scmi.h b/module/scmi/include/internal/mod_scmi.h index 99e981c65217453acec1aff5e55c47547771a546..5206db71e98af8f8f2e90263939ccc1d2c5ecd5d 100644 --- a/module/scmi/include/internal/mod_scmi.h +++ b/module/scmi/include/internal/mod_scmi.h @@ -12,6 +12,7 @@ #define MOD_INTERNAL_SCMI_H #include +#include #include @@ -20,25 +21,6 @@ #define SCMI_VERSION 0x10000 -#define SCMI_MESSAGE_HEADER_MESSAGE_ID_POS 0 -#define SCMI_MESSAGE_HEADER_PROTOCOL_ID_POS 10 -#define SCMI_MESSAGE_HEADER_TOKEN_POS 18 - -#define SCMI_MESSAGE_HEADER_MESSAGE_ID_MASK \ - (UINT32_C(0x3FF) << SCMI_MESSAGE_HEADER_MESSAGE_ID_POS) -#define SCMI_MESSAGE_HEADER_PROTOCOL_ID_MASK \ - (UINT32_C(0xFF) << SCMI_MESSAGE_HEADER_PROTOCOL_ID_POS) -#define SCMI_MESSAGE_HEADER_TOKEN_MASK \ - (UINT32_C(0x3FF) << SCMI_MESSAGE_HEADER_TOKEN_POS) - -#define SCMI_MESSAGE_HEADER(MESSAGE_ID, PROTOCOL_ID, TOKEN) \ - ((((MESSAGE_ID) << SCMI_MESSAGE_HEADER_MESSAGE_ID_POS) & \ - SCMI_MESSAGE_HEADER_MESSAGE_ID_MASK) | \ - (((PROTOCOL_ID) << SCMI_MESSAGE_HEADER_PROTOCOL_ID_POS) & \ - SCMI_MESSAGE_HEADER_PROTOCOL_ID_MASK) | \ - (((TOKEN) << SCMI_MESSAGE_HEADER_TOKEN_POS) & \ - SCMI_MESSAGE_HEADER_TOKEN_POS)) - /* SCMI service context */ struct scmi_service_ctx { /* Pointer to SCMI service configuration data */ @@ -53,9 +35,17 @@ struct scmi_service_ctx { /* Pointer to the transport API used to read and respond to messages */ const struct mod_scmi_to_transport_api *transport_api; - /* Copy of the pointer to the 'respond' function within the transport API */ + /* + * Copy of the pointer to the 'respond' function within the transport API. + */ int (*respond)(fwk_id_t transport_id, const void *payload, size_t size); + /* + * Copy of the pointer to the 'transmit' function within the transport API. + */ + int (*transmit)(fwk_id_t transport_id, uint32_t message_header, + const void *payload, size_t size); + /* SCMI message token, used by the agent to identify individual messages */ uint16_t scmi_token; @@ -64,6 +54,9 @@ struct scmi_service_ctx { /* SCMI identifier of the message currently being processed */ unsigned int scmi_message_id; + + /* SCMI type of the message currently being processed */ + enum mod_scmi_message_type scmi_message_type; }; #endif /* MOD_INTERNAL_SCMI_H */ diff --git a/module/scmi/include/internal/scmi.h b/module/scmi/include/internal/scmi.h index cc120706839034aea661d003d01a2dcd16bd8b6e..40b4f5652f530d73ae4c4adf6880fce4cc0afbfc 100644 --- a/module/scmi/include/internal/scmi.h +++ b/module/scmi/include/internal/scmi.h @@ -35,22 +35,6 @@ /*! Maximum value of an SCMI protocol identifier */ #define SCMI_PROTOCOL_ID_MAX 0xFF -/*! - * \brief Return a packed 32-bit message header comprised of a 10-bit message - * identifier, an 8-bit protocol identifier, and a 10-bit token. - * - * \param MESSAGE_ID Message identifier. - * \param PROTOCOL_ID Protocol identifier. - * \param TOKEN Token. - */ -#define SCMI_MESSAGE_HEADER(MESSAGE_ID, PROTOCOL_ID, TOKEN) \ - ((((MESSAGE_ID) << SCMI_MESSAGE_HEADER_MESSAGE_ID_POS) & \ - SCMI_MESSAGE_HEADER_MESSAGE_ID_MASK) | \ - (((PROTOCOL_ID) << SCMI_MESSAGE_HEADER_PROTOCOL_ID_POS) & \ - SCMI_MESSAGE_HEADER_PROTOCOL_ID_MASK) | \ - (((TOKEN) << SCMI_MESSAGE_HEADER_TOKEN_POS) & \ - SCMI_MESSAGE_HEADER_TOKEN_POS)) - /*! * \brief Entity role. */ diff --git a/module/scmi/include/mod_scmi.h b/module/scmi/include/mod_scmi.h index 700a22d2e256f39a822be7aab8bdf75d54a5637e..49b34fc9821e7b1866034ed772957ba0514b155a 100644 --- a/module/scmi/include/mod_scmi.h +++ b/module/scmi/include/mod_scmi.h @@ -242,6 +242,24 @@ struct mod_scmi_to_transport_api { * errors. */ int (*respond)(fwk_id_t channel_id, const void *payload, size_t size); + + /*! + * \brief Send a message on a channel. + * + * \param channel_id Channel identifier. + * \param message_header Message ID. + * \param payload Payload data to write. + * \param size Size of the payload source. + * + * \retval FWK_SUCCESS The operation succeeded. + * \retval FWK_E_PARAM The channel_id parameter is invalid. + * \retval FWK_E_PARAM The size parameter is less than the size of one + * payload entry. + * \return One of the standard error codes for implementation-defined + * errors. + */ + int (*transmit)(fwk_id_t channel_id, uint32_t message_header, + const void *payload, size_t size); }; /*! @@ -333,6 +351,16 @@ struct mod_scmi_to_protocol_api { * \brief SCMI protocol module to SCMI module API. */ struct mod_scmi_from_protocol_api { + /*! + * \brief Get the number of active agents. + * + * \param[out] agent_count Number of active agents. + * + * \retval FWK_SUCCESS The agent count was returned. + * \retval FWK_E_PARAM The parameter `agent_count` is equal to `NULL`. + */ + int (*get_agent_count)(int *agent_count); + /*! * \brief Get the identifier of the agent associated with a service * @@ -407,6 +435,19 @@ struct mod_scmi_from_protocol_api { * \param size Size of the payload. */ void (*respond)(fwk_id_t service_id, const void *payload, size_t size); + + /*! + * \brief Send a notification to the agent on behalf on an SCMI service. + * + * \param service_id Service identifier. + * \param protocol_id Protocol identifier. + * \param message_id Message identifier. + * \param payload Payload data to write, or NULL if a payload has already + * been written. + * \param size Size of the payload in bytes. + */ + void (*notify)(fwk_id_t service_id, int protocol_id, int message_id, + const void *payload, size_t size); }; diff --git a/module/scmi/include/mod_scmi_header.h b/module/scmi/include/mod_scmi_header.h new file mode 100644 index 0000000000000000000000000000000000000000..ef84fa3869283ad170d4e1660d4bab1d1f3404c0 --- /dev/null +++ b/module/scmi/include/mod_scmi_header.h @@ -0,0 +1,34 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * System Control and Management Interface (SCMI) support. + */ + +#ifndef MOD_SCMI_HEADER_H +#define MOD_SCMI_HEADER_H + +#define SCMI_MESSAGE_HEADER_MESSAGE_ID_POS 0 +#define SCMI_MESSAGE_HEADER_MESSAGE_TYPE_POS 8 +#define SCMI_MESSAGE_HEADER_PROTOCOL_ID_POS 10 +#define SCMI_MESSAGE_HEADER_TOKEN_POS 18 + +#define SCMI_MESSAGE_HEADER_MESSAGE_ID_MASK \ + (UINT32_C(0xFF) << SCMI_MESSAGE_HEADER_MESSAGE_ID_POS) +#define SCMI_MESSAGE_HEADER_MESSAGE_TYPE_MASK \ + (UINT32_C(0x3) << SCMI_MESSAGE_HEADER_MESSAGE_TYPE_POS) +#define SCMI_MESSAGE_HEADER_PROTOCOL_ID_MASK \ + (UINT32_C(0xFF) << SCMI_MESSAGE_HEADER_PROTOCOL_ID_POS) +#define SCMI_MESSAGE_HEADER_TOKEN_MASK \ + (UINT32_C(0x3FF) << SCMI_MESSAGE_HEADER_TOKEN_POS) + +enum mod_scmi_message_type { + MOD_SCMI_MESSAGE_TYPE_COMMAND = 0, + MOD_SCMI_MESSAGE_TYPE_DELAYED_RESPONSE = 2, + MOD_SCMI_MESSAGE_TYPE_NOTIFICATION = 3, +}; + +#endif /* MOD_SCMI_HEADER_H */ diff --git a/module/scmi/src/mod_scmi.c b/module/scmi/src/mod_scmi.c index 4c81e5be2c7d0b7bfd2f7703e775859dc070d526..b4656185af329f7b32e8bef9ee60820e9ab793c4 100644 --- a/module/scmi/src/mod_scmi.c +++ b/module/scmi/src/mod_scmi.c @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -132,12 +133,38 @@ static struct scmi_ctx scmi_ctx; /* * Utility functions */ + +/* + * Return a packed 32-bit message header comprised of an 8-bit message + * identifier, a 2-bit message type, an 8-bit protocol identifier, + * and a 10-bit token. + */ +static uint32_t scmi_message_header(uint8_t message_id, + uint8_t message_type, uint8_t protocol_id, uint8_t token) +{ + return ((((message_id) << SCMI_MESSAGE_HEADER_MESSAGE_ID_POS) & + SCMI_MESSAGE_HEADER_MESSAGE_ID_MASK) | + (((message_type) << SCMI_MESSAGE_HEADER_MESSAGE_TYPE_POS) & + SCMI_MESSAGE_HEADER_MESSAGE_TYPE_MASK) | + (((protocol_id) << SCMI_MESSAGE_HEADER_PROTOCOL_ID_POS) & + SCMI_MESSAGE_HEADER_PROTOCOL_ID_MASK) | + (((token) << SCMI_MESSAGE_HEADER_TOKEN_POS) & + SCMI_MESSAGE_HEADER_TOKEN_POS)); +} + static uint16_t read_message_id(uint32_t message_header) { return (message_header & SCMI_MESSAGE_HEADER_MESSAGE_ID_MASK) >> SCMI_MESSAGE_HEADER_MESSAGE_ID_POS; } +static uint8_t read_message_type(uint32_t message_header) +{ + return (message_header & SCMI_MESSAGE_HEADER_MESSAGE_TYPE_MASK) >> + SCMI_MESSAGE_HEADER_MESSAGE_TYPE_POS; +} + + static uint8_t read_protocol_id(uint32_t message_header) { return (message_header & SCMI_MESSAGE_HEADER_PROTOCOL_ID_MASK) >> @@ -150,6 +177,23 @@ static uint16_t read_token(uint32_t message_header) SCMI_MESSAGE_HEADER_TOKEN_POS; } +static const char *message_type_to_str(enum mod_scmi_message_type message_type) +{ + switch (message_type) { + case MOD_SCMI_MESSAGE_TYPE_COMMAND: + return "Command"; + + case MOD_SCMI_MESSAGE_TYPE_DELAYED_RESPONSE: + return "Delayed response"; + + case MOD_SCMI_MESSAGE_TYPE_NOTIFICATION: + return "Notification"; + + default: + return "Invalid message"; + } +} + /* * Transport entity -> SCMI module */ @@ -185,6 +229,18 @@ static const struct mod_scmi_from_transport_api mod_scmi_from_transport_api = { * SCMI protocol module -> SCMI module interface */ +static int get_agent_count(int *agent_count) +{ + if (agent_count == NULL) + return FWK_E_PARAM; + + /* Include the platform in the count */ + *agent_count = scmi_ctx.config->agent_count + 1; + + return FWK_SUCCESS; +} + + static int get_agent_id(fwk_id_t service_id, unsigned int *agent_id) { struct scmi_service_ctx *ctx; @@ -240,10 +296,12 @@ static void respond(fwk_id_t service_id, const void *payload, size_t size) int status; const struct scmi_service_ctx *ctx; const char *service_name; + const char *message_type_name; ctx = &scmi_ctx.service_ctx_table[fwk_id_get_element_idx(service_id)]; service_name = fwk_module_get_name(service_id); + message_type_name = message_type_to_str(ctx->scmi_message_type); /* * Print to the error log if the message was not successfully processed. @@ -254,18 +312,20 @@ static void respond(fwk_id_t service_id, const void *payload, size_t size) */ if ((payload != NULL) && (*((int32_t *)payload) < SCMI_SUCCESS)) { FWK_LOG_ERR( - "[SCMI] %s: Message [%" PRIu16 + "[SCMI] %s: %s [%" PRIu16 " (0x%x:0x%x)] returned with an error (%d)", service_name, + message_type_name, ctx->scmi_token, ctx->scmi_protocol_id, ctx->scmi_message_id, *((int *)payload)); } else { FWK_LOG_TRACE( - "[SCMI] %s: Message [%" PRIu16 + "[SCMI] %s: %s [%" PRIu16 " (0x%x:0x%x)] returned successfully", service_name, + message_type_name, ctx->scmi_token, ctx->scmi_protocol_id, ctx->scmi_message_id); @@ -274,9 +334,10 @@ static void respond(fwk_id_t service_id, const void *payload, size_t size) status = ctx->respond(ctx->transport_id, payload, size); if (status != FWK_SUCCESS) { FWK_LOG_ERR( - "[SCMI] %s: Message [%" PRIu16 + "[SCMI] %s: %s [%" PRIu16 " (0x%x:0x%x)] failed to respond (%s)", service_name, + message_type_name, ctx->scmi_token, ctx->scmi_protocol_id, ctx->scmi_message_id, @@ -284,12 +345,36 @@ static void respond(fwk_id_t service_id, const void *payload, size_t size) } } +static void scmi_notify(fwk_id_t id, int protocol_id, int message_id, + const void *payload, size_t size) +{ + const struct scmi_service_ctx *ctx; + uint32_t message_header; + + if (fwk_id_is_equal(id, FWK_ID_NONE)) + return; + + ctx = &scmi_ctx.service_ctx_table[fwk_id_get_element_idx(id)]; + + if ((ctx == NULL) || (ctx->transmit == NULL)) + return; /* No notification service configured */ + + message_header = scmi_message_header(message_id, + MOD_SCMI_MESSAGE_TYPE_NOTIFICATION, + protocol_id, 0); + + ctx->transmit(ctx->transport_id, message_header, + payload, size); +} + static const struct mod_scmi_from_protocol_api mod_scmi_from_protocol_api = { + .get_agent_count = get_agent_count, .get_agent_id = get_agent_id, .get_agent_type = get_agent_type, .get_max_payload_size = get_max_payload_size, .write_payload = write_payload, .respond = respond, + .notify = scmi_notify, }; /* @@ -667,13 +752,13 @@ static int scmi_bind(fwk_id_t id, unsigned int round) (transport_api->get_max_payload_size == NULL) || (transport_api->get_message_header == NULL) || (transport_api->get_payload == NULL) || - (transport_api->write_payload == NULL) || - (transport_api->respond == NULL)) + (transport_api->write_payload == NULL)) return FWK_E_DATA; ctx->transport_api = transport_api; ctx->transport_id = ctx->config->transport_id; ctx->respond = transport_api->respond; + ctx->transmit = transport_api->transmit; return FWK_SUCCESS; } @@ -762,12 +847,14 @@ static int scmi_process_event(const struct fwk_event *event, unsigned int protocol_idx; struct scmi_protocol *protocol; const char *service_name; + const char *message_type_name; ctx = &scmi_ctx.service_ctx_table[fwk_id_get_element_idx(event->target_id)]; transport_api = ctx->transport_api; transport_id = ctx->transport_id; service_name = fwk_module_get_name(event->target_id); + message_type_name = message_type_to_str(ctx->scmi_message_type); status = transport_api->get_message_header(transport_id, &message_header); if (status != FWK_SUCCESS) { @@ -783,26 +870,29 @@ static int scmi_process_event(const struct fwk_event *event, ctx->scmi_protocol_id = read_protocol_id(message_header); ctx->scmi_message_id = read_message_id(message_header); + ctx->scmi_message_type = read_message_type(message_header); ctx->scmi_token = read_token(message_header); FWK_LOG_TRACE( - "[SCMI] %s: Message [%" PRIu16 " (0x%x:0x%x)] was received", + "[SCMI] %s: Message [%" PRIu16 " (0x%x:0x%x:%s)] was received", service_name, ctx->scmi_token, ctx->scmi_protocol_id, - ctx->scmi_message_id); + ctx->scmi_message_id, + message_type_name); protocol_idx = scmi_ctx.scmi_protocol_id_to_idx[ctx->scmi_protocol_id]; if (protocol_idx == 0) { FWK_LOG_ERR( "[SCMI] %s: Message [%" PRIu16 - " (0x%x:0x%x)] requested an " + " (0x%x:0x%x:%s)] requested an " "unsupported protocol", service_name, ctx->scmi_token, ctx->scmi_protocol_id, - ctx->scmi_message_id); + ctx->scmi_message_id, + message_type_name); ctx->respond(transport_id, &(int32_t) { SCMI_NOT_SUPPORTED }, sizeof(int32_t)); return FWK_SUCCESS; @@ -814,11 +904,13 @@ static int scmi_process_event(const struct fwk_event *event, if (status != FWK_SUCCESS) { FWK_LOG_ERR( - "[SCMI] %s: Message [%" PRIu16 " (0x%x:0x%x)] handler error (%s)", + "[SCMI] %s: Message [%" PRIu16 " (0x%x:0x%x:%s)]" + " handler error (%s)", service_name, ctx->scmi_token, ctx->scmi_protocol_id, ctx->scmi_message_id, + message_type_name, fwk_status_str(status)); return FWK_SUCCESS; diff --git a/module/scmi_perf/include/internal/scmi_perf.h b/module/scmi_perf/include/internal/scmi_perf.h index 50df7f3e7f17e4da26b2ac671ed8311f0003bb26..6f5f63c721ef7a254e4011b8744a627e521e78f6 100644 --- a/module/scmi_perf/include/internal/scmi_perf.h +++ b/module/scmi_perf/include/internal/scmi_perf.h @@ -36,6 +36,11 @@ enum scmi_perf_command_id { SCMI_PERF_NOTIFY_LEVEL = 0x00A }; +enum scmi_perf_notification_id { + SCMI_PERF_LIMITS_CHANGED = 0x000, + SCMI_PERF_LEVEL_CHANGED = 0x001, +}; + /* * PROTOCOL_ATTRIBUTES */ @@ -77,6 +82,7 @@ struct __attribute((packed)) scmi_perf_protocol_attributes_p2a { (UINT32_C(0x1) << SCMI_PERF_DOMAIN_ATTRIBUTES_CAN_SET_LIMITS_POS) #define SCMI_PERF_DOMAIN_ATTRIBUTES_CAN_SET_LEVEL_MASK \ (UINT32_C(0x1) << SCMI_PERF_DOMAIN_ATTRIBUTES_CAN_SET_LEVEL_POS) + #define SCMI_PERF_DOMAIN_ATTRIBUTES_LIMITS_NOTIFY_MASK \ (UINT32_C(0x1) << SCMI_PERF_DOMAIN_ATTRIBUTES_LIMITS_NOTIFY_POS) #define SCMI_PERF_DOMAIN_ATTRIBUTES_LEVEL_NOTIFY_MASK \ @@ -245,4 +251,22 @@ struct __attribute((packed)) scmi_perf_notify_level_p2a { int32_t status; }; +/* + * PERFORMANCE_LEVEL_CHANGED + */ +struct __attribute((packed)) scmi_perf_level_changed { + uint32_t agent_id; + uint32_t domain_id; + uint32_t performance_level; +}; + +/* + * PERFORMANCE_LIMITS_CHANGED + */ +struct __attribute((packed)) scmi_perf_limits_changed { + uint32_t agent_id; + uint32_t domain_id; + uint32_t range_min; + uint32_t range_max; +}; #endif /* INTERNAL_SCMI_PERF_H */ diff --git a/module/scmi_perf/include/mod_scmi_perf.h b/module/scmi_perf/include/mod_scmi_perf.h index 23f6535783a19e6c590e9d56ea191419b1908762..070bf67b9b0965e4f874c58a42b26be87cb0dcdb 100644 --- a/module/scmi_perf/include/mod_scmi_perf.h +++ b/module/scmi_perf/include/mod_scmi_perf.h @@ -11,6 +11,8 @@ #ifndef MOD_SCMI_PERF_H #define MOD_SCMI_PERF_H +#include + #include #include @@ -53,6 +55,22 @@ struct mod_scmi_perf_config { const struct mod_scmi_perf_domain_config (*domains)[]; }; +/*! + * \brief SCMI Performance APIs. + * + * \details APIs exported by SCMI Performance Protocol. + */ +enum scmi_perf_api_idx { + /*! Index for the SCMI protocol API */ + MOD_SCMI_PERF_PROTOCOL_API, + + /*! Index of the notification API */ + MOD_SCMI_PERF_DVFS_NOTIFICATION_API, + + /*! Number of APIs */ + MOD_SCMI_PERF_API_COUNT +}; + /*! * @} */ diff --git a/module/scmi_perf/src/mod_scmi_perf.c b/module/scmi_perf/src/mod_scmi_perf.c index 67d7510da5643e24e3630eb55cdf98ad5bcfbb54..ea106506c2abf155544aec819fc5ab9edd260993 100644 --- a/module/scmi_perf/src/mod_scmi_perf.c +++ b/module/scmi_perf/src/mod_scmi_perf.c @@ -47,6 +47,10 @@ static int scmi_perf_limits_set_handler( fwk_id_t service_id, const uint32_t *payload); static int scmi_perf_limits_get_handler( fwk_id_t service_id, const uint32_t *payload); +static int scmi_perf_limits_notify( + fwk_id_t service_id, const uint32_t *payload); +static int scmi_perf_level_notify( + fwk_id_t service_id, const uint32_t *payload); static int (*handler_table[])(fwk_id_t, const uint32_t *) = { [SCMI_PROTOCOL_VERSION] = @@ -66,7 +70,11 @@ static int (*handler_table[])(fwk_id_t, const uint32_t *) = { [SCMI_PERF_LEVEL_SET] = scmi_perf_level_set_handler, [SCMI_PERF_LEVEL_GET] = - scmi_perf_level_get_handler + scmi_perf_level_get_handler, + [SCMI_PERF_NOTIFY_LIMITS] = + scmi_perf_limits_notify, + [SCMI_PERF_NOTIFY_LEVEL] = + scmi_perf_level_notify }; static unsigned int payload_size_table[] = { @@ -86,6 +94,10 @@ static unsigned int payload_size_table[] = { sizeof(struct scmi_perf_limits_set_a2p), [SCMI_PERF_LIMITS_GET] = sizeof(struct scmi_perf_limits_get_a2p), + [SCMI_PERF_NOTIFY_LIMITS] = + sizeof(struct scmi_perf_notify_limits_a2p), + [SCMI_PERF_NOTIFY_LEVEL] = + sizeof(struct scmi_perf_notify_level_a2p) }; struct perf_operations { @@ -96,6 +108,19 @@ struct perf_operations { fwk_id_t service_id; }; +struct agent_notifications { + /* + * Track whether an agent is requesting notifications on limit change + * operations. + */ + fwk_id_t *limit_notification; + + /* + * Track whether an agent is requesting notifications on level change + * operations. + */ + fwk_id_t *level_notification; +}; struct scmi_perf_ctx { /* SCMI Performance Module Configuration */ @@ -112,6 +137,12 @@ struct scmi_perf_ctx { /* Pointer to a table of operations */ struct perf_operations *perf_ops_table; + + /* Number of active agents */ + int agent_count; + + /* Agent notifications table */ + struct agent_notifications **agent_notifications; }; static struct scmi_perf_ctx scmi_perf_ctx; @@ -209,6 +240,7 @@ static int scmi_perf_domain_attributes_handler(fwk_id_t service_id, struct scmi_perf_domain_attributes_p2a return_values = { .status = SCMI_GENERIC_ERROR, }; + bool notifications = false; parameters = (const struct scmi_perf_domain_attributes_a2p *)payload; @@ -232,10 +264,13 @@ static int scmi_perf_domain_attributes_handler(fwk_id_t service_id, if (status != FWK_SUCCESS) goto exit; +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS + notifications = true; +#endif return_values = (struct scmi_perf_domain_attributes_p2a) { .status = SCMI_SUCCESS, .attributes = SCMI_PERF_DOMAIN_ATTRIBUTES( - false, false, + notifications, notifications, !!(permissions & MOD_SCMI_PERF_PERMS_SET_LEVEL), !!(permissions & MOD_SCMI_PERF_PERMS_SET_LIMITS) ), @@ -403,6 +438,7 @@ static int scmi_perf_limits_set_handler(fwk_id_t service_id, status = scmi_perf_ctx.dvfs_api->set_frequency_limits( FWK_ID_ELEMENT(FWK_MODULE_IDX_DVFS, parameters->domain_id), + agent_id, &((struct mod_dvfs_frequency_limits) { .minimum = parameters->range_min, .maximum = parameters->range_max @@ -520,7 +556,7 @@ static int scmi_perf_level_set_handler(fwk_id_t service_id, status = scmi_perf_ctx.dvfs_api->set_frequency( FWK_ID_ELEMENT(FWK_MODULE_IDX_DVFS, parameters->domain_id), - (uint64_t)parameters->performance_level); + agent_id, (uint64_t)parameters->performance_level); /* * Return immediately to the caller, fire-and-forget. @@ -598,6 +634,88 @@ exit: return status; } +static int scmi_perf_limits_notify(fwk_id_t service_id, + const uint32_t *payload) +{ + unsigned int agent_id; + int status; + unsigned int id; + const struct scmi_perf_notify_limits_a2p *parameters; + struct scmi_perf_notify_limits_p2a return_values = { + .status = SCMI_GENERIC_ERROR, + }; + + parameters = (const struct scmi_perf_notify_limits_a2p *)payload; + id = parameters->domain_id; + if (id >= scmi_perf_ctx.domain_count) { + status = FWK_SUCCESS; + return_values.status = SCMI_NOT_FOUND; + + goto exit; + } + + status = scmi_perf_ctx.scmi_api->get_agent_id(service_id, &agent_id); + if (status != FWK_SUCCESS) + goto exit; + + if (parameters->notify_enable) + scmi_perf_ctx.agent_notifications[id]->limit_notification[agent_id] = + service_id; + else + scmi_perf_ctx.agent_notifications[id]->limit_notification[agent_id] = + FWK_ID_NONE; + + return_values.status = SCMI_SUCCESS; + +exit: + scmi_perf_ctx.scmi_api->respond(service_id, &return_values, + (return_values.status == SCMI_SUCCESS) ? + sizeof(return_values) : sizeof(return_values.status)); + + return status; +} + +static int scmi_perf_level_notify(fwk_id_t service_id, + const uint32_t *payload) +{ + unsigned int agent_id; + int status; + unsigned int id; + const struct scmi_perf_notify_level_a2p *parameters; + struct scmi_perf_notify_level_p2a return_values = { + .status = SCMI_GENERIC_ERROR, + }; + + parameters = (const struct scmi_perf_notify_level_a2p *)payload; + id = parameters->domain_id; + if (id >= scmi_perf_ctx.domain_count) { + status = FWK_SUCCESS; + return_values.status = SCMI_NOT_FOUND; + + goto exit; + } + + status = scmi_perf_ctx.scmi_api->get_agent_id(service_id, &agent_id); + if (status != FWK_SUCCESS) + goto exit; + + if (parameters->notify_enable) + scmi_perf_ctx.agent_notifications[id]->level_notification[agent_id] = + service_id; + else + scmi_perf_ctx.agent_notifications[id]->level_notification[agent_id] = + FWK_ID_NONE; + + return_values.status = SCMI_SUCCESS; + +exit: + scmi_perf_ctx.scmi_api->respond(service_id, &return_values, + (return_values.status == SCMI_SUCCESS) ? + sizeof(return_values) : sizeof(return_values.status)); + + return status; +} + /* * SCMI module -> SCMI performance module interface */ @@ -671,6 +789,63 @@ static void scmi_perf_respond( scmi_perf_ctx.perf_ops_table[idx].service_id = FWK_ID_NONE; } +static void scmi_perf_notify_limits(fwk_id_t domain_id, + uintptr_t cookie, uint32_t range_min, uint32_t range_max) +{ + struct scmi_perf_limits_changed limits_changed; + fwk_id_t id; + int i, idx; + + idx = fwk_id_get_element_idx(domain_id); + limits_changed.agent_id = (uint32_t)cookie; + + /* note: skip agent 0, platform agent */ + for (i = 1; i < scmi_perf_ctx.agent_count; i++) { + id = + scmi_perf_ctx.agent_notifications[idx]->limit_notification[i]; + + if (!fwk_id_is_equal(id, FWK_ID_NONE)) { + limits_changed.domain_id = idx; + limits_changed.range_min = range_min; + limits_changed.range_max = range_max; + + scmi_perf_ctx.scmi_api->notify(id, + SCMI_PROTOCOL_ID_PERF, SCMI_PERF_LIMITS_CHANGED, + &limits_changed, sizeof(limits_changed)); + } + } +} + +static void scmi_perf_notify_level(fwk_id_t domain_id, + uintptr_t cookie, uint32_t level) +{ + struct scmi_perf_level_changed level_changed; + fwk_id_t id; + int i, idx; + + idx = fwk_id_get_element_idx(domain_id); + level_changed.agent_id = (uint32_t)cookie; + + /* note: skip agent 0, platform agent */ + for (i = 1; i < scmi_perf_ctx.agent_count; i++) { + id = + scmi_perf_ctx.agent_notifications[idx]->level_notification[i]; + if (!fwk_id_is_equal(id, FWK_ID_NONE)) { + level_changed.domain_id = idx; + level_changed.performance_level = level; + + scmi_perf_ctx.scmi_api->notify(id, + SCMI_PROTOCOL_ID_PERF, SCMI_PERF_LEVEL_CHANGED, + &level_changed, sizeof(level_changed)); + } + } +} + +static struct mod_dvfs_notification_api notification_api = { + .notify_limits = scmi_perf_notify_limits, + .notify_level = scmi_perf_notify_level, +}; + /* * Framework handlers */ @@ -700,6 +875,41 @@ static int scmi_perf_init(fwk_id_t module_id, unsigned int element_count, for (i = 0; i < return_val; i++) scmi_perf_ctx.perf_ops_table[i].service_id = FWK_ID_NONE; + + return FWK_SUCCESS; +} + +static int scmi_init_notifications(int domains) +{ + int i, j, status; + + status = scmi_perf_ctx.scmi_api->get_agent_count( + &scmi_perf_ctx.agent_count); + if (status != FWK_SUCCESS) + return status; + fwk_assert(scmi_perf_ctx.agent_count != 0); + + scmi_perf_ctx.agent_notifications = fwk_mm_calloc( + domains, sizeof(struct agent_notifications *)); + + for (i = 0; i < domains; i++) { + scmi_perf_ctx.agent_notifications[i] = + fwk_mm_calloc(1, sizeof(struct agent_notifications)); + scmi_perf_ctx.agent_notifications[i]->limit_notification = + fwk_mm_calloc(scmi_perf_ctx.agent_count, sizeof(fwk_id_t)); + scmi_perf_ctx.agent_notifications[i]->level_notification = + fwk_mm_calloc(scmi_perf_ctx.agent_count, sizeof(fwk_id_t)); + } + + for (i = 0; i < domains; i++) { + for (j = 0; j < scmi_perf_ctx.agent_count; j++) { + scmi_perf_ctx.agent_notifications[i]->limit_notification[j] = + FWK_ID_NONE; + scmi_perf_ctx.agent_notifications[i]->level_notification[j] = + FWK_ID_NONE; + } + } + return FWK_SUCCESS; } @@ -716,6 +926,10 @@ static int scmi_perf_bind(fwk_id_t id, unsigned int round) if (status != FWK_SUCCESS) return status; + status = scmi_init_notifications(scmi_perf_ctx.domain_count); + if (status != FWK_SUCCESS) + return status; + return fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_DVFS), FWK_ID_API(FWK_MODULE_IDX_DVFS, 0), &scmi_perf_ctx.dvfs_api); } @@ -723,10 +937,18 @@ static int scmi_perf_bind(fwk_id_t id, unsigned int round) static int scmi_perf_process_bind_request(fwk_id_t source_id, fwk_id_t target_id, fwk_id_t api_id, const void **api) { - if (!fwk_id_is_equal(source_id, FWK_ID_MODULE(FWK_MODULE_IDX_SCMI))) - return FWK_E_ACCESS; + switch (fwk_id_get_api_idx(api_id)) { + case MOD_SCMI_PERF_PROTOCOL_API: + *api = &scmi_perf_mod_scmi_to_protocol_api; + break; - *api = &scmi_perf_mod_scmi_to_protocol_api; + case MOD_SCMI_PERF_DVFS_NOTIFICATION_API: + *api = ¬ification_api; + break; + + default: + return FWK_E_ACCESS; + } return FWK_SUCCESS; } @@ -854,7 +1076,7 @@ static int scmi_perf_process_event(const struct fwk_event *event, /* SCMI Performance Management Protocol Definition */ const struct fwk_module module_scmi_perf = { .name = "SCMI Performance Management Protocol", - .api_count = 1, + .api_count = MOD_SCMI_PERF_API_COUNT, .event_count = SCMI_PERF_EVENT_IDX_COUNT, .type = FWK_MODULE_TYPE_PROTOCOL, .init = scmi_perf_init, diff --git a/module/smt/src/mod_smt.c b/module/smt/src/mod_smt.c index c6fbfee507d5867b4f17179ade648238ff8e5326..7d95295c61fdb4662318992c0c0d89d57eb194ee 100644 --- a/module/smt/src/mod_smt.c +++ b/module/smt/src/mod_smt.c @@ -224,6 +224,50 @@ static int smt_respond(fwk_id_t channel_id, const void *payload, size_t size) return FWK_SUCCESS; } + +static int smt_transmit(fwk_id_t channel_id, uint32_t message_header, + const void *payload, size_t size) +{ + struct smt_channel_ctx *channel_ctx; + struct mod_smt_memory *memory; + + if (payload == NULL) + return FWK_E_DATA; + + channel_ctx = + &smt_ctx.channel_ctx_table[fwk_id_get_element_idx(channel_id)]; + memory = ((struct mod_smt_memory *) + channel_ctx->config->mailbox_address); + + /* + * If the agent has not yet read the previous message we + * abandon this transmission. We don't want to poll on the BUSY/FREE + * bit, and while it is probably safe to just overwrite the data + * the agent could be in the process of reading. + */ + if (!(memory->status & MOD_SMT_MAILBOX_STATUS_FREE_MASK)) + return FWK_E_BUSY; + + memory->message_header = message_header; + + /* + * we do not want the agent to send an interrupt when it receives + * the message. + */ + memory->flags = 0; + + /* Copy the payload */ + memcpy(memory->payload, payload, size); + + memory->length = sizeof(memory->message_header) + size; + memory->status &= ~MOD_SMT_MAILBOX_STATUS_FREE_MASK; + + /* Notify the agent */ + channel_ctx->driver_api->raise_interrupt(channel_ctx->driver_id); + + return FWK_SUCCESS; +} + static const struct mod_scmi_to_transport_api smt_mod_scmi_to_transport_api = { .get_secure = smt_get_secure, .get_max_payload_size = smt_get_max_payload_size, @@ -231,6 +275,7 @@ static const struct mod_scmi_to_transport_api smt_mod_scmi_to_transport_api = { .get_payload = smt_get_payload, .write_payload = smt_write_payload, .respond = smt_respond, + .transmit = smt_transmit, }; /* diff --git a/product/juno/include/juno_scmi.h b/product/juno/include/juno_scmi.h index c7873869ccc5d5f623b62bf900a7ad35aa4e9843..f3a919039c076939b76d514d667643fe09bf8404 100644 --- a/product/juno/include/juno_scmi.h +++ b/product/juno/include/juno_scmi.h @@ -19,9 +19,12 @@ enum juno_scmi_agent_idx { }; enum juno_scmi_service_idx { - JUNO_SCMI_SERVICE_IDX_PSCI, - JUNO_SCMI_SERVICE_IDX_OSPM_0, - JUNO_SCMI_SERVICE_IDX_OSPM_1, + JUNO_SCMI_SERVICE_IDX_PSCI_A2P, + JUNO_SCMI_SERVICE_IDX_OSPM_A2P_0, + JUNO_SCMI_SERVICE_IDX_OSPM_A2P_1, +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS + JUNO_SCMI_SERVICE_IDX_OSPM_P2A, +#endif JUNO_SCMI_SERVICE_IDX_COUNT, }; diff --git a/product/juno/module/juno_system/src/mod_juno_system.c b/product/juno/module/juno_system/src/mod_juno_system.c index 9791cd02b726a3ea999012dc9061d1dd76a14541..774da4c9fa7009a7c4df107d1cd13ec5e12a362f 100644 --- a/product/juno/module/juno_system/src/mod_juno_system.c +++ b/product/juno/module/juno_system/src/mod_juno_system.c @@ -39,9 +39,12 @@ static fwk_id_t sds_feature_availability_id = /* SCMI services required to enable the messaging stack */ static unsigned int scmi_notification_table[] = { - JUNO_SCMI_SERVICE_IDX_PSCI, - JUNO_SCMI_SERVICE_IDX_OSPM_0, - JUNO_SCMI_SERVICE_IDX_OSPM_1, + JUNO_SCMI_SERVICE_IDX_PSCI_A2P, + JUNO_SCMI_SERVICE_IDX_OSPM_A2P_0, + JUNO_SCMI_SERVICE_IDX_OSPM_A2P_1, +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS + JUNO_SCMI_SERVICE_IDX_OSPM_P2A, +#endif }; struct juno_system_ctx { diff --git a/product/juno/scp_ramfw/config_dvfs.c b/product/juno/scp_ramfw/config_dvfs.c index 360473e42dc9721b2ca84933d68d9ec8bd931990..b16899e9e73628a6fd9c5afbcc9eacdb21d85d26 100644 --- a/product/juno/scp_ramfw/config_dvfs.c +++ b/product/juno/scp_ramfw/config_dvfs.c @@ -12,6 +12,7 @@ #include "juno_id.h" #include +#include #include #include @@ -40,6 +41,9 @@ static const struct mod_dvfs_domain_config cpu_group_little_r0 = { JUNO_CLOCK_IDX_LITTLECLK), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, JUNO_DVFS_ALARM_VLITTLE_IDX), + .notification_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCMI_PERF), + .notification_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SCMI_PERF, + MOD_SCMI_PERF_DVFS_NOTIFICATION_API), .retry_ms = 1, .latency = 1450, .sustained_idx = 2, @@ -80,6 +84,9 @@ static const struct mod_dvfs_domain_config cpu_group_little_r1 = { JUNO_CLOCK_IDX_LITTLECLK), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, JUNO_DVFS_ALARM_VLITTLE_IDX), + .notification_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCMI_PERF), + .notification_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SCMI_PERF, + MOD_SCMI_PERF_DVFS_NOTIFICATION_API), .retry_ms = 1, .latency = 1450, .sustained_idx = 0, @@ -100,6 +107,9 @@ static const struct mod_dvfs_domain_config cpu_group_little_r2 = { JUNO_CLOCK_IDX_LITTLECLK), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, JUNO_DVFS_ALARM_VLITTLE_IDX), + .notification_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCMI_PERF), + .notification_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SCMI_PERF, + MOD_SCMI_PERF_DVFS_NOTIFICATION_API), .retry_ms = 1, .latency = 1450, .sustained_idx = 1, @@ -130,6 +140,9 @@ static const struct mod_dvfs_domain_config cpu_group_big_r0 = { JUNO_CLOCK_IDX_BIGCLK), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, JUNO_DVFS_ALARM_BIG_IDX), + .notification_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCMI_PERF), + .notification_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SCMI_PERF, + MOD_SCMI_PERF_DVFS_NOTIFICATION_API), .retry_ms = 1, .latency = 1450, .sustained_idx = 2, @@ -170,6 +183,9 @@ static const struct mod_dvfs_domain_config cpu_group_big_r1 = { JUNO_CLOCK_IDX_BIGCLK), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, JUNO_DVFS_ALARM_BIG_IDX), + .notification_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCMI_PERF), + .notification_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SCMI_PERF, + MOD_SCMI_PERF_DVFS_NOTIFICATION_API), .retry_ms = 1, .latency = 1450, .sustained_idx = 1, @@ -200,6 +216,9 @@ static const struct mod_dvfs_domain_config cpu_group_big_r2 = { JUNO_CLOCK_IDX_BIGCLK), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, JUNO_DVFS_ALARM_BIG_IDX), + .notification_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCMI_PERF), + .notification_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SCMI_PERF, + MOD_SCMI_PERF_DVFS_NOTIFICATION_API), .retry_ms = 1, .latency = 1450, .sustained_idx = 1, @@ -230,6 +249,9 @@ static const struct mod_dvfs_domain_config gpu_r0 = { JUNO_CLOCK_IDX_GPUCLK), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, JUNO_DVFS_ALARM_GPU_IDX), + .notification_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCMI_PERF), + .notification_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SCMI_PERF, + MOD_SCMI_PERF_DVFS_NOTIFICATION_API), .retry_ms = 1, .latency = 1450, .sustained_idx = 4, @@ -270,6 +292,9 @@ static const struct mod_dvfs_domain_config gpu_r1 = { JUNO_CLOCK_IDX_GPUCLK), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, JUNO_DVFS_ALARM_GPU_IDX), + .notification_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCMI_PERF), + .notification_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SCMI_PERF, + MOD_SCMI_PERF_DVFS_NOTIFICATION_API), .retry_ms = 1, .latency = 1450, .sustained_idx = 4, @@ -310,6 +335,9 @@ static const struct mod_dvfs_domain_config gpu_r2 = { JUNO_CLOCK_IDX_GPUCLK), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, JUNO_DVFS_ALARM_GPU_IDX), + .notification_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCMI_PERF), + .notification_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SCMI_PERF, + MOD_SCMI_PERF_DVFS_NOTIFICATION_API), .retry_ms = 1, .latency = 1450, .sustained_idx = 1, diff --git a/product/juno/scp_ramfw/config_mhu.c b/product/juno/scp_ramfw/config_mhu.c index e09ce45107944fe85e964ae2d2d4fc6caa7cf976..160b3782cad4973e726d6ded40e5d0ce7154f253 100644 --- a/product/juno/scp_ramfw/config_mhu.c +++ b/product/juno/scp_ramfw/config_mhu.c @@ -29,7 +29,7 @@ static const struct fwk_element element_table[] = { }, [JUNO_MHU_DEVICE_IDX_NS_H] = { .name = "", - .sub_element_count = 1, + .sub_element_count = 2, .data = &(struct mod_mhu_device_config) { .irq = MHU_HIGH_PRIO_IRQ, .in = MHU_CPU_INTR_H_BASE, diff --git a/product/juno/scp_ramfw/config_scmi.c b/product/juno/scp_ramfw/config_scmi.c index 67b1cbee1d56730ad090cb0d850858712c11c54f..bb13e66889df3e4fe53e2cfddeb00315d7bd46e7 100644 --- a/product/juno/scp_ramfw/config_scmi.c +++ b/product/juno/scp_ramfw/config_scmi.c @@ -19,12 +19,12 @@ #include static const struct fwk_element element_table[] = { - [JUNO_SCMI_SERVICE_IDX_PSCI] = { + [JUNO_SCMI_SERVICE_IDX_PSCI_A2P] = { .name = "PSCI", .data = &(struct mod_scmi_service_config) { .transport_id = FWK_ID_ELEMENT_INIT( FWK_MODULE_IDX_SMT, - JUNO_SCMI_SERVICE_IDX_PSCI), + JUNO_SCMI_SERVICE_IDX_PSCI_A2P), .transport_api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), @@ -35,12 +35,12 @@ static const struct fwk_element element_table[] = { }, }, - [JUNO_SCMI_SERVICE_IDX_OSPM_0] = { - .name = "OSPM-0", + [JUNO_SCMI_SERVICE_IDX_OSPM_A2P_0] = { + .name = "OSPM-A2P-0", .data = &(struct mod_scmi_service_config) { .transport_id = FWK_ID_ELEMENT_INIT( FWK_MODULE_IDX_SMT, - JUNO_SCMI_SERVICE_IDX_OSPM_0), + JUNO_SCMI_SERVICE_IDX_OSPM_A2P_0), .transport_api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), @@ -51,12 +51,12 @@ static const struct fwk_element element_table[] = { }, }, - [JUNO_SCMI_SERVICE_IDX_OSPM_1] = { - .name = "OSPM-1", + [JUNO_SCMI_SERVICE_IDX_OSPM_A2P_1] = { + .name = "OSPM-A2P-1", .data = &(struct mod_scmi_service_config) { .transport_id = FWK_ID_ELEMENT_INIT( FWK_MODULE_IDX_SMT, - JUNO_SCMI_SERVICE_IDX_OSPM_1), + JUNO_SCMI_SERVICE_IDX_OSPM_A2P_1), .transport_api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_SCMI_TRANSPORT), @@ -67,6 +67,24 @@ static const struct fwk_element element_table[] = { }, }, +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS + [JUNO_SCMI_SERVICE_IDX_OSPM_P2A] = { + .name = "OSPM-P2A", + .data = &(struct mod_scmi_service_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SMT, + JUNO_SCMI_SERVICE_IDX_OSPM_P2A), + .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 = JUNO_SCMI_AGENT_IDX_OSPM, + }, + }, +#endif + [JUNO_SCMI_SERVICE_IDX_COUNT] = { 0 }, }; diff --git a/product/juno/scp_ramfw/config_smt.c b/product/juno/scp_ramfw/config_smt.c index 2fbe075608d6b0fa1b1c63f5871a50de99ed31bb..6b2b7ed82c6975649a0ee14a77e602b1c08f094c 100644 --- a/product/juno/scp_ramfw/config_smt.c +++ b/product/juno/scp_ramfw/config_smt.c @@ -21,7 +21,7 @@ #include static const struct fwk_element element_table[] = { - [JUNO_SCMI_SERVICE_IDX_PSCI] = { + [JUNO_SCMI_SERVICE_IDX_PSCI_A2P] = { .name = "", .data = &(struct mod_smt_channel_config) { .type = MOD_SMT_CHANNEL_TYPE_SLAVE, @@ -38,7 +38,7 @@ static const struct fwk_element element_table[] = { POWER_DOMAIN_IDX_SYSTOP), } }, - [JUNO_SCMI_SERVICE_IDX_OSPM_0] = { + [JUNO_SCMI_SERVICE_IDX_OSPM_A2P_0] = { .name = "", .data = &(struct mod_smt_channel_config) { .type = MOD_SMT_CHANNEL_TYPE_SLAVE, @@ -55,7 +55,7 @@ static const struct fwk_element element_table[] = { POWER_DOMAIN_IDX_SYSTOP), } }, - [JUNO_SCMI_SERVICE_IDX_OSPM_1] = { + [JUNO_SCMI_SERVICE_IDX_OSPM_A2P_1] = { .name = "", .data = &(struct mod_smt_channel_config) { .type = MOD_SMT_CHANNEL_TYPE_SLAVE, @@ -72,6 +72,25 @@ static const struct fwk_element element_table[] = { POWER_DOMAIN_IDX_SYSTOP), } }, +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS + [JUNO_SCMI_SERVICE_IDX_OSPM_P2A] = { + .name = "", + .data = &(struct mod_smt_channel_config) { + .type = MOD_SMT_CHANNEL_TYPE_MASTER, + .policies = MOD_SMT_POLICY_INIT_MAILBOX, + .mailbox_address = (uintptr_t)SCMI_PAYLOAD_HIGH_P2A_BASE, + .mailbox_size = SCMI_PAYLOAD_SIZE, + .driver_id = FWK_ID_SUB_ELEMENT_INIT( + FWK_MODULE_IDX_MHU, + JUNO_MHU_DEVICE_IDX_NS_H, + 1), + .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_MHU, 0), + .pd_source_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_POWER_DOMAIN, + POWER_DOMAIN_IDX_SYSTOP), + } + }, +#endif [JUNO_SCMI_SERVICE_IDX_COUNT] = { 0 }, }; diff --git a/product/juno/scp_ramfw/firmware.mk b/product/juno/scp_ramfw/firmware.mk index 8decd402ca916348d4ee66a0dbac5ea91d75be98..d2e2d5ecf7b24c498b6d5800874b67dd1bb4a2d2 100644 --- a/product/juno/scp_ramfw/firmware.mk +++ b/product/juno/scp_ramfw/firmware.mk @@ -11,6 +11,7 @@ BS_FIRMWARE_CPU := cortex-m3 BS_FIRMWARE_HAS_MULTITHREADING := yes BS_FIRMWARE_HAS_NOTIFICATION := yes +BS_FIRMWARE_HAS_SCMI_NOTIFICATIONS := no BS_FIRMWARE_MODULE_HEADERS_ONLY := diff --git a/product/rdn1e1/scp_ramfw/config_dvfs.c b/product/rdn1e1/scp_ramfw/config_dvfs.c index 4f3cba224fcf2fe07581d58092a5b36f1d2859da..60119e77b251678d778f7c80ccec804f09eaf861 100644 --- a/product/rdn1e1/scp_ramfw/config_dvfs.c +++ b/product/rdn1e1/scp_ramfw/config_dvfs.c @@ -46,6 +46,7 @@ static const struct mod_dvfs_domain_config cpu_group0 = { .psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 0), .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_CPU_GROUP0), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, 0), + .notification_id = FWK_ID_NONE_INIT, .retry_ms = 1, .latency = 1200, .sustained_idx = 2, @@ -56,6 +57,7 @@ static const struct mod_dvfs_domain_config cpu_group1 = { .psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 1), .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_CPU_GROUP1), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, 1), + .notification_id = FWK_ID_NONE_INIT, .retry_ms = 1, .latency = 1200, .sustained_idx = 2, diff --git a/product/sgi575/scp_ramfw/config_dvfs.c b/product/sgi575/scp_ramfw/config_dvfs.c index f19d4e9380694a52ef70784940774ac1cbe20a15..9b828b5be4112775ff3dacdfc3f425b2a726c0f1 100644 --- a/product/sgi575/scp_ramfw/config_dvfs.c +++ b/product/sgi575/scp_ramfw/config_dvfs.c @@ -43,6 +43,7 @@ static const struct mod_dvfs_domain_config cpu_group0 = { .psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 0), .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_CPU_GROUP0), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, 0), + .notification_id = FWK_ID_NONE_INIT, .retry_ms = 1, .latency = 1200, .sustained_idx = 2, @@ -53,6 +54,7 @@ static const struct mod_dvfs_domain_config cpu_group1 = { .psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 1), .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_CPU_GROUP1), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, 1), + .notification_id = FWK_ID_NONE_INIT, .retry_ms = 1, .latency = 1200, .sustained_idx = 2, diff --git a/product/sgm775/scp_ramfw/config_dvfs.c b/product/sgm775/scp_ramfw/config_dvfs.c index 1c01c85189d435fe958d0c1da410d71332202a87..4b4928bf84d0c1cf5da9082d93c1fda151c77994 100644 --- a/product/sgm775/scp_ramfw/config_dvfs.c +++ b/product/sgm775/scp_ramfw/config_dvfs.c @@ -26,6 +26,7 @@ static const struct mod_dvfs_domain_config cpu_group_little = { .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, 1), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, CONFIG_TIMER_DVFS_CPU_GROUP_LITTLE), + .notification_id = FWK_ID_NONE_INIT, .retry_ms = 1, .latency = 1200, .sustained_idx = 2, @@ -59,6 +60,7 @@ static const struct mod_dvfs_domain_config cpu_group_big = { .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, 0), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, CONFIG_TIMER_DVFS_CPU_GROUP_BIG), + .notification_id = FWK_ID_NONE_INIT, .retry_ms = 1, .latency = 1200, .sustained_idx = 2, @@ -92,6 +94,7 @@ static const struct mod_dvfs_domain_config gpu = { .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, 2), .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, CONFIG_TIMER_DVFS_GPU), + .notification_id = FWK_ID_NONE_INIT, .retry_ms = 1, .latency = 1200, .sustained_idx = 4, diff --git a/product/sgm776/scp_ramfw/config_dvfs.c b/product/sgm776/scp_ramfw/config_dvfs.c index 4edcf464c3854d49cd0cc711df7a0bc16fc9ec4d..ebba80ef8fd2a3e6e5da543f5652c8bf1deb8d91 100644 --- a/product/sgm776/scp_ramfw/config_dvfs.c +++ b/product/sgm776/scp_ramfw/config_dvfs.c @@ -21,6 +21,7 @@ static const struct mod_dvfs_domain_config cpu_group_little = { .psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 0), .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, 1), + .notification_id = FWK_ID_NONE_INIT, .latency = 1200, .sustained_idx = 2, .opps = (struct mod_dvfs_opp[]) { @@ -51,6 +52,7 @@ static const struct mod_dvfs_domain_config cpu_group_little = { static const struct mod_dvfs_domain_config cpu_group_big = { .psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 1), .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, 0), + .notification_id = FWK_ID_NONE_INIT, .latency = 1200, .sustained_idx = 2, .opps = (struct mod_dvfs_opp[]) { @@ -81,6 +83,7 @@ static const struct mod_dvfs_domain_config cpu_group_big = { static const struct mod_dvfs_domain_config gpu = { .psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 2), .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, 2), + .notification_id = FWK_ID_NONE_INIT, .latency = 1200, .sustained_idx = 4, .opps = (struct mod_dvfs_opp[]) { diff --git a/tools/build_system/doc.md b/tools/build_system/doc.md index 7067bf20bc4561a912512fefea8f49f5a8ace346..e8d3253a7fe0e3247e948d10527f7305dc0fec76 100644 --- a/tools/build_system/doc.md +++ b/tools/build_system/doc.md @@ -193,6 +193,13 @@ When notification support is enabled, the following applies: number of notification subscriptions supported and set to the value defined by BS_FIRMWARE_NOTIFICATION_COUNT parameter. +SCMI Notifications Support {#section_scmi_notifications} +========================== + +When building a firmware and its dependencies, the +BS_FIRMWARE_HAS_SCMI_NOTIFICATIONS parameter controls whether SCMI notifications +are enabled or not. + Definitions =========== diff --git a/tools/build_system/firmware.mk b/tools/build_system/firmware.mk index ba19b79f6d3d3114ef7b30842c8a066fc72dca19..205b40d1aee0d0efb8ba70b1140bbbc7c4733194 100644 --- a/tools/build_system/firmware.mk +++ b/tools/build_system/firmware.mk @@ -211,6 +211,12 @@ ifeq ($(BUILD_HAS_NOTIFICATION),yes) export BUILD_NOTIFICATION_COUNT endif +ifeq ($(BS_FIRMWARE_HAS_SCMI_NOTIFICATIONS),yes) + BUILD_HAS_SCMI_NOTIFICATIONS := yes +else + BUILD_HAS_SCMI_NOTIFICATIONS := no +endif + # Add directories to the list of targets to build LIB_TARGETS_y += $(patsubst %,$(MODULES_DIR)/%/src, \ $(BUILD_STANDARD_MODULES)) diff --git a/tools/build_system/rules.mk b/tools/build_system/rules.mk index a760d1e33c0862fd83ec78ec28b180e9127bae00..02b729c0d635e35951c23beb2ba8d8ae7e0e2698 100644 --- a/tools/build_system/rules.mk +++ b/tools/build_system/rules.mk @@ -25,6 +25,10 @@ ifdef BUILD_NOTIFICATION_COUNT DEFINES += NOTIFICATION_COUNT=$(BUILD_NOTIFICATION_COUNT) endif +ifeq ($(BUILD_HAS_SCMI_NOTIFICATIONS),yes) + DEFINES += BUILD_HAS_SCMI_NOTIFICATIONS +endif + export AS := $(CC) export LD := $(CC)