mbox series

[v3,0/7] Add powerdomain driver for corners on msm8996/sdm845

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

Message

Rajendra Nayak June 12, 2018, 4:40 a.m. UTC
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 powerdomain 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 powerdomain driver to communicate corner/level
values for qualcomm platforms to RPM (Remote Power Manager) and RPMh.

Rajendra Nayak (7):
  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
  dt-bindings: power: Add qcom rpmh power domain driver bindings
  soc: qcom: Add RPMh Power domain driver
  soc: qcom: rpmpd/rpmhpd: Add a max vote on all corners at init

 .../devicetree/bindings/power/qcom,rpmhpd.txt |  65 +++
 .../devicetree/bindings/power/qcom,rpmpd.txt  |  49 ++
 arch/arm64/boot/dts/qcom/msm8996.dtsi         |  34 ++
 drivers/soc/qcom/Kconfig                      |  18 +
 drivers/soc/qcom/Makefile                     |   2 +
 drivers/soc/qcom/rpmhpd.c                     | 437 ++++++++++++++++++
 drivers/soc/qcom/rpmpd.c                      | 356 ++++++++++++++
 include/dt-bindings/power/qcom-rpmhpd.h       |  31 ++
 include/dt-bindings/power/qcom-rpmpd.h        |  16 +
 9 files changed, 1008 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmhpd.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-rpmhpd.h
 create mode 100644 include/dt-bindings/power/qcom-rpmpd.h

Comments

Ulf Hansson June 12, 2018, 7:47 a.m. UTC | #1
On 12 June 2018 at 06:40, Rajendra Nayak <rnayak@codeaurora.org> wrote:
> 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 powerdomain 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 powerdomain driver to communicate corner/level
> values for qualcomm platforms to RPM (Remote Power Manager) and RPMh.
>
> Rajendra Nayak (7):
>   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
>   dt-bindings: power: Add qcom rpmh power domain driver bindings
>   soc: qcom: Add RPMh Power domain driver
>   soc: qcom: rpmpd/rpmhpd: Add a max vote on all corners at init
>
>  .../devicetree/bindings/power/qcom,rpmhpd.txt |  65 +++
>  .../devicetree/bindings/power/qcom,rpmpd.txt  |  49 ++
>  arch/arm64/boot/dts/qcom/msm8996.dtsi         |  34 ++
>  drivers/soc/qcom/Kconfig                      |  18 +
>  drivers/soc/qcom/Makefile                     |   2 +
>  drivers/soc/qcom/rpmhpd.c                     | 437 ++++++++++++++++++
>  drivers/soc/qcom/rpmpd.c                      | 356 ++++++++++++++
>  include/dt-bindings/power/qcom-rpmhpd.h       |  31 ++
>  include/dt-bindings/power/qcom-rpmpd.h        |  16 +
>  9 files changed, 1008 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmhpd.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-rpmhpd.h
>  create mode 100644 include/dt-bindings/power/qcom-rpmpd.h
>
> --
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
>

For the series:

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

Kind regards
Uffe
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Collins June 13, 2018, 10:28 p.m. UTC | #2
Hello Rajendra,

On 06/11/2018 09:40 PM, Rajendra Nayak wrote:
> As we move from no clients/consumers in kernel voting on corners,
> to *some* voting and some not voting, we might end up in a situation
> where the clients which remove votes can adversly impact others

s/adversly/adversely/

> who still don't have a way to vote.
> 
> To avoid this situation, have a max vote on all corners at init.
> This should/can be removed once we have all clients moved to
> be able to vote/unvote for themselves.

This change seems like a hack.  Do you intend for it to be merged and then
later reverted in Linus's tree?  Could it instead be implemented in a way
that does not require reverting and instead is enabled by some DT
property?  Alternatively, could this feature be added to the power domain
core since it is relatively generic?


> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
>  drivers/soc/qcom/rpmhpd.c | 12 +++++++++++-
>  drivers/soc/qcom/rpmpd.c  |  9 +++++++++
>  2 files changed, 20 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
> index 7083ec1590ff..3c753d33aeee 100644
> --- a/drivers/soc/qcom/rpmhpd.c
> +++ b/drivers/soc/qcom/rpmhpd.c
> @@ -329,7 +329,7 @@ static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd)
>  
>  static int rpmhpd_probe(struct platform_device *pdev)
>  {
> -	int i, ret;
> +	int i, ret, max_level;
>  	size_t num;
>  	struct genpd_onecell_data *data;
>  	struct rpmhpd **rpmhpds;
> @@ -390,6 +390,16 @@ static int rpmhpd_probe(struct platform_device *pdev)
>  		pm_genpd_init(&rpmhpds[i]->pd, NULL, true);
>  
>  		data->domains[i] = &rpmhpds[i]->pd;
> +
> +		/*
> +		 * Until we have all consumers voting on corners
> +		 * just vote the max corner on all PDs
> +		 * This should ideally be *removed* once we have
> +		 * all (most) consumers being able to vote
> +		 */
> +		max_level = rpmhpds[i]->level_count - 1;
> +		rpmhpd_set_performance(&rpmhpds[i]->pd, rpmhpds[i]->level[max_level]);
> +		rpmhpd_power_on(&rpmhpds[i]->pd);

Clearly these calls will result in max level requests being sent for all
power domains at probe time.  However, it isn't clear that this will
actually help at runtime in these two cases:

1. A consumer enables and then disables a power domain.
	- It seems like the PD would just be disabled in this case.

2. A consumer sets a non-max performance state of a power domain.
	- It seems like the PD would just be set to the new lower
	  performance state since the max vote isn't known to the
	  PD core for aggregation purposes.

Thanks,
David
Rajendra Nayak June 14, 2018, 6:35 a.m. UTC | #3
On 06/14/2018 03:58 AM, David Collins wrote:
> Hello Rajendra,
> 
> On 06/11/2018 09:40 PM, Rajendra Nayak wrote:
>> As we move from no clients/consumers in kernel voting on corners,
>> to *some* voting and some not voting, we might end up in a situation
>> where the clients which remove votes can adversly impact others
> 
> s/adversly/adversely/
> 
>> who still don't have a way to vote.
>>
>> To avoid this situation, have a max vote on all corners at init.
>> This should/can be removed once we have all clients moved to
>> be able to vote/unvote for themselves.
> 
> This change seems like a hack.  Do you intend for it to be merged and then
> later reverted in Linus's tree?  Could it instead be implemented in a way
> that does not require reverting and instead is enabled by some DT
> property?  Alternatively, could this feature be added to the power domain
> core since it is relatively generic?
> 
> 
>> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
>> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
>> ---
>>  drivers/soc/qcom/rpmhpd.c | 12 +++++++++++-
>>  drivers/soc/qcom/rpmpd.c  |  9 +++++++++
>>  2 files changed, 20 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
>> index 7083ec1590ff..3c753d33aeee 100644
>> --- a/drivers/soc/qcom/rpmhpd.c
>> +++ b/drivers/soc/qcom/rpmhpd.c
>> @@ -329,7 +329,7 @@ static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd)
>>  
>>  static int rpmhpd_probe(struct platform_device *pdev)
>>  {
>> -	int i, ret;
>> +	int i, ret, max_level;
>>  	size_t num;
>>  	struct genpd_onecell_data *data;
>>  	struct rpmhpd **rpmhpds;
>> @@ -390,6 +390,16 @@ static int rpmhpd_probe(struct platform_device *pdev)
>>  		pm_genpd_init(&rpmhpds[i]->pd, NULL, true);
>>  
>>  		data->domains[i] = &rpmhpds[i]->pd;
>> +
>> +		/*
>> +		 * Until we have all consumers voting on corners
>> +		 * just vote the max corner on all PDs
>> +		 * This should ideally be *removed* once we have
>> +		 * all (most) consumers being able to vote
>> +		 */
>> +		max_level = rpmhpds[i]->level_count - 1;
>> +		rpmhpd_set_performance(&rpmhpds[i]->pd, rpmhpds[i]->level[max_level]);
>> +		rpmhpd_power_on(&rpmhpds[i]->pd);
> 
> Clearly these calls will result in max level requests being sent for all
> power domains at probe time.  However, it isn't clear that this will
> actually help at runtime in these two cases:
> 
> 1. A consumer enables and then disables a power domain.
> 	- It seems like the PD would just be disabled in this case.
> 
> 2. A consumer sets a non-max performance state of a power domain.
> 	- It seems like the PD would just be set to the new lower
> 	  performance state since the max vote isn't known to the
> 	  PD core for aggregation purposes.

Yes, you are right. I certainly did not seem to have thought through this enough.

A need for something like this came up at a point where genpd could not deal with
devices with multiple power domains. So the concern at that point was that if some
consumers (which only need to vote on one corner) move to using this driver, while 
some others (which need to vote on multiple corners) cannot, we would end up breaking
them.

That does not seem to be true anymore since we do have patches from Ulf which support
having devices with multiple power domains attached which can be controlled individually.
So if some consumer voting makes some others break, they should just be fixed and patched
to vote as well. If all this gets handled centrally from within the clock drivers then we
most likely won't even end up with a situation like this.

I think I will just drop this one unless Stephen/Viresh still see an issue with some early
voters breaking others.
Viresh Kumar June 19, 2018, 10:10 a.m. UTC | #4
On 14-06-18, 12:05, Rajendra Nayak wrote:
> On 06/14/2018 03:58 AM, David Collins wrote:
> > Hello Rajendra,
> > 
> > On 06/11/2018 09:40 PM, Rajendra Nayak wrote:
> >> As we move from no clients/consumers in kernel voting on corners,
> >> to *some* voting and some not voting, we might end up in a situation
> >> where the clients which remove votes can adversly impact others
> > 
> > s/adversly/adversely/
> > 
> >> who still don't have a way to vote.
> >>
> >> To avoid this situation, have a max vote on all corners at init.
> >> This should/can be removed once we have all clients moved to
> >> be able to vote/unvote for themselves.
> > 
> > This change seems like a hack.  Do you intend for it to be merged and then
> > later reverted in Linus's tree?  Could it instead be implemented in a way
> > that does not require reverting and instead is enabled by some DT
> > property?  Alternatively, could this feature be added to the power domain
> > core since it is relatively generic?
> > 
> > 
> >> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
> >> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> >> ---
> >>  drivers/soc/qcom/rpmhpd.c | 12 +++++++++++-
> >>  drivers/soc/qcom/rpmpd.c  |  9 +++++++++
> >>  2 files changed, 20 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
> >> index 7083ec1590ff..3c753d33aeee 100644
> >> --- a/drivers/soc/qcom/rpmhpd.c
> >> +++ b/drivers/soc/qcom/rpmhpd.c
> >> @@ -329,7 +329,7 @@ static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd)
> >>  
> >>  static int rpmhpd_probe(struct platform_device *pdev)
> >>  {
> >> -	int i, ret;
> >> +	int i, ret, max_level;
> >>  	size_t num;
> >>  	struct genpd_onecell_data *data;
> >>  	struct rpmhpd **rpmhpds;
> >> @@ -390,6 +390,16 @@ static int rpmhpd_probe(struct platform_device *pdev)
> >>  		pm_genpd_init(&rpmhpds[i]->pd, NULL, true);
> >>  
> >>  		data->domains[i] = &rpmhpds[i]->pd;
> >> +
> >> +		/*
> >> +		 * Until we have all consumers voting on corners
> >> +		 * just vote the max corner on all PDs
> >> +		 * This should ideally be *removed* once we have
> >> +		 * all (most) consumers being able to vote
> >> +		 */
> >> +		max_level = rpmhpds[i]->level_count - 1;
> >> +		rpmhpd_set_performance(&rpmhpds[i]->pd, rpmhpds[i]->level[max_level]);
> >> +		rpmhpd_power_on(&rpmhpds[i]->pd);
> > 
> > Clearly these calls will result in max level requests being sent for all
> > power domains at probe time.  However, it isn't clear that this will
> > actually help at runtime in these two cases:
> > 
> > 1. A consumer enables and then disables a power domain.
> > 	- It seems like the PD would just be disabled in this case.

So instead of rpmhpd_power_on() we should be doing gepnd_power_on() or whatever
the API is, so the user count stays at 1.

> > 2. A consumer sets a non-max performance state of a power domain.
> > 	- It seems like the PD would just be set to the new lower
> > 	  performance state since the max vote isn't known to the
> > 	  PD core for aggregation purposes.

Right, and that's because the patch isn't implemented properly yet. I asked to
do a fake vote from some user with their dev structure, so the vote always
stays.

> Yes, you are right. I certainly did not seem to have thought through this enough.
> 
> A need for something like this came up at a point where genpd could not deal with
> devices with multiple power domains. So the concern at that point was that if some
> consumers (which only need to vote on one corner) move to using this driver, while 
> some others (which need to vote on multiple corners) cannot, we would end up breaking
> them.
> 
> That does not seem to be true anymore since we do have patches from Ulf which support
> having devices with multiple power domains attached which can be controlled individually.
> So if some consumer voting makes some others break, they should just be fixed and patched
> to vote as well. If all this gets handled centrally from within the clock drivers then we
> most likely won't even end up with a situation like this.
> 
> I think I will just drop this one unless Stephen/Viresh still see an issue with some early
> voters breaking others.

So what if the LCD/DDR/etc are getting used at boot and someone requests a lower
vote?  Wouldn't we just break ?
Ulf Hansson June 25, 2018, 8:57 a.m. UTC | #5
On 19 June 2018 at 12:10, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> On 14-06-18, 12:05, Rajendra Nayak wrote:
>> On 06/14/2018 03:58 AM, David Collins wrote:
>> > Hello Rajendra,
>> >
>> > On 06/11/2018 09:40 PM, Rajendra Nayak wrote:
>> >> As we move from no clients/consumers in kernel voting on corners,
>> >> to *some* voting and some not voting, we might end up in a situation
>> >> where the clients which remove votes can adversly impact others
>> >
>> > s/adversly/adversely/
>> >
>> >> who still don't have a way to vote.
>> >>
>> >> To avoid this situation, have a max vote on all corners at init.
>> >> This should/can be removed once we have all clients moved to
>> >> be able to vote/unvote for themselves.
>> >
>> > This change seems like a hack.  Do you intend for it to be merged and then
>> > later reverted in Linus's tree?  Could it instead be implemented in a way
>> > that does not require reverting and instead is enabled by some DT
>> > property?  Alternatively, could this feature be added to the power domain
>> > core since it is relatively generic?
>> >
>> >
>> >> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
>> >> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
>> >> ---
>> >>  drivers/soc/qcom/rpmhpd.c | 12 +++++++++++-
>> >>  drivers/soc/qcom/rpmpd.c  |  9 +++++++++
>> >>  2 files changed, 20 insertions(+), 1 deletion(-)
>> >>
>> >> diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
>> >> index 7083ec1590ff..3c753d33aeee 100644
>> >> --- a/drivers/soc/qcom/rpmhpd.c
>> >> +++ b/drivers/soc/qcom/rpmhpd.c
>> >> @@ -329,7 +329,7 @@ static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd)
>> >>
>> >>  static int rpmhpd_probe(struct platform_device *pdev)
>> >>  {
>> >> -  int i, ret;
>> >> +  int i, ret, max_level;
>> >>    size_t num;
>> >>    struct genpd_onecell_data *data;
>> >>    struct rpmhpd **rpmhpds;
>> >> @@ -390,6 +390,16 @@ static int rpmhpd_probe(struct platform_device *pdev)
>> >>            pm_genpd_init(&rpmhpds[i]->pd, NULL, true);
>> >>
>> >>            data->domains[i] = &rpmhpds[i]->pd;
>> >> +
>> >> +          /*
>> >> +           * Until we have all consumers voting on corners
>> >> +           * just vote the max corner on all PDs
>> >> +           * This should ideally be *removed* once we have
>> >> +           * all (most) consumers being able to vote
>> >> +           */
>> >> +          max_level = rpmhpds[i]->level_count - 1;
>> >> +          rpmhpd_set_performance(&rpmhpds[i]->pd, rpmhpds[i]->level[max_level]);
>> >> +          rpmhpd_power_on(&rpmhpds[i]->pd);
>> >
>> > Clearly these calls will result in max level requests being sent for all
>> > power domains at probe time.  However, it isn't clear that this will
>> > actually help at runtime in these two cases:
>> >
>> > 1. A consumer enables and then disables a power domain.
>> >     - It seems like the PD would just be disabled in this case.
>
> So instead of rpmhpd_power_on() we should be doing gepnd_power_on() or whatever
> the API is, so the user count stays at 1.

There is no such API.

Instead a device needs to be attached to genpd and that's it. As long
as the device don't enables runtime PM and that the device gets
runtime suspended, genpd will remain powered on.

>
>> > 2. A consumer sets a non-max performance state of a power domain.
>> >     - It seems like the PD would just be set to the new lower
>> >       performance state since the max vote isn't known to the
>> >       PD core for aggregation purposes.
>
> Right, and that's because the patch isn't implemented properly yet. I asked to
> do a fake vote from some user with their dev structure, so the vote always
> stays.
>
>> Yes, you are right. I certainly did not seem to have thought through this enough.
>>
>> A need for something like this came up at a point where genpd could not deal with
>> devices with multiple power domains. So the concern at that point was that if some
>> consumers (which only need to vote on one corner) move to using this driver, while
>> some others (which need to vote on multiple corners) cannot, we would end up breaking
>> them.
>>
>> That does not seem to be true anymore since we do have patches from Ulf which support
>> having devices with multiple power domains attached which can be controlled individually.
>> So if some consumer voting makes some others break, they should just be fixed and patched
>> to vote as well. If all this gets handled centrally from within the clock drivers then we
>> most likely won't even end up with a situation like this.
>>
>> I think I will just drop this one unless Stephen/Viresh still see an issue with some early
>> voters breaking others.
>
> So what if the LCD/DDR/etc are getting used at boot and someone requests a lower
> vote?  Wouldn't we just break ?

Sounds like we need a way to manage votes for "boot constraints
performance levels". :-)

Anyway, to deal with this via the existing genpd APIs, we need to
attach a device to a genpd and then call
dev_pm_genpd_set_performance_state() on it. I guess at a late
initcall, the votes can be dropped and the device can be detached. Or
something along these lines.

Kind regards
Uffe
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rajendra Nayak June 25, 2018, 10:10 a.m. UTC | #6
On 06/25/2018 02:27 PM, Ulf Hansson wrote:
> On 19 June 2018 at 12:10, Viresh Kumar <viresh.kumar@linaro.org> wrote:
>> On 14-06-18, 12:05, Rajendra Nayak wrote:
>>> On 06/14/2018 03:58 AM, David Collins wrote:
>>>> Hello Rajendra,
>>>>
>>>> On 06/11/2018 09:40 PM, Rajendra Nayak wrote:
>>>>> As we move from no clients/consumers in kernel voting on corners,
>>>>> to *some* voting and some not voting, we might end up in a situation
>>>>> where the clients which remove votes can adversly impact others
>>>>
>>>> s/adversly/adversely/
>>>>
>>>>> who still don't have a way to vote.
>>>>>
>>>>> To avoid this situation, have a max vote on all corners at init.
>>>>> This should/can be removed once we have all clients moved to
>>>>> be able to vote/unvote for themselves.
>>>>
>>>> This change seems like a hack.  Do you intend for it to be merged and then
>>>> later reverted in Linus's tree?  Could it instead be implemented in a way
>>>> that does not require reverting and instead is enabled by some DT
>>>> property?  Alternatively, could this feature be added to the power domain
>>>> core since it is relatively generic?
>>>>
>>>>
>>>>> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
>>>>> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
>>>>> ---
>>>>>  drivers/soc/qcom/rpmhpd.c | 12 +++++++++++-
>>>>>  drivers/soc/qcom/rpmpd.c  |  9 +++++++++
>>>>>  2 files changed, 20 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
>>>>> index 7083ec1590ff..3c753d33aeee 100644
>>>>> --- a/drivers/soc/qcom/rpmhpd.c
>>>>> +++ b/drivers/soc/qcom/rpmhpd.c
>>>>> @@ -329,7 +329,7 @@ static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd)
>>>>>
>>>>>  static int rpmhpd_probe(struct platform_device *pdev)
>>>>>  {
>>>>> -  int i, ret;
>>>>> +  int i, ret, max_level;
>>>>>    size_t num;
>>>>>    struct genpd_onecell_data *data;
>>>>>    struct rpmhpd **rpmhpds;
>>>>> @@ -390,6 +390,16 @@ static int rpmhpd_probe(struct platform_device *pdev)
>>>>>            pm_genpd_init(&rpmhpds[i]->pd, NULL, true);
>>>>>
>>>>>            data->domains[i] = &rpmhpds[i]->pd;
>>>>> +
>>>>> +          /*
>>>>> +           * Until we have all consumers voting on corners
>>>>> +           * just vote the max corner on all PDs
>>>>> +           * This should ideally be *removed* once we have
>>>>> +           * all (most) consumers being able to vote
>>>>> +           */
>>>>> +          max_level = rpmhpds[i]->level_count - 1;
>>>>> +          rpmhpd_set_performance(&rpmhpds[i]->pd, rpmhpds[i]->level[max_level]);
>>>>> +          rpmhpd_power_on(&rpmhpds[i]->pd);
>>>>
>>>> Clearly these calls will result in max level requests being sent for all
>>>> power domains at probe time.  However, it isn't clear that this will
>>>> actually help at runtime in these two cases:
>>>>
>>>> 1. A consumer enables and then disables a power domain.
>>>>     - It seems like the PD would just be disabled in this case.
>>
>> So instead of rpmhpd_power_on() we should be doing gepnd_power_on() or whatever
>> the API is, so the user count stays at 1.
> 
> There is no such API.
> 
> Instead a device needs to be attached to genpd and that's it. As long
> as the device don't enables runtime PM and that the device gets
> runtime suspended, genpd will remain powered on.

Its more to do with keeping the power domains at a desired 'performance level'
than just keeping them on.

> 
>>
>>>> 2. A consumer sets a non-max performance state of a power domain.
>>>>     - It seems like the PD would just be set to the new lower
>>>>       performance state since the max vote isn't known to the
>>>>       PD core for aggregation purposes.
>>
>> Right, and that's because the patch isn't implemented properly yet. I asked to
>> do a fake vote from some user with their dev structure, so the vote always
>> stays.
>>
>>> Yes, you are right. I certainly did not seem to have thought through this enough.
>>>
>>> A need for something like this came up at a point where genpd could not deal with
>>> devices with multiple power domains. So the concern at that point was that if some
>>> consumers (which only need to vote on one corner) move to using this driver, while
>>> some others (which need to vote on multiple corners) cannot, we would end up breaking
>>> them.
>>>
>>> That does not seem to be true anymore since we do have patches from Ulf which support
>>> having devices with multiple power domains attached which can be controlled individually.
>>> So if some consumer voting makes some others break, they should just be fixed and patched
>>> to vote as well. If all this gets handled centrally from within the clock drivers then we
>>> most likely won't even end up with a situation like this.
>>>
>>> I think I will just drop this one unless Stephen/Viresh still see an issue with some early
>>> voters breaking others.
>>
>> So what if the LCD/DDR/etc are getting used at boot and someone requests a lower
>> vote?  Wouldn't we just break ?
> 
> Sounds like we need a way to manage votes for "boot constraints
> performance levels". :-)

Yes, I think we are mixing up whats needed for 'boot constraints' and what this
patch was meant to do.
Boot constraints is a generic problem not limited to power domains alone and this patch
isn't trying to solve that.