From da6311bb3bdd443f1470568531b25fc8a4d58555 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Thu, 28 Nov 2024 15:53:59 +0100 Subject: [PATCH] stm-st-stm32mp: scp-firmware: remove recipe integrated in optee-os v4.0.0 This commit removes the scp-firmware recipe, as it has been integrated into the optee-os recipe with the latest v4.0.0 from the ST BSP release. This update is based on the openstlinux-6.6-yocto-scarthgap-mpu-v24.11.06 tag for Yocto 5.0 (Scarthgap). https://onedigi.atlassian.net/browse/DEL-9381 Signed-off-by: Arturo Buzarra --- .../scp-firmware/scp-firmware-archiver.inc | 10 - .../scp-firmware/scp-firmware.bb | 74 - .../scp-firmware/0001-2.12-stm32mp-r1.patch | 5722 ----------------- .../scp-firmware/0001-Correct-git-error.patch | 32 - .../scp-firmware/README.HOW_TO.txt | 56 - 5 files changed, 5894 deletions(-) delete mode 100644 meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware-archiver.inc delete mode 100644 meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware.bb delete mode 100644 meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-2.12-stm32mp-r1.patch delete mode 100644 meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-Correct-git-error.patch delete mode 100644 meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/README.HOW_TO.txt diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware-archiver.inc b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware-archiver.inc deleted file mode 100644 index c3a587bc1..000000000 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware-archiver.inc +++ /dev/null @@ -1,10 +0,0 @@ -# -# Archiver Configuration -# -SRC_URI:append = " file://README.HOW_TO.txt " -COPYLEFT_LICENSE_INCLUDE:append = " BSD-3* " - -inherit archiver -ARCHIVER_MODE[src] = "original" - -inherit archiver_stm32mp_clean diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware.bb b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware.bb deleted file mode 100644 index b78447ab6..000000000 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware.bb +++ /dev/null @@ -1,74 +0,0 @@ -SUMMARY = "SCP Firmware for stm32mp" -LICENSE = "BSD-3-Clause" -LIC_FILES_CHKSUM = "file://${S}/license.md;md5=ef610a65bfb6d16f79778877cbfd45df" - -SRC_URI = "gitsm://github.com/ARM-software/SCP-firmware;protocol=https;nobranch=1" -SRCREV = "0c7236b1851d90124210a0414fd982dc55322c7c" - -SRC_URI += " \ - file://0001-2.12-stm32mp-r1.patch \ - file://0001-Correct-git-error.patch \ -" - -SCPFW_VERSION = "2.12" -SCPFW_SUBVERSION = "stm32mp" -SCPFW_RELEASE = "r1" - -PV = "${SCPFW_VERSION}-${SCPFW_SUBVERSION}-${SCPFW_RELEASE}" - -S = "${WORKDIR}/git" - -################################################################### -#inherit scp-firmware - -# Enable use of scp-firmware shared folder -STAGING_SCPFW_DIR = "${TMPDIR}/work-shared/${MACHINE}/scp-firmware" - -do_compile[depends] += "scp-firmware:do_configure" -################################################################### - -PACKAGE_ARCH = "${MACHINE_ARCH}" -COMPATIBLE_MACHINE = "(stm32mpcommon)" - -# Do not remove source code, even if rm_work is configured -RM_WORK_EXCLUDE += "${PN}" - -# ----------------------------------------------- -# Enable use of work-shared folder -# Make sure to move ${S} to STAGING_SCPFW_DIR. We can't just -# create the symlink in advance as the git fetcher can't cope with -# the symlink. -do_unpack[cleandirs] += "${S}" -do_unpack[cleandirs] += "${STAGING_SCPFW_DIR}" -do_clean[cleandirs] += "${S}" -do_clean[cleandirs] += "${STAGING_SCPFW_DIR}" -python do_symlink_scpfirmwaresrc() { - # Specific part to update devtool-source class - if bb.data.inherits_class('devtool-source', d): - # We don't want to move the source to STAGING_SCPFW_DIR here - if d.getVar('STAGING_SCPFW_DIR', d): - d.setVar('STAGING_SCPFW_DIR', '${S}') - - # Copy/Paste from kernel class with adaptation to SCPFW var - s = d.getVar("S") - if s[-1] == '/': - # drop trailing slash, so that os.symlink(scpscr, s) doesn't use s as directory name and fail - s=s[:-1] - scpscr = d.getVar("STAGING_SCPFW_DIR") - if s != scpscr: - bb.utils.mkdirhier(scpscr) - bb.utils.remove(scpscr, recurse=True) - if d.getVar("EXTERNALSRC"): - # With EXTERNALSRC S will not be wiped so we can symlink to it - os.symlink(s, scpscr) - else: - import shutil - shutil.move(s, scpscr) - os.symlink(scpscr, s) -} -addtask symlink_scpfirmwaresrc before do_patch do_configure after do_unpack - -# --------------------------------- -# Configure archiver use -# --------------------------------- -include ${@oe.utils.ifelse(d.getVar('ST_ARCHIVER_ENABLE') == '1', 'scp-firmware-archiver.inc','')} diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-2.12-stm32mp-r1.patch b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-2.12-stm32mp-r1.patch deleted file mode 100644 index 65c88f23a..000000000 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-2.12-stm32mp-r1.patch +++ /dev/null @@ -1,5722 +0,0 @@ -From 223bf375c59e78bd4791a3ae40eb9bdc6d361199 Mon Sep 17 00:00:00 2001 -From: Christophe Priouzeau -Date: Mon, 27 Nov 2023 09:44:21 +0100 -Subject: [PATCH] 2.12-stm32mp-r1 - -Signed-off-by: Christophe Priouzeau ---- - framework/include/fwk_dlist.h | 4 +- - framework/include/fwk_slist.h | 4 +- - framework/src/fwk_dlist.c | 6 +- - module/clock/include/mod_clock.h | 60 +- - module/clock/src/mod_clock.c | 33 + - module/optee/clock/src/mod_optee_clock.c | 81 +- - .../include/mod_resource_perms.h | 6 + - module/scmi/include/mod_scmi_std.h | 7 +- - .../scmi_clock/include/internal/scmi_clock.h | 71 ++ - module/scmi_clock/src/mod_scmi_clock.c | 245 ++++++ - .../include/mod_voltage_domain.h | 4 +- - product/optee-stm32mp1/fw/CMakeLists.txt | 7 +- - product/optee-stm32mp1/fw/Firmware.cmake | 15 +- - product/optee-stm32mp1/fw/config_all.c | 797 ++++++++++++++++++ - product/optee-stm32mp1/fw/config_mbx_smt.c | 68 -- - product/optee-stm32mp1/fw/config_scmi.c | 55 -- - .../optee-stm32mp1/fw/config_scmi_clocks.c | 254 ------ - .../fw/config_scmi_reset_domains.c | 204 ----- - .../fw/config_scmi_voltage_domains.c | 262 ------ - .../CMakeLists.txt | 6 +- - .../module/psu_optee_regulator/Module.cmake | 9 + - .../include/mod_psu_optee_regulator.h | 25 + - .../src/mod_psu_optee_regulator.c | 190 +++++ - .../module/stm32_pmic_regu/Module.cmake | 9 - - .../include/mod_stm32_pmic_regu.h | 24 - - .../stm32_pmic_regu/src/mod_stm32_pmic_regu.c | 367 -------- - .../module/stm32_pwr_regu/Module.cmake | 9 - - .../include/mod_stm32_pwr_regu.h | 19 - - .../stm32_pwr_regu/src/mod_stm32_pwr_regu.c | 293 ------- - .../CMakeLists.txt | 9 +- - .../module/stm32_regu_consumer/Module.cmake | 9 + - .../include/mod_stm32_regu_consumer.h | 37 + - .../src/mod_stm32_regu_consumer.c | 343 ++++++++ - product/optee-stm32mp2/fw/CMakeLists.txt | 24 + - product/optee-stm32mp2/fw/Firmware.cmake | 57 ++ - product/optee-stm32mp2/fw/Toolchain-GNU.cmake | 22 + - product/optee-stm32mp2/fw/config_all.c | 793 +++++++++++++++++ - product/optee-stm32mp2/include/fmw_io.h | 17 + - product/optee-stm32mp2/include/fmw_log.h | 16 + - .../optee-stm32mp2/include/gnu/stubs-soft.h | 0 - product/optee-stm32mp2/include/scmi_agents.h | 29 + - .../module/psu_optee_regulator/CMakeLists.txt | 17 + - .../module/psu_optee_regulator/Module.cmake | 9 + - .../include/mod_psu_optee_regulator.h | 25 + - .../src/mod_psu_optee_regulator.c | 190 +++++ - .../module/stm32_regu_consumer/CMakeLists.txt | 17 + - .../module/stm32_regu_consumer/Module.cmake | 9 + - .../include/mod_stm32_regu_consumer.h | 37 + - .../src/mod_stm32_regu_consumer.c | 345 ++++++++ - 49 files changed, 3540 insertions(+), 1599 deletions(-) - create mode 100644 product/optee-stm32mp1/fw/config_all.c - delete mode 100644 product/optee-stm32mp1/fw/config_mbx_smt.c - delete mode 100644 product/optee-stm32mp1/fw/config_scmi.c - delete mode 100644 product/optee-stm32mp1/fw/config_scmi_clocks.c - delete mode 100644 product/optee-stm32mp1/fw/config_scmi_reset_domains.c - delete mode 100644 product/optee-stm32mp1/fw/config_scmi_voltage_domains.c - rename product/optee-stm32mp1/module/{stm32_pwr_regu => psu_optee_regulator}/CMakeLists.txt (80%) - create mode 100644 product/optee-stm32mp1/module/psu_optee_regulator/Module.cmake - create mode 100644 product/optee-stm32mp1/module/psu_optee_regulator/include/mod_psu_optee_regulator.h - create mode 100644 product/optee-stm32mp1/module/psu_optee_regulator/src/mod_psu_optee_regulator.c - delete mode 100644 product/optee-stm32mp1/module/stm32_pmic_regu/Module.cmake - delete mode 100644 product/optee-stm32mp1/module/stm32_pmic_regu/include/mod_stm32_pmic_regu.h - delete mode 100644 product/optee-stm32mp1/module/stm32_pmic_regu/src/mod_stm32_pmic_regu.c - delete mode 100644 product/optee-stm32mp1/module/stm32_pwr_regu/Module.cmake - delete mode 100644 product/optee-stm32mp1/module/stm32_pwr_regu/include/mod_stm32_pwr_regu.h - delete mode 100644 product/optee-stm32mp1/module/stm32_pwr_regu/src/mod_stm32_pwr_regu.c - rename product/optee-stm32mp1/module/{stm32_pmic_regu => stm32_regu_consumer}/CMakeLists.txt (64%) - create mode 100644 product/optee-stm32mp1/module/stm32_regu_consumer/Module.cmake - create mode 100644 product/optee-stm32mp1/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h - create mode 100644 product/optee-stm32mp1/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c - create mode 100644 product/optee-stm32mp2/fw/CMakeLists.txt - create mode 100644 product/optee-stm32mp2/fw/Firmware.cmake - create mode 100644 product/optee-stm32mp2/fw/Toolchain-GNU.cmake - create mode 100644 product/optee-stm32mp2/fw/config_all.c - create mode 100644 product/optee-stm32mp2/include/fmw_io.h - create mode 100644 product/optee-stm32mp2/include/fmw_log.h - create mode 100644 product/optee-stm32mp2/include/gnu/stubs-soft.h - create mode 100644 product/optee-stm32mp2/include/scmi_agents.h - create mode 100644 product/optee-stm32mp2/module/psu_optee_regulator/CMakeLists.txt - create mode 100644 product/optee-stm32mp2/module/psu_optee_regulator/Module.cmake - create mode 100644 product/optee-stm32mp2/module/psu_optee_regulator/include/mod_psu_optee_regulator.h - create mode 100644 product/optee-stm32mp2/module/psu_optee_regulator/src/mod_psu_optee_regulator.c - create mode 100644 product/optee-stm32mp2/module/stm32_regu_consumer/CMakeLists.txt - create mode 100644 product/optee-stm32mp2/module/stm32_regu_consumer/Module.cmake - create mode 100644 product/optee-stm32mp2/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h - create mode 100644 product/optee-stm32mp2/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c - -diff --git a/framework/include/fwk_dlist.h b/framework/include/fwk_dlist.h -index fc560b4e..ffe2dc56 100644 ---- a/framework/include/fwk_dlist.h -+++ b/framework/include/fwk_dlist.h -@@ -1,6 +1,6 @@ - /* - * Arm SCP/MCP Software -- * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - * -@@ -92,7 +92,7 @@ struct fwk_dlist_node *__fwk_dlist_pop_head(struct fwk_dlist *list) FWK_LEAF - * See fwk_list_remove(list, node) for the public interface. - */ - void __fwk_dlist_remove(struct fwk_dlist *list, struct fwk_dlist_node *node) -- FWK_LEAF FWK_NOTHROW FWK_NONNULL(1) FWK_NONNULL(2) FWK_UNTOUCHED(1) -+ FWK_LEAF FWK_NOTHROW FWK_NONNULL(1) FWK_NONNULL(2) FWK_READ_ONLY1(1) - FWK_READ_WRITE1(2); - - /* -diff --git a/framework/include/fwk_slist.h b/framework/include/fwk_slist.h -index df690999..42830d20 100644 ---- a/framework/include/fwk_slist.h -+++ b/framework/include/fwk_slist.h -@@ -1,6 +1,6 @@ - /* - * Arm SCP/MCP Software -- * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - * -@@ -116,7 +116,7 @@ struct fwk_slist_node *__fwk_slist_pop_head(struct fwk_slist *list) FWK_LEAF - struct fwk_slist_node *__fwk_slist_next( - const struct fwk_slist *list, - const struct fwk_slist_node *node) FWK_PURE FWK_LEAF FWK_NOTHROW -- FWK_NONNULL(1) FWK_NONNULL(2) FWK_UNTOUCHED(1) FWK_READ_ONLY1(2); -+ FWK_NONNULL(1) FWK_NONNULL(2) FWK_READ_ONLY1(1) FWK_READ_ONLY1(2); - - /* - * Remove a node from a singly-linked list. -diff --git a/framework/src/fwk_dlist.c b/framework/src/fwk_dlist.c -index 6fcfd08b..e8c1ba62 100644 ---- a/framework/src/fwk_dlist.c -+++ b/framework/src/fwk_dlist.c -@@ -1,6 +1,6 @@ - /* - * Arm SCP/MCP Software -- * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - * -@@ -73,7 +73,7 @@ void __fwk_dlist_remove( - fwk_assert(node->prev != NULL); - fwk_assert(node->next != NULL); - -- assert(__fwk_slist_contains( -+ fwk_assert(__fwk_slist_contains( - (struct fwk_slist *)list, - (struct fwk_slist_node *)node)); - -@@ -104,7 +104,7 @@ void __fwk_dlist_insert( - fwk_assert(node->prev != NULL); - fwk_assert(node->next != NULL); - -- assert(__fwk_slist_contains( -+ fwk_assert(__fwk_slist_contains( - (struct fwk_slist *)list, - (struct fwk_slist_node *)node)); - -diff --git a/module/clock/include/mod_clock.h b/module/clock/include/mod_clock.h -index 4d6f6ead..38bf0400 100644 ---- a/module/clock/include/mod_clock.h -+++ b/module/clock/include/mod_clock.h -@@ -175,10 +175,10 @@ struct mod_clock_config { - */ - struct mod_clock_dev_config { - /*! Reference to the device element within the associated driver module */ -- const fwk_id_t driver_id; -+ fwk_id_t driver_id; - - /*! Reference to the API provided by the device driver module */ -- const fwk_id_t api_id; -+ fwk_id_t api_id; - - /*! - * \brief Reference to the element or module that is the source of the -@@ -424,6 +424,34 @@ struct mod_clock_drv_api { - fwk_id_t clock_id, - uint64_t in_rate, - uint64_t *out_rate); -+ -+ /*! -+ * \brief Get the clock duty cycle. -+ * -+ * \param clock_id Clock device identifier. -+ * -+ * \param[out] num Numerator of the clock duty cycle. -+ * -+ * \param[out] den Denominator of the clock duty cycle. -+ * -+ * \retval ::FWK_SUCCESS The operation succeeded. -+ * \return One of the standard framework error codes. -+ */ -+ int (*get_duty_cycle)(fwk_id_t clock_id, uint32_t *num, uint32_t *den); -+ -+ /*! -+ * \brief Get the rounded rate the clock supports for requested input @rate -+ * -+ * \param clock_id Clock device identifier. -+ * -+ * \param[int] rate Requested rate in Hertz. -+ * -+ * \param[out] rounded_rate Output rounded rate supported. -+ * -+ * \retval ::FWK_SUCCESS The operation succeeded. -+ * \return One of the standard framework error codes. -+ */ -+ int (*round_rate)(fwk_id_t clock_id, uint64_t rate, uint64_t *rounded_rate); - }; - - /*! -@@ -538,6 +566,34 @@ struct mod_clock_api { - * \return One of the standard framework error codes. - */ - int (*get_info)(fwk_id_t clock_id, struct mod_clock_info *info); -+ -+ /*! -+ * \brief Get the clock duty cycle. -+ * -+ * \param clock_id Clock device identifier. -+ * -+ * \param[out] num Numerator of the clock duty cycle. -+ * -+ * \param[out] den Denominator of the clock duty cycle. -+ * -+ * \retval ::FWK_SUCCESS The operation succeeded. -+ * \return One of the standard framework error codes. -+ */ -+ int (*get_duty_cycle)(fwk_id_t clock_id, uint32_t *num, uint32_t *den); -+ -+ /*! -+ * \brief Get the rounded rate the clock supports for requested input @rate -+ * -+ * \param clock_id Clock device identifier. -+ * -+ * \param[int] rate Requested rate in Hertz. -+ * -+ * \param[out] rounded_rate Output rounded rate supported. -+ * -+ * \retval ::FWK_SUCCESS The operation succeeded. -+ * \return One of the standard framework error codes. -+ */ -+ int (*round_rate)(fwk_id_t clock_id, uint64_t rate, uint64_t *rounded_rate); - }; - - /*! -diff --git a/module/clock/src/mod_clock.c b/module/clock/src/mod_clock.c -index 15a1b331..f4b27b24 100644 ---- a/module/clock/src/mod_clock.c -+++ b/module/clock/src/mod_clock.c -@@ -345,6 +345,37 @@ static int clock_get_info(fwk_id_t clock_id, struct mod_clock_info *info) - return FWK_SUCCESS; - } - -+static int clock_get_duty_cycle(fwk_id_t clock_id, uint32_t *num, uint32_t *den) -+{ -+ struct clock_dev_ctx *ctx; -+ -+ clock_get_ctx(clock_id, &ctx); -+ -+ if (!ctx->api->get_duty_cycle) { -+ return FWK_E_SUPPORT; -+ } -+ -+ return ctx->api->get_duty_cycle(ctx->config->driver_id, num, den); -+} -+ -+static int clock_round_rate(fwk_id_t clock_id, uint64_t rate, -+ uint64_t *rounded_rate) -+{ -+ struct clock_dev_ctx *ctx; -+ -+ clock_get_ctx(clock_id, &ctx); -+ -+ if (rounded_rate == NULL) { -+ return FWK_E_PARAM; -+ } -+ -+ if (!ctx->api->round_rate) { -+ return FWK_E_SUPPORT; -+ } -+ -+ return ctx->api->round_rate(ctx->config->driver_id, rate, rounded_rate); -+} -+ - static const struct mod_clock_api clock_api = { - .set_rate = clock_set_rate, - .get_rate = clock_get_rate, -@@ -352,6 +383,8 @@ static const struct mod_clock_api clock_api = { - .set_state = clock_set_state, - .get_state = clock_get_state, - .get_info = clock_get_info, -+ .get_duty_cycle = clock_get_duty_cycle, -+ .round_rate = clock_round_rate, - }; - - /* -diff --git a/module/optee/clock/src/mod_optee_clock.c b/module/optee/clock/src/mod_optee_clock.c -index 0ccaade7..36d9fa9d 100644 ---- a/module/optee/clock/src/mod_optee_clock.c -+++ b/module/optee/clock/src/mod_optee_clock.c -@@ -179,9 +179,8 @@ static int get_range(fwk_id_t dev_id, struct mod_clock_range *range) - return FWK_E_PARAM; - } - -- range->rate_type = MOD_CLOCK_RATE_TYPE_DISCRETE; -- - if (!is_exposed(ctx)) { -+ range->rate_type = MOD_CLOCK_RATE_TYPE_DISCRETE; - range->min = 0; - range->max = 0; - range->rate_count = 1; -@@ -191,9 +190,23 @@ static int get_range(fwk_id_t dev_id, struct mod_clock_range *range) - - res = clk_get_rates_array(ctx->clk, 0, NULL, &rate_count); - if (res == TEE_ERROR_NOT_SUPPORTED) { -- range->min = clk_get_rate(ctx->clk); -- range->max = range->min; -- range->rate_count = 1; -+ unsigned long max = 0; -+ unsigned long min = 0; -+ unsigned long step = 0; -+ -+ res = clk_get_rates_steps(ctx->clk, &min, &max, &step); -+ -+ if (res == TEE_ERROR_NOT_SUPPORTED) { -+ range->rate_type = MOD_CLOCK_RATE_TYPE_DISCRETE; -+ range->min = clk_get_rate(ctx->clk); -+ range->max = range->min; -+ range->rate_count = 1; -+ } -+ -+ range->rate_type = MOD_CLOCK_RATE_TYPE_CONTINUOUS; -+ range->min = min; -+ range->max = max; -+ range->step = step; - - return FWK_SUCCESS; - } -@@ -293,6 +306,62 @@ static int get_rate_from_index(fwk_id_t dev_id, - return FWK_SUCCESS; - } - -+static int get_duty_cycle(fwk_id_t dev_id, uint32_t *num, uint32_t *den) -+{ -+ struct optee_clock_dev_ctx *ctx = elt_id_to_ctx(dev_id); -+ struct clk_duty duty = { 0 }; -+ TEE_Result res; -+ -+ if (ctx == NULL) { -+ return FWK_E_PARAM; -+ } -+ -+ if (!is_exposed(ctx)) { -+ /* Return a dummy value to prevent an error trace */ -+ *num = 1; -+ *den = 2; -+ return FWK_SUCCESS; -+ } -+ -+ res = clk_get_duty_cycle(ctx->clk, &duty); -+ -+ FWK_LOG_DEBUG( -+ MOD_NAME "SCMI optee_clock (%u/\"%s\"): %" PRIx32, -+ fwk_id_get_element_idx(dev_id), -+ clk_get_name(ctx->clk), -+ res); -+ -+ if (res == TEE_ERROR_NOT_SUPPORTED) { -+ /* Assume a 50% duty cycle */ -+ duty = (struct clk_duty){ .num = 1, .den = 2 }; -+ } else if (res != TEE_SUCCESS) { -+ return FWK_E_DEVICE; -+ } -+ -+ *num = duty.num; -+ *den = duty.den; -+ -+ return FWK_SUCCESS; -+} -+ -+static int get_rounded_rate(fwk_id_t dev_id, uint64_t rate, -+ uint64_t *rounded_rate) -+{ -+ struct optee_clock_dev_ctx *ctx = elt_id_to_ctx(dev_id); -+ -+ if (ctx == NULL) { -+ return FWK_E_PARAM; -+ } -+ -+ if (!is_exposed(ctx)) { -+ return FWK_E_SUPPORT; -+ } -+ -+ *rounded_rate = (uint64_t)clk_round_rate(ctx->clk, (unsigned long)rate); -+ -+ return FWK_SUCCESS; -+} -+ - static int stub_process_power_transition(fwk_id_t dev_id, unsigned int state) - { - return FWK_E_SUPPORT; -@@ -312,6 +381,8 @@ static const struct mod_clock_drv_api api_optee_clock = { - .get_range = get_range, - .get_rate_from_index = get_rate_from_index, - .set_rate = set_rate, -+ .get_duty_cycle = get_duty_cycle, -+ .round_rate = get_rounded_rate, - /* Not supported */ - .process_power_transition = stub_process_power_transition, - .process_pending_power_transition = stub_pending_power_transition, -diff --git a/module/resource_perms/include/mod_resource_perms.h b/module/resource_perms/include/mod_resource_perms.h -index 99d2f3d0..78da6799 100644 ---- a/module/resource_perms/include/mod_resource_perms.h -+++ b/module/resource_perms/include/mod_resource_perms.h -@@ -187,6 +187,12 @@ enum mod_res_clock_permissions_idx { - MOD_SCMI_CLOCK_RATE_GET - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, - MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX = - MOD_SCMI_CLOCK_CONFIG_SET - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, -+ MOD_RES_PERMS_SCMI_CLOCK_NAME_GET_IDX = -+ MOD_SCMI_CLOCK_NAME_GET - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, -+ MOD_RES_PERMS_SCMI_CLOCK_RATE_NOTIFY_IDX = -+ MOD_SCMI_CLOCK_RATE_NOTIFY - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, -+ MOD_RES_PERMS_SCMI_CLOCK_CHANGE_REQUESTED_NOTIFY_IDX = -+ MOD_SCMI_CLOCK_CHANGE_REQUESTED_NOTIFY - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, - }; - - /*! -diff --git a/module/scmi/include/mod_scmi_std.h b/module/scmi/include/mod_scmi_std.h -index d212c687..1724406b 100644 ---- a/module/scmi/include/mod_scmi_std.h -+++ b/module/scmi/include/mod_scmi_std.h -@@ -161,7 +161,12 @@ enum scmi_clock_command_id { - MOD_SCMI_CLOCK_RATE_SET = 0x005, - MOD_SCMI_CLOCK_RATE_GET = 0x006, - MOD_SCMI_CLOCK_CONFIG_SET = 0x007, -- MOD_SCMI_CLOCK_COMMAND_COUNT, -+ MOD_SCMI_CLOCK_NAME_GET = 0x008, -+ MOD_SCMI_CLOCK_RATE_NOTIFY = 0x009, -+ MOD_SCMI_CLOCK_RATE_CHANGE_REQUESTED_NOTIFY = 0x00A, -+ MOD_SCMI_CLOCK_DUTY_CYCLE_GET = 0x00B, -+ MOD_SCMI_CLOCK_ROUND_RATE_GET = 0x00C, -+ MOD_SCMI_CLOCK_COMMAND_COUNT - }; - - /*! -diff --git a/module/scmi_clock/include/internal/scmi_clock.h b/module/scmi_clock/include/internal/scmi_clock.h -index f3b51e5b..7671e0e8 100644 ---- a/module/scmi_clock/include/internal/scmi_clock.h -+++ b/module/scmi_clock/include/internal/scmi_clock.h -@@ -244,4 +244,75 @@ struct scmi_clock_describe_rates_p2a { - struct scmi_clock_rate rates[]; - }; - -+/* -+ * Clock get name (extended 64byte name) -+ */ -+ -+struct scmi_clock_name_get_a2p { -+ uint32_t clock_id; -+}; -+ -+#define SCMI_CLOCK_EXTTENDED_NAME_LENGTH_MAX 64 -+ -+struct scmi_clock_name_get_p2a { -+ int32_t status; -+ uint32_t flags; -+ char clock_name[SCMI_CLOCK_EXTTENDED_NAME_LENGTH_MAX]; -+}; -+ -+/* -+ * Clock notify on clock rate change -+ */ -+ -+struct scmi_clock_rate_notify_a2p { -+ uint32_t clock_id; -+ uint32_t notify_enable; -+}; -+ -+struct scmi_clock_rate_notify_p2a { -+ int32_t status; -+}; -+ -+/* -+ * Clock notify on clock rate change requests -+ */ -+ -+struct scmi_clock_rate_change_request_notify_a2p { -+ uint32_t clock_id; -+ uint32_t notify_enable; -+}; -+ -+struct scmi_clock_rate_change_request_notify_p2a { -+ int32_t status; -+}; -+ -+/* -+ * Clock get duty cycle -+ */ -+ -+struct scmi_clock_duty_cycle_get_a2p { -+ uint32_t clock_id; -+}; -+ -+struct scmi_clock_duty_cycle_get_p2a { -+ int32_t status; -+ uint32_t numerator; -+ uint32_t denominator; -+}; -+ -+/* -+ * Clock get round rate -+ */ -+ -+struct scmi_clock_round_rate_get_a2p { -+ uint32_t flags; -+ uint32_t clock_id; -+ uint32_t rate[2]; -+}; -+ -+struct scmi_clock_round_rate_get_p2a { -+ int32_t status; -+ uint32_t rate[2]; -+}; -+ - #endif /* INTERNAL_SCMI_CLOCK_H */ -diff --git a/module/scmi_clock/src/mod_scmi_clock.c b/module/scmi_clock/src/mod_scmi_clock.c -index 59a1fb14..5999e03f 100644 ---- a/module/scmi_clock/src/mod_scmi_clock.c -+++ b/module/scmi_clock/src/mod_scmi_clock.c -@@ -128,6 +128,16 @@ static int scmi_clock_config_set_handler(fwk_id_t service_id, - const uint32_t *payload); - static int scmi_clock_describe_rates_handler(fwk_id_t service_id, - const uint32_t *payload); -+static int scmi_clock_name_get_handler(fwk_id_t service_id, -+ const uint32_t *payload); -+static int scmi_clock_rate_notify_handler(fwk_id_t service_id, -+ const uint32_t *payload); -+static int scmi_clock_rate_change_request_notify_handler(fwk_id_t service_id, -+ const uint32_t *payload); -+static int scmi_clock_duty_cycle_get_handler(fwk_id_t service_id, -+ const uint32_t *payload); -+static int scmi_clock_round_rate_get_handler(fwk_id_t service_id, -+ const uint32_t *payload); - - /* - * Internal variables. -@@ -146,6 +156,11 @@ static int (*const handler_table[MOD_SCMI_CLOCK_COMMAND_COUNT])( - [MOD_SCMI_CLOCK_RATE_SET] = scmi_clock_rate_set_handler, - [MOD_SCMI_CLOCK_CONFIG_SET] = scmi_clock_config_set_handler, - [MOD_SCMI_CLOCK_DESCRIBE_RATES] = scmi_clock_describe_rates_handler, -+ [MOD_SCMI_CLOCK_NAME_GET] = scmi_clock_name_get_handler, -+ [MOD_SCMI_CLOCK_RATE_NOTIFY] = scmi_clock_rate_notify_handler, -+ [MOD_SCMI_CLOCK_RATE_CHANGE_REQUESTED_NOTIFY] = scmi_clock_rate_change_request_notify_handler, -+ [MOD_SCMI_CLOCK_DUTY_CYCLE_GET] = scmi_clock_duty_cycle_get_handler, -+ [MOD_SCMI_CLOCK_ROUND_RATE_GET] = scmi_clock_round_rate_get_handler, - }; - - static const unsigned int payload_size_table[MOD_SCMI_CLOCK_COMMAND_COUNT] = { -@@ -163,6 +178,16 @@ static const unsigned int payload_size_table[MOD_SCMI_CLOCK_COMMAND_COUNT] = { - (unsigned int)sizeof(struct scmi_clock_config_set_a2p), - [MOD_SCMI_CLOCK_DESCRIBE_RATES] = - (unsigned int)sizeof(struct scmi_clock_describe_rates_a2p), -+ [MOD_SCMI_CLOCK_NAME_GET] = -+ (unsigned int)sizeof(struct scmi_clock_describe_rates_a2p), -+ [MOD_SCMI_CLOCK_RATE_NOTIFY] = -+ (unsigned int)sizeof(struct scmi_clock_rate_notify_a2p), -+ [MOD_SCMI_CLOCK_RATE_CHANGE_REQUESTED_NOTIFY] = -+ (unsigned int)sizeof(struct scmi_clock_rate_change_request_notify_a2p), -+ [MOD_SCMI_CLOCK_DUTY_CYCLE_GET] = -+ (unsigned int)sizeof(struct scmi_clock_duty_cycle_get_a2p), -+ [MOD_SCMI_CLOCK_ROUND_RATE_GET] = -+ (unsigned int)sizeof(struct scmi_clock_round_rate_get_a2p), - }; - - /* -@@ -1368,6 +1393,226 @@ exit: - return status; - } - -+static int scmi_clock_name_get_handler(fwk_id_t service_id, -+ const uint32_t *payload) -+{ -+ int status, respond_status; -+ const struct mod_scmi_clock_device *clock_device; -+ size_t response_size; -+ const struct scmi_clock_name_get_a2p *parameters; -+ struct scmi_clock_name_get_p2a return_values = { -+ .status = (int32_t)SCMI_GENERIC_ERROR -+ }; -+ -+ parameters = (const struct scmi_clock_name_get_a2p*)payload; -+ -+ status = scmi_clock_get_clock_device_entry( -+ service_id, parameters->clock_id, &clock_device); -+ if (status != FWK_SUCCESS) { -+ return_values.status = (int32_t)SCMI_NOT_FOUND; -+ goto exit; -+ } -+ -+#ifdef BUILD_HAS_MOD_RESOURCE_PERMS -+ status = scmi_clock_permissions_handler( -+ parameters->clock_id, -+ service_id, -+ (unsigned int)MOD_SCMI_CLOCK_NAME_GET); -+ if (status != FWK_SUCCESS) { -+ return_values.status = (int32_t)SCMI_DENIED; -+ goto exit; -+ } -+#endif -+ -+ fwk_str_strncpy( -+ return_values.clock_name, -+ fwk_module_get_element_name(clock_device->element_id), -+ sizeof(return_values.clock_name) - 1); -+ -+ return_values.status = (int32_t)SCMI_SUCCESS; -+ response_size = sizeof(return_values); -+ return FWK_SUCCESS; -+ -+exit: -+ response_size = sizeof(return_values.status); -+ respond_status = scmi_clock_ctx.scmi_api->respond( -+ service_id, &return_values, response_size); -+ if (respond_status != FWK_SUCCESS) { -+ FWK_LOG_DEBUG("[SCMI-CLK] %s @%d", __func__, __LINE__); -+ } -+ -+ return status; -+} -+ -+static int scmi_clock_rate_notify_handler(fwk_id_t service_id, -+ const uint32_t *payload) -+{ -+ struct scmi_clock_rate_notify_p2a return_values = { -+ .status = (int32_t)SCMI_NOT_SUPPORTED, -+ }; -+ int respond_status; -+ -+ respond_status = scmi_clock_ctx.scmi_api->respond( -+ service_id, -+ &return_values, -+ sizeof(return_values.status)); -+ -+ if (respond_status != FWK_SUCCESS) { -+ FWK_LOG_DEBUG("[SCMI-CLK] %s @%d", __func__, __LINE__); -+ } -+ -+ return FWK_SUCCESS; -+} -+ -+static int scmi_clock_rate_change_request_notify_handler(fwk_id_t service_id, -+ const uint32_t *payload) -+{ -+ struct scmi_clock_rate_change_request_notify_p2a return_values = { -+ .status = (int32_t)SCMI_NOT_SUPPORTED, -+ }; -+ int respond_status; -+ -+ respond_status = scmi_clock_ctx.scmi_api->respond( -+ service_id, -+ &return_values, -+ sizeof(return_values.status)); -+ -+ if (respond_status != FWK_SUCCESS) { -+ FWK_LOG_DEBUG("[SCMI-CLK] %s @%d", __func__, __LINE__); -+ } -+ -+ return FWK_SUCCESS; -+} -+ -+static int scmi_clock_duty_cycle_get_handler(fwk_id_t service_id, -+ const uint32_t *payload) -+ -+{ -+ const struct scmi_clock_duty_cycle_get_a2p *parameters; -+ struct scmi_clock_duty_cycle_get_p2a return_values = { -+ .status = (int32_t)SCMI_SUCCESS -+ }; -+ const struct mod_scmi_clock_device *clock_device; -+ unsigned int agent_id; -+ size_t response_size; -+ int status; -+ -+ parameters = (const struct scmi_clock_duty_cycle_get_a2p*)payload; -+ -+ status = scmi_clock_get_clock_device_entry( -+ service_id, parameters->clock_id, &clock_device); -+ if (status != FWK_SUCCESS) { -+ return_values.status = (int32_t)SCMI_NOT_FOUND; -+ goto exit; -+ } -+ -+#ifdef BUILD_HAS_MOD_RESOURCE_PERMS -+ /* Test SET_RATE permission until we have a DUTY_CYCLE permission flag */ -+ status = scmi_clock_permissions_handler( -+ parameters->clock_id, -+ service_id, -+ (unsigned int)MOD_SCMI_CLOCK_RATE_SET); -+ if (status != FWK_SUCCESS) { -+ return_values.status = (int32_t)SCMI_DENIED; -+ goto exit; -+ } -+#endif -+ -+ status = scmi_clock_ctx.scmi_api->get_agent_id(service_id, &agent_id); -+ if (status != FWK_SUCCESS) { -+ goto exit; -+ } -+ -+ status = scmi_clock_ctx.clock_api->get_duty_cycle(clock_device->element_id, -+ &return_values.numerator, -+ &return_values.denominator); -+ -+ if (status == FWK_E_SUPPORT) { -+ return_values.status = (int32_t)SCMI_NOT_SUPPORTED; -+ } else if (status != FWK_SUCCESS) { -+ return_values.status = (int32_t)SCMI_GENERIC_ERROR; -+ } -+ -+exit: -+ response_size = (return_values.status == SCMI_SUCCESS) ? -+ sizeof(return_values) : sizeof(return_values.status); -+ return scmi_clock_ctx.scmi_api->respond( -+ service_id, &return_values, response_size); -+} -+ -+/* -+ * Use clock set rate with round nearest flag support to -+ * get rounded value. -+ */ -+static int scmi_clock_round_rate_get_handler(fwk_id_t service_id, -+ const uint32_t *payload) -+{ -+ const struct scmi_clock_round_rate_get_a2p *parameters; -+ struct scmi_clock_round_rate_get_p2a return_values = { -+ .status = (int32_t)SCMI_SUCCESS, -+ }; -+ const struct mod_scmi_clock_device *clock_device; -+ unsigned long input_rate; -+ uint64_t output_rate; -+ size_t response_size; -+ int status; -+ -+ parameters = (const struct scmi_clock_round_rate_get_a2p*)payload; -+ -+ status = scmi_clock_get_clock_device_entry( -+ service_id, -+ parameters->clock_id, -+ &clock_device); -+ -+ if (status != FWK_SUCCESS) { -+ return_values.status = (int32_t)SCMI_NOT_FOUND; -+ goto exit; -+ } -+ -+#ifdef BUILD_HAS_MOD_RESOURCE_PERMS -+ status = scmi_clock_permissions_handler( -+ parameters->clock_id, -+ service_id, -+ (unsigned int)MOD_SCMI_CLOCK_RATE_SET); -+ if (status != FWK_SUCCESS) { -+ return_values.status = (int32_t)SCMI_DENIED; -+ goto exit; -+ } -+#endif -+ -+ if ((parameters->flags & SCMI_CLOCK_RATE_SET_ASYNC_MASK) != 0) { -+ /* Support for async clock set commands not yet implemented */ -+ return_values.status = (int32_t)SCMI_NOT_SUPPORTED; -+ goto exit; -+ } -+ -+ input_rate = parameters->rate[0]; -+ if (parameters->rate[1]) { -+ return_values.status = (int32_t)SCMI_INVALID_PARAMETERS; -+ goto exit; -+ } -+ -+ status = scmi_clock_ctx.clock_api->round_rate(clock_device->element_id, -+ input_rate, &output_rate); -+ if (status == FWK_E_SUPPORT) { -+ return_values.status = (int32_t)SCMI_NOT_SUPPORTED; -+ } else if (status != FWK_SUCCESS) { -+ return_values.status = (int32_t)SCMI_GENERIC_ERROR; -+ } else { -+ return_values.rate[0] = (uint32_t)output_rate; -+ return_values.rate[1] = 0; -+ return_values.status = (int32_t)SCMI_SUCCESS; -+ } -+ -+exit: -+ -+ -+ response_size = (return_values.status == SCMI_SUCCESS) ? -+ sizeof(return_values) : sizeof(return_values.status); -+ return scmi_clock_ctx.scmi_api->respond( -+ service_id, &return_values, response_size); -+} -+ - /* - * SCMI module -> SCMI clock module interface - */ -diff --git a/module/voltage_domain/include/mod_voltage_domain.h b/module/voltage_domain/include/mod_voltage_domain.h -index 85b09606..cd0c21f1 100644 ---- a/module/voltage_domain/include/mod_voltage_domain.h -+++ b/module/voltage_domain/include/mod_voltage_domain.h -@@ -78,10 +78,10 @@ enum mod_voltd_voltage_level_type { - */ - struct mod_voltd_dev_config { - /*! Reference to the device element within the associated driver module */ -- const fwk_id_t driver_id; -+ fwk_id_t driver_id; - - /*! Reference to the API provided by the device driver module */ -- const fwk_id_t api_id; -+ fwk_id_t api_id; - }; - - /*! -diff --git a/product/optee-stm32mp1/fw/CMakeLists.txt b/product/optee-stm32mp1/fw/CMakeLists.txt -index c3a47b21..8674a1eb 100644 ---- a/product/optee-stm32mp1/fw/CMakeLists.txt -+++ b/product/optee-stm32mp1/fw/CMakeLists.txt -@@ -20,8 +20,5 @@ target_include_directories( - - target_sources( - ${SCP_FIRMWARE_TARGET} -- PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_mbx_smt.c" -- "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi.c" -- "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi_clocks.c" -- "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi_reset_domains.c" -- "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi_voltage_domains.c") -+ PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_all.c" -+) -diff --git a/product/optee-stm32mp1/fw/Firmware.cmake b/product/optee-stm32mp1/fw/Firmware.cmake -index b0d55b83..0b84f335 100644 ---- a/product/optee-stm32mp1/fw/Firmware.cmake -+++ b/product/optee-stm32mp1/fw/Firmware.cmake -@@ -31,15 +31,15 @@ set(SCP_ENABLE_SCMI_RESET_INIT TRUE) - - set(SCP_ENABLE_IPO_INIT FALSE) - --list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/stm32_pmic_regu") --list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/stm32_pwr_regu") -+list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/stm32_regu_consumer") -+list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/psu_optee_regulator") - - # The order of the modules in the following list is the order in which the - # modules are initialized, bound, started during the pre-runtime phase. - # any change in the order will cause firmware initialization errors. - - list(APPEND SCP_MODULES "optee-mbx") --list(APPEND SCP_MODULES "optee-smt") -+list(APPEND SCP_MODULES "msg-smt") - list(APPEND SCP_MODULES "scmi") - list(APPEND SCP_MODULES "optee-clock") - list(APPEND SCP_MODULES "clock") -@@ -47,8 +47,13 @@ list(APPEND SCP_MODULES "scmi-clock") - list(APPEND SCP_MODULES "optee-reset") - list(APPEND SCP_MODULES "reset-domain") - list(APPEND SCP_MODULES "scmi-reset-domain") --list(APPEND SCP_MODULES "stm32-pmic-regu") --list(APPEND SCP_MODULES "stm32-pwr-regu") -+list(APPEND SCP_MODULES "stm32-regu-consumer") - list(APPEND SCP_MODULES "voltage-domain") - list(APPEND SCP_MODULES "scmi-voltage-domain") -+if (CFG_STM32MP13) -+ list(APPEND SCP_MODULES "psu-optee-regulator") -+ list(APPEND SCP_MODULES "psu") -+ list(APPEND SCP_MODULES "dvfs") -+ list(APPEND SCP_MODULES "scmi-perf") -+endif (CFG_STM32MP13) - list(APPEND SCP_MODULES "optee-console") -diff --git a/product/optee-stm32mp1/fw/config_all.c b/product/optee-stm32mp1/fw/config_all.c -new file mode 100644 -index 00000000..afff9283 ---- /dev/null -+++ b/product/optee-stm32mp1/fw/config_all.c -@@ -0,0 +1,797 @@ -+/* -+ * Arm SCP/MCP Software -+ * Copyright (c) 2022-2023, Linaro Limited and Contributors. All rights reserved. -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#ifdef CFG_SCPFW_MOD_DVFS -+#include -+#endif -+#include -+#include -+#include -+#include -+#ifdef CFG_SCPFW_MOD_PSU -+#include -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* SCMI agent and services (channels) */ -+static struct mod_scmi_agent *scmi_agent_table; -+static struct mod_scmi_config scmi_data; -+static struct fwk_element *scmi_service_elt; -+ -+/* SCMI channel mailbox/shmem */ -+static struct fwk_element *msg_smt_elt; -+static struct mod_msg_smt_channel_config *msg_smt_data; -+static struct fwk_element *optee_mbx_elt; -+static struct mod_optee_mbx_channel_config *optee_mbx_data; -+ -+#ifdef CFG_SCPFW_MOD_SCMI_CLOCK -+/* SCMI clock generic */ -+static struct mod_scmi_clock_agent *scmi_clk_agent_tbl; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_CLOCK -+/* Clocks and optee/clock, same number/indices. Elements and configuration data */ -+static struct fwk_element *optee_clock_elt; /* Optee/clock elements */ -+static struct mod_optee_clock_config *optee_clock_cfg; /* Config data for optee/clock elements */ -+static struct fwk_element *clock_elt; /* Clock elements */ -+static struct mod_clock_dev_config *clock_data; /* Config data for clock elements */ -+#endif -+ -+#ifdef CFG_SCPFW_MOD_DVFS -+/* 1 DVFS (elt & data) per DVFS exposed */ -+static struct mod_dvfs_domain_config *dvfs_data; -+static struct fwk_element *dvfs_elt; -+/* A unique scmi_perf instance refers to perf domains data (DVFS instance) */ -+static struct mod_scmi_perf_domain_config *scmi_perf_domain_data; -+struct fwk_module_config config_scmi_perf; -+ -+/* PSU and optee/psu-regu, used with DVFS. Elements and configuration data */ -+static struct fwk_element *psu_optee_regu_elt; -+static struct mod_psu_optee_regulator_dev_config *psu_optee_regu_data; -+static struct fwk_element *psu_elt; -+static struct mod_psu_element_cfg *psu_data; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_RESET_DOMAIN -+/* SCMI reset domains and optee reset controller */ -+static struct mod_scmi_reset_domain_agent *scmi_reset_agent_tbl; -+static struct fwk_element *optee_reset_elt; -+static struct mod_optee_reset_dev_config *optee_reset_data; -+static struct fwk_element *reset_elt; -+static struct mod_reset_domain_dev_config *reset_data; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN -+/* SCMI voltage domains and optee regulators */ -+static struct mod_scmi_voltd_agent *scmi_voltd_agent_tbl; -+static struct fwk_element *optee_regu_elt; -+static struct mod_stm32_regu_consumer_dev_config *optee_regu_data; -+static struct fwk_element *voltd_elt; -+static struct mod_voltd_dev_config *voltd_data; -+#endif -+ -+/* Config data for scmi module */ -+static const struct fwk_element *get_scmi_service_table(fwk_id_t module_id) -+{ -+ return scmi_service_elt; /* scmi_service_elt filled during initialization */ -+} -+ -+struct fwk_module_config config_scmi = { -+ .data = (void *)&scmi_data, /* scmi_data filled during initialization */ -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_scmi_service_table), -+}; -+ -+/* Config data for optee_mbx module */ -+static const struct fwk_element *optee_mbx_get_element_table(fwk_id_t module_id) -+{ -+ return (const struct fwk_element *)optee_mbx_elt; -+} -+ -+struct fwk_module_config config_optee_mbx = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_mbx_get_element_table), -+}; -+ -+/* Config data for msg_smt module */ -+static const struct fwk_element *msg_smt_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_MSG_SMT); -+ return (const struct fwk_element *)msg_smt_elt; -+} -+ -+struct fwk_module_config config_msg_smt = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(msg_smt_get_element_table), -+}; -+ -+/* Config data for scmi_clock, clock and optee_clock modules */ -+#ifdef CFG_SCPFW_MOD_SCMI_CLOCK -+struct fwk_module_config config_scmi_clock = { -+ .data = &((struct mod_scmi_clock_config){ -+ .agent_table = NULL, /* Allocated during initialization */ -+ .agent_count = 0, /* Set during initialization */ -+ }), -+}; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_CLOCK -+static const struct fwk_element *clock_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_CLOCK); -+ return (const struct fwk_element *)clock_elt; -+} -+ -+struct fwk_module_config config_clock = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(clock_get_element_table), -+}; -+ -+static const struct fwk_element *optee_clock_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_OPTEE_CLOCK); -+ return (const struct fwk_element *)optee_clock_elt; -+} -+ -+struct fwk_module_config config_optee_clock = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_clock_get_element_table), -+}; -+#endif -+ -+/* Config data for scmi_reset_domain, reset_domain and optee_reset modules */ -+#ifdef CFG_SCPFW_MOD_RESET_DOMAIN -+struct fwk_module_config config_scmi_reset_domain = { -+ .data = &((struct mod_scmi_reset_domain_config){ -+ .agent_table = NULL, /* Allocated during initialization */ -+ .agent_count = 0, /* Set during initialization */ -+ }), -+}; -+ -+static const struct fwk_element *reset_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_RESET_DOMAIN); -+ return (const struct fwk_element *)reset_elt; -+} -+ -+struct fwk_module_config config_reset_domain = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(reset_get_element_table), -+}; -+ -+static const struct fwk_element *optee_reset_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_OPTEE_RESET); -+ return (const struct fwk_element *)optee_reset_elt; -+} -+ -+struct fwk_module_config config_optee_reset = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_reset_get_element_table), -+}; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN -+/* Config data for scmi_voltage_domain, voltage_domain and optee_regu modules */ -+struct fwk_module_config config_scmi_voltage_domain = { -+ .data = &((struct mod_scmi_voltd_config){ -+ .agent_table = NULL, /* Allocated during initialization */ -+ .agent_count = 0, /* Set during initialization */ -+ }), -+}; -+ -+static const struct fwk_element *voltd_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_VOLTAGE_DOMAIN); -+ return (const struct fwk_element *)voltd_elt; -+} -+ -+struct fwk_module_config config_voltage_domain = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(voltd_get_element_table), -+}; -+ -+static const struct fwk_element *stm32_regu_consumer_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_STM32_REGU_CONSUMER); -+ return (const struct fwk_element *)optee_regu_elt; -+} -+ -+struct fwk_module_config config_stm32_regu_consumer = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(stm32_regu_consumer_get_element_table), -+}; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_DVFS -+/* Config data for scmi_perf and dvfs module */ -+struct fwk_module_config config_scmi_perf = { -+ .data = &((struct mod_scmi_perf_config){ -+ .domains = NULL, /* Allocated during initialization */ -+ .perf_doms_count = 0, /* Set during initialization */ -+ .fast_channels_alarm_id = FWK_ID_NONE_INIT, -+#ifdef BUILD_HAS_MOD_STATISTICS -+ .stats_enabled = true, -+#endif -+ }), -+}; -+ -+static const struct fwk_element *dvfs_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_DVFS); -+ return (const struct fwk_element *)dvfs_elt; -+} -+ -+struct fwk_module_config config_dvfs = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(dvfs_get_element_table), -+}; -+ -+/* Config data for psu and optee/psu module */ -+static const struct fwk_element *psu_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_PSU); -+ return (const struct fwk_element *)psu_elt; -+} -+ -+struct fwk_module_config config_psu = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(psu_get_element_table), -+}; -+ -+static const struct fwk_element *psu_optee_regu_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_PSU_OPTEE_REGULATOR); -+ return (const struct fwk_element *)psu_optee_regu_elt ; -+} -+ -+struct fwk_module_config config_psu_optee_regulator = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(psu_optee_regu_get_element_table), -+}; -+#endif -+ -+/* -+ * Indices state when applying agents configuration -+ * @channel_count: Number of channels (mailbox/shmem links) used -+ * @clock_index: Current index for clock and optee/clock (same indices) -+ * @clock_count: Number of clocks (also number of optee/clocks) -+ * @reset_index: Current index for reset controller and optee/reset -+ * @reset_count: Number of reset controller (optee/reset) instances -+ * @regu_index: Current index for voltd and optee/regulator -+ * @regu_count: Number of voltd (optee/regulator) instances -+ * @psu_index: Current index for PSU and optee/PSU instances -+ * @psu_count: Number of PSU (optee/PSU) instances -+ * @dvfs_index: Current index for DVFS instance -+ * @dvfs_count: Number of DVFS instances -+ */ -+struct scpfw_resource_counter { -+ size_t channel_count; -+ size_t clock_index; -+ size_t clock_count; -+ size_t reset_index; -+ size_t reset_count; -+ size_t regu_index; -+ size_t regu_count; -+ size_t psu_index; -+ size_t psu_count; -+ size_t dvfs_index; -+ size_t dvfs_count; -+} scpfw_resource_counter; -+ -+/* -+ * Count once for all the several instances and allocate global resources. -+ * Global resources are clock, optee/clock, reset, optee/reset, regu, -+ * optee/regu, psu, optee/psu, dvfs, perfd, ...; -+ */ -+static void count_resources(struct scpfw_config *cfg) -+{ -+ size_t i, j; -+ -+ for (i = 0; i < cfg->agent_count; i++) { -+ struct scpfw_agent_config *agent_cfg = cfg->agent_config + i; -+ -+ scpfw_resource_counter.channel_count += agent_cfg->channel_count; -+ -+ for (j = 0; j < agent_cfg->channel_count; j++) { -+ struct scpfw_channel_config *channel_cfg = agent_cfg->channel_config + j; -+ -+ /* Clocks for scmi_clock and for DVFS */ -+ scpfw_resource_counter.clock_count += channel_cfg->clock_count; -+ scpfw_resource_counter.clock_count += channel_cfg->perfd_count; -+ /* Reset for smci_reset only */ -+ scpfw_resource_counter.reset_count += channel_cfg->reset_count; -+ /* Regulators for smci_voltage_domain only */ -+ scpfw_resource_counter.regu_count += channel_cfg->voltd_count; -+ /* DVFS and PSU DVFS only */ -+ scpfw_resource_counter.dvfs_count += channel_cfg->perfd_count; -+ scpfw_resource_counter.psu_count += channel_cfg->perfd_count; -+ } -+ } -+ -+#ifndef CFG_SCPFW_MOD_CLOCK -+ fwk_assert(!scpfw_resource_counter.clock_count); -+#endif -+#ifndef CFG_SCPFW_MOD_RESET_DOMAIN -+ fwk_assert(!scpfw_resource_counter.reset_count); -+#endif -+#ifndef CFG_SCPFW_MOD_VOLTAGE_DOMAIN -+ fwk_assert(!scpfw_resource_counter.regu_count); -+#endif -+#ifndef CFG_SCPFW_MOD_DVFS -+ fwk_assert(!scpfw_resource_counter.dvfs_count); -+#endif -+#ifndef CFG_SCPFW_MOD_PSU -+ fwk_assert(!scpfw_resource_counter.psu_count); -+#endif -+} -+ -+/* -+ * Allocate all tables that may be needed. An optimized implementation would -+ * allocate a single piece of memory and set the pointers accordingly. -+ * */ -+static void allocate_global_resources(struct scpfw_config *cfg) -+{ -+ struct mod_scmi_reset_domain_config *scmi_reset_config __maybe_unused; -+ struct mod_scmi_voltd_config *scmi_voltd_config __maybe_unused; -+ struct mod_scmi_clock_config *scmi_clock_config __maybe_unused; -+ /* @cfg does not consider agent #0 this the reserved platform/server agent */ -+ size_t __maybe_unused scmi_agent_count = cfg->agent_count + 1; -+ -+#ifdef CFG_SCPFW_MOD_SCMI_CLOCK -+ /* SCMI clock domains resources */ -+ scmi_clk_agent_tbl = fwk_mm_calloc(scmi_agent_count, -+ sizeof(*scmi_clk_agent_tbl)); -+ scmi_clock_config = (void *)config_scmi_clock.data; -+ scmi_clock_config->agent_table = scmi_clk_agent_tbl; -+ scmi_clock_config->agent_count = scmi_agent_count; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_CLOCK -+ /* Clock domains resources */ -+ optee_clock_cfg = fwk_mm_calloc(scpfw_resource_counter.clock_count, -+ sizeof(*optee_clock_cfg)); -+ optee_clock_elt = fwk_mm_calloc(scpfw_resource_counter.clock_count + 1, -+ sizeof(*optee_clock_elt)); -+ -+ clock_data = fwk_mm_calloc(scpfw_resource_counter.clock_count, -+ sizeof(*clock_data)); -+ clock_elt = fwk_mm_calloc(scpfw_resource_counter.clock_count + 1, -+ sizeof(*clock_elt)); -+#endif -+ -+#ifdef CFG_SCPFW_MOD_RESET_DOMAIN -+ /* SCMI reset domains resources */ -+ scmi_reset_agent_tbl = fwk_mm_calloc(scmi_agent_count, -+ sizeof(*scmi_reset_agent_tbl)); -+ scmi_reset_config = (void *)config_scmi_reset_domain.data; -+ scmi_reset_config->agent_table = scmi_reset_agent_tbl; -+ scmi_reset_config->agent_count = scmi_agent_count; -+ -+ optee_reset_data = fwk_mm_calloc(scpfw_resource_counter.reset_count, -+ sizeof(*optee_reset_data)); -+ optee_reset_elt = fwk_mm_calloc(scpfw_resource_counter.reset_count + 1, -+ sizeof(*optee_reset_elt)); -+ -+ reset_data = fwk_mm_calloc(scpfw_resource_counter.reset_count, -+ sizeof(*reset_data)); -+ reset_elt = fwk_mm_calloc(scpfw_resource_counter.reset_count + 1, -+ sizeof(*reset_elt)); -+#endif -+ -+#ifdef CFG_SCPFW_MOD_DVFS -+ /* PSU and related optee PSU regulator resources */ -+ psu_optee_regu_elt = fwk_mm_calloc(scpfw_resource_counter.dvfs_count + 1, -+ sizeof(*psu_optee_regu_elt)); -+ psu_optee_regu_data = fwk_mm_calloc(scpfw_resource_counter.dvfs_count, -+ sizeof(*psu_optee_regu_data)); -+ -+ psu_elt = fwk_mm_calloc(scpfw_resource_counter.psu_count + 1, -+ sizeof(*psu_elt)); -+ psu_data = fwk_mm_calloc(scpfw_resource_counter.psu_count, -+ sizeof(*psu_data)); -+ -+ /* DVFS and SCMI performance management resources */ -+ dvfs_elt = fwk_mm_calloc(scpfw_resource_counter.dvfs_count + 1, -+ sizeof(*dvfs_elt)); -+ dvfs_data = fwk_mm_calloc(scpfw_resource_counter.dvfs_count, -+ sizeof(*dvfs_data)); -+ -+ scmi_perf_domain_data = fwk_mm_calloc(scpfw_resource_counter.dvfs_count, -+ sizeof(*scmi_perf_domain_data)); -+#endif -+ -+#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN -+ /* SCMI voltage domains resources */ -+ scmi_voltd_agent_tbl = fwk_mm_calloc(scmi_agent_count, -+ sizeof(*scmi_voltd_agent_tbl)); -+ scmi_voltd_config = (void *)config_scmi_voltage_domain.data; -+ scmi_voltd_config->agent_table = scmi_voltd_agent_tbl; -+ scmi_voltd_config->agent_count = scmi_agent_count; -+ -+ optee_regu_data = fwk_mm_calloc(scpfw_resource_counter.regu_count, -+ sizeof(*optee_regu_data)); -+ optee_regu_elt = fwk_mm_calloc(scpfw_resource_counter.regu_count + 1, -+ sizeof(*optee_regu_elt)); -+ -+ voltd_data = fwk_mm_calloc(scpfw_resource_counter.regu_count, -+ sizeof(*voltd_data)); -+ voltd_elt = fwk_mm_calloc(scpfw_resource_counter.regu_count + 1, -+ sizeof(*voltd_elt)); -+#endif -+} -+ -+static void set_scmi_comm_resources(struct scpfw_config *cfg) -+{ -+ unsigned int channel_index; -+ size_t i, j; -+ /* @cfg does not consider agent #0 this the reserved platform/server agent */ -+ size_t scmi_agent_count = cfg->agent_count + 1; -+ -+ scmi_agent_table = fwk_mm_calloc(scmi_agent_count, -+ sizeof(*scmi_agent_table)); -+ -+ scmi_service_elt = fwk_mm_calloc(scpfw_resource_counter.channel_count + 1, -+ sizeof(*scmi_service_elt)); -+ -+ msg_smt_elt = fwk_mm_calloc(scpfw_resource_counter.channel_count + 1, -+ sizeof(*msg_smt_elt)); -+ msg_smt_data = fwk_mm_calloc(scpfw_resource_counter.channel_count, -+ sizeof(*msg_smt_data)); -+ -+ optee_mbx_elt = fwk_mm_calloc(scpfw_resource_counter.channel_count + 1, -+ sizeof(*optee_mbx_elt)); -+ optee_mbx_data = fwk_mm_calloc(scpfw_resource_counter.channel_count, -+ sizeof(*optee_mbx_data)); -+ -+ /* Set now the uniqnue scmi module instance configuration data */ -+ scmi_data = (struct mod_scmi_config){ -+ .agent_table = scmi_agent_table, -+ .agent_count = scmi_agent_count, -+ .protocol_count_max = 9, -+ .vendor_identifier = "STMicroelectronics", -+ .sub_vendor_identifier = "STMicroelectronics", -+ }; -+ -+ channel_index = 0; -+ -+ for (i = 0; i < cfg->agent_count; i++) { -+ struct scpfw_agent_config *agent_cfg = cfg->agent_config + i; -+ size_t agent_index = i + 1; -+ -+ scmi_agent_table[agent_index].type = SCMI_AGENT_TYPE_OSPM; -+ scmi_agent_table[agent_index].name = agent_cfg->name; -+ -+ for (j = 0; j < agent_cfg->channel_count; j++) { -+ struct scpfw_channel_config *channel_cfg = agent_cfg->channel_config + j; -+ struct mod_scmi_service_config *service_data; -+ -+ service_data = fwk_mm_calloc(1, sizeof(*service_data)); -+ *service_data = (struct mod_scmi_service_config){ -+ .transport_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MSG_SMT, 0), -+ .transport_api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_MSG_SMT, -+ MOD_MSG_SMT_API_IDX_SCMI_TRANSPORT), -+ .scmi_agent_id = agent_cfg->agent_id, -+ .scmi_p2a_id = FWK_ID_NONE_INIT, -+ }; -+ -+ /* Currently expect 1 agent with ID SCMI_AGENT_ID_NSEC0 (1) */ -+ fwk_assert(service_data->scmi_agent_id == SCMI_AGENT_ID_NSEC0); -+ -+ scmi_service_elt[channel_index].name = channel_cfg->name; -+ scmi_service_elt[channel_index].data = service_data; -+ -+ msg_smt_elt[channel_index].name = channel_cfg->name; -+ msg_smt_elt[channel_index].data = (void *)(msg_smt_data + channel_index); -+ -+ msg_smt_data[channel_index] = (struct mod_msg_smt_channel_config){ -+ .type = MOD_MSG_SMT_CHANNEL_TYPE_REQUESTER, -+ .mailbox_size = 128, -+ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_MBX, -+ channel_index), -+ .driver_api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_MBX, 0), -+ }; -+ -+ optee_mbx_elt[channel_index].name = channel_cfg->name; -+ optee_mbx_elt[channel_index].data = (void *)(optee_mbx_data + channel_index); -+ -+ optee_mbx_data[channel_index] = (struct mod_optee_mbx_channel_config){ -+ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MSG_SMT, channel_index), -+ .driver_api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_MSG_SMT, -+ MOD_MSG_SMT_API_IDX_DRIVER_INPUT), -+ }; -+ -+ channel_index++; -+ } -+ } -+}; -+ -+static void set_resources(struct scpfw_config *cfg) -+{ -+ size_t i, j, k, l __maybe_unused; -+ -+ for (i = 0; i < cfg->agent_count; i++) { -+ struct scpfw_agent_config *agent_cfg = cfg->agent_config + i; -+ size_t agent_index = i + 1; -+ -+ if (agent_index != agent_cfg->agent_id) { -+ panic("scpfw config expects agent ID is agent index"); -+ } -+ -+ for (j = 0; j < agent_cfg->channel_count; j++) { -+ struct scpfw_channel_config *channel_cfg = agent_cfg->channel_config + j; -+ -+#ifdef CFG_SCPFW_MOD_SCMI_CLOCK -+ /* Add first SCMI clock. We will add later the clocks used for DVFS */ -+ if (channel_cfg->clock_count) { -+ size_t clock_index = scpfw_resource_counter.clock_index; -+ struct mod_scmi_clock_device *dev = NULL; -+ -+ /* Set SCMI clocks array for the SCMI agent */ -+ dev = fwk_mm_calloc(channel_cfg->clock_count, -+ sizeof(struct mod_scmi_clock_device)); -+ -+ fwk_assert(!scmi_clk_agent_tbl[agent_index].device_table); -+ scmi_clk_agent_tbl[agent_index].device_count = channel_cfg->clock_count; -+ scmi_clk_agent_tbl[agent_index].device_table = dev; -+ -+ /* Set clock and optee/clock elements and config data */ -+ for (k = 0; k < channel_cfg->clock_count; k++) { -+ struct scmi_clock *clock_cfg = channel_cfg->clock + k; -+ -+ dev[k].element_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, clock_index); -+ -+ optee_clock_cfg[clock_index].clk = clock_cfg->clk; -+ optee_clock_cfg[clock_index].default_enabled = clock_cfg->enabled; -+ -+ optee_clock_elt[clock_index].name = clock_cfg->name; -+ optee_clock_elt[clock_index].data = (void *)(optee_clock_cfg + clock_index); -+ -+ clock_data[clock_index] = (struct mod_clock_dev_config){ -+ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, -+ clock_index), -+ .api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, -+ 0), -+ }; -+ -+ clock_elt[clock_index].name = clock_cfg->name; -+ clock_elt[clock_index].data = (void *)(clock_data + clock_index); -+ -+ clock_index++; -+ } -+ -+ scpfw_resource_counter.clock_index = clock_index; -+ } -+#endif -+ -+#ifdef CFG_SCPFW_MOD_RESET_DOMAIN -+ if (channel_cfg->reset_count) { -+ struct mod_scmi_reset_domain_device *dev = NULL; -+ size_t reset_index = scpfw_resource_counter.reset_index; -+ -+ /* Set SCMI reset domains array for the SCMI agent */ -+ dev = fwk_mm_calloc(channel_cfg->reset_count, sizeof(*dev)); -+ -+ fwk_assert(!scmi_reset_agent_tbl[agent_index].device_table); -+ scmi_reset_agent_tbl[agent_index].agent_domain_count = channel_cfg->reset_count; -+ scmi_reset_agent_tbl[agent_index].device_table = dev; -+ -+ /* Set reset_domain and optee/reset elements and config data */ -+ for (k = 0; k < channel_cfg->reset_count; k++) { -+ struct scmi_reset *reset_cfg = channel_cfg->reset + k; -+ -+ dev[k].element_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_RESET_DOMAIN, -+ reset_index); -+ -+ optee_reset_data[reset_index].rstctrl = reset_cfg->rstctrl; -+ -+ optee_reset_elt[reset_index].name = reset_cfg->name; -+ optee_reset_elt[reset_index].data = -+ (void *)(optee_reset_data + reset_index); -+ -+ reset_data[reset_index] = (struct mod_reset_domain_dev_config){ -+ .driver_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_RESET, -+ reset_index), -+ .driver_api_id = -+ (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_RESET, 0), -+ .modes = MOD_RESET_DOMAIN_AUTO_RESET | -+ MOD_RESET_DOMAIN_MODE_EXPLICIT_ASSERT | -+ MOD_RESET_DOMAIN_MODE_EXPLICIT_DEASSERT, -+ }; -+ -+ reset_elt[reset_index].name = reset_cfg->name; -+ reset_elt[reset_index].data = (void *)(reset_data + reset_index); -+ -+ reset_index++; -+ } -+ -+ scpfw_resource_counter.reset_index = reset_index; -+ } -+#endif -+ -+#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN -+ if (channel_cfg->voltd_count) { -+ size_t regu_index = scpfw_resource_counter.regu_index; -+ struct mod_scmi_voltd_device *dev = NULL; -+ -+ /* Set SCMI voltage domains array for the SCMI agent */ -+ dev = fwk_mm_calloc(channel_cfg->voltd_count, -+ sizeof(struct mod_scmi_voltd_device)); -+ -+ fwk_assert(!scmi_voltd_agent_tbl[agent_index].device_table); -+ scmi_voltd_agent_tbl[agent_index].domain_count = channel_cfg->voltd_count; -+ scmi_voltd_agent_tbl[agent_index].device_table = dev; -+ -+ /* Set voltage_domain and optee/regu elements and config data */ -+ for (k = 0; k < channel_cfg->voltd_count; k++) { -+ struct scmi_voltd *voltd_cfg = channel_cfg->voltd + k; -+ static const char reserved[] = "reserved"; -+ const char *name = NULL; -+ -+ if (voltd_cfg->rdev) { -+ name = voltd_cfg->rdev->reg_name; -+ } else { -+ name = reserved; -+ } -+ -+ dev[regu_index].element_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_VOLTAGE_DOMAIN, k); -+ -+ optee_regu_elt[regu_index].name = name; -+ optee_regu_elt[regu_index].data = (void *)(optee_regu_data + regu_index); -+ optee_regu_data[regu_index].rdev = voltd_cfg->rdev; -+ optee_regu_data[regu_index].default_enabled = voltd_cfg->enabled; -+ -+ voltd_data[regu_index].driver_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_STM32_REGU_CONSUMER, -+ regu_index); -+ voltd_data[regu_index].api_id = -+ (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_STM32_REGU_CONSUMER, 0); -+ -+ voltd_elt[regu_index].name = name; -+ voltd_elt[regu_index].data = (void *)(voltd_data + regu_index); -+ regu_index++; -+ } -+ -+ scpfw_resource_counter.regu_index = regu_index; -+ } -+#endif -+ -+#ifdef CFG_SCPFW_MOD_DVFS -+ if (channel_cfg->perfd_count) { -+ size_t clock_index = scpfw_resource_counter.clock_index; -+ size_t psu_index = scpfw_resource_counter.psu_index; -+ size_t dvfs_index = scpfw_resource_counter.dvfs_index; -+ -+ for (k = 0; k < channel_cfg->perfd_count; k++) { -+ struct mod_scmi_perf_config *scmi_perf_data = NULL; -+ struct scmi_perfd *perfd_cfg = channel_cfg->perfd + k; -+ -+ /* -+ * DVFS with SCMI performance management domains -+ * 1 initial scmi_perf instance defines the number of DVFS's -+ * For each DVFS instance: -+ * - 1 instance (elt/config) of dvfs, psu, optee/psu, clock, optee/clock -+ * Clocks and optee/clocks are already allocated but not yet set. -+ */ -+ -+ /* scmi_perf: data defines the DVFS domains indices */ -+ scmi_perf_domain_data[dvfs_index] = (struct mod_scmi_perf_domain_config){ }; -+ -+ scmi_perf_data = (void *)config_scmi_perf.data; -+ -+ scmi_perf_data[dvfs_index].domains = (void *)scmi_perf_domain_data; -+ scmi_perf_data[dvfs_index].perf_doms_count = scpfw_resource_counter.dvfs_count; -+ scmi_perf_data[dvfs_index].fast_channels_alarm_id = (fwk_id_t)FWK_ID_NONE_INIT; -+#ifdef BUILD_HAS_MOD_STATISTICS -+ scmi_perf_data[dvfs_index].stats_enabled = true; -+#endif -+ -+ /* dvfs instances: 1 instance per expose DVFS service */ -+ dvfs_data[dvfs_index].psu_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, psu_index); -+ dvfs_data[dvfs_index].clock_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, clock_index); -+ dvfs_data[dvfs_index].latency = 0; /* not set, used for async access */ -+ dvfs_data[dvfs_index].opps = -+ fwk_mm_calloc(perfd_cfg->dvfs_opp_count, -+ sizeof(struct mod_dvfs_opp)); -+ -+ for (l = 0; l < perfd_cfg->dvfs_opp_count; l++) { -+ uint64_t power = 0; -+ -+ /* Quick estimation of power consumpsion */ -+ power = perfd_cfg->dvfs_opp_khz[l]; -+ power *= perfd_cfg->dvfs_opp_mv[l]; -+ power *= perfd_cfg->dvfs_opp_mv[l]; -+ power /= 100 * 1000 * 1000; -+ -+ dvfs_data[dvfs_index].opps[l] = (struct mod_dvfs_opp){ -+ .level = perfd_cfg->dvfs_opp_khz[l] * 1000UL, -+ .frequency = perfd_cfg->dvfs_opp_khz[l], -+ .voltage = perfd_cfg->dvfs_opp_mv[l], -+ .power = (uint32_t)power, -+ }; -+ } -+ -+ dvfs_elt[dvfs_index].name = perfd_cfg->name; -+ dvfs_elt[dvfs_index].data = (void *)(dvfs_data + dvfs_index); -+ -+ /* Module psu_optee module (elements and configuration data) */ -+ psu_optee_regu_elt[psu_index].name = perfd_cfg->rdev->reg_name; -+ psu_optee_regu_elt[psu_index].sub_element_count = scpfw_resource_counter.psu_count; -+ psu_optee_regu_elt[psu_index].data = (void *)(psu_optee_regu_data + psu_index); -+ -+ psu_optee_regu_data[psu_index].rdev = perfd_cfg->rdev; -+ -+ /* Module psu (elements and configuration data) */ -+ psu_elt[psu_index].name = perfd_cfg->rdev->reg_name; -+ psu_elt[psu_index].data = (void *)(psu_data + psu_index); -+ psu_data[psu_index].driver_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU_OPTEE_REGULATOR, psu_index); -+ psu_data[psu_index].driver_api_id = -+ (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_PSU_OPTEE_REGULATOR, 0); -+ -+ /* Module clock and optee_clock */ -+ fwk_assert(!clock_elt[clock_index].data); -+ -+ clock_elt[clock_index].name = perfd_cfg->clk->name; -+ clock_elt[clock_index].data = (void *)(clock_data + clock_index); -+ -+ clock_data[clock_index] = (struct mod_clock_dev_config){ -+ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, -+ clock_index), -+ .api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, -+ 0), -+ }; -+ -+ optee_clock_cfg[clock_index].clk = perfd_cfg->clk; -+ optee_clock_cfg[clock_index].default_enabled = false; -+ -+ optee_clock_elt[clock_index].name = perfd_cfg->clk->name; -+ optee_clock_elt[clock_index].data = (void *)(optee_clock_cfg + clock_index); -+ -+ clock_index++; -+ psu_index++; -+ dvfs_index++; -+ } -+ -+ scpfw_resource_counter.clock_index = clock_index; -+ scpfw_resource_counter.psu_index = psu_index; -+ scpfw_resource_counter.dvfs_index = dvfs_index; -+ } -+#endif -+ } -+ } -+} -+ -+void scpfw_configure(struct scpfw_config *cfg) -+{ -+ count_resources(cfg); -+ allocate_global_resources(cfg); -+ set_scmi_comm_resources(cfg); -+ set_resources(cfg); -+} -diff --git a/product/optee-stm32mp1/fw/config_mbx_smt.c b/product/optee-stm32mp1/fw/config_mbx_smt.c -deleted file mode 100644 -index 21d606d7..00000000 ---- a/product/optee-stm32mp1/fw/config_mbx_smt.c -+++ /dev/null -@@ -1,68 +0,0 @@ --/* -- * Arm SCP/MCP Software -- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#include --#include --#include --#include --#include -- --#include --#include --#include -- --#include -- --#define OSPM0_SMT_MAILBOX_PA 0x2ffff000 --#define OSPM0_SMT_MAILBOX_SIZE SCMI_SHMEM_SIZE -- --static const struct fwk_element mbx_element_table[] = { -- [SCMI_CHANNEL_DEVICE_IDX_NS0] = { -- .name = "SCMI non-secure to OP-TEE channel 0", -- .data = &((struct mod_optee_mbx_channel_config){ -- .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_SMT, 0), -- .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_SMT, -- MOD_OPTEE_SMT_API_IDX_DRIVER_INPUT) -- }) -- }, -- [SCMI_CHANNEL_DEVICE_IDX_COUNT] = { 0 }, --}; -- --static const struct fwk_element *mbx_get_element_table(fwk_id_t module_id) --{ -- return (const struct fwk_element *)mbx_element_table; --} -- --struct fwk_module_config config_optee_mbx = { -- .elements = FWK_MODULE_DYNAMIC_ELEMENTS(mbx_get_element_table), --}; -- --static struct fwk_element smt_elt_table[] = { -- [0] = { -- .name = "OSPM0", -- .data = &((struct mod_optee_smt_channel_config) { -- .type = MOD_OPTEE_SMT_CHANNEL_TYPE_REQUESTER, -- .mailbox_address = OSPM0_SMT_MAILBOX_PA, -- .mailbox_size = OSPM0_SMT_MAILBOX_SIZE, -- .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_MBX, -- SCMI_CHANNEL_DEVICE_IDX_NS0), -- .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_MBX, 0), -- }) -- }, -- [1] = { 0 }, --}; -- --static const struct fwk_element *smt_get_element_table(fwk_id_t module_id) --{ -- fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_OPTEE_SMT); -- -- return (const struct fwk_element *)smt_elt_table; --} -- --struct fwk_module_config config_optee_smt = { -- .elements = FWK_MODULE_DYNAMIC_ELEMENTS(smt_get_element_table), --}; -diff --git a/product/optee-stm32mp1/fw/config_scmi.c b/product/optee-stm32mp1/fw/config_scmi.c -deleted file mode 100644 -index 4f3442cc..00000000 ---- a/product/optee-stm32mp1/fw/config_scmi.c -+++ /dev/null -@@ -1,55 +0,0 @@ --/* -- * Arm SCP/MCP Software -- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#include --#include --#include --#include --#include --#include -- --#include --#include --#include --#include -- --static const struct fwk_element service_table[] = { -- [SCMI_SERVICE_IDX_NS_CHANNEL0] = { -- .name = "service-0", -- .data = &((struct mod_scmi_service_config) { -- .transport_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_SMT, 0), -- .transport_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_SMT, -- MOD_OPTEE_SMT_API_IDX_SCMI_TRANSPORT), -- .scmi_agent_id = SCMI_AGENT_ID_NSEC0, -- .scmi_p2a_id = FWK_ID_NONE_INIT, -- }), -- }, -- [SCMI_SERVICE_IDX_COUNT] = { 0 } --}; -- --static const struct fwk_element *get_scmi_service_table(fwk_id_t module_id) --{ -- return service_table; --} -- --static const struct mod_scmi_agent agent_table[] = { -- [SCMI_AGENT_ID_NSEC0] = { -- .type = SCMI_AGENT_TYPE_OSPM, -- .name = "OSPM0", -- }, --}; -- --struct fwk_module_config config_scmi = { -- .data = &((struct mod_scmi_config) { -- .protocol_count_max = 9, -- .agent_count = FWK_ARRAY_SIZE(agent_table) - 1, -- .agent_table = agent_table, -- .vendor_identifier = "Linaro", -- .sub_vendor_identifier = "PMWG", -- }), -- .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_scmi_service_table), --}; -diff --git a/product/optee-stm32mp1/fw/config_scmi_clocks.c b/product/optee-stm32mp1/fw/config_scmi_clocks.c -deleted file mode 100644 -index 478ae588..00000000 ---- a/product/optee-stm32mp1/fw/config_scmi_clocks.c -+++ /dev/null -@@ -1,254 +0,0 @@ --/* -- * Arm SCP/MCP Software -- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#include --#include --#include --#include -- --#include --#include --#include --#include -- --#include --#include --#include -- --#include --#include --#include -- --/* -- * Indices of clock elements exposed through a SCMI agent. -- * As all exposed SCMI clocks relate to a single backend dirver -- * these indices are used as indices for fwk elements for modules -- * CLOCK and STM32_CLOCK. Note these are not the clock ID values -- * exposed through SCMI. -- */ --enum clock_elt_idx { -- /* Clocks exposed to agent SCMI */ -- CLK_IDX_SCMI_HSE, -- CLK_IDX_SCMI_HSI, -- CLK_IDX_SCMI_CSI, -- CLK_IDX_SCMI_LSE, -- CLK_IDX_SCMI_LSI, -- CLK_IDX_SCMI_PLL2_Q, -- CLK_IDX_SCMI_PLL2_R, -- CLK_IDX_SCMI_MPU, -- CLK_IDX_SCMI_AXI, -- CLK_IDX_SCMI_BSEC, -- CLK_IDX_SCMI_CRYP1, -- CLK_IDX_SCMI_GPIOZ, -- CLK_IDX_SCMI_HASH1, -- CLK_IDX_SCMI_I2C4, -- CLK_IDX_SCMI_I2C6, -- CLK_IDX_SCMI_IWDG1, -- CLK_IDX_SCMI_RNG1, -- CLK_IDX_SCMI_RTC, -- CLK_IDX_SCMI_RTCAPB, -- CLK_IDX_SCMI_SPI6, -- CLK_IDX_SCMI_USART1, -- /* Count indices */ -- CLK_IDX_COUNT --}; -- --struct mod_stm32_clock_dev_config { -- const char *name; -- unsigned long rcc_clk_id; -- bool default_enabled; --}; -- --/* -- * stm32_clock_cfg - Common configuration for exposed SCMI clocks -- * -- * Clock name defined here is used for all CLOCK and STM32_CLOCK -- * fwk elements names. -- */ --#define STM32_CLOCK_CFG(_idx, _rcc_clk_id, _name, _default_enabled) \ -- [(_idx)] = { \ -- .rcc_clk_id = (_rcc_clk_id), \ -- .name = (_name), \ -- .default_enabled = (_default_enabled), \ -- } -- --static const struct mod_stm32_clock_dev_config stm32_clock_cfg[] = { -- STM32_CLOCK_CFG(CLK_IDX_SCMI_HSE, CK_HSE, "ck_hse", true), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_HSI, CK_HSI, "ck_hsi", true), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_CSI, CK_CSI, "ck_csi", true), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_LSE, CK_LSE, "ck_lse", true), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_LSI, CK_LSI, "ck_lsi", true), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_PLL2_Q, PLL2_Q, "pll2_q", true), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_PLL2_R, PLL2_R, "pll2_r", true), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_MPU, CK_MCU, "ck_mpu", true), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_AXI, CK_AXI, "ck_axi", true), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_BSEC, BSEC, "bsec", false), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_CRYP1, CRYP1, "cryp1", false), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_GPIOZ, GPIOZ, "gpioz", false), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_HASH1, HASH1, "hash1", false), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_I2C4, I2C4_K, "i2c4_k", false), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_I2C6, I2C6_K, "i2c6_k", false), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_IWDG1, IWDG1, "iwdg1", false), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_RNG1, RNG1_K, "rng1_k", true), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_RTC, RTC, "ck_rtc", true), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_RTCAPB, RTCAPB, "rtcapb", true), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_SPI6, SPI6_K, "spi6_k", false), -- STM32_CLOCK_CFG(CLK_IDX_SCMI_USART1, USART1_K, "usart1_k", false), --}; -- --/* -- * Bindgins between SCMI clock_id value and clock module element in fwk -- */ --#define SCMI_CLOCK_ELT_ID(_idx) \ -- { .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, (_idx)) } -- --static struct mod_scmi_clock_device scmi_clock_device[] = { -- [CK_SCMI_HSE] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_HSE), -- [CK_SCMI_HSI] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_HSI), -- [CK_SCMI_CSI] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_CSI), -- [CK_SCMI_LSE] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_LSE), -- [CK_SCMI_LSI] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_LSI), -- [CK_SCMI_PLL2_Q] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_PLL2_Q), -- [CK_SCMI_PLL2_R] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_PLL2_R), -- [CK_SCMI_MPU] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_MPU), -- [CK_SCMI_AXI] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_AXI), -- [CK_SCMI_BSEC] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_BSEC), -- [CK_SCMI_CRYP1] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_CRYP1), -- [CK_SCMI_GPIOZ] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_GPIOZ), -- [CK_SCMI_HASH1] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_HASH1), -- [CK_SCMI_I2C4] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_I2C4), -- [CK_SCMI_I2C6] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_I2C6), -- [CK_SCMI_IWDG1] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_IWDG1), -- [CK_SCMI_RNG1] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_RNG1), -- [CK_SCMI_RTC] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_RTC), -- [CK_SCMI_RTCAPB] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_RTCAPB), -- [CK_SCMI_SPI6] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_SPI6), -- [CK_SCMI_USART1] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_USART1), --}; -- --/* Agents and clocks references */ --static const struct mod_scmi_clock_agent clk_agent_tbl[SCMI_AGENT_ID_COUNT] = { -- [SCMI_AGENT_ID_NSEC0] = { -- .device_table = (void *)scmi_clock_device, -- .device_count = FWK_ARRAY_SIZE(scmi_clock_device), -- }, --}; -- --/* Exported configuration data for module SCMI_CLOCK */ --struct fwk_module_config config_scmi_clock = { -- .data = &((struct mod_scmi_clock_config){ -- .agent_table = clk_agent_tbl, -- .agent_count = FWK_ARRAY_SIZE(clk_agent_tbl), -- }), --}; -- --/* -- * Clock backend driver configuration -- * STM32_CLOCK element index is the related CLOCK element index. -- */ --#define CLOCK_DATA(_idx) ((struct mod_clock_dev_config){ \ -- .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, \ -- (_idx)), \ -- .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, 0), \ -- }) -- --#define CLOCK_ELT(_idx) [(_idx)] = { \ -- .name = stm32_clock_cfg[(_idx)].name, \ -- .data = &CLOCK_DATA((_idx)), \ -- } -- --/* Element names are the clock names exposed by the SCMI service */ --static struct fwk_element clock_elt[] = { -- /* Clocks exposed to agent SCMI */ -- CLOCK_ELT(CLK_IDX_SCMI_HSE), -- CLOCK_ELT(CLK_IDX_SCMI_HSI), -- CLOCK_ELT(CLK_IDX_SCMI_CSI), -- CLOCK_ELT(CLK_IDX_SCMI_LSE), -- CLOCK_ELT(CLK_IDX_SCMI_LSI), -- CLOCK_ELT(CLK_IDX_SCMI_PLL2_Q), -- CLOCK_ELT(CLK_IDX_SCMI_PLL2_R), -- CLOCK_ELT(CLK_IDX_SCMI_MPU), -- CLOCK_ELT(CLK_IDX_SCMI_AXI), -- CLOCK_ELT(CLK_IDX_SCMI_BSEC), -- CLOCK_ELT(CLK_IDX_SCMI_CRYP1), -- CLOCK_ELT(CLK_IDX_SCMI_GPIOZ), -- CLOCK_ELT(CLK_IDX_SCMI_HASH1), -- CLOCK_ELT(CLK_IDX_SCMI_I2C4), -- CLOCK_ELT(CLK_IDX_SCMI_I2C6), -- CLOCK_ELT(CLK_IDX_SCMI_IWDG1), -- CLOCK_ELT(CLK_IDX_SCMI_RNG1), -- CLOCK_ELT(CLK_IDX_SCMI_RTC), -- CLOCK_ELT(CLK_IDX_SCMI_RTCAPB), -- CLOCK_ELT(CLK_IDX_SCMI_SPI6), -- CLOCK_ELT(CLK_IDX_SCMI_USART1), -- /* Termination entry */ -- [CLK_IDX_COUNT] = { 0 } --}; -- --static_assert(FWK_ARRAY_SIZE(clock_elt) == CLK_IDX_COUNT + 1, -- "Invalid range for CLOCK and STM32_CLOCK indices"); -- --/* Exported configuration data for module VOLTAGE_DOMAIN */ --const struct fwk_module_config config_clock = { -- .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(clock_elt), --}; -- --#define CLOCK_COUNT FWK_ARRAY_SIZE(stm32_clock_cfg) --static struct mod_optee_clock_config optee_clock_cfg[CLOCK_COUNT]; -- --#define OPTEE_CLOCK_ELT(_idx) \ -- [(_idx)] = { \ -- .name = stm32_clock_cfg[(_idx)].name, \ -- .data = &optee_clock_cfg[(_idx)], \ -- } -- --static const struct fwk_element optee_clock_elt[] = { -- /* Clocks exposed to agent SCMI */ -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_HSE), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_HSI), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_CSI), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_LSE), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_LSI), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_PLL2_Q), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_PLL2_R), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_MPU), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_AXI), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_BSEC), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_CRYP1), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_GPIOZ), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_HASH1), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_I2C4), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_I2C6), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_IWDG1), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_RNG1), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_RTC), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_RTCAPB), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_SPI6), -- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_USART1), -- /* Termination entry */ -- [CLK_IDX_COUNT] = { 0 } --}; -- --static_assert(FWK_ARRAY_SIZE(optee_clock_elt) == CLK_IDX_COUNT + 1, -- "Invalid range for CLOCK and STM32_CLOCK indices"); -- --static const struct fwk_element *optee_clock_get_elt_table(fwk_id_t module_id) --{ -- size_t n; -- -- for (n = 0; n < FWK_ARRAY_SIZE(optee_clock_cfg); n++) { -- optee_clock_cfg[n].clk = -- stm32mp_rcc_clock_id_to_clk(stm32_clock_cfg[n].rcc_clk_id); -- optee_clock_cfg[n].default_enabled = stm32_clock_cfg[n].default_enabled; -- } -- -- return optee_clock_elt; --} -- --struct fwk_module_config config_optee_clock = { -- .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_clock_get_elt_table), --}; -diff --git a/product/optee-stm32mp1/fw/config_scmi_reset_domains.c b/product/optee-stm32mp1/fw/config_scmi_reset_domains.c -deleted file mode 100644 -index bb9794d6..00000000 ---- a/product/optee-stm32mp1/fw/config_scmi_reset_domains.c -+++ /dev/null -@@ -1,204 +0,0 @@ --/* -- * Arm SCP/MCP Software -- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#include --#include --#include -- --#include --#include --#include -- --#include --#include --#include --#include --#include -- --/* -- * Indices of reset domain elements exposed through a SCMI agent. -- * As all exposed SCMI reset domains relate to a single backend dirver -- * these indices are used as indices for fwk elements for modules -- * RESET_DOMAIN and STM32_RESET. -- */ --enum resetd_elt_idx { -- /* Reset domain exposed to agent SCMI */ -- RESETD_IDX_SCMI_SPI6, -- RESETD_IDX_SCMI_I2C4, -- RESETD_IDX_SCMI_I2C6, -- RESETD_IDX_SCMI_USART1, -- RESETD_IDX_SCMI_STGEN, -- RESETD_IDX_SCMI_GPIOZ, -- RESETD_IDX_SCMI_CRYP1, -- RESETD_IDX_SCMI_HASH1, -- RESETD_IDX_SCMI_RNG1, -- RESETD_IDX_SCMI_MDMA, -- RESETD_IDX_SCMI_MCU, -- RESETD_IDX_SCMI_MCU_HOLD_BOOT, -- RESETD_IDX_COUNT --}; -- --struct mod_stm32_reset_dev_config { -- const char *name; -- unsigned long rcc_rst_id; --}; -- --/* -- * stm32_resetd_cfg - Common configuration for exposed SCMI reset domains -- * -- * Domain names defined here are used for all RESET_DOMAIN and STM32_RESET -- * fwk elements names. -- */ --#define STM32_RESET_CFG(_idx, _rcc_rst_id, _name) \ -- [(_idx)] = { .rcc_rst_id = (_rcc_rst_id), .name = (_name) } -- --static const struct mod_stm32_reset_dev_config stm32_resetd_cfg[] = { -- STM32_RESET_CFG(RESETD_IDX_SCMI_SPI6, SPI6_R, "spi6"), -- STM32_RESET_CFG(RESETD_IDX_SCMI_I2C4, I2C4_R, "i2c4"), -- STM32_RESET_CFG(RESETD_IDX_SCMI_I2C6, I2C6_R, "i2c6"), -- STM32_RESET_CFG(RESETD_IDX_SCMI_USART1, USART1_R, "usart1"), -- STM32_RESET_CFG(RESETD_IDX_SCMI_STGEN, STGEN_R, "stgen"), -- STM32_RESET_CFG(RESETD_IDX_SCMI_GPIOZ, GPIOZ_R, "gpioz"), -- STM32_RESET_CFG(RESETD_IDX_SCMI_CRYP1, CRYP1_R, "cryp1"), -- STM32_RESET_CFG(RESETD_IDX_SCMI_HASH1, HASH1_R, "hash1"), -- STM32_RESET_CFG(RESETD_IDX_SCMI_RNG1, RNG1_R, "rng1"), -- STM32_RESET_CFG(RESETD_IDX_SCMI_MDMA, MDMA_R, "mdma"), -- STM32_RESET_CFG(RESETD_IDX_SCMI_MCU, MCU_R, "mcu"), -- STM32_RESET_CFG(RESETD_IDX_SCMI_MCU_HOLD_BOOT, MCU_HOLD_BOOT_R, "mcu-hold-boot"), --}; -- --/* -- * Bindgins between SCMI domain_id value and reset domain module element in fwk -- */ --#define SCMI_RESETD_ELT_ID(_idx) \ -- { .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_RESET_DOMAIN, (_idx)) } -- --static const struct mod_scmi_reset_domain_device scmi_resetd_device[] = { -- [RST_SCMI_SPI6] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_SPI6), -- [RST_SCMI_I2C4] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_I2C4), -- [RST_SCMI_I2C6] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_I2C6), -- [RST_SCMI_USART1] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_USART1), -- [RST_SCMI_STGEN] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_STGEN), -- [RST_SCMI_GPIOZ] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_GPIOZ), -- [RST_SCMI_CRYP1] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_CRYP1), -- [RST_SCMI_HASH1] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_HASH1), -- [RST_SCMI_RNG1] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_RNG1), -- [RST_SCMI_MDMA] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_MDMA), -- [RST_SCMI_MCU] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_MCU), -- [RST_SCMI_MCU_HOLD_BOOT] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_MCU_HOLD_BOOT), --}; -- --/* Agents andreset domains references */ --static const struct mod_scmi_reset_domain_agent resetd_agent_table[SCMI_AGENT_ID_COUNT] = { -- [SCMI_AGENT_ID_NSEC0] = { -- .device_table = (void *)scmi_resetd_device, -- .agent_domain_count = FWK_ARRAY_SIZE(scmi_resetd_device), -- }, --}; -- --/* Exported configuration data for module SCMI_RESET_DOMAIN */ --struct fwk_module_config config_scmi_reset_domain = { -- .data = &((struct mod_scmi_reset_domain_config){ -- .agent_table = resetd_agent_table, -- .agent_count = FWK_ARRAY_SIZE(resetd_agent_table), -- }), --}; -- --/* -- * Reset controller backend driver configuration -- * STM32_RESET element index is the related RESET_DOMAIN element index. -- */ --#define RESETD_DATA(_idx) ((struct mod_reset_domain_dev_config){ \ -- .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_RESET, (_idx)), \ -- .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_RESET, 0), \ -- .modes = MOD_RESET_DOMAIN_AUTO_RESET | \ -- MOD_RESET_DOMAIN_MODE_EXPLICIT_ASSERT | \ -- MOD_RESET_DOMAIN_MODE_EXPLICIT_DEASSERT, \ -- .capabilities = 0, /* No notif, no async */ \ -- }) -- -- --#define RESETD_ELT(_idx) [(_idx)] = { \ -- .name = stm32_resetd_cfg[(_idx)].name, \ -- .data = &RESETD_DATA((_idx)), \ -- } -- --/* Element names are the reset domain names exposed by the SCMI service */ --static const struct fwk_element resetd_elt[] = { -- /* Reset domains exposed to agent SCMI */ -- RESETD_ELT(RESETD_IDX_SCMI_SPI6), -- RESETD_ELT(RESETD_IDX_SCMI_I2C4), -- RESETD_ELT(RESETD_IDX_SCMI_I2C6), -- RESETD_ELT(RESETD_IDX_SCMI_USART1), -- RESETD_ELT(RESETD_IDX_SCMI_STGEN), -- RESETD_ELT(RESETD_IDX_SCMI_GPIOZ), -- RESETD_ELT(RESETD_IDX_SCMI_CRYP1), -- RESETD_ELT(RESETD_IDX_SCMI_HASH1), -- RESETD_ELT(RESETD_IDX_SCMI_RNG1), -- RESETD_ELT(RESETD_IDX_SCMI_MDMA), -- RESETD_ELT(RESETD_IDX_SCMI_MCU), -- RESETD_ELT(RESETD_IDX_SCMI_MCU_HOLD_BOOT), -- /* Termination entry */ -- [RESETD_IDX_COUNT] = { 0 } --}; -- --static_assert(FWK_ARRAY_SIZE(resetd_elt) == RESETD_IDX_COUNT + 1, -- "Invalid range for RESET_DOMAIN and STM32_RESET indices"); -- --/* Exported configuration data for module VOLTAGE_DOMAIN */ --const struct fwk_module_config config_reset_domain = { -- .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(resetd_elt), --}; -- --/* -- * Configuration for module OPTEE_RESET -- */ --#define RESET_COUNT FWK_ARRAY_SIZE(stm32_resetd_cfg) --static struct mod_optee_reset_dev_config optee_reset_cfg[RESET_COUNT]; -- --#define OPTEE_RESET_ELT(_idx) \ -- [(_idx)] = { \ -- .name = stm32_resetd_cfg[(_idx)].name, \ -- .data = &optee_reset_cfg[(_idx)], \ -- } -- --static const struct fwk_element optee_reset_elt[] = { -- /* Reset domaines exposed to agent SCMI */ -- OPTEE_RESET_ELT(RESETD_IDX_SCMI_SPI6), -- OPTEE_RESET_ELT(RESETD_IDX_SCMI_I2C4), -- OPTEE_RESET_ELT(RESETD_IDX_SCMI_I2C6), -- OPTEE_RESET_ELT(RESETD_IDX_SCMI_USART1), -- OPTEE_RESET_ELT(RESETD_IDX_SCMI_STGEN), -- OPTEE_RESET_ELT(RESETD_IDX_SCMI_GPIOZ), -- OPTEE_RESET_ELT(RESETD_IDX_SCMI_CRYP1), -- OPTEE_RESET_ELT(RESETD_IDX_SCMI_HASH1), -- OPTEE_RESET_ELT(RESETD_IDX_SCMI_RNG1), -- OPTEE_RESET_ELT(RESETD_IDX_SCMI_MDMA), -- OPTEE_RESET_ELT(RESETD_IDX_SCMI_MCU), -- OPTEE_RESET_ELT(RESETD_IDX_SCMI_MCU_HOLD_BOOT), -- /* Termination entry */ -- [RESETD_IDX_COUNT] = { 0 } --}; -- --static_assert(FWK_ARRAY_SIZE(optee_reset_elt) == RESETD_IDX_COUNT + 1, -- "Invalid range for RESET and OPTEE_RESET indices"); -- --static const struct fwk_element *optee_reset_get_elt_table(fwk_id_t module_id) --{ -- size_t n; -- -- for (n = 0; n < FWK_ARRAY_SIZE(optee_reset_cfg); n++) { -- optee_reset_cfg[n].rstctrl = -- stm32mp_rcc_reset_id_to_rstctrl(stm32_resetd_cfg[n].rcc_rst_id); -- } -- -- return optee_reset_elt; --} -- --struct fwk_module_config config_optee_reset = { -- .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_reset_get_elt_table), --}; -diff --git a/product/optee-stm32mp1/fw/config_scmi_voltage_domains.c b/product/optee-stm32mp1/fw/config_scmi_voltage_domains.c -deleted file mode 100644 -index 54270128..00000000 ---- a/product/optee-stm32mp1/fw/config_scmi_voltage_domains.c -+++ /dev/null -@@ -1,262 +0,0 @@ --/* -- * Arm SCP/MCP Software -- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#include --#include --#include --#include -- --#include --#include --#include --#include --#include -- --#include --#include --#include -- --#include --#include --#include --#include -- --/* -- * stm32_pwr_cfg - Configuration data for PWR regulators exposed thru SCMI -- * -- * These configation data is referenced in the fwk config data of -- * fwk modules VOLTAGE_DOMAIN and STM32_PMIC_REGU. -- */ --enum stm32_pwr_regu { -- STM32_PWR_REG11, -- STM32_PWR_REG18, -- STM32_PWR_USB33, --}; -- --static const struct mod_stm32_pwr_regu_dev_config stm32_pwr_cfg[] = { -- [STM32_PWR_REG11] = { .pwr_id = PWR_REG11, .regu_name = "reg11" }, -- [STM32_PWR_REG18] = { .pwr_id = PWR_REG18, .regu_name = "reg18" }, -- [STM32_PWR_USB33] = { .pwr_id = PWR_USB33, .regu_name = "usb33" }, --}; -- --/* -- * stm32_pmic_cfg - Configuration data for PMIC regulators exposed thru SCMI -- * -- * These configation data are referenced in the fwk config data of -- * fwk modules VOLTAGE_DOMAIN and STM32_PMIC_REGU. -- * @regu_name is used both in PMIC regulator driver API and as SCMI -- * voltage domain name. -- */ --enum stpmic1_regu { -- STPMIC1_REGU_BUCK1, -- STPMIC1_REGU_BUCK2, -- STPMIC1_REGU_BUCK3, -- STPMIC1_REGU_BUCK4, -- STPMIC1_REGU_LDO1, -- STPMIC1_REGU_LDO2, -- STPMIC1_REGU_LDO3, -- STPMIC1_REGU_LDO4, -- STPMIC1_REGU_LDO5, -- STPMIC1_REGU_LDO6, -- STPMIC1_REGU_VREFDDR, -- STPMIC1_REGU_BOOST, -- STPMIC1_REGU_PWR_SW1, -- STPMIC1_REGU_PWR_SW2, --}; -- --static const struct mod_stm32_pmic_regu_dev_config stm32_pmic_cfg[] = { -- [STPMIC1_REGU_BUCK1] = { .regu_name = "buck1" }, -- [STPMIC1_REGU_BUCK2] = { .regu_name = "buck2", .read_only = true }, -- [STPMIC1_REGU_BUCK3] = { .regu_name = "buck3" }, -- [STPMIC1_REGU_BUCK4] = { .regu_name = "buck4" }, -- [STPMIC1_REGU_LDO1] = { .regu_name = "ldo1" }, -- [STPMIC1_REGU_LDO2] = { .regu_name = "ldo2" }, -- [STPMIC1_REGU_LDO3] = { .regu_name = "ldo3", .read_only = true }, -- [STPMIC1_REGU_LDO4] = { .regu_name = "ldo4" }, -- [STPMIC1_REGU_LDO5] = { .regu_name = "ldo5" }, -- [STPMIC1_REGU_LDO6] = { .regu_name = "ldo6" }, -- [STPMIC1_REGU_VREFDDR] = { .regu_name = "vref_ddr", .read_only = true }, -- [STPMIC1_REGU_BOOST] = { .regu_name = "boost" }, -- [STPMIC1_REGU_PWR_SW1] = { .regu_name = "pwr_sw1" }, -- [STPMIC1_REGU_PWR_SW2] = { .regu_name = "pwr_sw2" }, --}; -- --/* -- * Indices of voltage domain module elements exposed through a SCMI agent. -- */ --enum voltd_elt_idx { -- /* Voltage domains exposed to agent SCMI */ -- VOLTD_IDX_SCMI_REG11, -- VOLTD_IDX_SCMI_REG18, -- VOLTD_IDX_SCMI_USB33, -- VOLTD_IDX_SCMI_STPMIC1_BUCK1, -- VOLTD_IDX_SCMI_STPMIC1_BUCK2, -- VOLTD_IDX_SCMI_STPMIC1_BUCK3, -- VOLTD_IDX_SCMI_STPMIC1_BUCK4, -- VOLTD_IDX_SCMI_STPMIC1_LDO1, -- VOLTD_IDX_SCMI_STPMIC1_LDO2, -- VOLTD_IDX_SCMI_STPMIC1_LDO3, -- VOLTD_IDX_SCMI_STPMIC1_LDO4, -- VOLTD_IDX_SCMI_STPMIC1_LDO5, -- VOLTD_IDX_SCMI_STPMIC1_LDO6, -- VOLTD_IDX_SCMI_STPMIC1_VREFDDR, -- VOLTD_IDX_SCMI_STPMIC1_BOOST, -- VOLTD_IDX_SCMI_STPMIC1_PWR_SW1, -- VOLTD_IDX_SCMI_STPMIC1_PWR_SW2, -- VOLTD_IDX_COUNT --}; -- --/* -- * SCMI Voltage Domain driver configuration -- */ --#define SCMI_VOLTD_ELT_ID(_idx) \ -- { .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_VOLTAGE_DOMAIN, (_idx)) } -- --static struct mod_scmi_voltd_device scmi_voltd_device[] = { -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_REG11), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_REG18), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_USB33), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_BUCK1), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_BUCK2), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_BUCK3), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_BUCK4), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_LDO1), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_LDO2), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_LDO3), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_LDO4), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_LDO5), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_LDO6), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_VREFDDR), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_BOOST), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_PWR_SW1), -- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_PWR_SW2), --}; -- --static const struct mod_scmi_voltd_agent voltd_agent_table[SCMI_AGENT_ID_COUNT] = { -- [SCMI_AGENT_ID_NSEC0] = { -- .device_table = scmi_voltd_device, -- .domain_count = FWK_ARRAY_SIZE(scmi_voltd_device), -- }, --}; -- --/* Exported configuration data for module SCMI_VOLTAGE_DOMAIN */ --const struct fwk_module_config config_scmi_voltage_domain = { -- .data = &((struct mod_scmi_voltd_config){ -- .agent_table = voltd_agent_table, -- .agent_count = FWK_ARRAY_SIZE(voltd_agent_table), -- }), --}; -- --/* -- * Voltage Domain driver configuration describes STM32_PWR_REGU elements -- * and STM32_PMIC_REGU elements. -- */ --#define VOLTD_STM32_PWR_DATA(_idx) \ -- ((struct mod_voltd_dev_config){ \ -- .driver_id = \ -- FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_STM32_PWR_REGU, (_idx)), \ -- .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_STM32_PWR_REGU, 0), \ -- }) -- --#define VOLTD_STM32_PWR_ELT_ID(_idx) \ -- { \ -- .name = stm32_pwr_cfg[(_idx)].regu_name, \ -- .data = &VOLTD_STM32_PWR_DATA(_idx), \ -- } -- --#define VOLTD_STM32_PMIC_DATA(_idx) \ -- ((struct mod_voltd_dev_config){ \ -- .driver_id = \ -- FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_STM32_PMIC_REGU, (_idx)), \ -- .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_STM32_PMIC_REGU, 0), \ -- }) -- --#define VOLTD_STM32_PMIC_ELT_ID(_dev_idx) \ -- { \ -- .name = stm32_pmic_cfg[(_dev_idx)].regu_name, \ -- .data = &VOLTD_STM32_PMIC_DATA(_dev_idx), \ -- } -- --/* Elements names are the voltage domain names exposed by the SCMI service */ --static const struct fwk_element voltd_elt[] = { -- [VOLTD_IDX_SCMI_REG11] = VOLTD_STM32_PWR_ELT_ID(STM32_PWR_REG11), -- [VOLTD_IDX_SCMI_REG18] = VOLTD_STM32_PWR_ELT_ID(STM32_PWR_REG18), -- [VOLTD_IDX_SCMI_USB33] = VOLTD_STM32_PWR_ELT_ID(STM32_PWR_USB33), -- [VOLTD_IDX_SCMI_STPMIC1_BUCK1] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_BUCK1), -- [VOLTD_IDX_SCMI_STPMIC1_BUCK2] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_BUCK2), -- [VOLTD_IDX_SCMI_STPMIC1_BUCK3] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_BUCK3), -- [VOLTD_IDX_SCMI_STPMIC1_BUCK4] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_BUCK4), -- [VOLTD_IDX_SCMI_STPMIC1_LDO1] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_LDO1), -- [VOLTD_IDX_SCMI_STPMIC1_LDO2] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_LDO2), -- [VOLTD_IDX_SCMI_STPMIC1_LDO3] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_LDO3), -- [VOLTD_IDX_SCMI_STPMIC1_LDO4] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_LDO4), -- [VOLTD_IDX_SCMI_STPMIC1_LDO5] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_LDO5), -- [VOLTD_IDX_SCMI_STPMIC1_LDO6] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_LDO6), -- [VOLTD_IDX_SCMI_STPMIC1_VREFDDR] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_VREFDDR), -- [VOLTD_IDX_SCMI_STPMIC1_BOOST] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_BOOST), -- [VOLTD_IDX_SCMI_STPMIC1_PWR_SW1] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_PWR_SW1), -- [VOLTD_IDX_SCMI_STPMIC1_PWR_SW2] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_PWR_SW2), -- [VOLTD_IDX_COUNT] = { 0 } /* Termination entry */ --}; -- --/* Exported configuration data for module VOLTAGE_DOMAIN */ --const struct fwk_module_config config_voltage_domain = { -- .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(voltd_elt), --}; -- --/* -- * STM32 PWR driver configuration -- */ --#define STM32_PWR_ELT(_dev_idx) \ -- [(_dev_idx)] = { \ -- .name = stm32_pwr_cfg[(_dev_idx)].regu_name, \ -- .data = &stm32_pwr_cfg[(_dev_idx)], \ -- } -- --static const struct fwk_element stm32_pwr_elt[] = { -- STM32_PWR_ELT(STM32_PWR_REG11), -- STM32_PWR_ELT(STM32_PWR_REG18), -- STM32_PWR_ELT(STM32_PWR_USB33), -- { 0 } /* Termination entry */ --}; -- --/* Exported configuration data for module STM32_PWR_REGU */ --const struct fwk_module_config config_stm32_pwr_regu = { -- .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(stm32_pwr_elt), --}; -- --/* -- * STM32 PMIC regulator driver configuration -- */ --#define STM32_PMIC_ELT(_dev_idx) \ -- [(_dev_idx)] = { \ -- .name = stm32_pmic_cfg[(_dev_idx)].regu_name, \ -- .data = &stm32_pmic_cfg[(_dev_idx)], \ -- } -- --static const struct fwk_element stm32_pmic_elt[] = { -- STM32_PMIC_ELT(STPMIC1_REGU_BUCK1), -- STM32_PMIC_ELT(STPMIC1_REGU_BUCK2), -- STM32_PMIC_ELT(STPMIC1_REGU_BUCK3), -- STM32_PMIC_ELT(STPMIC1_REGU_BUCK4), -- STM32_PMIC_ELT(STPMIC1_REGU_LDO1), -- STM32_PMIC_ELT(STPMIC1_REGU_LDO2), -- STM32_PMIC_ELT(STPMIC1_REGU_LDO3), -- STM32_PMIC_ELT(STPMIC1_REGU_LDO4), -- STM32_PMIC_ELT(STPMIC1_REGU_LDO5), -- STM32_PMIC_ELT(STPMIC1_REGU_LDO6), -- STM32_PMIC_ELT(STPMIC1_REGU_VREFDDR), -- STM32_PMIC_ELT(STPMIC1_REGU_BOOST), -- STM32_PMIC_ELT(STPMIC1_REGU_PWR_SW1), -- STM32_PMIC_ELT(STPMIC1_REGU_PWR_SW2), -- { 0 } /* Termination entry */ --}; -- --/* Exported configuration data for module STM32_PMIC_REGU */ --const struct fwk_module_config config_stm32_pmic_regu = { -- .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(stm32_pmic_elt), --}; -diff --git a/product/optee-stm32mp1/module/stm32_pwr_regu/CMakeLists.txt b/product/optee-stm32mp1/module/psu_optee_regulator/CMakeLists.txt -similarity index 80% -rename from product/optee-stm32mp1/module/stm32_pwr_regu/CMakeLists.txt -rename to product/optee-stm32mp1/module/psu_optee_regulator/CMakeLists.txt -index 7471acc6..77af63f2 100644 ---- a/product/optee-stm32mp1/module/stm32_pwr_regu/CMakeLists.txt -+++ b/product/optee-stm32mp1/module/psu_optee_regulator/CMakeLists.txt -@@ -1,6 +1,6 @@ - # - # Arm SCP/MCP Software --# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -+# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. - # - # SPDX-License-Identifier: BSD-3-Clause - # -@@ -9,9 +9,9 @@ add_library(${SCP_MODULE_TARGET} SCP_MODULE) - - target_include_directories(${SCP_MODULE_TARGET} - PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" -- "${SCP_OPTEE_DIR}/core/arch/arm/plat-stm32mp1") -+ "${SCP_OPTEE_DIR}/core/arch/arm/plat-stm32mp2") - - target_sources( -- ${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_stm32_pwr_regu.c") -+ ${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_psu_optee_regulator.c") - - target_link_libraries(${SCP_MODULE_TARGET} PUBLIC module-voltage-domain) -diff --git a/product/optee-stm32mp1/module/psu_optee_regulator/Module.cmake b/product/optee-stm32mp1/module/psu_optee_regulator/Module.cmake -new file mode 100644 -index 00000000..26dc706e ---- /dev/null -+++ b/product/optee-stm32mp1/module/psu_optee_regulator/Module.cmake -@@ -0,0 +1,9 @@ -+# -+# Arm SCP/MCP Software -+# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+ -+set(SCP_MODULE "psu-optee-regulator") -+set(SCP_MODULE_TARGET "psu-optee-regulator") -diff --git a/product/optee-stm32mp1/module/psu_optee_regulator/include/mod_psu_optee_regulator.h b/product/optee-stm32mp1/module/psu_optee_regulator/include/mod_psu_optee_regulator.h -new file mode 100644 -index 00000000..789c9591 ---- /dev/null -+++ b/product/optee-stm32mp1/module/psu_optee_regulator/include/mod_psu_optee_regulator.h -@@ -0,0 +1,25 @@ -+/* -+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2023, STMicroelectronics -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef MOD_PSU_OPTEE_REGULATOR_H -+#define MOD_PSU_OPTEE_REGULATOR_H -+ -+#include -+#include -+#include -+#include -+ -+struct rdev; -+ -+/*! -+ * \brief Platform regulator configuration. -+ */ -+struct mod_psu_optee_regulator_dev_config { -+ struct rdev *rdev; -+}; -+ -+#endif /* MOD_PSU_OPTEE_REGULATOR_H */ -diff --git a/product/optee-stm32mp1/module/psu_optee_regulator/src/mod_psu_optee_regulator.c b/product/optee-stm32mp1/module/psu_optee_regulator/src/mod_psu_optee_regulator.c -new file mode 100644 -index 00000000..73a82b45 ---- /dev/null -+++ b/product/optee-stm32mp1/module/psu_optee_regulator/src/mod_psu_optee_regulator.c -@@ -0,0 +1,190 @@ -+/* -+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2022, STMicroelectronics -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define DEBUG_MSG(...) FMSG(__VA_ARGS__) -+ -+/* Module context */ -+struct psu_optee_regulator_ctx { -+ struct mod_psu_optee_regulator_dev_config *config; -+ unsigned int dev_count; -+}; -+ -+/* A single instance handles all voltage regulators abstracted by regulator.h */ -+static struct psu_optee_regulator_ctx module_ctx; -+ -+static char __maybe_unused *regulator_name(struct rdev *rdev) -+{ -+ if (rdev) -+ return (char *)rdev->reg_name; -+ -+ return NULL; -+} -+ -+static struct rdev *get_regulator(fwk_id_t id) -+{ -+ unsigned int elt_index; -+ -+ elt_index = fwk_id_get_element_idx(id); -+ if (elt_index >= module_ctx.dev_count) -+ return NULL; -+ -+ return module_ctx.config[elt_index].rdev; -+} -+ -+/* -+ * Driver functions for the PSU API -+ */ -+static int psu_optee_regulator_set_enabled(fwk_id_t id, bool enabled) -+{ -+ TEE_Result res = TEE_ERROR_GENERIC; -+ struct rdev *regulator; -+ -+ regulator = get_regulator(id); -+ if (!regulator) { -+ return FWK_E_PARAM; -+ } -+ -+ DEBUG_MSG("PSU set %s %s", regulator_name(regulator), -+ enabled ? "ON" : "OFF"); -+ -+ if (enabled) { -+ res = regulator_enable(regulator); -+ } else { -+ res = regulator_disable(regulator); -+ } -+ -+ if (res) { -+ return FWK_E_HANDLER; -+ } else { -+ return FWK_SUCCESS; -+ } -+} -+ -+static int psu_optee_regulator_get_enabled(fwk_id_t id, bool *enabled) -+{ -+ struct rdev *regulator; -+ -+ regulator = get_regulator(id); -+ if (!regulator || (enabled == NULL)) { -+ return FWK_E_PARAM; -+ } -+ -+ *enabled = regulator_is_enabled((const struct rdev *)regulator); -+ DEBUG_MSG("PSU get %s state: %s", regulator_name(regulator), -+ enabled ? "ON" : "OFF"); -+ -+ return FWK_SUCCESS; -+} -+ -+static int psu_optee_regulator_set_voltage(fwk_id_t id, uint32_t voltage) -+{ -+ TEE_Result res = TEE_ERROR_GENERIC; -+ struct rdev *regulator; -+ uint16_t level_mv = voltage; -+ -+ regulator = get_regulator(id); -+ if (!regulator) { -+ return FWK_E_PARAM; -+ } -+ -+ DEBUG_MSG("PSU set regulator %s level: %"PRIu32"mV", -+ regulator_name(regulator), (uint32_t)level_mv); -+ -+ res = regulator_set_voltage(regulator, level_mv); -+ -+ if (res) { -+ return FWK_E_HANDLER; -+ } else { -+ -+ return FWK_SUCCESS; -+ } -+} -+ -+static int psu_optee_regulator_get_voltage(fwk_id_t id, uint32_t *voltage) -+{ -+ TEE_Result res = TEE_ERROR_GENERIC; -+ struct rdev *regulator; -+ uint16_t level_mv; -+ -+ regulator = get_regulator(id); -+ if (!regulator || (voltage == NULL)) { -+ return FWK_E_PARAM; -+ } -+ -+ res = regulator_get_voltage(regulator, &level_mv); -+ -+ DEBUG_MSG("PSU get regulator %s level: %"PRIu32"mV (res %#"PRIx32")", -+ regulator_name(regulator), (uint32_t)level_mv, res); -+ -+ if (res) { -+ return FWK_E_HANDLER; -+ } -+ -+ *voltage = level_mv; -+ -+ return FWK_SUCCESS; -+} -+ -+static struct mod_psu_driver_api psu_driver_api = { -+ .set_enabled = psu_optee_regulator_set_enabled, -+ .get_enabled = psu_optee_regulator_get_enabled, -+ .set_voltage = psu_optee_regulator_set_voltage, -+ .get_voltage = psu_optee_regulator_get_voltage, -+}; -+ -+static int psu_optee_regulator_init(fwk_id_t module_id, -+ unsigned int element_count, -+ const void *data) -+{ -+ return FWK_SUCCESS; -+} -+ -+static int psu_optee_regulator_element_init(fwk_id_t element_id, -+ unsigned int sub_element_count, -+ const void *data) -+{ -+ fwk_assert(data != NULL); -+ -+ module_ctx.config = (struct mod_psu_optee_regulator_dev_config *)data; -+ module_ctx.dev_count = sub_element_count; -+ -+ return FWK_SUCCESS; -+} -+ -+static int psu_optee_regulator_process_bind_request(fwk_id_t source_id, -+ fwk_id_t target_id, -+ fwk_id_t api_id, -+ const void **api) -+{ -+ *api = &psu_driver_api; -+ -+ return FWK_SUCCESS; -+} -+ -+const struct fwk_module module_psu_optee_regulator = { -+ .api_count = 1, -+ .type = FWK_MODULE_TYPE_DRIVER, -+ .init = psu_optee_regulator_init, -+ .element_init = psu_optee_regulator_element_init, -+ .process_bind_request = psu_optee_regulator_process_bind_request, -+}; -diff --git a/product/optee-stm32mp1/module/stm32_pmic_regu/Module.cmake b/product/optee-stm32mp1/module/stm32_pmic_regu/Module.cmake -deleted file mode 100644 -index 51bfae5b..00000000 ---- a/product/optee-stm32mp1/module/stm32_pmic_regu/Module.cmake -+++ /dev/null -@@ -1,9 +0,0 @@ --# --# Arm SCP/MCP Software --# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. --# --# SPDX-License-Identifier: BSD-3-Clause --# -- --set(SCP_MODULE "stm32-pmic-regu") --set(SCP_MODULE_TARGET "module-stm32-pmic-regu") -diff --git a/product/optee-stm32mp1/module/stm32_pmic_regu/include/mod_stm32_pmic_regu.h b/product/optee-stm32mp1/module/stm32_pmic_regu/include/mod_stm32_pmic_regu.h -deleted file mode 100644 -index 120f1351..00000000 ---- a/product/optee-stm32mp1/module/stm32_pmic_regu/include/mod_stm32_pmic_regu.h -+++ /dev/null -@@ -1,24 +0,0 @@ --/* -- * Arm SCP/MCP Software -- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#ifndef MOD_STPMIC1_REGU_H --#define MOD_STPMIC1_REGU_H -- --#include --#include -- --#include -- --/*! -- * \brief Platform regulator configuration. -- */ --struct mod_stm32_pmic_regu_dev_config { -- const char *regu_name; -- bool read_only; --}; -- --#endif /* MOD_STPMIC1_REGU_H */ -diff --git a/product/optee-stm32mp1/module/stm32_pmic_regu/src/mod_stm32_pmic_regu.c b/product/optee-stm32mp1/module/stm32_pmic_regu/src/mod_stm32_pmic_regu.c -deleted file mode 100644 -index b22702b6..00000000 ---- a/product/optee-stm32mp1/module/stm32_pmic_regu/src/mod_stm32_pmic_regu.c -+++ /dev/null -@@ -1,367 +0,0 @@ --/* -- * Arm SCP/MCP Software -- * Copyright (c) 2022-2023, Linaro Limited and Contributors. All rights -- * reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- * -- * Description: -- * Interface SCP-firmare VOLTD instances with OP-TEE stm32mp1 -- * PMIC regulator driver for voltage regulator controller from -- * an external PMIC access with a I2C bus using OP-TEE resources. -- * -- * The OP-TEE drvier is accessed by API function named like -- * stpmic1_regulator_*(). They execute in a threaded interruptible, -- * and rescheduable context. -- */ --#include --#include --#include --#include -- --#include --#include --#include -- --#include -- --#include --#include --#include -- --#define MOD_NAME "[STM32 PMIC] " -- --/* Device context */ --struct stm32_pmic_regu_dev_ctx { -- const char *regu_id; /* Both name and backend regu ID */ -- bool read_only; --}; -- --/* Module context */ --struct stm32_pmic_regu_ctx { -- struct stm32_pmic_regu_dev_ctx *dev_ctx_table; -- unsigned int dev_count; --}; -- --static struct stm32_pmic_regu_ctx module_ctx; -- --static int32_t get_regu_voltage(const char *regu_id) --{ -- unsigned long level_uv = 0; -- -- stm32mp_get_pmic(); -- level_uv = stpmic1_regulator_voltage_get(regu_id) * 1000; -- stm32mp_put_pmic(); -- -- return (int32_t)level_uv; --} -- --static int32_t set_regu_voltage(const char *regu_id, int32_t level_uv) --{ -- int rc = 0; -- unsigned int level_mv = level_uv / 1000; -- -- FWK_LOG_DEBUG( -- MOD_NAME "Set STPMIC1 regulator %s level to %dmV", -- regu_id, -- level_uv / 1000); -- -- fwk_assert(level_mv < UINT16_MAX); -- -- stm32mp_get_pmic(); -- rc = stpmic1_regulator_voltage_set(regu_id, level_mv); -- stm32mp_put_pmic(); -- -- return rc ? SCMI_GENERIC_ERROR : SCMI_SUCCESS; --} -- --static bool regu_is_enable(const char *regu_id) --{ -- bool rc = false; -- -- stm32mp_get_pmic(); -- rc = stpmic1_is_regulator_enabled(regu_id); -- stm32mp_put_pmic(); -- -- return rc; --} -- --static int32_t set_regu_state(const char *regu_id, bool enable) --{ -- int rc = 0; -- -- stm32mp_get_pmic(); -- -- FWK_LOG_DEBUG( -- MOD_NAME "%sable STPMIC1 %s (was %s)", -- enable ? "En" : "Dis", -- regu_id, -- stpmic1_is_regulator_enabled(regu_id) ? "on" : "off"); -- -- if (enable) { -- rc = stpmic1_regulator_enable(regu_id); -- } else { -- rc = stpmic1_regulator_disable(regu_id); -- } -- -- stm32mp_put_pmic(); -- -- return rc ? SCMI_GENERIC_ERROR : SCMI_SUCCESS; --} -- --/* -- * Voltage domain driver API functions -- */ --static int pmic_regu_get_config(fwk_id_t dev_id, uint8_t *mode_type, -- uint8_t *mode_id) --{ -- struct stm32_pmic_regu_dev_ctx *ctx; -- -- if (!fwk_module_is_valid_element_id(dev_id) || -- mode_id == NULL || mode_type == NULL) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -- -- *mode_type = MOD_VOLTD_MODE_TYPE_ARCH; -- -- if (regu_is_enable(ctx->regu_id)) { -- *mode_id = MOD_VOLTD_MODE_ID_ON; -- } else { -- *mode_id = MOD_VOLTD_MODE_ID_OFF; -- } -- -- FWK_LOG_DEBUG( -- MOD_NAME "SCMI voltd %u: get config PMIC %s: %s", -- fwk_id_get_element_idx(dev_id), -- ctx->regu_id, -- *mode_id == MOD_VOLTD_MODE_ID_ON ? "on" : "off"); -- -- return FWK_SUCCESS; --} -- --static int pmic_regu_set_config(fwk_id_t dev_id, uint8_t mode_type, -- uint8_t mode_id) --{ -- struct stm32_pmic_regu_dev_ctx *ctx = NULL; -- -- if (!fwk_module_is_valid_element_id(dev_id) || -- mode_type != MOD_VOLTD_MODE_TYPE_ARCH || -- (mode_id == MOD_VOLTD_MODE_ID_ON && mode_id == MOD_VOLTD_MODE_ID_OFF)) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -- -- if (ctx->read_only) { -- return FWK_E_ACCESS; -- } -- -- if (set_regu_state(ctx->regu_id, mode_id == MOD_VOLTD_MODE_ID_ON)) { -- return FWK_E_DEVICE; -- } -- -- FWK_LOG_DEBUG( -- MOD_NAME "SCMI voltd %u: set config PMIC %s to %s", -- fwk_id_get_element_idx(dev_id), -- ctx->regu_id, -- mode_id == MOD_VOLTD_MODE_ID_ON ? "on" : "off"); -- -- return FWK_SUCCESS; --} -- --static int pmic_regu_get_level(fwk_id_t dev_id, int *level_uv) --{ -- struct stm32_pmic_regu_dev_ctx *ctx = NULL; -- -- if (!fwk_module_is_valid_element_id(dev_id) || level_uv == NULL) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -- -- *level_uv = get_regu_voltage(ctx->regu_id); -- -- FWK_LOG_DEBUG( -- MOD_NAME "SCMI voltd %u: get level PMIC %s = %d", -- fwk_id_get_element_idx(dev_id), -- ctx->regu_id, -- *level_uv); -- -- return FWK_SUCCESS; --} -- --static int pmic_regu_set_level(fwk_id_t dev_id, int level_uv) --{ -- struct stm32_pmic_regu_dev_ctx *ctx = NULL; -- -- if (!fwk_module_is_valid_element_id(dev_id)) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -- -- if (ctx->read_only) { -- return FWK_E_ACCESS; -- } -- -- FWK_LOG_DEBUG( -- MOD_NAME "SCMI voltd %u: set level PMIC %s to %d", -- fwk_id_get_element_idx(dev_id), -- ctx->regu_id, -- level_uv); -- -- if (set_regu_voltage(ctx->regu_id, level_uv)) { -- return FWK_E_DEVICE; -- } -- -- return FWK_SUCCESS; --} -- --static void find_bound_uv(const uint16_t *levels, size_t count, -- int32_t *min, int32_t *max) --{ -- size_t n = 0; -- -- fwk_assert((count == 0 || levels != NULL) && min != NULL && max != NULL); -- -- *min = INT32_MAX; -- *max = INT32_MIN; -- -- for (n = 0; n < count; n++) { -- if (*min > levels[n]) { -- *min = levels[n]; -- } -- if (*max < levels[n]) { -- *max = levels[n]; -- } -- } -- -- /* Convert from mV to uV */ -- *min *= 1000; -- *max *= 1000; --} -- --static int pmic_regu_get_info(fwk_id_t dev_id, struct mod_voltd_info *info) --{ -- struct stm32_pmic_regu_dev_ctx *ctx = NULL; -- const uint16_t *levels = NULL; -- size_t full_count = 0; -- -- if (!fwk_module_is_valid_element_id(dev_id) || info == NULL) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -- -- stpmic1_regulator_levels_mv(ctx->regu_id, &levels, &full_count); -- -- memset(info, 0, sizeof(*info)); -- info->name = ctx->regu_id; -- info->level_range.level_type = MOD_VOLTD_VOLTAGE_LEVEL_DISCRETE; -- info->level_range.level_count = full_count; -- find_bound_uv(levels, full_count, -- &info->level_range.min_uv, &info->level_range.max_uv); -- -- FWK_LOG_DEBUG( -- MOD_NAME "SCMI voltd %u: get_info PMIC %s, range [%d %d]", -- fwk_id_get_element_idx(dev_id), -- ctx->regu_id, -- info->level_range.min_uv, -- info->level_range.max_uv); -- -- return FWK_SUCCESS; --} -- --static int pmic_regu_level_from_index(fwk_id_t dev_id, unsigned int index, -- int32_t *level_uv) --{ -- struct stm32_pmic_regu_dev_ctx *ctx = NULL; -- const uint16_t *levels = NULL; -- size_t full_count = 0; -- -- if (!fwk_module_is_valid_element_id(dev_id) || level_uv == NULL) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -- -- stpmic1_regulator_levels_mv(ctx->regu_id, &levels, &full_count); -- if (index >= full_count) { -- return FWK_E_RANGE; -- } -- -- *level_uv = (int32_t)levels[index] * 1000; -- -- FWK_LOG_DEBUG( -- MOD_NAME "SCMI voltd %u: get level PMIC %s = %d", -- fwk_id_get_element_idx(dev_id), -- ctx->regu_id, -- *level_uv); -- -- return FWK_SUCCESS; --} -- --static const struct mod_voltd_drv_api api_stm32_pmic_regu = { -- .get_config = pmic_regu_get_config, -- .set_config = pmic_regu_set_config, -- .get_level = pmic_regu_get_level, -- .set_level = pmic_regu_set_level, -- .get_info = pmic_regu_get_info, -- .get_level_from_index = pmic_regu_level_from_index, --}; -- --/* -- * Framework handler functions -- */ -- --static int stm32_pmic_regu_init(fwk_id_t module_id, unsigned int element_count, -- const void *data) --{ -- module_ctx.dev_count = element_count; -- -- if (element_count) { -- module_ctx.dev_ctx_table = -- fwk_mm_calloc(element_count, sizeof(*module_ctx.dev_ctx_table)); -- } -- -- return FWK_SUCCESS; --} -- --static int stm32_pmic_regu_element_init(fwk_id_t element_id, -- unsigned int unused, -- const void *data) --{ -- struct stm32_pmic_regu_dev_ctx *ctx = NULL; -- const struct mod_stm32_pmic_regu_dev_config *dev_config = data; -- -- if (!fwk_module_is_valid_element_id(element_id)) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(element_id); -- -- ctx->regu_id = dev_config->regu_name; -- ctx->read_only = dev_config->read_only; -- -- return FWK_SUCCESS; --} -- --static int stm32_pmic_regu_process_bind_request(fwk_id_t requester_id, -- fwk_id_t target_id, -- fwk_id_t api_type, -- const void **api) --{ -- *api = &api_stm32_pmic_regu; -- -- return FWK_SUCCESS; --} -- --const struct fwk_module module_stm32_pmic_regu = { -- .type = FWK_MODULE_TYPE_DRIVER, -- .api_count = 1, -- .init = stm32_pmic_regu_init, -- .element_init = stm32_pmic_regu_element_init, -- .process_bind_request = stm32_pmic_regu_process_bind_request, --}; -diff --git a/product/optee-stm32mp1/module/stm32_pwr_regu/Module.cmake b/product/optee-stm32mp1/module/stm32_pwr_regu/Module.cmake -deleted file mode 100644 -index b8c5be8d..00000000 ---- a/product/optee-stm32mp1/module/stm32_pwr_regu/Module.cmake -+++ /dev/null -@@ -1,9 +0,0 @@ --# --# Arm SCP/MCP Software --# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. --# --# SPDX-License-Identifier: BSD-3-Clause --# -- --set(SCP_MODULE "stm32-pwr-regu") --set(SCP_MODULE_TARGET "module-stm32-pwr-regu") -diff --git a/product/optee-stm32mp1/module/stm32_pwr_regu/include/mod_stm32_pwr_regu.h b/product/optee-stm32mp1/module/stm32_pwr_regu/include/mod_stm32_pwr_regu.h -deleted file mode 100644 -index 567ab18e..00000000 ---- a/product/optee-stm32mp1/module/stm32_pwr_regu/include/mod_stm32_pwr_regu.h -+++ /dev/null -@@ -1,19 +0,0 @@ --/* -- * Arm SCP/MCP Software -- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#ifndef MOD_STM32_PWR_REGU_H --#define MOD_STM32_PWR_REGU_H -- --/*! -- * \brief Platform clocks configuration. -- */ --struct mod_stm32_pwr_regu_dev_config { -- unsigned long pwr_id; -- const char *regu_name; --}; -- --#endif /* MOD_STM32_PWR_REGU_H */ -diff --git a/product/optee-stm32mp1/module/stm32_pwr_regu/src/mod_stm32_pwr_regu.c b/product/optee-stm32mp1/module/stm32_pwr_regu/src/mod_stm32_pwr_regu.c -deleted file mode 100644 -index 65c02f43..00000000 ---- a/product/optee-stm32mp1/module/stm32_pwr_regu/src/mod_stm32_pwr_regu.c -+++ /dev/null -@@ -1,293 +0,0 @@ --/* -- * Arm SCP/MCP Software -- * Copyright (c) 2022-2023, Linaro Limited and Contributors. All rights -- * reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- * -- * Description: -- * Interface SCP-firmare VOLTD instances with OP-TEE stm32mp1 -- * PWR regulator driver for SoC voltage regulator controller by -- * OP-TEE for this platform. -- * -- * The OP-TEE drvier is accessed by API function named -- * stm32mp1_regultor_*(). They execute in a threaded interruptible, -- * and rescheduable context. -- */ -- --#include --#include --#include --#include -- --#include --#include -- --#include --#include -- --#define MOD_NAME "[STM32 PWR] " -- --/* Device context */ --struct stm32_pwr_regu_dev_ctx { -- enum pwr_regulator pwr_id; -- const char *name; --}; -- --/* Module context */ --struct stm32_pwr_regu_ctx { -- struct stm32_pwr_regu_dev_ctx *dev_ctx_table; -- unsigned int dev_count; --}; -- --static struct stm32_pwr_regu_ctx module_ctx; -- --static bool nsec_can_access_pwr_regu(enum pwr_regulator pwr_id) --{ -- /* Currently allow non-secure world to access all PWR regulators */ -- return true; --} -- --static int32_t pwr_regu_level(enum pwr_regulator pwr_id) --{ -- return (int32_t)stm32mp1_pwr_regulator_mv(pwr_id) * 1000; --} -- --/* -- * Voltage domain driver API functions -- */ --static int pwr_regu_get_config(fwk_id_t dev_id, uint8_t *mode_type, -- uint8_t *mode_id) --{ -- struct stm32_pwr_regu_dev_ctx *ctx; -- -- if (!fwk_module_is_valid_element_id(dev_id) || -- mode_type == NULL || mode_id == NULL) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -- -- if (!nsec_can_access_pwr_regu(ctx->pwr_id)) { -- return FWK_E_ACCESS; -- } -- -- *mode_type = MOD_VOLTD_MODE_TYPE_ARCH; -- -- if (stm32mp1_pwr_regulator_is_enabled(ctx->pwr_id)) { -- *mode_id = MOD_VOLTD_MODE_ID_ON; -- } else { -- *mode_id = MOD_VOLTD_MODE_ID_OFF; -- } -- -- FWK_LOG_DEBUG( -- MOD_NAME "SCMI voltd %u: get_config PWR#%u = %s", -- fwk_id_get_element_idx(dev_id), -- ctx->pwr_id, -- *mode_id == MOD_VOLTD_MODE_ID_ON ? "on" : "off"); -- -- return FWK_SUCCESS; --} -- --static int pwr_regu_set_config(fwk_id_t dev_id, uint8_t mode_type, -- uint8_t mode_id) --{ -- struct stm32_pwr_regu_dev_ctx *ctx = NULL; -- -- if (!fwk_module_is_valid_element_id(dev_id) || -- mode_type != MOD_VOLTD_MODE_TYPE_ARCH || -- (mode_id == MOD_VOLTD_MODE_ID_ON && mode_id == MOD_VOLTD_MODE_ID_OFF)) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -- -- if (!nsec_can_access_pwr_regu(ctx->pwr_id)) { -- return FWK_E_ACCESS; -- } -- -- stm32mp1_pwr_regulator_set_state(ctx->pwr_id, -- mode_id == MOD_VOLTD_MODE_ID_ON); -- -- FWK_LOG_DEBUG( -- MOD_NAME "SCMI voltd %u: set_config PWR#%u %s", -- fwk_id_get_element_idx(dev_id), -- ctx->pwr_id, -- mode_id == MOD_VOLTD_MODE_ID_ON ? "on" : "off"); -- -- return FWK_SUCCESS; --} -- --static int pwr_regu_get_level(fwk_id_t dev_id, int *level_uv) --{ -- struct stm32_pwr_regu_dev_ctx *ctx = NULL; -- -- if (!fwk_module_is_valid_element_id(dev_id) || level_uv == NULL) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -- -- if (!nsec_can_access_pwr_regu(ctx->pwr_id)) { -- return FWK_E_ACCESS; -- } -- -- *level_uv = pwr_regu_level(ctx->pwr_id); -- -- FWK_LOG_DEBUG( -- MOD_NAME "SCMI voltd %u: get_level PWR#%u = %d", -- fwk_id_get_element_idx(dev_id), -- ctx->pwr_id, -- *level_uv); -- -- return FWK_SUCCESS; --} -- --static int pwr_regu_set_level(fwk_id_t dev_id, int level_uv) --{ -- struct stm32_pwr_regu_dev_ctx *ctx = NULL; -- -- if (!fwk_module_is_valid_element_id(dev_id)) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -- -- if (!nsec_can_access_pwr_regu(ctx->pwr_id)) { -- return FWK_E_ACCESS; -- } -- -- FWK_LOG_DEBUG( -- MOD_NAME "SCMI voltd %u: set_level PWR#%u to %d", -- fwk_id_get_element_idx(dev_id), -- ctx->pwr_id, -- level_uv); -- -- if (level_uv != pwr_regu_level(ctx->pwr_id)) { -- return FWK_E_RANGE; -- } -- -- return FWK_SUCCESS; --} -- --static int pwr_regu_get_info(fwk_id_t dev_id, struct mod_voltd_info *info) --{ -- struct stm32_pwr_regu_dev_ctx *ctx = NULL; -- -- if (!fwk_module_is_valid_element_id(dev_id) || info == NULL) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -- -- if (!nsec_can_access_pwr_regu(ctx->pwr_id)) { -- return FWK_E_ACCESS; -- } -- -- memset(info, 0, sizeof(*info)); -- info->level_range.level_type = MOD_VOLTD_VOLTAGE_LEVEL_DISCRETE; -- info->level_range.min_uv = pwr_regu_level(ctx->pwr_id); -- info->level_range.max_uv = info->level_range.min_uv; -- info->level_range.level_count = 1; -- info->name = ctx->name; -- -- FWK_LOG_DEBUG( -- MOD_NAME "SCMI voltd %u: get_info PWR#%u", -- fwk_id_get_element_idx(dev_id), -- ctx->pwr_id); -- -- return FWK_SUCCESS; --} -- --static int pwr_regu_level_from_index(fwk_id_t dev_id, unsigned int index, -- int32_t *level_uv) --{ -- struct stm32_pwr_regu_dev_ctx *ctx = NULL; -- -- if (!fwk_module_is_valid_element_id(dev_id) || level_uv == NULL) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -- -- if (!nsec_can_access_pwr_regu(ctx->pwr_id)) { -- return FWK_E_ACCESS; -- } -- -- if (index > 0) { -- return FWK_E_RANGE; -- } -- -- *level_uv = pwr_regu_level(ctx->pwr_id); -- -- FWK_LOG_DEBUG( -- MOD_NAME "SCMI voltd %u: get_level_from_index PWR#%u = %" PRId32, -- fwk_id_get_element_idx(dev_id), -- ctx->pwr_id, -- *level_uv); -- -- return FWK_SUCCESS; --} -- --static const struct mod_voltd_drv_api api_stm32_pwr_regu = { -- .get_config = pwr_regu_get_config, -- .set_config = pwr_regu_set_config, -- .get_level = pwr_regu_get_level, -- .set_level = pwr_regu_set_level, -- .get_info = pwr_regu_get_info, -- .get_level_from_index = pwr_regu_level_from_index, --}; -- --/* -- * Framework handler functions -- */ -- --static int stm32_pwr_regu_init(fwk_id_t module_id, unsigned int element_count, -- const void *data) --{ -- module_ctx.dev_count = element_count; -- -- if (element_count) { -- module_ctx.dev_ctx_table = -- fwk_mm_calloc(element_count, sizeof(*module_ctx.dev_ctx_table)); -- } -- -- return FWK_SUCCESS; --} -- --static int stm32_pwr_regu_element_init(fwk_id_t element_id, -- unsigned int unused, -- const void *data) --{ -- struct stm32_pwr_regu_dev_ctx *ctx = NULL; -- const struct mod_stm32_pwr_regu_dev_config *dev_config = data; -- -- if (!fwk_module_is_valid_element_id(element_id)) { -- return FWK_E_PARAM; -- } -- -- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(element_id); -- -- ctx->pwr_id = dev_config->pwr_id; -- ctx->name = dev_config->regu_name; -- -- return FWK_SUCCESS; --} -- --static int stm32_pwr_regu_process_bind_request(fwk_id_t requester_id, -- fwk_id_t target_id, -- fwk_id_t api_type, -- const void **api) --{ -- *api = &api_stm32_pwr_regu; -- -- return FWK_SUCCESS; --} -- --const struct fwk_module module_stm32_pwr_regu = { -- .type = FWK_MODULE_TYPE_DRIVER, -- .api_count = 1, -- .init = stm32_pwr_regu_init, -- .element_init = stm32_pwr_regu_element_init, -- .process_bind_request = stm32_pwr_regu_process_bind_request, --}; -diff --git a/product/optee-stm32mp1/module/stm32_pmic_regu/CMakeLists.txt b/product/optee-stm32mp1/module/stm32_regu_consumer/CMakeLists.txt -similarity index 64% -rename from product/optee-stm32mp1/module/stm32_pmic_regu/CMakeLists.txt -rename to product/optee-stm32mp1/module/stm32_regu_consumer/CMakeLists.txt -index e93bb764..adf79cfc 100644 ---- a/product/optee-stm32mp1/module/stm32_pmic_regu/CMakeLists.txt -+++ b/product/optee-stm32mp1/module/stm32_regu_consumer/CMakeLists.txt -@@ -1,6 +1,6 @@ - # - # Arm SCP/MCP Software --# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -+# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. - # - # SPDX-License-Identifier: BSD-3-Clause - # -@@ -9,10 +9,9 @@ add_library(${SCP_MODULE_TARGET} SCP_MODULE) - - target_include_directories(${SCP_MODULE_TARGET} - PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" -- "${SCP_OPTEE_DIR}/core/arch/arm/plat-stm32mp1") -+ "${SCP_OPTEE_DIR}/core/arch/arm/plat-stm32mp2") - - target_sources( -- ${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_stm32_pmic_regu.c") -+ ${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_stm32_regu_consumer.c") - --target_link_libraries(${SCP_MODULE_TARGET} -- PUBLIC module-scmi module-voltage-domain) -+target_link_libraries(${SCP_MODULE_TARGET} PUBLIC module-voltage-domain) -diff --git a/product/optee-stm32mp1/module/stm32_regu_consumer/Module.cmake b/product/optee-stm32mp1/module/stm32_regu_consumer/Module.cmake -new file mode 100644 -index 00000000..dc988ed3 ---- /dev/null -+++ b/product/optee-stm32mp1/module/stm32_regu_consumer/Module.cmake -@@ -0,0 +1,9 @@ -+# -+# Arm SCP/MCP Software -+# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+ -+set(SCP_MODULE "stm32-regu-consumer") -+set(SCP_MODULE_TARGET "module-stm32-regu-consumer") -diff --git a/product/optee-stm32mp1/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h b/product/optee-stm32mp1/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h -new file mode 100644 -index 00000000..6671eab3 ---- /dev/null -+++ b/product/optee-stm32mp1/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h -@@ -0,0 +1,37 @@ -+/* -+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2022, STMicroelectronics -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef MOD_STM32_REGU_CONSUMER_H -+#define MOD_STM32_REGU_CONSUMER_H -+ -+#include -+#include -+#include -+#include -+ -+struct scmi_server_regu_channel; -+struct rdev; -+ -+/*! -+ * \brief Platform regulator configuration. -+ */ -+struct mod_stm32_regu_consumer_dev_config { -+ struct rdev *rdev; -+ bool default_enabled; -+}; -+ -+/* -+ * Build SCMI server resource tables for the voltage domains exposed -+ * by platform. -+ * -+ * @plat - reference to platform data -+ * @plat_count - Number of elements in platform data -+ */ -+void scmi_server_build_optee_regu_config(struct scmi_server_regu_channel *plat, -+ size_t plat_count); -+ -+#endif /* MOD_STM32_REGU_CONSUMER_H */ -diff --git a/product/optee-stm32mp1/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c b/product/optee-stm32mp1/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c -new file mode 100644 -index 00000000..76955728 ---- /dev/null -+++ b/product/optee-stm32mp1/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c -@@ -0,0 +1,343 @@ -+/* -+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2022, STMicroelectronics -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define DEBUG_MSG(...) FMSG(__VA_ARGS__) -+ -+/* Device context */ -+struct stm32_regu_consumer_dev_ctx { -+ struct rdev *rdev; -+ bool enabled; -+}; -+ -+/* Module context */ -+struct stm32_regu_consumer_ctx { -+ struct stm32_regu_consumer_dev_ctx *dev_ctx_table; -+ unsigned int dev_count; -+}; -+ -+/* A single instance handles all voltage regulators abstracted by regulator.h */ -+static struct stm32_regu_consumer_ctx module_ctx; -+ -+static char *regu_name(struct rdev *rdev) -+{ -+ if (rdev) -+ return (char *)rdev->reg_name; -+ -+ return NULL; -+} -+ -+static int find_ctx(fwk_id_t dev_id, -+ struct stm32_regu_consumer_dev_ctx **out_ctx) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ -+ ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -+ -+ if (!fwk_module_is_valid_element_id(dev_id)) -+ return FWK_E_PARAM; -+ -+ if (!ctx->rdev) -+ return FWK_E_ACCESS; -+ -+ *out_ctx = ctx; -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_get_config(fwk_id_t dev_id, uint8_t *mode_type, -+ uint8_t *mode_id) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ int ret; -+ -+ ret = find_ctx(dev_id, &ctx); -+ if (ret) -+ return ret; -+ -+ *mode_type = MOD_VOLTD_MODE_TYPE_ARCH; -+ -+ if (ctx->enabled) -+ *mode_id = MOD_VOLTD_MODE_ID_ON; -+ else -+ *mode_id = MOD_VOLTD_MODE_ID_OFF; -+ -+ DEBUG_MSG("SCMI voltd %u: get config PMIC %s = %#"PRIx8", %#"PRIx8, -+ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), *mode_type, -+ *mode_id); -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_set_config(fwk_id_t dev_id, uint8_t mode_type, -+ uint8_t mode_id) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ int ret; -+ -+ ret = find_ctx(dev_id, &ctx); -+ if (ret) -+ return ret; -+ -+ if (mode_type != MOD_VOLTD_MODE_TYPE_ARCH) { -+ return FWK_E_PARAM; -+ } -+ -+ switch (mode_id) { -+ case MOD_VOLTD_MODE_ID_ON: -+ if (!ctx->enabled) { -+ if (regulator_enable(ctx->rdev)) -+ return FWK_E_DEVICE; -+ -+ ctx->enabled = true; -+ } -+ break; -+ -+ case MOD_VOLTD_MODE_ID_OFF: -+ if (ctx->enabled) { -+ if (regulator_disable(ctx->rdev)) -+ return FWK_E_DEVICE; -+ -+ ctx->enabled = false; -+ } -+ break; -+ -+ default: -+ return FWK_E_PARAM; -+ } -+ -+ DEBUG_MSG("SCMI voltd %u: set config PMIC %s to type %#"PRIx8" / mode %#"PRIx8, -+ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), mode_type, -+ mode_id); -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_get_level(fwk_id_t dev_id, int *level_uv) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ uint16_t level_mv; -+ int ret; -+ -+ ret = find_ctx(dev_id, &ctx); -+ if (ret) -+ return ret; -+ -+ if (regulator_get_voltage(ctx->rdev, &level_mv)) -+ return FWK_E_PANIC; -+ -+ *level_uv = (int)level_mv * 1000; -+ -+ DEBUG_MSG("SCMI voltd %u: get level PMIC %s = %d", -+ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), *level_uv); -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_set_level(fwk_id_t dev_id, int level_uv) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx = NULL; -+ int ret = FWK_E_PANIC; -+ -+ if (level_uv / 1000 > UINT16_MAX) { -+ FWK_LOG_ERR("Volatge level too high (mV shall fit in 16 bits)"); -+ return FWK_E_PARAM; -+ } -+ -+ ret = find_ctx(dev_id, &ctx); -+ if (ret) -+ return ret; -+ -+ if (regulator_set_voltage(ctx->rdev, level_uv / 1000)) -+ return FWK_E_DEVICE; -+ -+ DEBUG_MSG("SCMI voltd %u: set level PMIC %s to %d", -+ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), level_uv); -+ -+ return FWK_SUCCESS; -+} -+ -+static void find_bound_uv(const uint16_t *levels, size_t count, -+ int32_t *min, int32_t *max) -+{ -+ size_t n = 0; -+ -+ *min = INT32_MAX; -+ *max = INT32_MIN; -+ -+ for (n = 0; n < count; n++) { -+ if (*min > levels[n]) -+ *min = levels[n]; -+ if (*max < levels[n]) -+ *max = levels[n]; -+ } -+ -+ /* Convert from mV to uV */ -+ *min *= 1000; -+ *max *= 1000; -+} -+ -+static int stm32_regu_consumer_get_info(fwk_id_t dev_id, -+ struct mod_voltd_info *info) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ uint16_t *levels; -+ size_t full_count; -+ int ret; -+ -+ ret = find_ctx(dev_id, &ctx); -+ if (ret == FWK_E_ACCESS) { -+ static const char reserved[] = "reserved"; -+ -+ memset(info, 0, sizeof(*info)); -+ info->name = reserved; -+ info->level_range.level_type = MOD_VOLTD_VOLTAGE_LEVEL_DISCRETE; -+ info->level_range.level_count = 1; -+ info->level_range.min_uv = 0; -+ info->level_range.max_uv = 0; -+ -+ return FWK_SUCCESS; -+ } else if (ret != FWK_SUCCESS) { -+ return ret; -+ } -+ -+ if (regulator_list_voltages(ctx->rdev, &levels, &full_count)) { -+ return FWK_E_SUPPORT; -+ } -+ -+ memset(info, 0, sizeof(*info)); -+ info->name = regu_name(ctx->rdev); -+ info->level_range.level_type = MOD_VOLTD_VOLTAGE_LEVEL_DISCRETE; -+ info->level_range.level_count = full_count; -+ find_bound_uv(levels, full_count, -+ &info->level_range.min_uv, &info->level_range.max_uv); -+ -+ DEBUG_MSG("SCMI voltd %u: get_info PMIC %s, range [%d %d]", -+ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), -+ info->level_range.min_uv, info->level_range.max_uv); -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_level_from_index(fwk_id_t dev_id, -+ unsigned int index, -+ int32_t *level_uv) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ uint16_t *levels; -+ size_t full_count; -+ int ret; -+ -+ ret = find_ctx(dev_id, &ctx); -+ if (ret == FWK_E_ACCESS) { -+ if (index > 0) { -+ return FWK_E_RANGE; -+ } -+ *level_uv = 0; -+ -+ return FWK_SUCCESS; -+ } else if (ret != FWK_SUCCESS) { -+ return ret; -+ } -+ -+ if (regulator_list_voltages(ctx->rdev, &levels, &full_count)) { -+ return FWK_E_SUPPORT; -+ } -+ -+ if (index >= full_count) -+ return FWK_E_RANGE; -+ -+ *level_uv = (int32_t)levels[index] * 1000; -+ -+ DEBUG_MSG("SCMI voltd %u: get level PMIC %s = %"PRId32, -+ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), *level_uv); -+ -+ return FWK_SUCCESS; -+} -+ -+static const struct mod_voltd_drv_api api_optee_regu = { -+ .get_level = stm32_regu_consumer_get_level, -+ .set_level = stm32_regu_consumer_set_level, -+ .set_config = stm32_regu_consumer_set_config, -+ .get_config = stm32_regu_consumer_get_config, -+ .get_info = stm32_regu_consumer_get_info, -+ .get_level_from_index = stm32_regu_consumer_level_from_index, -+}; -+ -+/* -+ * Framework handler functions -+ */ -+ -+static int stm32_regu_consumer_init(fwk_id_t module_id, -+ unsigned int element_count, -+ const void *data) -+{ -+ module_ctx.dev_count = element_count; -+ -+ if (element_count) -+ module_ctx.dev_ctx_table = -+ fwk_mm_calloc(element_count, sizeof(*module_ctx.dev_ctx_table)); -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_element_init(fwk_id_t element_id, -+ unsigned int unused, -+ const void *data) -+{ -+ const struct mod_stm32_regu_consumer_dev_config *dev_config = data; -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ -+ if (!fwk_module_is_valid_element_id(element_id)) -+ return FWK_E_PANIC; -+ -+ ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(element_id); -+ -+ ctx->rdev = dev_config->rdev; -+ ctx->enabled = dev_config->default_enabled; -+ -+ if (ctx->enabled) { -+ if (!ctx->rdev) -+ return FWK_E_PARAM; -+ if (regulator_enable(ctx->rdev)) -+ return FWK_E_DEVICE; -+ } -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_process_bind_request(fwk_id_t requester_id, -+ fwk_id_t target_id, -+ fwk_id_t api_type, -+ const void **api) -+{ -+ *api = &api_optee_regu; -+ -+ return FWK_SUCCESS; -+} -+ -+const struct fwk_module module_stm32_regu_consumer = { -+ .type = FWK_MODULE_TYPE_DRIVER, -+ .api_count = 1, -+ .init = stm32_regu_consumer_init, -+ .element_init = stm32_regu_consumer_element_init, -+ .process_bind_request = stm32_regu_consumer_process_bind_request, -+}; -diff --git a/product/optee-stm32mp2/fw/CMakeLists.txt b/product/optee-stm32mp2/fw/CMakeLists.txt -new file mode 100644 -index 00000000..8674a1eb ---- /dev/null -+++ b/product/optee-stm32mp2/fw/CMakeLists.txt -@@ -0,0 +1,24 @@ -+# -+# Arm SCP/MCP Software -+# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+ -+# -+# Create the firmware target. -+# -+ -+add_library(${SCP_FIRMWARE_TARGET}) -+ -+# cmake-lint: disable=E1122 -+ -+target_include_directories( -+ ${SCP_FIRMWARE_TARGET} -+ PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include" -+ "${CMAKE_CURRENT_SOURCE_DIR}") -+ -+target_sources( -+ ${SCP_FIRMWARE_TARGET} -+ PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_all.c" -+) -diff --git a/product/optee-stm32mp2/fw/Firmware.cmake b/product/optee-stm32mp2/fw/Firmware.cmake -new file mode 100644 -index 00000000..0e5b0665 ---- /dev/null -+++ b/product/optee-stm32mp2/fw/Firmware.cmake -@@ -0,0 +1,57 @@ -+# -+# Arm SCP/MCP Software -+# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+ -+# -+# Configure the build system. -+# -+ -+set(SCP_FIRMWARE "scmi-fw") -+ -+set(SCP_FIRMWARE_TARGET "scmi-fw") -+ -+set(SCP_TOOLCHAIN_INIT "GNU") -+ -+set(SCP_ARCHITECTURE "optee") -+ -+set(CMAKE_BUILD_TYPE "Release") -+ -+set(SCP_ENABLE_NOTIFICATIONS_INIT FALSE) -+ -+set(SCP_ENABLE_SCMI_NOTIFICATIONS_INIT FALSE) -+ -+set(SCP_ENABLE_SCMI_SENSOR_EVENTS_INIT FALSE) -+ -+set(SCP_ENABLE_FAST_CHANNELS_INIT FALSE) -+ -+set(SCP_ENABLE_SCMI_RESET_INIT TRUE) -+ -+set(SCP_ENABLE_IPO_INIT FALSE) -+ -+list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/stm32_regu_consumer") -+list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/psu_optee_regulator") -+ -+# The order of the modules in the following list is the order in which the -+# modules are initialized, bound, started during the pre-runtime phase. -+# any change in the order will cause firmware initialization errors. -+ -+list(APPEND SCP_MODULES "optee-mbx") -+list(APPEND SCP_MODULES "msg-smt") -+list(APPEND SCP_MODULES "scmi") -+list(APPEND SCP_MODULES "optee-clock") -+list(APPEND SCP_MODULES "clock") -+list(APPEND SCP_MODULES "scmi-clock") -+list(APPEND SCP_MODULES "optee-reset") -+list(APPEND SCP_MODULES "reset-domain") -+list(APPEND SCP_MODULES "scmi-reset-domain") -+list(APPEND SCP_MODULES "stm32-regu-consumer") -+list(APPEND SCP_MODULES "voltage-domain") -+list(APPEND SCP_MODULES "scmi-voltage-domain") -+list(APPEND SCP_MODULES "psu-optee-regulator") -+list(APPEND SCP_MODULES "psu") -+list(APPEND SCP_MODULES "dvfs") -+list(APPEND SCP_MODULES "scmi-perf") -+list(APPEND SCP_MODULES "optee-console") -diff --git a/product/optee-stm32mp2/fw/Toolchain-GNU.cmake b/product/optee-stm32mp2/fw/Toolchain-GNU.cmake -new file mode 100644 -index 00000000..ab5d91f2 ---- /dev/null -+++ b/product/optee-stm32mp2/fw/Toolchain-GNU.cmake -@@ -0,0 +1,22 @@ -+# -+# Arm SCP/MCP Software -+# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+ -+include_guard() -+ -+set(CMAKE_SYSTEM_PROCESSOR "optee") -+set(CMAKE_TOOLCHAIN_PREFIX ${CFG_CROSS_COMPILE}) -+ -+set(CMAKE_ASM_COMPILER_TARGET ${CFG_CROSS_COMPILE}) -+set(CMAKE_C_COMPILER_TARGET ${CFG_CROSS_COMPILE}) -+set(CMAKE_CXX_COMPILER_TARGET ${CFG_CROSS_COMPILE}) -+ -+include( -+ "${CMAKE_CURRENT_LIST_DIR}/../../../cmake/Toolchain/GNU-Baremetal.cmake") -+ -+foreach(language IN ITEMS ASM C CXX) -+ string(APPEND CMAKE_${language}_FLAGS_INIT ${CFG_CFLAGS_OPTEE}) -+endforeach() -diff --git a/product/optee-stm32mp2/fw/config_all.c b/product/optee-stm32mp2/fw/config_all.c -new file mode 100644 -index 00000000..3aa24d76 ---- /dev/null -+++ b/product/optee-stm32mp2/fw/config_all.c -@@ -0,0 +1,793 @@ -+/* -+ * Arm SCP/MCP Software -+ * Copyright (c) 2022-2023, Linaro Limited and Contributors. All rights reserved. -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* SCMI agent and services (channels) */ -+static struct mod_scmi_agent *scmi_agent_table; -+static struct mod_scmi_config scmi_data; -+static struct fwk_element *scmi_service_elt; -+ -+/* SCMI channel mailbox/shmem */ -+static struct fwk_element *msg_smt_elt; -+static struct mod_msg_smt_channel_config *msg_smt_data; -+static struct fwk_element *optee_mbx_elt; -+static struct mod_optee_mbx_channel_config *optee_mbx_data; -+ -+#ifdef CFG_SCPFW_MOD_SCMI_CLOCK -+/* SCMI clock generic */ -+static struct mod_scmi_clock_agent *scmi_clk_agent_tbl; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_CLOCK -+/* Clocks and optee/clock, same number/indices. Elements and configuration data */ -+static struct fwk_element *optee_clock_elt; /* Optee/clock elements */ -+static struct mod_optee_clock_config *optee_clock_cfg; /* Config data for optee/clock elements */ -+static struct fwk_element *clock_elt; /* Clock elements */ -+static struct mod_clock_dev_config *clock_data; /* Config data for clock elements */ -+#endif -+ -+#ifdef CFG_SCPFW_MOD_DVFS -+/* 1 DVFS (elt & data) per DVFS exposed */ -+static struct mod_dvfs_domain_config *dvfs_data; -+static struct fwk_element *dvfs_elt; -+/* A unique scmi_perf instance refers to perf domains data (DVFS instance) */ -+static struct mod_scmi_perf_domain_config *scmi_perf_domain_data; -+struct fwk_module_config config_scmi_perf; -+ -+/* PSU and optee/psu-regu, used with DVFS. Elements and configuration data */ -+static struct fwk_element *psu_optee_regu_elt; -+static struct mod_psu_optee_regulator_dev_config *psu_optee_regu_data; -+static struct fwk_element *psu_elt; -+static struct mod_psu_element_cfg *psu_data; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_RESET_DOMAIN -+/* SCMI reset domains and optee reset controller */ -+static struct mod_scmi_reset_domain_agent *scmi_reset_agent_tbl; -+static struct fwk_element *optee_reset_elt; -+static struct mod_optee_reset_dev_config *optee_reset_data; -+static struct fwk_element *reset_elt; -+static struct mod_reset_domain_dev_config *reset_data; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN -+/* SCMI voltage domains and optee regulators */ -+static struct mod_scmi_voltd_agent *scmi_voltd_agent_tbl; -+static struct fwk_element *optee_regu_elt; -+static struct mod_stm32_regu_consumer_dev_config *optee_regu_data; -+static struct fwk_element *voltd_elt; -+static struct mod_voltd_dev_config *voltd_data; -+#endif -+ -+/* Config data for scmi module */ -+static const struct fwk_element *get_scmi_service_table(fwk_id_t module_id) -+{ -+ return scmi_service_elt; /* scmi_service_elt filled during initialization */ -+} -+ -+struct fwk_module_config config_scmi = { -+ .data = (void *)&scmi_data, /* scmi_data filled during initialization */ -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_scmi_service_table), -+}; -+ -+/* Config data for optee_mbx module */ -+static const struct fwk_element *optee_mbx_get_element_table(fwk_id_t module_id) -+{ -+ return (const struct fwk_element *)optee_mbx_elt; -+} -+ -+struct fwk_module_config config_optee_mbx = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_mbx_get_element_table), -+}; -+ -+/* Config data for msg_smt module */ -+static const struct fwk_element *msg_smt_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_MSG_SMT); -+ return (const struct fwk_element *)msg_smt_elt; -+} -+ -+struct fwk_module_config config_msg_smt = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(msg_smt_get_element_table), -+}; -+ -+/* Config data for scmi_clock, clock and optee_clock modules */ -+#ifdef CFG_SCPFW_MOD_SCMI_CLOCK -+struct fwk_module_config config_scmi_clock = { -+ .data = &((struct mod_scmi_clock_config){ -+ .agent_table = NULL, /* Allocated during initialization */ -+ .agent_count = 0, /* Set during initialization */ -+ }), -+}; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_CLOCK -+static const struct fwk_element *clock_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_CLOCK); -+ return (const struct fwk_element *)clock_elt; -+} -+ -+struct fwk_module_config config_clock = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(clock_get_element_table), -+}; -+ -+static const struct fwk_element *optee_clock_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_OPTEE_CLOCK); -+ return (const struct fwk_element *)optee_clock_elt; -+} -+ -+struct fwk_module_config config_optee_clock = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_clock_get_element_table), -+}; -+#endif -+ -+/* Config data for scmi_reset_domain, reset_domain and optee_reset modules */ -+#ifdef CFG_SCPFW_MOD_RESET_DOMAIN -+struct fwk_module_config config_scmi_reset_domain = { -+ .data = &((struct mod_scmi_reset_domain_config){ -+ .agent_table = NULL, /* Allocated during initialization */ -+ .agent_count = 0, /* Set during initialization */ -+ }), -+}; -+ -+static const struct fwk_element *reset_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_RESET_DOMAIN); -+ return (const struct fwk_element *)reset_elt; -+} -+ -+struct fwk_module_config config_reset_domain = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(reset_get_element_table), -+}; -+ -+static const struct fwk_element *optee_reset_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_OPTEE_RESET); -+ return (const struct fwk_element *)optee_reset_elt; -+} -+ -+struct fwk_module_config config_optee_reset = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_reset_get_element_table), -+}; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN -+/* Config data for scmi_voltage_domain, voltage_domain and optee_regu modules */ -+struct fwk_module_config config_scmi_voltage_domain = { -+ .data = &((struct mod_scmi_voltd_config){ -+ .agent_table = NULL, /* Allocated during initialization */ -+ .agent_count = 0, /* Set during initialization */ -+ }), -+}; -+ -+static const struct fwk_element *voltd_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_VOLTAGE_DOMAIN); -+ return (const struct fwk_element *)voltd_elt; -+} -+ -+struct fwk_module_config config_voltage_domain = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(voltd_get_element_table), -+}; -+ -+static const struct fwk_element *stm32_regu_consumer_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_STM32_REGU_CONSUMER); -+ return (const struct fwk_element *)optee_regu_elt; -+} -+ -+struct fwk_module_config config_stm32_regu_consumer = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(stm32_regu_consumer_get_element_table), -+}; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_DVFS -+/* Config data for scmi_perf and dvfs module */ -+struct fwk_module_config config_scmi_perf = { -+ .data = &((struct mod_scmi_perf_config){ -+ .domains = NULL, /* Allocated during initialization */ -+ .perf_doms_count = 0, /* Set during initialization */ -+ .fast_channels_alarm_id = FWK_ID_NONE_INIT, -+#ifdef BUILD_HAS_MOD_STATISTICS -+ .stats_enabled = true, -+#endif -+ }), -+}; -+ -+static const struct fwk_element *dvfs_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_DVFS); -+ return (const struct fwk_element *)dvfs_elt; -+} -+ -+struct fwk_module_config config_dvfs = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(dvfs_get_element_table), -+}; -+ -+/* Config data for psu and optee/psu module */ -+static const struct fwk_element *psu_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_PSU); -+ return (const struct fwk_element *)psu_elt; -+} -+ -+struct fwk_module_config config_psu = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(psu_get_element_table), -+}; -+ -+static const struct fwk_element *psu_optee_regu_get_element_table(fwk_id_t module_id) -+{ -+ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_PSU_OPTEE_REGULATOR); -+ return (const struct fwk_element *)psu_optee_regu_elt ; -+} -+ -+struct fwk_module_config config_psu_optee_regulator = { -+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(psu_optee_regu_get_element_table), -+}; -+#endif -+ -+/* -+ * Indices state when applying agents configuration -+ * @channel_count: Number of channels (mailbox/shmem links) used -+ * @clock_index: Current index for clock and optee/clock (same indices) -+ * @clock_count: Number of clocks (also number of optee/clocks) -+ * @reset_index: Current index for reset controller and optee/reset -+ * @reset_count: Number of reset controller (optee/reset) instances -+ * @regu_index: Current index for voltd and optee/regulator -+ * @regu_count: Number of voltd (optee/regulator) instances -+ * @psu_index: Current index for PSU and optee/PSU instances -+ * @psu_count: Number of PSU (optee/PSU) instances -+ * @dvfs_index: Current index for DVFS instance -+ * @dvfs_count: Number of DVFS instances -+ */ -+struct scpfw_resource_counter { -+ size_t channel_count; -+ size_t clock_index; -+ size_t clock_count; -+ size_t reset_index; -+ size_t reset_count; -+ size_t regu_index; -+ size_t regu_count; -+ size_t psu_index; -+ size_t psu_count; -+ size_t dvfs_index; -+ size_t dvfs_count; -+} scpfw_resource_counter; -+ -+/* -+ * Count once for all the several instances and allocate global resources. -+ * Global resources are clock, optee/clock, reset, optee/reset, regu, -+ * optee/regu, psu, optee/psu, dvfs, perfd, ...; -+ */ -+static void count_resources(struct scpfw_config *cfg) -+{ -+ size_t i, j; -+ -+ for (i = 0; i < cfg->agent_count; i++) { -+ struct scpfw_agent_config *agent_cfg = cfg->agent_config + i; -+ -+ scpfw_resource_counter.channel_count += agent_cfg->channel_count; -+ -+ for (j = 0; j < agent_cfg->channel_count; j++) { -+ struct scpfw_channel_config *channel_cfg = agent_cfg->channel_config + j; -+ -+ /* Clocks for scmi_clock and for DVFS */ -+ scpfw_resource_counter.clock_count += channel_cfg->clock_count; -+ scpfw_resource_counter.clock_count += channel_cfg->perfd_count; -+ /* Reset for smci_reset only */ -+ scpfw_resource_counter.reset_count += channel_cfg->reset_count; -+ /* Regulators for smci_voltage_domain only */ -+ scpfw_resource_counter.regu_count += channel_cfg->voltd_count; -+ /* DVFS and PSU DVFS only */ -+ scpfw_resource_counter.dvfs_count += channel_cfg->perfd_count; -+ scpfw_resource_counter.psu_count += channel_cfg->perfd_count; -+ } -+ } -+ -+#ifndef CFG_SCPFW_MOD_CLOCK -+ fwk_assert(!scpfw_resource_counter.clock_count); -+#endif -+#ifndef CFG_SCPFW_MOD_RESET_DOMAIN -+ fwk_assert(!scpfw_resource_counter.reset_count); -+#endif -+#ifndef CFG_SCPFW_MOD_VOLTAGE_DOMAIN -+ fwk_assert(!scpfw_resource_counter.regu_count); -+#endif -+#ifndef CFG_SCPFW_MOD_DVFS -+ fwk_assert(!scpfw_resource_counter.dvfs_count); -+#endif -+#ifndef CFG_SCPFW_MOD_PSU -+ fwk_assert(!scpfw_resource_counter.psu_count); -+#endif -+} -+ -+/* -+ * Allocate all tables that may be needed. An optimized implementation would -+ * allocate a single piece of memory and set the pointers accordingly. -+ * */ -+static void allocate_global_resources(struct scpfw_config *cfg) -+{ -+ struct mod_scmi_reset_domain_config *scmi_reset_config __maybe_unused; -+ struct mod_scmi_voltd_config *scmi_voltd_config __maybe_unused; -+ struct mod_scmi_clock_config *scmi_clock_config __maybe_unused; -+ /* @cfg does not consider agent #0 this the reserved platform/server agent */ -+ size_t __maybe_unused scmi_agent_count = cfg->agent_count + 1; -+ -+#ifdef CFG_SCPFW_MOD_SCMI_CLOCK -+ /* SCMI clock domains resources */ -+ scmi_clk_agent_tbl = fwk_mm_calloc(scmi_agent_count, -+ sizeof(*scmi_clk_agent_tbl)); -+ scmi_clock_config = (void *)config_scmi_clock.data; -+ scmi_clock_config->agent_table = scmi_clk_agent_tbl; -+ scmi_clock_config->agent_count = scmi_agent_count; -+#endif -+ -+#ifdef CFG_SCPFW_MOD_CLOCK -+ /* Clock domains resources */ -+ optee_clock_cfg = fwk_mm_calloc(scpfw_resource_counter.clock_count, -+ sizeof(*optee_clock_cfg)); -+ optee_clock_elt = fwk_mm_calloc(scpfw_resource_counter.clock_count + 1, -+ sizeof(*optee_clock_elt)); -+ -+ clock_data = fwk_mm_calloc(scpfw_resource_counter.clock_count, -+ sizeof(*clock_data)); -+ clock_elt = fwk_mm_calloc(scpfw_resource_counter.clock_count + 1, -+ sizeof(*clock_elt)); -+#endif -+ -+#ifdef CFG_SCPFW_MOD_RESET_DOMAIN -+ /* SCMI reset domains resources */ -+ scmi_reset_agent_tbl = fwk_mm_calloc(scmi_agent_count, -+ sizeof(*scmi_reset_agent_tbl)); -+ scmi_reset_config = (void *)config_scmi_reset_domain.data; -+ scmi_reset_config->agent_table = scmi_reset_agent_tbl; -+ scmi_reset_config->agent_count = scmi_agent_count; -+ -+ optee_reset_data = fwk_mm_calloc(scpfw_resource_counter.reset_count, -+ sizeof(*optee_reset_data)); -+ optee_reset_elt = fwk_mm_calloc(scpfw_resource_counter.reset_count + 1, -+ sizeof(*optee_reset_elt)); -+ -+ reset_data = fwk_mm_calloc(scpfw_resource_counter.reset_count, -+ sizeof(*reset_data)); -+ reset_elt = fwk_mm_calloc(scpfw_resource_counter.reset_count + 1, -+ sizeof(*reset_elt)); -+#endif -+ -+#ifdef CFG_SCPFW_MOD_DVFS -+ /* PSU and related optee PSU regulator resources */ -+ psu_optee_regu_elt = fwk_mm_calloc(scpfw_resource_counter.dvfs_count + 1, -+ sizeof(*psu_optee_regu_elt)); -+ psu_optee_regu_data = fwk_mm_calloc(scpfw_resource_counter.dvfs_count, -+ sizeof(*psu_optee_regu_data)); -+ -+ psu_elt = fwk_mm_calloc(scpfw_resource_counter.psu_count + 1, -+ sizeof(*psu_elt)); -+ psu_data = fwk_mm_calloc(scpfw_resource_counter.psu_count, -+ sizeof(*psu_data)); -+ -+ /* DVFS and SCMI performance management resources */ -+ dvfs_elt = fwk_mm_calloc(scpfw_resource_counter.dvfs_count + 1, -+ sizeof(*dvfs_elt)); -+ dvfs_data = fwk_mm_calloc(scpfw_resource_counter.dvfs_count, -+ sizeof(*dvfs_data)); -+ -+ scmi_perf_domain_data = fwk_mm_calloc(scpfw_resource_counter.dvfs_count, -+ sizeof(*scmi_perf_domain_data)); -+#endif -+ -+#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN -+ /* SCMI voltage domains resources */ -+ scmi_voltd_agent_tbl = fwk_mm_calloc(scmi_agent_count, -+ sizeof(*scmi_voltd_agent_tbl)); -+ scmi_voltd_config = (void *)config_scmi_voltage_domain.data; -+ scmi_voltd_config->agent_table = scmi_voltd_agent_tbl; -+ scmi_voltd_config->agent_count = scmi_agent_count; -+ -+ optee_regu_data = fwk_mm_calloc(scpfw_resource_counter.regu_count, -+ sizeof(*optee_regu_data)); -+ optee_regu_elt = fwk_mm_calloc(scpfw_resource_counter.regu_count + 1, -+ sizeof(*optee_regu_elt)); -+ -+ voltd_data = fwk_mm_calloc(scpfw_resource_counter.regu_count, -+ sizeof(*voltd_data)); -+ voltd_elt = fwk_mm_calloc(scpfw_resource_counter.regu_count + 1, -+ sizeof(*voltd_elt)); -+#endif -+} -+ -+static void set_scmi_comm_resources(struct scpfw_config *cfg) -+{ -+ unsigned int channel_index; -+ size_t i, j; -+ /* @cfg does not consider agent #0 this the reserved platform/server agent */ -+ size_t scmi_agent_count = cfg->agent_count + 1; -+ -+ scmi_agent_table = fwk_mm_calloc(scmi_agent_count, -+ sizeof(*scmi_agent_table)); -+ -+ scmi_service_elt = fwk_mm_calloc(scpfw_resource_counter.channel_count + 1, -+ sizeof(*scmi_service_elt)); -+ -+ msg_smt_elt = fwk_mm_calloc(scpfw_resource_counter.channel_count + 1, -+ sizeof(*msg_smt_elt)); -+ msg_smt_data = fwk_mm_calloc(scpfw_resource_counter.channel_count, -+ sizeof(*msg_smt_data)); -+ -+ optee_mbx_elt = fwk_mm_calloc(scpfw_resource_counter.channel_count + 1, -+ sizeof(*optee_mbx_elt)); -+ optee_mbx_data = fwk_mm_calloc(scpfw_resource_counter.channel_count, -+ sizeof(*optee_mbx_data)); -+ -+ /* Set now the uniqnue scmi module instance configuration data */ -+ scmi_data = (struct mod_scmi_config){ -+ .agent_table = scmi_agent_table, -+ .agent_count = scmi_agent_count, -+ .protocol_count_max = 9, -+ .vendor_identifier = "STMicroelectronics", -+ .sub_vendor_identifier = "STMicroelectronics", -+ }; -+ -+ channel_index = 0; -+ -+ for (i = 0; i < cfg->agent_count; i++) { -+ struct scpfw_agent_config *agent_cfg = cfg->agent_config + i; -+ size_t agent_index = i + 1; -+ -+ scmi_agent_table[agent_index].type = SCMI_AGENT_TYPE_OSPM; -+ scmi_agent_table[agent_index].name = agent_cfg->name; -+ -+ for (j = 0; j < agent_cfg->channel_count; j++) { -+ struct scpfw_channel_config *channel_cfg = agent_cfg->channel_config + j; -+ struct mod_scmi_service_config *service_data; -+ -+ service_data = fwk_mm_calloc(1, sizeof(*service_data)); -+ *service_data = (struct mod_scmi_service_config){ -+ .transport_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MSG_SMT, 0), -+ .transport_api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_MSG_SMT, -+ MOD_MSG_SMT_API_IDX_SCMI_TRANSPORT), -+ .scmi_agent_id = agent_cfg->agent_id, -+ .scmi_p2a_id = FWK_ID_NONE_INIT, -+ }; -+ -+ /* Currently expect 1 agent with ID SCMI_AGENT_ID_NSEC0 (1) */ -+ fwk_assert(service_data->scmi_agent_id == SCMI_AGENT_ID_NSEC0); -+ -+ scmi_service_elt[channel_index].name = channel_cfg->name; -+ scmi_service_elt[channel_index].data = service_data; -+ -+ msg_smt_elt[channel_index].name = channel_cfg->name; -+ msg_smt_elt[channel_index].data = (void *)(msg_smt_data + channel_index); -+ -+ msg_smt_data[channel_index] = (struct mod_msg_smt_channel_config){ -+ .type = MOD_MSG_SMT_CHANNEL_TYPE_REQUESTER, -+ .mailbox_size = 128, -+ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_MBX, -+ channel_index), -+ .driver_api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_MBX, 0), -+ }; -+ -+ optee_mbx_elt[channel_index].name = channel_cfg->name; -+ optee_mbx_elt[channel_index].data = (void *)(optee_mbx_data + channel_index); -+ -+ optee_mbx_data[channel_index] = (struct mod_optee_mbx_channel_config){ -+ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MSG_SMT, channel_index), -+ .driver_api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_MSG_SMT, -+ MOD_MSG_SMT_API_IDX_DRIVER_INPUT), -+ }; -+ -+ channel_index++; -+ } -+ } -+}; -+ -+static void set_resources(struct scpfw_config *cfg) -+{ -+ size_t i, j, k, l; -+ -+ for (i = 0; i < cfg->agent_count; i++) { -+ struct scpfw_agent_config *agent_cfg = cfg->agent_config + i; -+ size_t agent_index = i + 1; -+ -+ if (agent_index != agent_cfg->agent_id) { -+ panic("scpfw config expects agent ID is agent index"); -+ } -+ -+ for (j = 0; j < agent_cfg->channel_count; j++) { -+ struct scpfw_channel_config *channel_cfg = agent_cfg->channel_config + j; -+ -+#ifdef CFG_SCPFW_MOD_SCMI_CLOCK -+ /* Add first SCMI clock. We will add later the clocks used for DVFS */ -+ if (channel_cfg->clock_count) { -+ size_t clock_index = scpfw_resource_counter.clock_index; -+ struct mod_scmi_clock_device *dev = NULL; -+ -+ /* Set SCMI clocks array for the SCMI agent */ -+ dev = fwk_mm_calloc(channel_cfg->clock_count, -+ sizeof(struct mod_scmi_clock_device)); -+ -+ fwk_assert(!scmi_clk_agent_tbl[agent_index].device_table); -+ scmi_clk_agent_tbl[agent_index].device_count = channel_cfg->clock_count; -+ scmi_clk_agent_tbl[agent_index].device_table = dev; -+ -+ /* Set clock and optee/clock elements and config data */ -+ for (k = 0; k < channel_cfg->clock_count; k++) { -+ struct scmi_clock *clock_cfg = channel_cfg->clock + k; -+ -+ dev[k].element_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, clock_index); -+ -+ optee_clock_cfg[clock_index].clk = clock_cfg->clk; -+ optee_clock_cfg[clock_index].default_enabled = clock_cfg->enabled; -+ -+ optee_clock_elt[clock_index].name = clock_cfg->name; -+ optee_clock_elt[clock_index].data = (void *)(optee_clock_cfg + clock_index); -+ -+ clock_data[clock_index] = (struct mod_clock_dev_config){ -+ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, -+ clock_index), -+ .api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, -+ 0), -+ }; -+ -+ clock_elt[clock_index].name = clock_cfg->name; -+ clock_elt[clock_index].data = (void *)(clock_data + clock_index); -+ -+ clock_index++; -+ } -+ -+ scpfw_resource_counter.clock_index = clock_index; -+ } -+#endif -+ -+#ifdef CFG_SCPFW_MOD_RESET_DOMAIN -+ if (channel_cfg->reset_count) { -+ struct mod_scmi_reset_domain_device *dev = NULL; -+ size_t reset_index = scpfw_resource_counter.reset_index; -+ -+ /* Set SCMI reset domains array for the SCMI agent */ -+ dev = fwk_mm_calloc(channel_cfg->reset_count, sizeof(*dev)); -+ -+ fwk_assert(!scmi_reset_agent_tbl[agent_index].device_table); -+ scmi_reset_agent_tbl[agent_index].agent_domain_count = channel_cfg->reset_count; -+ scmi_reset_agent_tbl[agent_index].device_table = dev; -+ -+ /* Set reset_domain and optee/reset elements and config data */ -+ for (k = 0; k < channel_cfg->reset_count; k++) { -+ struct scmi_reset *reset_cfg = channel_cfg->reset + k; -+ -+ dev[k].element_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_RESET_DOMAIN, -+ reset_index); -+ -+ optee_reset_data[reset_index].rstctrl = reset_cfg->rstctrl; -+ -+ optee_reset_elt[reset_index].name = reset_cfg->name; -+ optee_reset_elt[reset_index].data = -+ (void *)(optee_reset_data + reset_index); -+ -+ reset_data[reset_index] = (struct mod_reset_domain_dev_config){ -+ .driver_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_RESET, -+ reset_index), -+ .driver_api_id = -+ (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_RESET, 0), -+ .modes = MOD_RESET_DOMAIN_AUTO_RESET | -+ MOD_RESET_DOMAIN_MODE_EXPLICIT_ASSERT | -+ MOD_RESET_DOMAIN_MODE_EXPLICIT_DEASSERT, -+ }; -+ -+ reset_elt[reset_index].name = reset_cfg->name; -+ reset_elt[reset_index].data = (void *)(reset_data + reset_index); -+ -+ reset_index++; -+ } -+ -+ scpfw_resource_counter.reset_index = reset_index; -+ } -+#endif -+ -+#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN -+ if (channel_cfg->voltd_count) { -+ size_t regu_index = scpfw_resource_counter.regu_index; -+ struct mod_scmi_voltd_device *dev = NULL; -+ -+ /* Set SCMI voltage domains array for the SCMI agent */ -+ dev = fwk_mm_calloc(channel_cfg->voltd_count, -+ sizeof(struct mod_scmi_voltd_device)); -+ -+ fwk_assert(!scmi_voltd_agent_tbl[agent_index].device_table); -+ scmi_voltd_agent_tbl[agent_index].domain_count = channel_cfg->voltd_count; -+ scmi_voltd_agent_tbl[agent_index].device_table = dev; -+ -+ /* Set voltage_domain and optee/regu elements and config data */ -+ for (k = 0; k < channel_cfg->voltd_count; k++) { -+ struct scmi_voltd *voltd_cfg = channel_cfg->voltd + k; -+ static const char reserved[] = "reserved"; -+ const char *name = NULL; -+ -+ if (voltd_cfg->rdev) { -+ name = voltd_cfg->rdev->reg_name; -+ } else { -+ name = reserved; -+ } -+ -+ dev[regu_index].element_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_VOLTAGE_DOMAIN, k); -+ -+ optee_regu_elt[regu_index].name = name; -+ optee_regu_elt[regu_index].data = (void *)(optee_regu_data + regu_index); -+ optee_regu_data[regu_index].rdev = voltd_cfg->rdev; -+ optee_regu_data[regu_index].default_enabled = voltd_cfg->enabled; -+ -+ voltd_data[regu_index].driver_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_STM32_REGU_CONSUMER, -+ regu_index); -+ voltd_data[regu_index].api_id = -+ (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_STM32_REGU_CONSUMER, 0); -+ -+ voltd_elt[regu_index].name = name; -+ voltd_elt[regu_index].data = (void *)(voltd_data + regu_index); -+ regu_index++; -+ } -+ -+ scpfw_resource_counter.regu_index = regu_index; -+ } -+#endif -+ -+#ifdef CFG_SCPFW_MOD_DVFS -+ if (channel_cfg->perfd_count) { -+ size_t clock_index = scpfw_resource_counter.clock_index; -+ size_t psu_index = scpfw_resource_counter.psu_index; -+ size_t dvfs_index = scpfw_resource_counter.dvfs_index; -+ -+ for (k = 0; k < channel_cfg->perfd_count; k++) { -+ struct mod_scmi_perf_config *scmi_perf_data = NULL; -+ struct scmi_perfd *perfd_cfg = channel_cfg->perfd + k; -+ -+ /* -+ * DVFS with SCMI performance management domains -+ * 1 initial scmi_perf instance defines the number of DVFS's -+ * For each DVFS instance: -+ * - 1 instance (elt/config) of dvfs, psu, optee/psu, clock, optee/clock -+ * Clocks and optee/clocks are already allocated but not yet set. -+ */ -+ -+ /* scmi_perf: data defines the DVFS domains indices */ -+ scmi_perf_domain_data[dvfs_index] = (struct mod_scmi_perf_domain_config){ }; -+ -+ scmi_perf_data = (void *)config_scmi_perf.data; -+ -+ scmi_perf_data[dvfs_index].domains = (void *)scmi_perf_domain_data; -+ scmi_perf_data[dvfs_index].perf_doms_count = scpfw_resource_counter.dvfs_count; -+ scmi_perf_data[dvfs_index].fast_channels_alarm_id = (fwk_id_t)FWK_ID_NONE_INIT; -+#ifdef BUILD_HAS_MOD_STATISTICS -+ scmi_perf_data[dvfs_index].stats_enabled = true; -+#endif -+ -+ /* dvfs instances: 1 instance per expose DVFS service */ -+ dvfs_data[dvfs_index].psu_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, psu_index); -+ dvfs_data[dvfs_index].clock_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, clock_index); -+ dvfs_data[dvfs_index].latency = 0; /* not set, used for async access */ -+ dvfs_data[dvfs_index].opps = -+ fwk_mm_calloc(perfd_cfg->dvfs_opp_count, -+ sizeof(struct mod_dvfs_opp)); -+ -+ for (l = 0; l < perfd_cfg->dvfs_opp_count; l++) { -+ uint64_t power = 0; -+ -+ /* Quick estimation of power consumpsion */ -+ power = perfd_cfg->dvfs_opp_khz[l]; -+ power *= perfd_cfg->dvfs_opp_mv[l]; -+ power *= perfd_cfg->dvfs_opp_mv[l]; -+ power /= 100 * 1000 * 1000; -+ -+ dvfs_data[dvfs_index].opps[l] = (struct mod_dvfs_opp){ -+ .level = perfd_cfg->dvfs_opp_khz[l] * 1000UL, -+ .frequency = perfd_cfg->dvfs_opp_khz[l], -+ .voltage = perfd_cfg->dvfs_opp_mv[l], -+ .power = (uint32_t)power, -+ }; -+ } -+ -+ dvfs_elt[dvfs_index].name = perfd_cfg->name; -+ dvfs_elt[dvfs_index].data = (void *)(dvfs_data + dvfs_index); -+ -+ /* Module psu_optee module (elements and configuration data) */ -+ psu_optee_regu_elt[psu_index].name = perfd_cfg->rdev->reg_name; -+ psu_optee_regu_elt[psu_index].sub_element_count = scpfw_resource_counter.psu_count; -+ psu_optee_regu_elt[psu_index].data = (void *)(psu_optee_regu_data + psu_index); -+ -+ psu_optee_regu_data[psu_index].rdev = perfd_cfg->rdev; -+ -+ /* Module psu (elements and configuration data) */ -+ psu_elt[psu_index].name = perfd_cfg->rdev->reg_name; -+ psu_elt[psu_index].data = (void *)(psu_data + psu_index); -+ psu_data[psu_index].driver_id = -+ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU_OPTEE_REGULATOR, psu_index); -+ psu_data[psu_index].driver_api_id = -+ (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_PSU_OPTEE_REGULATOR, 0); -+ -+ /* Module clock and optee_clock */ -+ fwk_assert(!clock_elt[clock_index].data); -+ -+ clock_elt[clock_index].name = perfd_cfg->clk->name; -+ clock_elt[clock_index].data = (void *)(clock_data + clock_index); -+ -+ clock_data[clock_index] = (struct mod_clock_dev_config){ -+ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, -+ clock_index), -+ .api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, -+ 0), -+ }; -+ -+ optee_clock_cfg[clock_index].clk = perfd_cfg->clk; -+ optee_clock_cfg[clock_index].default_enabled = false; -+ -+ optee_clock_elt[clock_index].name = perfd_cfg->clk->name; -+ optee_clock_elt[clock_index].data = (void *)(optee_clock_cfg + clock_index); -+ -+ clock_index++; -+ psu_index++; -+ dvfs_index++; -+ } -+ -+ scpfw_resource_counter.clock_index = clock_index; -+ scpfw_resource_counter.psu_index = psu_index; -+ scpfw_resource_counter.dvfs_index = dvfs_index; -+ } -+#endif -+ } -+ } -+} -+ -+void scpfw_configure(struct scpfw_config *cfg) -+{ -+ count_resources(cfg); -+ allocate_global_resources(cfg); -+ set_scmi_comm_resources(cfg); -+ set_resources(cfg); -+} -diff --git a/product/optee-stm32mp2/include/fmw_io.h b/product/optee-stm32mp2/include/fmw_io.h -new file mode 100644 -index 00000000..8e53e139 ---- /dev/null -+++ b/product/optee-stm32mp2/include/fmw_io.h -@@ -0,0 +1,17 @@ -+/* -+ * Arm SCP/MCP Software -+ * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef FMW_IO_H -+#define FMW_IO_H -+ -+#include -+#include -+ -+#define FMW_IO_STDIN_ID FWK_ID_NONE -+#define FMW_IO_STDOUT_ID FWK_ID_ELEMENT(FWK_MODULE_IDX_OPTEE_CONSOLE, 0) -+ -+#endif /* FMW_IO_H */ -diff --git a/product/optee-stm32mp2/include/fmw_log.h b/product/optee-stm32mp2/include/fmw_log.h -new file mode 100644 -index 00000000..4e0bdd0e ---- /dev/null -+++ b/product/optee-stm32mp2/include/fmw_log.h -@@ -0,0 +1,16 @@ -+/* -+ * Arm SCP/MCP Software -+ * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef FMW_LOG_H -+#define FMW_LOG_H -+ -+/* -+ * Disable log buffering by setting buffer size to 0. -+ */ -+#define FMW_LOG_BUFFER_SIZE 0 -+ -+#endif /* FMW_LOG_H */ -diff --git a/product/optee-stm32mp2/include/gnu/stubs-soft.h b/product/optee-stm32mp2/include/gnu/stubs-soft.h -new file mode 100644 -index 00000000..e69de29b -diff --git a/product/optee-stm32mp2/include/scmi_agents.h b/product/optee-stm32mp2/include/scmi_agents.h -new file mode 100644 -index 00000000..13d29618 ---- /dev/null -+++ b/product/optee-stm32mp2/include/scmi_agents.h -@@ -0,0 +1,29 @@ -+/* -+ * Arm SCP/MCP Software -+ * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef SCMI_AGENTS_H -+#define SCMI_AGENTS_H -+ -+enum scmi_agent_id { -+ SCMI_AGENT_ID_RSV = 0, /* 0 is reserved for the platform */ -+ SCMI_AGENT_ID_NSEC0, -+ SCMI_AGENT_ID_COUNT -+}; -+ -+enum scmi_service_idx { -+ SCMI_SERVICE_IDX_NS_CHANNEL0 = 0, -+ SCMI_SERVICE_IDX_COUNT -+}; -+ -+enum scmi_channel_device_idx { -+ SCMI_CHANNEL_DEVICE_IDX_NS0 = 0, -+ SCMI_CHANNEL_DEVICE_IDX_COUNT -+}; -+ -+#define SCMI_SHMEM_SIZE 128 -+ -+#endif /* SCMI_AGENTS_H */ -diff --git a/product/optee-stm32mp2/module/psu_optee_regulator/CMakeLists.txt b/product/optee-stm32mp2/module/psu_optee_regulator/CMakeLists.txt -new file mode 100644 -index 00000000..77af63f2 ---- /dev/null -+++ b/product/optee-stm32mp2/module/psu_optee_regulator/CMakeLists.txt -@@ -0,0 +1,17 @@ -+# -+# Arm SCP/MCP Software -+# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+ -+add_library(${SCP_MODULE_TARGET} SCP_MODULE) -+ -+target_include_directories(${SCP_MODULE_TARGET} -+ PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" -+ "${SCP_OPTEE_DIR}/core/arch/arm/plat-stm32mp2") -+ -+target_sources( -+ ${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_psu_optee_regulator.c") -+ -+target_link_libraries(${SCP_MODULE_TARGET} PUBLIC module-voltage-domain) -diff --git a/product/optee-stm32mp2/module/psu_optee_regulator/Module.cmake b/product/optee-stm32mp2/module/psu_optee_regulator/Module.cmake -new file mode 100644 -index 00000000..26dc706e ---- /dev/null -+++ b/product/optee-stm32mp2/module/psu_optee_regulator/Module.cmake -@@ -0,0 +1,9 @@ -+# -+# Arm SCP/MCP Software -+# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+ -+set(SCP_MODULE "psu-optee-regulator") -+set(SCP_MODULE_TARGET "psu-optee-regulator") -diff --git a/product/optee-stm32mp2/module/psu_optee_regulator/include/mod_psu_optee_regulator.h b/product/optee-stm32mp2/module/psu_optee_regulator/include/mod_psu_optee_regulator.h -new file mode 100644 -index 00000000..5b0347c7 ---- /dev/null -+++ b/product/optee-stm32mp2/module/psu_optee_regulator/include/mod_psu_optee_regulator.h -@@ -0,0 +1,25 @@ -+/* -+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2023, STMicroelectronics -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef MOD_PSU_OPTEE_REGULATOR_H -+#define MOD_PSU_OPTEE_REGULATOR_H -+ -+#include -+#include -+#include -+#include -+ -+struct rdev; -+ -+/*! -+ * \brief Platform regulator configuration. -+ */ -+struct mod_psu_optee_regulator_dev_config { -+ struct rdev *rdev; -+}; -+ -+#endif /* MOD_PSU_OPTEE_REGULATOR_H */ -diff --git a/product/optee-stm32mp2/module/psu_optee_regulator/src/mod_psu_optee_regulator.c b/product/optee-stm32mp2/module/psu_optee_regulator/src/mod_psu_optee_regulator.c -new file mode 100644 -index 00000000..f1e8c444 ---- /dev/null -+++ b/product/optee-stm32mp2/module/psu_optee_regulator/src/mod_psu_optee_regulator.c -@@ -0,0 +1,190 @@ -+/* -+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2022, STMicroelectronics -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define DEBUG_MSG(...) FMSG(__VA_ARGS__) -+ -+/* Module context */ -+struct psu_optee_regulator_ctx { -+ struct mod_psu_optee_regulator_dev_config *config; -+ unsigned int dev_count; -+}; -+ -+/* A single instance handles all voltage regulators abstracted by regulator.h */ -+static struct psu_optee_regulator_ctx module_ctx; -+ -+static char __maybe_unused *regulator_name(struct rdev *rdev) -+{ -+ if (rdev) -+ return (char *)rdev->reg_name; -+ -+ return NULL; -+} -+ -+static struct rdev *get_regulator(fwk_id_t id) -+{ -+ unsigned int elt_index; -+ -+ elt_index = fwk_id_get_element_idx(id); -+ if (elt_index >= module_ctx.dev_count) -+ return NULL; -+ -+ return module_ctx.config[elt_index].rdev; -+} -+ -+/* -+ * Driver functions for the PSU API -+ */ -+static int psu_optee_regulator_set_enabled(fwk_id_t id, bool enabled) -+{ -+ TEE_Result res = TEE_ERROR_GENERIC; -+ struct rdev *regulator; -+ -+ regulator = get_regulator(id); -+ if (!regulator) { -+ return FWK_E_PARAM; -+ } -+ -+ DEBUG_MSG("PSU set %s %s", regulator_name(regulator), -+ enabled ? "ON" : "OFF"); -+ -+ if (enabled) { -+ res = regulator_enable(regulator); -+ } else { -+ res = regulator_disable(regulator); -+ } -+ -+ if (res) { -+ return FWK_E_HANDLER; -+ } else { -+ return FWK_SUCCESS; -+ } -+} -+ -+static int psu_optee_regulator_get_enabled(fwk_id_t id, bool *enabled) -+{ -+ struct rdev *regulator; -+ -+ regulator = get_regulator(id); -+ if (!regulator || (enabled == NULL)) { -+ return FWK_E_PARAM; -+ } -+ -+ *enabled = regulator_is_enabled((const struct rdev *)regulator); -+ DEBUG_MSG("PSU get %s state: %s", regulator_name(regulator), -+ enabled ? "ON" : "OFF"); -+ -+ return FWK_SUCCESS; -+} -+ -+static int psu_optee_regulator_set_voltage(fwk_id_t id, uint32_t voltage) -+{ -+ TEE_Result res = TEE_ERROR_GENERIC; -+ struct rdev *regulator; -+ uint16_t level_mv = voltage; -+ -+ regulator = get_regulator(id); -+ if (!regulator) { -+ return FWK_E_PARAM; -+ } -+ -+ DEBUG_MSG("PSU set regulator %s level: %"PRIu32"mV", -+ regulator_name(regulator), (uint32_t)level_mv); -+ -+ res = regulator_set_voltage(regulator, level_mv); -+ -+ if (res) { -+ return FWK_E_HANDLER; -+ } else { -+ -+ return FWK_SUCCESS; -+ } -+} -+ -+static int psu_optee_regulator_get_voltage(fwk_id_t id, uint32_t *voltage) -+{ -+ TEE_Result res = TEE_ERROR_GENERIC; -+ struct rdev *regulator; -+ uint16_t level_mv; -+ -+ regulator = get_regulator(id); -+ if (!regulator || (voltage == NULL)) { -+ return FWK_E_PARAM; -+ } -+ -+ res = regulator_get_voltage(regulator, &level_mv); -+ -+ DEBUG_MSG("PSU get regulator %s level: %"PRIu32"mV (res %#"PRIx32")", -+ regulator_name(regulator), (uint32_t)level_mv, res); -+ -+ if (res) { -+ return FWK_E_HANDLER; -+ } -+ -+ *voltage = level_mv; -+ -+ return FWK_SUCCESS; -+} -+ -+static struct mod_psu_driver_api psu_driver_api = { -+ .set_enabled = psu_optee_regulator_set_enabled, -+ .get_enabled = psu_optee_regulator_get_enabled, -+ .set_voltage = psu_optee_regulator_set_voltage, -+ .get_voltage = psu_optee_regulator_get_voltage, -+}; -+ -+static int psu_optee_regulator_init(fwk_id_t module_id, -+ unsigned int element_count, -+ const void *data) -+{ -+ return FWK_SUCCESS; -+} -+ -+static int psu_optee_regulator_element_init(fwk_id_t element_id, -+ unsigned int sub_element_count, -+ const void *data) -+{ -+ fwk_assert(data != NULL); -+ -+ module_ctx.config = (struct mod_psu_optee_regulator_dev_config *)data; -+ module_ctx.dev_count = sub_element_count; -+ -+ return FWK_SUCCESS; -+} -+ -+static int psu_optee_regulator_process_bind_request(fwk_id_t source_id, -+ fwk_id_t target_id, -+ fwk_id_t api_id, -+ const void **api) -+{ -+ *api = &psu_driver_api; -+ -+ return FWK_SUCCESS; -+} -+ -+const struct fwk_module module_psu_optee_regulator = { -+ .api_count = 1, -+ .type = FWK_MODULE_TYPE_DRIVER, -+ .init = psu_optee_regulator_init, -+ .element_init = psu_optee_regulator_element_init, -+ .process_bind_request = psu_optee_regulator_process_bind_request, -+}; -diff --git a/product/optee-stm32mp2/module/stm32_regu_consumer/CMakeLists.txt b/product/optee-stm32mp2/module/stm32_regu_consumer/CMakeLists.txt -new file mode 100644 -index 00000000..adf79cfc ---- /dev/null -+++ b/product/optee-stm32mp2/module/stm32_regu_consumer/CMakeLists.txt -@@ -0,0 +1,17 @@ -+# -+# Arm SCP/MCP Software -+# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+ -+add_library(${SCP_MODULE_TARGET} SCP_MODULE) -+ -+target_include_directories(${SCP_MODULE_TARGET} -+ PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" -+ "${SCP_OPTEE_DIR}/core/arch/arm/plat-stm32mp2") -+ -+target_sources( -+ ${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_stm32_regu_consumer.c") -+ -+target_link_libraries(${SCP_MODULE_TARGET} PUBLIC module-voltage-domain) -diff --git a/product/optee-stm32mp2/module/stm32_regu_consumer/Module.cmake b/product/optee-stm32mp2/module/stm32_regu_consumer/Module.cmake -new file mode 100644 -index 00000000..dc988ed3 ---- /dev/null -+++ b/product/optee-stm32mp2/module/stm32_regu_consumer/Module.cmake -@@ -0,0 +1,9 @@ -+# -+# Arm SCP/MCP Software -+# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+ -+set(SCP_MODULE "stm32-regu-consumer") -+set(SCP_MODULE_TARGET "module-stm32-regu-consumer") -diff --git a/product/optee-stm32mp2/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h b/product/optee-stm32mp2/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h -new file mode 100644 -index 00000000..d3f3358e ---- /dev/null -+++ b/product/optee-stm32mp2/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h -@@ -0,0 +1,37 @@ -+/* -+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2022, STMicroelectronics -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef MOD_STM32_REGU_CONSUMER_H -+#define MOD_STM32_REGU_CONSUMER_H -+ -+#include -+#include -+#include -+#include -+ -+struct scmi_server_regu_channel; -+struct rdev; -+ -+/*! -+ * \brief Platform regulator configuration. -+ */ -+struct mod_stm32_regu_consumer_dev_config { -+ struct rdev *rdev; -+ bool default_enabled; -+}; -+ -+/* -+ * Build SCMI server resource tables for the voltage domains exposed -+ * by platform. -+ * -+ * @plat - reference to platform data -+ * @plat_count - Number of elements in platform data -+ */ -+void scmi_server_build_optee_regu_config(struct scmi_server_regu_channel *plat, -+ size_t plat_count); -+ -+#endif /* MOD_STM32_REGU_CONSUMER_H */ -diff --git a/product/optee-stm32mp2/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c b/product/optee-stm32mp2/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c -new file mode 100644 -index 00000000..2a344d90 ---- /dev/null -+++ b/product/optee-stm32mp2/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c -@@ -0,0 +1,345 @@ -+/* -+ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2022, STMicroelectronics -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define DEBUG_MSG(...) FMSG(__VA_ARGS__) -+ -+/* Device context */ -+struct stm32_regu_consumer_dev_ctx { -+ struct rdev *rdev; -+ bool enabled; -+}; -+ -+/* Module context */ -+struct stm32_regu_consumer_ctx { -+ struct stm32_regu_consumer_dev_ctx *dev_ctx_table; -+ unsigned int dev_count; -+}; -+ -+/* A single instance handles all voltage regulators abstracted by regulator.h */ -+static struct stm32_regu_consumer_ctx module_ctx; -+ -+static char *regu_name(struct rdev *rdev) -+{ -+ if (rdev) -+ return (char *)rdev->reg_name; -+ -+ return NULL; -+} -+ -+static int find_ctx(fwk_id_t dev_id, -+ struct stm32_regu_consumer_dev_ctx **out_ctx) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ -+ ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); -+ -+ if (!fwk_module_is_valid_element_id(dev_id)) -+ return FWK_E_PARAM; -+ -+ if (!ctx->rdev) -+ return FWK_E_ACCESS; -+ -+ *out_ctx = ctx; -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_get_config(fwk_id_t dev_id, uint8_t *mode_type, -+ uint8_t *mode_id) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ int ret; -+ -+ ret = find_ctx(dev_id, &ctx); -+ if (ret) -+ return ret; -+ -+ *mode_type = MOD_VOLTD_MODE_TYPE_ARCH; -+ -+ if (ctx->enabled) -+ *mode_id = MOD_VOLTD_MODE_ID_ON; -+ else -+ *mode_id = MOD_VOLTD_MODE_ID_OFF; -+ -+ DEBUG_MSG("SCMI voltd %u: get config PMIC %s = %#"PRIx8", %#"PRIx8, -+ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), *mode_type, -+ *mode_id); -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_set_config(fwk_id_t dev_id, uint8_t mode_type, -+ uint8_t mode_id) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ int ret; -+ -+ ret = find_ctx(dev_id, &ctx); -+ if (ret) -+ return ret; -+ -+ if (mode_type != MOD_VOLTD_MODE_TYPE_ARCH) { -+ return FWK_E_PARAM; -+ } -+ -+ switch (mode_id) { -+ case MOD_VOLTD_MODE_ID_ON: -+ if (!ctx->enabled) { -+ if (regulator_enable(ctx->rdev)) -+ return FWK_E_DEVICE; -+ -+ ctx->enabled = true; -+ } -+ break; -+ -+ case MOD_VOLTD_MODE_ID_OFF: -+ if (ctx->enabled) { -+ if (regulator_disable(ctx->rdev)) -+ return FWK_E_DEVICE; -+ -+ ctx->enabled = false; -+ } -+ break; -+ -+ default: -+ return FWK_E_PARAM; -+ } -+ -+ DEBUG_MSG("SCMI voltd %u: set config PMIC %s to type %#"PRIx8" / mode %#"PRIx8, -+ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), mode_type, -+ mode_id); -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_get_level(fwk_id_t dev_id, int *level_uv) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ uint16_t level_mv; -+ int ret; -+ -+ ret = find_ctx(dev_id, &ctx); -+ if (ret) -+ return ret; -+ -+ if (regulator_get_voltage(ctx->rdev, &level_mv)) -+ return FWK_E_PANIC; -+ -+ *level_uv = (int)level_mv * 1000; -+ -+ DEBUG_MSG("SCMI voltd %u: get level PMIC %s = %d", -+ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), *level_uv); -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_set_level(fwk_id_t dev_id, int level_uv) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx = NULL; -+ int ret = FWK_E_PANIC; -+ -+ if (level_uv / 1000 > UINT16_MAX) { -+ FWK_LOG_ERR("Volatge level too high (mV shall fit in 16 bits)"); -+ return FWK_E_PARAM; -+ } -+ -+ ret = find_ctx(dev_id, &ctx); -+ if (ret) -+ return ret; -+ -+ if (regulator_set_voltage(ctx->rdev, level_uv / 1000)) -+ return FWK_E_DEVICE; -+ -+ DEBUG_MSG("SCMI voltd %u: set level PMIC %s to %d", -+ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), level_uv); -+ -+ return FWK_SUCCESS; -+} -+ -+static void find_bound_uv(const uint16_t *levels, size_t count, -+ int32_t *min, int32_t *max) -+{ -+ size_t n = 0; -+ -+ *min = INT32_MAX; -+ *max = INT32_MIN; -+ -+ for (n = 0; n < count; n++) { -+ if (*min > levels[n]) { -+ *min = levels[n]; -+ } -+ if (*max < levels[n]) { -+ *max = levels[n]; -+ } -+ } -+ -+ /* Convert from mV to uV */ -+ *min *= 1000; -+ *max *= 1000; -+} -+ -+static int stm32_regu_consumer_get_info(fwk_id_t dev_id, -+ struct mod_voltd_info *info) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ uint16_t *levels; -+ size_t full_count; -+ int ret; -+ -+ ret = find_ctx(dev_id, &ctx); -+ if (ret == FWK_E_ACCESS) { -+ static const char reserved[] = "reserved"; -+ -+ memset(info, 0, sizeof(*info)); -+ info->name = reserved; -+ info->level_range.level_type = MOD_VOLTD_VOLTAGE_LEVEL_DISCRETE; -+ info->level_range.level_count = 1; -+ info->level_range.min_uv = 0; -+ info->level_range.max_uv = 0; -+ -+ return FWK_SUCCESS; -+ } else if (ret != FWK_SUCCESS) { -+ return ret; -+ } -+ -+ if (regulator_list_voltages(ctx->rdev, &levels, &full_count)) { -+ return FWK_E_SUPPORT; -+ } -+ -+ memset(info, 0, sizeof(*info)); -+ info->name = regu_name(ctx->rdev); -+ info->level_range.level_type = MOD_VOLTD_VOLTAGE_LEVEL_DISCRETE; -+ info->level_range.level_count = full_count; -+ find_bound_uv(levels, full_count, -+ &info->level_range.min_uv, &info->level_range.max_uv); -+ -+ DEBUG_MSG("SCMI voltd %u: get_info PMIC %s, range [%d %d]", -+ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), -+ info->level_range.min_uv, info->level_range.max_uv); -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_level_from_index(fwk_id_t dev_id, -+ unsigned int index, -+ int32_t *level_uv) -+{ -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ uint16_t *levels; -+ size_t full_count; -+ int ret; -+ -+ ret = find_ctx(dev_id, &ctx); -+ if (ret == FWK_E_ACCESS) { -+ if (index > 0) { -+ return FWK_E_RANGE; -+ } -+ *level_uv = 0; -+ -+ return FWK_SUCCESS; -+ } else if (ret != FWK_SUCCESS) { -+ return ret; -+ } -+ -+ if (regulator_list_voltages(ctx->rdev, &levels, &full_count)) { -+ return FWK_E_SUPPORT; -+ } -+ -+ if (index >= full_count) -+ return FWK_E_RANGE; -+ -+ *level_uv = (int32_t)levels[index] * 1000; -+ -+ DEBUG_MSG("SCMI voltd %u: get level PMIC %s = %"PRId32, -+ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), *level_uv); -+ -+ return FWK_SUCCESS; -+} -+ -+static const struct mod_voltd_drv_api api_optee_regu = { -+ .get_level = stm32_regu_consumer_get_level, -+ .set_level = stm32_regu_consumer_set_level, -+ .set_config = stm32_regu_consumer_set_config, -+ .get_config = stm32_regu_consumer_get_config, -+ .get_info = stm32_regu_consumer_get_info, -+ .get_level_from_index = stm32_regu_consumer_level_from_index, -+}; -+ -+/* -+ * Framework handler functions -+ */ -+ -+static int stm32_regu_consumer_init(fwk_id_t module_id, -+ unsigned int element_count, -+ const void *data) -+{ -+ module_ctx.dev_count = element_count; -+ -+ if (element_count) -+ module_ctx.dev_ctx_table = -+ fwk_mm_calloc(element_count, sizeof(*module_ctx.dev_ctx_table)); -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_element_init(fwk_id_t element_id, -+ unsigned int unused, -+ const void *data) -+{ -+ const struct mod_stm32_regu_consumer_dev_config *dev_config = data; -+ struct stm32_regu_consumer_dev_ctx *ctx; -+ -+ if (!fwk_module_is_valid_element_id(element_id)) -+ return FWK_E_PANIC; -+ -+ ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(element_id); -+ -+ ctx->rdev = dev_config->rdev; -+ ctx->enabled = dev_config->default_enabled; -+ -+ if (ctx->enabled) { -+ if (!ctx->rdev) -+ return FWK_E_PARAM; -+ if (regulator_enable(ctx->rdev)) -+ return FWK_E_DEVICE; -+ } -+ -+ return FWK_SUCCESS; -+} -+ -+static int stm32_regu_consumer_process_bind_request(fwk_id_t requester_id, -+ fwk_id_t target_id, -+ fwk_id_t api_type, -+ const void **api) -+{ -+ *api = &api_optee_regu; -+ -+ return FWK_SUCCESS; -+} -+ -+const struct fwk_module module_stm32_regu_consumer = { -+ .type = FWK_MODULE_TYPE_DRIVER, -+ .api_count = 1, -+ .init = stm32_regu_consumer_init, -+ .element_init = stm32_regu_consumer_element_init, -+ .process_bind_request = stm32_regu_consumer_process_bind_request, -+}; --- -2.34.1 - diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-Correct-git-error.patch b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-Correct-git-error.patch deleted file mode 100644 index 1943abcbb..000000000 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-Correct-git-error.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 27dd5642469b49aa6a94d99d97bce793f2473053 Mon Sep 17 00:00:00 2001 -From: Christophe Priouzeau -Date: Tue, 28 Nov 2023 14:18:02 +0100 -Subject: [PATCH] Correct git error - -When there is no .git for scp firmware, the git describe command -return error: -fatal: not a git repository (or any parent up to mount point /mnt) -Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set). - -To correct this kind of error, we can redirect the error on a variable - -Signed-off-by: Christophe Priouzeau ---- - framework/CMakeLists.txt | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt -index 9b9bb229..9a9f0bd4 100644 ---- a/framework/CMakeLists.txt -+++ b/framework/CMakeLists.txt -@@ -197,6 +197,7 @@ if(GIT_FOUND) - COMMAND "${GIT_EXECUTABLE}" describe --tags --dirty --always - WORKING_DIRECTORY "${SCP_SOURCE_DIR}" - OUTPUT_VARIABLE SCP_DESCRIBE -+ ERROR_VARIABLE _errorOut - OUTPUT_STRIP_TRAILING_WHITESPACE) - endif() - --- -2.34.1 - diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/README.HOW_TO.txt b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/README.HOW_TO.txt deleted file mode 100644 index 579be8b66..000000000 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/README.HOW_TO.txt +++ /dev/null @@ -1,56 +0,0 @@ -Sharing scp firmware -1. Prepare scp firmware source -2. Manage scp firmware source code with GIT -3. Configure scp firmware source code -4. Test scp firmware source code - --------------------------------------- -1. Prepare scp-firmware source --------------------------------------- -If not already done, extract the sources from Developer Package tarball, for example: - $ tar xf en.SOURCES-stm32mp1-*.tar.xz - -In the scp firmware source directory (sources/*/##BP##-##PR##), -you have one external dt tarball: - - ##BP##-##PR##.tar.xz - - 00*.patch - -If you would like to have a git management for the source code move to -to section 2 [Management of external dt source code with GIT]. - -Otherwise, to manage scp firmware source code without git, you must extract the -tarball now and apply the patch: - - $> tar xf ##BP##-##PR##.tar.xz - $> cd ##BP## - $> for p in `ls -1 ../*.patch`; do patch -p1 < $p; done - -You can now move to section 3 [Configure scp firmware source code]. - -------------------------------------- -2. Manage external dt source code with GIT -------------------------------------- -If you like to have a better management of change made on external dt source, you -have following solutions to use git. - -2.1 Create Git from tarball ---------------------------- - $ cd - $ test -d .git || git init . && git add . && git commit -m "new scp-firwmare" && git gc - $ git checkout -b WORKING - NB: this is the fastest way to get your scp firmware source code ready for development - -------------------------------- -3. Configure scp firmware source code -------------------------------- -To enable use of scp firmware source code for other component, you must set the -SCPFW_DIR variable to your shell environement: - - $> export SCPFW_DIR=$PWD/##BP## - ---------------------------- -4. Test scp firmware source code ---------------------------- -Nothing to do, scp-firmware is directly used by other component. - - #> echo "*** Nothing to test ***"