Changes in v2:
- Split up the series, to get the basic support in place as the first
step. The part that remains is the integration with the OPP library, to
allow consumer drivers to change performance level using the OPP lib.
- Re-based on top v6.5-rc1.
- Other changes will be described for each patch.
The current SCMI performance scaling support is limited to cpufreq. This series
extends the support, so it can be used for all kind of devices and not only for
CPUs.
The changes are spread over a couple of different subsystems, although the
changes that affects the other subsystems than the arm_scmi directory are
mostly smaller. The series is based upon v6.5-rc1.
Note that, I am runing this on the Qemu virt platform with Optee running an SCMI
server. If you want some more details about my test setup, I am certainly open
to share that with you!
Looking forward to your feedback!
Kind regards
Ulf Hansson
Ulf Hansson (11):
firmware: arm_scmi: Extend perf protocol ops to get number of domains
firmware: arm_scmi: Extend perf protocol ops to get information of a
domain
cpufreq: scmi: Prepare to move OF parsing of domain-id to cpufreq
firmware: arm_scmi: Align perf ops to use domain-id as in-parameter
firmware: arm_scmi: Drop redundant ->device_domain_id() from perf ops
cpufreq: scmi: Avoid one OF parsing in scmi_get_sharing_cpus()
PM: domains: Allow genpd providers to manage OPP tables directly by
its FW
dt-bindings: firmware: arm,scmi: Extend bindings for protocol@13
cpufreq: scmi: Add support to parse domain-id using
#power-domain-cells
firmware: arm_scmi: Add the SCMI performance domain
cpufreq: scmi: Drop redundant ifdef in scmi_cpufreq_probe()
.../bindings/firmware/arm,scmi.yaml | 11 +-
drivers/base/power/domain.c | 11 +-
drivers/cpufreq/scmi-cpufreq.c | 48 ++++--
drivers/firmware/arm_scmi/Kconfig | 12 ++
drivers/firmware/arm_scmi/Makefile | 1 +
drivers/firmware/arm_scmi/perf.c | 60 ++++---
drivers/firmware/arm_scmi/scmi_perf_domain.c | 155 ++++++++++++++++++
include/linux/pm_domain.h | 5 +
include/linux/scmi_protocol.h | 18 +-
9 files changed, 262 insertions(+), 59 deletions(-)
create mode 100644 drivers/firmware/arm_scmi/scmi_perf_domain.c
--
2.34.1
The performance domain-id can be described in DT using the power-domains
property or the clock property. The latter is already supported, so let's
add support for the power-domains too.
Signed-off-by: Ulf Hansson <[email protected]>
---
Changes in v2:
- New patch.
---
drivers/cpufreq/scmi-cpufreq.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index 78f53e388094..b42f43d9bd89 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -72,13 +72,19 @@ static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy,
static int scmi_cpu_domain_id(struct device *cpu_dev)
{
- struct of_phandle_args clkspec;
+ struct of_phandle_args domain_id;
if (of_parse_phandle_with_args(cpu_dev->of_node, "clocks",
- "#clock-cells", 0, &clkspec))
- return -EINVAL;
+ "#clock-cells", 0, &domain_id)) {
- return clkspec.args[0];
+ if (of_parse_phandle_with_args(cpu_dev->of_node,
+ "power-domains",
+ "#power-domain-cells", 0,
+ &domain_id))
+ return -EINVAL;
+ }
+
+ return domain_id.args[0];
}
static int
--
2.34.1
Similar to other protocol ops, it's useful for an scmi module driver to get
the number of supported performance domains, hence let's make this
available by adding a new perf protocol callback. Note that, a user is
being added from subsequent changes.
Signed-off-by: Ulf Hansson <[email protected]>
---
Changes in v2:
- None.
---
drivers/firmware/arm_scmi/perf.c | 8 ++++++++
include/linux/scmi_protocol.h | 2 ++
2 files changed, 10 insertions(+)
diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index ecf5c4de851b..cf7f0de4d6db 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -333,6 +333,13 @@ scmi_perf_describe_levels_get(const struct scmi_protocol_handle *ph, u32 domain,
return ret;
}
+static int scmi_perf_num_domains_get(const struct scmi_protocol_handle *ph)
+{
+ struct scmi_perf_info *pi = ph->get_priv(ph);
+
+ return pi->num_domains;
+}
+
static int scmi_perf_mb_limits_set(const struct scmi_protocol_handle *ph,
u32 domain, u32 max_perf, u32 min_perf)
{
@@ -687,6 +694,7 @@ scmi_power_scale_get(const struct scmi_protocol_handle *ph)
}
static const struct scmi_perf_proto_ops perf_proto_ops = {
+ .num_domains_get = scmi_perf_num_domains_get,
.limits_set = scmi_perf_limits_set,
.limits_get = scmi_perf_limits_get,
.level_set = scmi_perf_level_set,
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index e6fe4f73ffe6..71b39cbbdace 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -101,6 +101,7 @@ struct scmi_clk_proto_ops {
* struct scmi_perf_proto_ops - represents the various operations provided
* by SCMI Performance Protocol
*
+ * @num_domains_get: gets the number of supported performance domains
* @limits_set: sets limits on the performance level of a domain
* @limits_get: gets limits on the performance level of a domain
* @level_set: sets the performance level of a domain
@@ -120,6 +121,7 @@ struct scmi_clk_proto_ops {
* or in some other (abstract) scale
*/
struct scmi_perf_proto_ops {
+ int (*num_domains_get)(const struct scmi_protocol_handle *ph);
int (*limits_set)(const struct scmi_protocol_handle *ph, u32 domain,
u32 max_perf, u32 min_perf);
int (*limits_get)(const struct scmi_protocol_handle *ph, u32 domain,
--
2.34.1
On Thu, Jul 13, 2023 at 04:17:36PM +0200, Ulf Hansson wrote:
> The performance domain-id can be described in DT using the power-domains
> property or the clock property. The latter is already supported, so let's
> add support for the power-domains too.
>
How is this supposed to work for the CPUs ? The CPU power domains are
generally PSCI on most of the platforms and the one using OSI explicitly
need to specify the details while ones using PC will not need to. Also they
can never be performance domains too. So I am not sure if I am following this
correctly.
--
Regards,
Sudeep
On Wed, 19 Jul 2023 at 17:24, Sudeep Holla <[email protected]> wrote:
>
> On Thu, Jul 13, 2023 at 04:17:36PM +0200, Ulf Hansson wrote:
> > The performance domain-id can be described in DT using the power-domains
> > property or the clock property. The latter is already supported, so let's
> > add support for the power-domains too.
> >
>
> How is this supposed to work for the CPUs ? The CPU power domains are
> generally PSCI on most of the platforms and the one using OSI explicitly
> need to specify the details while ones using PC will not need to. Also they
> can never be performance domains too. So I am not sure if I am following this
> correctly.
Your concerns are certainly correct, I completely forgot about this.
We need to specify what power-domain index belongs to what, by using
power-domain-names in DT. So a CPU node, that has both psci for power
and scmi for performance would then typically look like this:
power-domains = <&CPU_PD0>, <&scmi_dvfs 4>;
power-domain-names = "psci", "scmi";
I will take care of this in the next version - and thanks a lot for
pointing this out!
Kind regards
Uffe
On Fri, Jul 21, 2023 at 01:52:17PM +0200, Ulf Hansson wrote:
> On Wed, 19 Jul 2023 at 17:24, Sudeep Holla <[email protected]> wrote:
> >
> > On Thu, Jul 13, 2023 at 04:17:36PM +0200, Ulf Hansson wrote:
> > > The performance domain-id can be described in DT using the power-domains
> > > property or the clock property. The latter is already supported, so let's
> > > add support for the power-domains too.
> > >
> >
> > How is this supposed to work for the CPUs ? The CPU power domains are
> > generally PSCI on most of the platforms and the one using OSI explicitly
> > need to specify the details while ones using PC will not need to. Also they
> > can never be performance domains too. So I am not sure if I am following this
> > correctly.
>
> Your concerns are certainly correct, I completely forgot about this.
> We need to specify what power-domain index belongs to what, by using
> power-domain-names in DT. So a CPU node, that has both psci for power
> and scmi for performance would then typically look like this:
>
> power-domains = <&CPU_PD0>, <&scmi_dvfs 4>;
> power-domain-names = "psci", "scmi";
>
> I will take care of this in the next version - and thanks a lot for
> pointing this out!
Yes something like this will work. Just curious will this impact the idle
paths ? By that I mean will the presence of additional domains add more
work or will they be skipped as early as possible with just one additional
check ?
--
Regards,
Sudeep
On Fri, Jul 21, 2023 at 01:52:17PM +0200, Ulf Hansson wrote:
> On Wed, 19 Jul 2023 at 17:24, Sudeep Holla <[email protected]> wrote:
> >
> > On Thu, Jul 13, 2023 at 04:17:36PM +0200, Ulf Hansson wrote:
> > > The performance domain-id can be described in DT using the power-domains
> > > property or the clock property. The latter is already supported, so let's
> > > add support for the power-domains too.
> > >
> >
> > How is this supposed to work for the CPUs ? The CPU power domains are
> > generally PSCI on most of the platforms and the one using OSI explicitly
> > need to specify the details while ones using PC will not need to. Also they
> > can never be performance domains too. So I am not sure if I am following this
> > correctly.
>
> Your concerns are certainly correct, I completely forgot about this.
> We need to specify what power-domain index belongs to what, by using
> power-domain-names in DT. So a CPU node, that has both psci for power
> and scmi for performance would then typically look like this:
>
> power-domains = <&CPU_PD0>, <&scmi_dvfs 4>;
> power-domain-names = "psci", "scmi";
That is completely backwards. Entries are named based on the consumer
side. The function of each clock or interrupt for example. Here your
entries are based on the provider which should be opaque to the
consumer.
Rob
On Fri, 21 Jul 2023 at 13:59, Sudeep Holla <[email protected]> wrote:
>
> On Fri, Jul 21, 2023 at 01:52:17PM +0200, Ulf Hansson wrote:
> > On Wed, 19 Jul 2023 at 17:24, Sudeep Holla <[email protected]> wrote:
> > >
> > > On Thu, Jul 13, 2023 at 04:17:36PM +0200, Ulf Hansson wrote:
> > > > The performance domain-id can be described in DT using the power-domains
> > > > property or the clock property. The latter is already supported, so let's
> > > > add support for the power-domains too.
> > > >
> > >
> > > How is this supposed to work for the CPUs ? The CPU power domains are
> > > generally PSCI on most of the platforms and the one using OSI explicitly
> > > need to specify the details while ones using PC will not need to. Also they
> > > can never be performance domains too. So I am not sure if I am following this
> > > correctly.
> >
> > Your concerns are certainly correct, I completely forgot about this.
> > We need to specify what power-domain index belongs to what, by using
> > power-domain-names in DT. So a CPU node, that has both psci for power
> > and scmi for performance would then typically look like this:
> >
> > power-domains = <&CPU_PD0>, <&scmi_dvfs 4>;
> > power-domain-names = "psci", "scmi";
> >
> > I will take care of this in the next version - and thanks a lot for
> > pointing this out!
>
>
> Yes something like this will work. Just curious will this impact the idle
> paths ? By that I mean will the presence of additional domains add more
> work or will they be skipped as early as possible with just one additional
> check ?
Unless I misunderstand your concern, I don't think there is any impact
on the idle path whatsoever. This should be entirely orthogonal.
The scmi-cpufreq driver should only have to care about the
scmi-performance domain, while the cpuidle-psci driver cares only
about psci.
Did that make sense?
Kind regards
Uffe
On Fri, 21 Jul 2023 at 16:37, Rob Herring <[email protected]> wrote:
>
> On Fri, Jul 21, 2023 at 01:52:17PM +0200, Ulf Hansson wrote:
> > On Wed, 19 Jul 2023 at 17:24, Sudeep Holla <[email protected]> wrote:
> > >
> > > On Thu, Jul 13, 2023 at 04:17:36PM +0200, Ulf Hansson wrote:
> > > > The performance domain-id can be described in DT using the power-domains
> > > > property or the clock property. The latter is already supported, so let's
> > > > add support for the power-domains too.
> > > >
> > >
> > > How is this supposed to work for the CPUs ? The CPU power domains are
> > > generally PSCI on most of the platforms and the one using OSI explicitly
> > > need to specify the details while ones using PC will not need to. Also they
> > > can never be performance domains too. So I am not sure if I am following this
> > > correctly.
> >
> > Your concerns are certainly correct, I completely forgot about this.
> > We need to specify what power-domain index belongs to what, by using
> > power-domain-names in DT. So a CPU node, that has both psci for power
> > and scmi for performance would then typically look like this:
> >
> > power-domains = <&CPU_PD0>, <&scmi_dvfs 4>;
> > power-domain-names = "psci", "scmi";
>
> That is completely backwards. Entries are named based on the consumer
> side. The function of each clock or interrupt for example. Here your
> entries are based on the provider which should be opaque to the
> consumer.
Okay, so you would rather prefer something along the lines of the below?
power-domain-names = "power", "perf";
The "psci" name is already part of the current cpus DT binding
(Documentation/devicetree/bindings/arm/cpus.yaml), so then it looks
like that deserves an update too. Right?
Kind regards
Uffe