Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stm32mp1 cpu opp #7219

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open

Stm32mp1 cpu opp #7219

wants to merge 16 commits into from

Conversation

ppaillet
Copy link

The goal of this patch-set is to be able to use SCMI performance protocol to drive the CPU frequency of STM32MP1:

  • add a CPU OPP driver for STM32MP,
  • add support for SCMI Performance to SCMI-MSG,
  • connect SCMI performance to the new STM32MP CPU OPP driver.

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Pascal, here is a round of comments for this series.
Could you remove the Change-Id tags from the commit messages.

* @channel_id: SCMI channel ID
* @domain_id: SCMI performance domain ID
* @level: Target performance level
* @latency: Output latency value (microsecond) for the target level

This comment was marked as resolved.

* @channel_id: SCMI channel ID
* @domain_id: SCMI performance domain ID
* @start_index: Level index to start from.
* @elt: If NULL, function returns, else output level array
Copy link
Contributor

@etienne-lms etienne-lms Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

 * @elt: Array where to store levels or NULL if querying only @nb_elts
 * @nb_elts: [in] @elt array size, [out] number of levels
 *
 * When @elt is NULL, @nb_elt output value gives full number of levels
 * remaining starting from @start_index. When @elt is not NULL,
 * @nb_elt output value gives the number of levels stored in @elt.

Nitpicking: can return remove the terminal dot at lines 453 and 455 (and at line 441).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you update the description as per above suggestion or like?

int32_t __weak plat_scmi_perf_level_power_cost(unsigned int channel_id __unused,
unsigned int domain_id __unused,
unsigned int level __unused,
unsigned int *cost __unused)

This comment was marked as resolved.

return false;

if (get_part_number(&part_number)) {
DMSG("Cannot get part number\n");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can drop trailing \n.
Ditto at line 742.

* @opp_count: Number of cells of @dvfs
* @clock: CPU clock handle
* @regul: CPU regulator supply handle
* @dvfs: Arrays of the supported CPU operating points

This comment was marked as off-topic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Arrays/Array/

@ppaillet ppaillet force-pushed the stm32mp1_cpu_opp branch 2 times, most recently from 904abd3 to ada6a12 Compare January 23, 2025 08:33
Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes in commit "plat-stm32mp1: SCMI performance domain for CPU DVFS" related to stm32_cpu_opp.c and stm32_cpu_opp.h (pm + sustained level) should be squashed in commit "drivers: add stm32 CPU DVFS driver".


/* nothing to do if OPP is managed by Linux and not by SCMI */
if (!IS_ENABLED(CFG_SCMI_MSG_PERF_DOMAIN))
return TEE_SUCCESS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer no call register_pm_driver_cb() if build config tells the PM sequences are not needed.

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments for commit "drivers: add stm32 CPU DVFS driver".
In the commit message: s/cpu_opp.c/stm32_cpu_opp.c/ + s/ah higher/a higher/

#include <drivers/clk_dt.h>
#include <drivers/regulator.h>
#include <drivers/stm32_cpu_opp.h>
#ifdef CFG_STM32MP13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could remove this #ifdef / #endif

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for compatibility issue with MP2

#include <trace.h>

/*
* struct cpu_dvfs - CPU DVFS registered operating points
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/points/point/

* @opp_count: Number of cells of @dvfs
* @clock: CPU clock handle
* @regul: CPU regulator supply handle
* @dvfs: Arrays of the supported CPU operating points
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Arrays/Array/

TEE_Result res = TEE_ERROR_GENERIC;
unsigned int opp = 0;

DMSG("Set OPP to %ukHz", level);

This comment was marked as resolved.

}

TEE_Result stm32_cpu_opp_read_level(unsigned int *level)
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency, here also we should check the OPPs are defined:

if (!cpu_opp.opp_count) {
    EMSG("No CPU OPP defined");
    return TEE_ERROR_GENERIC;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad: I may have been confusing. Testing whether OPP support was initialized or not, we should test a unique pattern. This function check cpu_opp.opp_count != 0 whereas stm32_cpu_opp_set_level() checks cpu_opp.dvfs != NULL. On the ohter hand, stm32_cpu_opp_get_dt_subnode() only resets cpu_opp.opp_count, not cpu_opp_dvfs upon failure. Could you make all these more consistent?


return TEE_SUCCESS;

err:

This comment was marked as resolved.

return TEE_SUCCESS;
}

driver_init(stm32_cpu_initcall);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use early_init()?

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed-by: Etienne Carriere <[email protected]> for commit:

  • "dts: stm32: describe CPU OPP for STM32MP13"
    *"plat-stm32mp1: default enable CFG_STM32_CPU_OPP for STM32MP13" (s/OPP/OPPs/ in commit message)
  • "drivers: stm32_cpu_opp: skip OPP with unsupported voltage" (with a minor comment).

*/
static bool opp_voltage_is_supported(struct regulator *regul, uint32_t *volt_uv)
{
const int target_volt_uv = *volt_uv;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think their should be a cast here to convert the unsigned value into a signed value.

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments for commits "plat-stm32mp1: retrieve chip id from syscfg"
and "plat-stm32mp1: chip and STM32MP15 platform identification":

  • For consistency of these 2 commit messages, I propose to squash them into a single commit "plat-stm32mp1: chip identification and supported features".
  • Replace "id" with "ID" in the former commit message (header line and body).


bool stm32mp_supports_second_core(void)
{
uint32_t __maybe_unused part_number = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove __maybe_unused

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acked-by: Etienne Carriere <[email protected]> for commits
"dts: stm32: describe supported-hw on CPU OPP for STM32MP13" and
"drivers: stm32_cpu_opp: skip OPP unsupported by SOC".

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For commit "plat-stm32mp1: SCMI performance domain for CPU DVFS":
could you move all changes on stm32_cpu_opp.c|.h from this commit back into 1st commit "drivers: add stm32 CPU DVFS driver" where, I think, they belong.

@@ -0,0 +1,402 @@
/* SPDX-License-Identifier: BSD-3-Clause */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address this comment.

{
if (opp >= cpu_opp.opp_count) {
EMSG("Bad OPP number");
return TEE_ERROR_BAD_PARAMETERS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these lines (current function does not return a TEE_Result value). The assertion below is enough.

DMSG("Set OPP to %ukHz", level);

if (!cpu_opp.dvfs)
return TEE_ERROR_GENERIC;

This comment was marked as resolved.

}

TEE_Result stm32_cpu_opp_read_level(unsigned int *level)
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad: I may have been confusing. Testing whether OPP support was initialized or not, we should test a unique pattern. This function check cpu_opp.opp_count != 0 whereas stm32_cpu_opp_set_level() checks cpu_opp.dvfs != NULL. On the ohter hand, stm32_cpu_opp_get_dt_subnode() only resets cpu_opp.opp_count, not cpu_opp_dvfs upon failure. Could you make all these more consistent?

int subnode = 0;
TEE_Result res = TEE_ERROR_GENERIC;

cpu_opp.dvfs = calloc(CFG_STM32MP_OPP_COUNT, sizeof(*cpu_opp.dvfs));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we always allocate CFG_STM32MP_OPP_COUNT cells, maybe worth to make the array size statically defined in the struct:

 struct cpu_opp {
 	unsigned int current_opp;
 	unsigned int opp_count;
 	struct clk *clock;
 	struct regulator *regul;
-	struct cpu_dvfs *dvfs;
+	struct cpu_dvfs dvfs[CFG_STM32MP_OPP_COUNT];
 	unsigned int sustained_freq_khz;
 };


/*
* Get power cost value related to target performance level.
* A default (weak) implementation output latency of 0.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/latency/power cost/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To fix


/*
* Get latency is microseconds for transition to target performance level.
* A default (weak) implementation output cost value of 0.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/cost value of 0/latency of 1 microsecond/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To fix

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you squash all fixup commits?

if (*domain_id >= domain_count)
return SCMI_INVALID_PARAMETERS;

*domain_id = confine_array_index(*domain_id, domain_count);

This comment was marked as resolved.

unsigned int domain_id = in_args->domain_id;
int32_t status = SCMI_GENERIC_ERROR;
struct scmi_perf_attributes_p2a return_values = {
.attributes = SCMI_PERF_DOMAIN_ATTRIBUTES_CAN_SET_LEVEL,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed-by: Etienne Carriere <[email protected]> for commits:
"drivers: add stm32 CPU DVFS driver",
"plat-stm32mp1: default enable CFG_STM32_CPU_OPP for STM32MP13",
"drivers: stm32_cpu_opp: skip OPP with unsupported voltage",
"plat-stm32mp1: retrieve chip id from syscfg",
"plat-stm32mp1: chip and STM32MP15 platform identification" (with a minor comment addressed or not),

Acked-by: Etienne Carriere <[email protected]> for commit:
"dts: stm32: describe supported-hw on CPU OPP for STM32MP13"

Commits "drivers: scmi-msg: support performance domains for DVFS"
and "plat-stm32mp1: SCMI performance domain for CPU DVFS" LGTM but few minor comments to address.

Maybe default value for CFG_STM32MP_OPP_LATENCY_US should be set from commit "plat-stm32mp1: conf: enable SCMI PERF for stm32mp13".

uint32_t id = STM32MP1_CHIP_ID;

if (!chip_dev_id)
return TEE_ERROR_BAD_PARAMETERS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: assert(chip_dev_id) should be enough.

@@ -341,6 +362,14 @@ static TEE_Result stm32_cpu_opp_get_dt_subnode(const void *fdt, int node)

volt_uv = fdt32_to_cpu(*cuint32);

/* skip OPP when the SOC does not support it */
if (stm32_cpu_opp_is_supported(fdt, subnode) != TEE_SUCCESS) {
DMSG("Skip soc OPP %"PRIu64"kHz/%"PRIu32"uV",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/soc/SoC/ (or maybe simply "Skip OPP ...")

* @channel_id: SCMI channel ID
* @domain_id: SCMI performance domain ID
* @start_index: Level index to start from.
* @elt: If NULL, function returns, else output level array
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you update the description as per above suggestion or like?


/*
* Get latency is microseconds for transition to target performance level.
* A default (weak) implementation output cost value of 0.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To fix


/*
* Get power cost value related to target performance level.
* A default (weak) implementation output latency of 0.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To fix

.name = (_name), \
}

struct stm32_scmi_perfd scmi_performance_domain[] = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs __maybe_unused.

if (!perfd)
return SCMI_NOT_FOUND;

/* Measured latency on STM32MP13 is around 650uS */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The config switch is set to 1000, not 650.

Pascal Paillet added 9 commits February 20, 2025 14:38
drivers/cpu_opp.c implements dynamic voltage and frequency
scaling for the CPU.
It is used at boot time to set an higher operating point than
the one used to boot.
It will be used by the SCMI performance service.

Signed-off-by: Pascal Paillet <[email protected]>
Reviewed-by: Etienne Carriere <[email protected]>
Describe CPU operating points for STM32MP13 boards.

Acked-by: Etienne Carriere <[email protected]>
Signed-off-by: Pascal Paillet <[email protected]>
Enable CFG_STM32_CPU_OPP for STM32MP13 and increase
CFG_STM32MP_OPP_COUNT to 3 OPP.

Signed-off-by: Pascal Paillet <[email protected]>
Reviewed-by: Etienne Carriere <[email protected]>
Remove operating points that could not be handled
by the regulator supplying the CPU.

Signed-off-by: Patrick Delaunay <[email protected]>
Signed-off-by: Pascal Paillet <[email protected]>
Reviewed-by: Etienne Carriere <[email protected]>
Chip ID is read from SYSCFG. Add the associated read
function and new CHIP IDs.

Use the chip id to dynamically detect the CRYPTO hardware
support, the second CPU core, and CPU OPP.

Signed-off-by: Lionel Debieve <[email protected]>
Signed-off-by: Pascal Paillet <[email protected]>
Reviewed-by: Etienne Carriere <[email protected]>
New platform function to get the chip identification using
DBGMCU SoC register.

Signed-off-by: Lionel Debieve <[email protected]>
Signed-off-by: Pascal Paillet <[email protected]>
Reviewed-by: Etienne Carriere <[email protected]>
Replace a test by an assert.

Signed-off-by: Pascal Paillet <[email protected]>
Describe supported hardware for each OPP.

Signed-off-by: Pascal Paillet <[email protected]>
Acked-by: Etienne Carriere <[email protected]>
Use device ID to remove not supported OPP.

Acked-by: Etienne Carriere <[email protected]>
Signed-off-by: Pascal Paillet <[email protected]>
@ppaillet
Copy link
Author

Maybe default value for CFG_STM32MP_OPP_LATENCY_US should be set from commit "plat-stm32mp1: conf: enable SCMI PERF for stm32mp13".
CFG_STM32MP_OPP_LATENCY_US is set for MP13 in this patch.
If we enable CPU OPP for MP15, we will ahve to define this value.

Pascal Paillet added 4 commits February 20, 2025 15:33
Improve comment. The Opp is skipped because it is not supported
on this SoC.

Signed-off-by: Pascal Paillet <[email protected]>
Implement some of the SCMI performance domain management messages
in scmi-msg drivers to support basic DVFS scenario.

Co-developed-by: Etienne Carriere <[email protected]>
Signed-off-by: Etienne Carriere <[email protected]>
Signed-off-by: Pascal Paillet <[email protected]>
Implement scmi-msg perf protocol platform handlers to drive CPU
voltage/frequency scaling support.

Co-developed-by: Etienne Carriere <[email protected]>
Signed-off-by: Etienne Carriere <[email protected]>
Signed-off-by: Pascal Paillet <[email protected]>
Pascal Paillet added 3 commits February 20, 2025 15:33
Fix compilation without CFG_SCMI_MSG_PERF_DOMAIN
Fix comment

Signed-off-by: Pascal Paillet <[email protected]>
Enable CFG_SCMI_MSG_PERF_DOMAIN for STM32MP13 that is used
to provide CPU OPP to linux.

Signed-off-by: Pascal Paillet <[email protected]>
Confine domain id before returning errors.

Signed-off-by: Pascal Paillet <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants