mbox series

[v8,00/10] Add power domain driver for corners on msm8996/sdm845

Message ID 20181221085622.25573-1-rnayak@codeaurora.org
Headers show
Series Add power domain driver for corners on msm8996/sdm845 | expand

Message

Rajendra Nayak Dec. 21, 2018, 8:56 a.m. UTC
Changes in v8:
* Patch 01/10: Bindings updated to mention opp-hz is optional
* Patch 02/10: Fixed #power-domain-cells
* All dependencies for 'Patch 10/10' are on their way to 4.21 via the pm tree

Changes in v7:
* Rebased on Andy's for-next, and used the updated cmd_db_read_aux_data()
* Other minor fixes, all in 'PATCH 06/10' as suggested by Stephen

Changes in v6:
* OPP binding updates for qcom,level reviewed by Rob
* DT bindings for rpmpd and rpmhpd updated to specify the
OPP tables as child nodes of the power-controller itself
* Removed some module specific remains from the drivers,
now that they can only be built-in
* Added a simple_opp_to_performance_state() helper

Changes in v5:
* First 6 patches are unchanged
* Patch 7/8 adds the DT node for rpmh power-controller on sdm845 and the
corresponding OPP tables for it to describe the performance states
* Patch 8/8 adds a parent/child relationship across mx/cx and mx_ao/cx_ao
as needed on sdm845 platform. This patch is dependent on the series from
Viresh [1] which adds support to propogate performance states across the
power domain hierarchy which is still being reviewed

Changes in v4:
* Included the patch to add qcom-opp bindings (dropped accidentally in v3)
* merged the patches to add bindings for rpm and rpmh, added consumer binding example
* Made the drivers built in, removed .remove
* Added better description in changelog for PATCH 6/6
* Updated rpmhpd_aggregate_corner() based on Davids feedback
* rpmhpd_set_performance_state() returns max corner, in cases where its called
with an INT_MAX
* Dropped the patch to max vote on all corners at init, the patch did not
work anyway, and it shouldn't be needed now

Changes in v3:
* Bindings split into seperate patches
* Bindings updated to remove duplicate OPP table phandles
* DT headers defining macros for Power domain indexes and OPP levels
* Optimisations to use rpmh_write_async() whereever applicable
* Fixed up handling of ACTIVE_ONLY/WAKE_ONLY/SLEEP voting for RPMh
* Fixed the vlvl to hlvl conversions in set_performance
* Other minor fixes based on review of v2
* TODO: This series does not handle the case where all VDD_MX votes
should be higher than VDD_CX from APPs, as pointed out
by David Collins in v2. This needs support at genpd to propogate performance
state up the parents, if we model these as Parent/Child to handle the
interdependency.

Changes in v2:
* added a power domain driver for sdm845 which supports communicating to RPMh
* dropped the changes to sdhc driver to move over to using OPP
as there is active discussion on using OPP as the interface vs
handling all of it in clock drivers
* Other minor binding updates based on review of v1

With performance state support for genpd/OPP merged, this is an effort
to model a power domain driver to communicate corner/level
values for qualcomm platforms to RPM (Remote Power Manager) and RPMh.

[1] https://lkml.org/lkml/2018/11/26/333

Rajendra Nayak (10):
  dt-bindings: opp: Introduce qcom-opp bindings
  dt-bindings: power: Add qcom rpm power domain driver bindings
  soc: qcom: rpmpd: Add a Power domain driver to model corners
  soc: qcom: rpmpd: Add support for get/set performance state
  arm64: dts: msm8996: Add rpmpd device node
  soc: qcom: rpmhpd: Add RPMh power domain driver
  arm64: dts: sdm845: Add rpmh powercontroller node
  PM / Domains: Add a simple_opp_to_performance_state() helper
  soc: qcom: rpmpd: Use simple_opp_to_performance_state() helper
  soc: qcom: rpmhpd: Mark mx as a parent for cx

 .../devicetree/bindings/opp/qcom-opp.txt      |  28 ++
 .../devicetree/bindings/power/qcom,rpmpd.txt  | 146 +++++++
 arch/arm64/boot/dts/qcom/msm8996.dtsi         |  34 ++
 arch/arm64/boot/dts/qcom/sdm845.dtsi          |  51 +++
 drivers/base/power/domain.c                   |  17 +
 drivers/soc/qcom/Kconfig                      |  18 +
 drivers/soc/qcom/Makefile                     |   2 +
 drivers/soc/qcom/rpmhpd.c                     | 402 ++++++++++++++++++
 drivers/soc/qcom/rpmpd.c                      | 317 ++++++++++++++
 include/dt-bindings/power/qcom-rpmpd.h        |  39 ++
 include/linux/pm_domain.h                     |   9 +
 11 files changed, 1063 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/qcom-opp.txt
 create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmpd.txt
 create mode 100644 drivers/soc/qcom/rpmhpd.c
 create mode 100644 drivers/soc/qcom/rpmpd.c
 create mode 100644 include/dt-bindings/power/qcom-rpmpd.h

Comments

Ulf Hansson Dec. 21, 2018, 10:31 a.m. UTC | #1
On Fri, 21 Dec 2018 at 09:57, Rajendra Nayak <rnayak@codeaurora.org> wrote:
>
> Now that we have atleast 2 genpd providers, both using a simple
> routine to read a performance state value from device tree and
> return it, in order to implement the .opp_to_performance_state
> callback, add a simple_opp_to_performance_state() helper to do
> it, so it can be resued across all such genpd providers which
> just need to read the value from DT.
>
> Suggested-by: Stephen Boyd <sboyd@kernel.org>
> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> ---
>  drivers/base/power/domain.c | 17 +++++++++++++++++
>  include/linux/pm_domain.h   |  9 +++++++++
>  2 files changed, 26 insertions(+)
>
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index 8e554e6a82a2..193872afbe20 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -2520,6 +2520,23 @@ int of_genpd_parse_idle_states(struct device_node *dn,
>  }
>  EXPORT_SYMBOL_GPL(of_genpd_parse_idle_states);
>
> +unsigned int simple_opp_to_performance_state(struct generic_pm_domain *genpd,
> +                                            struct dev_pm_opp *opp,
> +                                            const char *name)
> +{

Looks like this function should be moved into the OPP library instead.
There is no use of the genpd.

> +       struct device_node *np;
> +       unsigned int perf_state = 0;
> +
> +       np = dev_pm_opp_get_of_node(opp);
> +       if (of_property_read_u32(np, name, &perf_state))
> +               pr_err("%s: missing %s property\n", __func__, name);
> +
> +       of_node_put(np);
> +
> +       return perf_state;
> +}
> +EXPORT_SYMBOL_GPL(simple_opp_to_performance_state);
> +

Kind regards
Uffe
Ulf Hansson Dec. 21, 2018, 10:32 a.m. UTC | #2
On Fri, 21 Dec 2018 at 09:57, Rajendra Nayak <rnayak@codeaurora.org> wrote:
>
> Get rid of the duplicate code across rpmpd and rpmhpd to read the
> performance state value from Device tree and use the
> simple_opp_to_performance_state() helper instead.
>
> Suggested-by: Stephen Boyd <sboyd@kernel.org>
> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>

Kind regards
Uffe

> ---
>  drivers/soc/qcom/rpmhpd.c | 11 +----------
>  drivers/soc/qcom/rpmpd.c  | 11 +----------
>  2 files changed, 2 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
> index e37976e87370..f7fbe57f31ae 100644
> --- a/drivers/soc/qcom/rpmhpd.c
> +++ b/drivers/soc/qcom/rpmhpd.c
> @@ -276,16 +276,7 @@ static int rpmhpd_set_performance_state(struct generic_pm_domain *domain,
>  static unsigned int rpmhpd_get_performance_state(struct generic_pm_domain *genpd,
>                                                  struct dev_pm_opp *opp)
>  {
> -       struct device_node *np;
> -       unsigned int level = 0;
> -
> -       np = dev_pm_opp_get_of_node(opp);
> -       if (of_property_read_u32(np, "qcom,level", &level))
> -               pr_err("%s: missing 'qcom,level' property\n", __func__);
> -
> -       of_node_put(np);
> -
> -       return level;
> +       return simple_opp_to_performance_state(genpd, opp, "qcom,level");
>  }
>
>  static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd)
> diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c
> index 59e21c88a144..29288af502b0 100644
> --- a/drivers/soc/qcom/rpmpd.c
> +++ b/drivers/soc/qcom/rpmpd.c
> @@ -248,16 +248,7 @@ static int rpmpd_set_performance(struct generic_pm_domain *domain,
>  static unsigned int rpmpd_get_performance(struct generic_pm_domain *genpd,
>                                           struct dev_pm_opp *opp)
>  {
> -       struct device_node *np;
> -       unsigned int corner = 0;
> -
> -       np = dev_pm_opp_get_of_node(opp);
> -       if (of_property_read_u32(np, "qcom,level", &corner))
> -               pr_err("%s: missing 'qcom,level' property\n", __func__);
> -
> -       of_node_put(np);
> -
> -       return corner;
> +       return simple_opp_to_performance_state(genpd, opp, "qcom,level");
>  }
>
>  static int rpmpd_probe(struct platform_device *pdev)
> --
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
>
Ulf Hansson Dec. 21, 2018, 10:33 a.m. UTC | #3
On Fri, 21 Dec 2018 at 09:57, Rajendra Nayak <rnayak@codeaurora.org> wrote:
>
> Specify the active + sleep and active-only MX power domains as
> the parents of the corresponding CX power domains. This will ensure that
> performance state requests on CX automatically generate equivalent requests
> on MX power domains.
>
> This is used to enforce a requirement that exists for various
> hardware blocks on SDM845 that MX performance state >= CX performance
> state for a given operating frequency.
>
> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>

Kind regards
Uffe

> ---
>  drivers/soc/qcom/rpmhpd.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
> index f7fbe57f31ae..71d693c31e3b 100644
> --- a/drivers/soc/qcom/rpmhpd.c
> +++ b/drivers/soc/qcom/rpmhpd.c
> @@ -97,12 +97,14 @@ static struct rpmhpd sdm845_cx_ao;
>  static struct rpmhpd sdm845_cx = {
>         .pd = { .name = "cx", },
>         .peer = &sdm845_cx_ao,
> +       .parent = &sdm845_mx.pd,
>         .res_name = "cx.lvl",
>  };
>
>  static struct rpmhpd sdm845_cx_ao = {
>         .pd = { .name = "cx_ao", },
>         .peer = &sdm845_cx,
> +       .parent = &sdm845_mx_ao.pd,
>         .res_name = "cx.lvl",
>  };
>
> @@ -372,6 +374,15 @@ static int rpmhpd_probe(struct platform_device *pdev)
>                 data->domains[i] = &rpmhpds[i]->pd;
>         }
>
> +       /* Add subdomains */
> +       for (i = 0; i < num_pds; i++) {
> +               if (!rpmhpds[i])
> +                       continue;
> +               if (rpmhpds[i]->parent)
> +                       pm_genpd_add_subdomain(rpmhpds[i]->parent,
> +                                              &rpmhpds[i]->pd);
> +       }
> +
>         return of_genpd_add_provider_onecell(pdev->dev.of_node, data);
>  }
>
> --
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
>
Viresh Kumar Jan. 2, 2019, 9 a.m. UTC | #4
On 21-12-18, 14:26, Rajendra Nayak wrote:
> +unsigned int simple_opp_to_performance_state(struct generic_pm_domain *genpd,
> +					     struct dev_pm_opp *opp,

Maybe name it as:

dev_pm_opp_read_u32_prop().