All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] PM / Domains: Add support for 'required-opps' to set default perf state
@ 2021-07-16  5:13 Rajendra Nayak
  2021-07-16  5:13 ` [PATCH v3 1/2] " Rajendra Nayak
  2021-07-16  5:13 ` [PATCH v3 2/2] arm64: dts: sc7180: Add required-opps for i2c Rajendra Nayak
  0 siblings, 2 replies; 4+ messages in thread
From: Rajendra Nayak @ 2021-07-16  5:13 UTC (permalink / raw)
  To: ulf.hansson, bjorn.andersson, viresh.kumar
  Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, swboyd, rojay,
	stephan, Rajendra Nayak

This is a re-spin of the series [1] which was adding support for a new
DT binding (assigned-performance-state) and based on the discussions on
that thread [2] it was concluded that we could achieve the same with the
existing 'required-opps' binding instead.

So this series, just drops the new binding and uses required-opps to achieve
the default perf state setting thats needed by some devices.

---
Some devics within power-domains with performance states do not
support DVFS, but still need to vote on a default/static state
while they are active. Add support for this using the 'required-opps'
property in device tree.

[1] https://lore.kernel.org/patchwork/project/lkml/list/?series=501336&state=%2A&archive=both
[2] https://lore.kernel.org/patchwork/patch/1436886/

Rajendra Nayak (2):
  PM / Domains: Add support for 'required-opps' to set default perf
    state
  arm64: dts: sc7180: Add required-opps for i2c

 arch/arm64/boot/dts/qcom/sc7180.dtsi | 24 ++++++++++++++++++++++++
 drivers/base/power/domain.c          | 27 +++++++++++++++++++++++++++
 include/linux/pm_domain.h            |  1 +
 3 files changed, 52 insertions(+)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3 1/2] PM / Domains: Add support for 'required-opps' to set default perf state
  2021-07-16  5:13 [PATCH v3 0/2] PM / Domains: Add support for 'required-opps' to set default perf state Rajendra Nayak
@ 2021-07-16  5:13 ` Rajendra Nayak
  2021-07-16  9:29   ` Rajendra Nayak
  2021-07-16  5:13 ` [PATCH v3 2/2] arm64: dts: sc7180: Add required-opps for i2c Rajendra Nayak
  1 sibling, 1 reply; 4+ messages in thread
From: Rajendra Nayak @ 2021-07-16  5:13 UTC (permalink / raw)
  To: ulf.hansson, bjorn.andersson, viresh.kumar
  Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, swboyd, rojay,
	stephan, Rajendra Nayak

Some devics within power domains with performance states do not
support DVFS, but still need to vote on a default/static state
while they are active. They can express this using the 'required-opps'
property in device tree, which points to the phandle of the OPP
supported by the corresponding power-domains.

Add support to parse this information from DT and then set the
specified performance state during attach and drop it on detach.
Also drop/set as part of runtime suspend/resume callbacks.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
 drivers/base/power/domain.c | 29 ++++++++++++++++++++++++++++-
 include/linux/pm_domain.h   |  1 +
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index a934c67..eef5507 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -917,6 +917,10 @@ static int genpd_runtime_suspend(struct device *dev)
 	if (irq_safe_dev_in_no_sleep_domain(dev, genpd))
 		return 0;
 
+	/* Drop the default performance state */
+	if (dev_gpd_data(dev)->default_pstate)
+		dev_pm_genpd_set_performance_state(dev, 0);
+
 	genpd_lock(genpd);
 	gpd_data->rpm_pstate = genpd_drop_performance_state(dev);
 	genpd_power_off(genpd, true, 0);
@@ -937,6 +941,7 @@ static int genpd_runtime_resume(struct device *dev)
 {
 	struct generic_pm_domain *genpd;
 	struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev);
+	unsigned int default_pstate = gpd_data->default_pstate;
 	struct gpd_timing_data *td = &gpd_data->td;
 	bool runtime_pm = pm_runtime_enabled(dev);
 	ktime_t time_start;
@@ -968,6 +973,9 @@ static int genpd_runtime_resume(struct device *dev)
 	if (ret)
 		return ret;
 
+	/* Set the default performance state */
+	if (default_pstate)
+		dev_pm_genpd_set_performance_state(dev, default_pstate);
  out:
 	/* Measure resume latency. */
 	time_start = 0;
@@ -1000,6 +1008,8 @@ static int genpd_runtime_resume(struct device *dev)
 	genpd_stop_dev(genpd, dev);
 err_poweroff:
 	if (!pm_runtime_is_irq_safe(dev) || genpd_is_irq_safe(genpd)) {
+		if (default_pstate)
+			dev_pm_genpd_set_performance_state(dev, 0);
 		genpd_lock(genpd);
 		gpd_data->rpm_pstate = genpd_drop_performance_state(dev);
 		genpd_power_off(genpd, true, 0);
@@ -2598,6 +2608,12 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
 
 	dev_dbg(dev, "removing from PM domain %s\n", pd->name);
 
+	/* Drop the default performance state */
+	if (dev_gpd_data(dev)->default_pstate) {
+		dev_pm_genpd_set_performance_state(dev, 0);
+		dev_gpd_data(dev)->default_pstate = 0;
+	}
+
 	for (i = 1; i < GENPD_RETRY_MAX_MS; i <<= 1) {
 		ret = genpd_remove_device(pd, dev);
 		if (ret != -EAGAIN)
@@ -2635,9 +2651,10 @@ static void genpd_dev_pm_sync(struct device *dev)
 static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev,
 				 unsigned int index, bool power_on)
 {
+	struct device_node *np;
 	struct of_phandle_args pd_args;
 	struct generic_pm_domain *pd;
-	int ret;
+	int ret, pstate;
 
 	ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
 				"#power-domain-cells", index, &pd_args);
@@ -2678,6 +2695,16 @@ static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev,
 	if (ret)
 		genpd_remove_device(pd, dev);
 
+	/* Set the default performance state */
+	np = base_dev->of_node;
+	if (of_parse_phandle(np, "required-opps", index)) {
+		pstate = of_get_required_opp_performance_state(np, index);
+		if (pstate > 0) {
+			dev_pm_genpd_set_performance_state(dev, pstate);
+			dev_gpd_data(dev)->default_pstate = pstate;
+		}
+	}
+
 	return ret ? -EPROBE_DEFER : 1;
 }
 
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 21a0577..67017c9 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -198,6 +198,7 @@ struct generic_pm_domain_data {
 	struct notifier_block *power_nb;
 	int cpu;
 	unsigned int performance_state;
+	unsigned int default_pstate;
 	unsigned int rpm_pstate;
 	ktime_t	next_wakeup;
 	void *data;
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/2] arm64: dts: sc7180: Add required-opps for i2c
  2021-07-16  5:13 [PATCH v3 0/2] PM / Domains: Add support for 'required-opps' to set default perf state Rajendra Nayak
  2021-07-16  5:13 ` [PATCH v3 1/2] " Rajendra Nayak
@ 2021-07-16  5:13 ` Rajendra Nayak
  1 sibling, 0 replies; 4+ messages in thread
From: Rajendra Nayak @ 2021-07-16  5:13 UTC (permalink / raw)
  To: ulf.hansson, bjorn.andersson, viresh.kumar
  Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, swboyd, rojay,
	stephan, Rajendra Nayak

qup-i2c devices on sc7180 are clocked with a fixed clock (19.2 MHz)
Though qup-i2c does not support DVFS, it still needs to vote for a
performance state on 'CX' to satisfy the 19.2 Mhz clock frequency
requirement.

Use 'required-opps' to pass this information from
device tree, and also add the power-domains property to specify
the CX power-domain.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
 arch/arm64/boot/dts/qcom/sc7180.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index a5d58eb..cd30185 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -785,8 +785,10 @@
 						<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
 						<&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
 				interconnect-names = "qup-core", "qup-config",
 							"qup-memory";
+				power-domains = <&rpmhpd SC7180_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
 				status = "disabled";
 			};
 
 			spi0: spi@880000 {
@@ -837,8 +839,10 @@
 						<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
 						<&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
 				interconnect-names = "qup-core", "qup-config",
 							"qup-memory";
+				power-domains = <&rpmhpd SC7180_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
 				status = "disabled";
 			};
 
 			spi1: spi@884000 {
@@ -889,8 +893,10 @@
 						<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
 						<&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
 				interconnect-names = "qup-core", "qup-config",
 							"qup-memory";
+				power-domains = <&rpmhpd SC7180_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
 				status = "disabled";
 			};
 
 			uart2: serial@888000 {
@@ -923,8 +929,10 @@
 						<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
 						<&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
 				interconnect-names = "qup-core", "qup-config",
 							"qup-memory";
+				power-domains = <&rpmhpd SC7180_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
 				status = "disabled";
 			};
 
 			spi3: spi@88c000 {
@@ -975,8 +983,10 @@
 						<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
 						<&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
 				interconnect-names = "qup-core", "qup-config",
 							"qup-memory";
+				power-domains = <&rpmhpd SC7180_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
 				status = "disabled";
 			};
 
 			uart4: serial@890000 {
@@ -1009,8 +1019,10 @@
 						<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
 						<&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
 				interconnect-names = "qup-core", "qup-config",
 							"qup-memory";
+				power-domains = <&rpmhpd SC7180_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
 				status = "disabled";
 			};
 
 			spi5: spi@894000 {
@@ -1074,8 +1086,10 @@
 						<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
 						<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
 				interconnect-names = "qup-core", "qup-config",
 							"qup-memory";
+				power-domains = <&rpmhpd SC7180_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
 				status = "disabled";
 			};
 
 			spi6: spi@a80000 {
@@ -1126,8 +1140,10 @@
 						<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
 						<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
 				interconnect-names = "qup-core", "qup-config",
 							"qup-memory";
+				power-domains = <&rpmhpd SC7180_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
 				status = "disabled";
 			};
 
 			uart7: serial@a84000 {
@@ -1160,8 +1176,10 @@
 						<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
 						<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
 				interconnect-names = "qup-core", "qup-config",
 							"qup-memory";
+				power-domains = <&rpmhpd SC7180_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
 				status = "disabled";
 			};
 
 			spi8: spi@a88000 {
@@ -1212,8 +1230,10 @@
 						<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
 						<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
 				interconnect-names = "qup-core", "qup-config",
 							"qup-memory";
+				power-domains = <&rpmhpd SC7180_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
 				status = "disabled";
 			};
 
 			uart9: serial@a8c000 {
@@ -1246,8 +1266,10 @@
 						<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
 						<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
 				interconnect-names = "qup-core", "qup-config",
 							"qup-memory";
+				power-domains = <&rpmhpd SC7180_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
 				status = "disabled";
 			};
 
 			spi10: spi@a90000 {
@@ -1298,8 +1320,10 @@
 						<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
 						<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
 				interconnect-names = "qup-core", "qup-config",
 							"qup-memory";
+				power-domains = <&rpmhpd SC7180_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
 				status = "disabled";
 			};
 
 			spi11: spi@a94000 {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 1/2] PM / Domains: Add support for 'required-opps' to set default perf state
  2021-07-16  5:13 ` [PATCH v3 1/2] " Rajendra Nayak
@ 2021-07-16  9:29   ` Rajendra Nayak
  0 siblings, 0 replies; 4+ messages in thread
From: Rajendra Nayak @ 2021-07-16  9:29 UTC (permalink / raw)
  To: ulf.hansson, bjorn.andersson, viresh.kumar
  Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, swboyd, rojay,
	stephan


On 7/16/2021 10:43 AM, Rajendra Nayak wrote:
> Some devics within power domains with performance states do not
> support DVFS, but still need to vote on a default/static state
> while they are active. They can express this using the 'required-opps'
> property in device tree, which points to the phandle of the OPP
> supported by the corresponding power-domains.
> 
> Add support to parse this information from DT and then set the
> specified performance state during attach and drop it on detach.
> Also drop/set as part of runtime suspend/resume callbacks.
> 
> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
> ---
>   drivers/base/power/domain.c | 29 ++++++++++++++++++++++++++++-
>   include/linux/pm_domain.h   |  1 +
>   2 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index a934c67..eef5507 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -917,6 +917,10 @@ static int genpd_runtime_suspend(struct device *dev)
>   	if (irq_safe_dev_in_no_sleep_domain(dev, genpd))
>   		return 0;
>   
> +	/* Drop the default performance state */
> +	if (dev_gpd_data(dev)->default_pstate)
> +		dev_pm_genpd_set_performance_state(dev, 0);
> +
>   	genpd_lock(genpd);
>   	gpd_data->rpm_pstate = genpd_drop_performance_state(dev);
>   	genpd_power_off(genpd, true, 0);
> @@ -937,6 +941,7 @@ static int genpd_runtime_resume(struct device *dev)
>   {
>   	struct generic_pm_domain *genpd;
>   	struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev);
> +	unsigned int default_pstate = gpd_data->default_pstate;
>   	struct gpd_timing_data *td = &gpd_data->td;
>   	bool runtime_pm = pm_runtime_enabled(dev);
>   	ktime_t time_start;
> @@ -968,6 +973,9 @@ static int genpd_runtime_resume(struct device *dev)
>   	if (ret)
>   		return ret;
>   
> +	/* Set the default performance state */
> +	if (default_pstate)
> +		dev_pm_genpd_set_performance_state(dev, default_pstate);
>    out:
>   	/* Measure resume latency. */
>   	time_start = 0;
> @@ -1000,6 +1008,8 @@ static int genpd_runtime_resume(struct device *dev)
>   	genpd_stop_dev(genpd, dev);
>   err_poweroff:
>   	if (!pm_runtime_is_irq_safe(dev) || genpd_is_irq_safe(genpd)) {
> +		if (default_pstate)
> +			dev_pm_genpd_set_performance_state(dev, 0);
>   		genpd_lock(genpd);
>   		gpd_data->rpm_pstate = genpd_drop_performance_state(dev);
>   		genpd_power_off(genpd, true, 0);
> @@ -2598,6 +2608,12 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
>   
>   	dev_dbg(dev, "removing from PM domain %s\n", pd->name);
>   
> +	/* Drop the default performance state */
> +	if (dev_gpd_data(dev)->default_pstate) {
> +		dev_pm_genpd_set_performance_state(dev, 0);
> +		dev_gpd_data(dev)->default_pstate = 0;
> +	}
> +
>   	for (i = 1; i < GENPD_RETRY_MAX_MS; i <<= 1) {
>   		ret = genpd_remove_device(pd, dev);
>   		if (ret != -EAGAIN)
> @@ -2635,9 +2651,10 @@ static void genpd_dev_pm_sync(struct device *dev)
>   static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev,
>   				 unsigned int index, bool power_on)
>   {
> +	struct device_node *np;
>   	struct of_phandle_args pd_args;
>   	struct generic_pm_domain *pd;
> -	int ret;
> +	int ret, pstate;
>   
>   	ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
>   				"#power-domain-cells", index, &pd_args);
> @@ -2678,6 +2695,16 @@ static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev,
>   	if (ret)
>   		genpd_remove_device(pd, dev);
>   
> +	/* Set the default performance state */
> +	np = base_dev->of_node;
> +	if (of_parse_phandle(np, "required-opps", index)) {
> +		pstate = of_get_required_opp_performance_state(np, index);
> +		if (pstate > 0) {
> +			dev_pm_genpd_set_performance_state(dev, pstate);
> +			dev_gpd_data(dev)->default_pstate = pstate;
> +		}
> +	}

I realized this needs better error handling after I sent it out,
I'll fix and respin.

> +
>   	return ret ? -EPROBE_DEFER : 1;
>   }
>   
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index 21a0577..67017c9 100644
> --- a/include/linux/pm_domain.h
> +++ b/include/linux/pm_domain.h
> @@ -198,6 +198,7 @@ struct generic_pm_domain_data {
>   	struct notifier_block *power_nb;
>   	int cpu;
>   	unsigned int performance_state;
> +	unsigned int default_pstate;
>   	unsigned int rpm_pstate;
>   	ktime_t	next_wakeup;
>   	void *data;
> 

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-07-16  9:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-16  5:13 [PATCH v3 0/2] PM / Domains: Add support for 'required-opps' to set default perf state Rajendra Nayak
2021-07-16  5:13 ` [PATCH v3 1/2] " Rajendra Nayak
2021-07-16  9:29   ` Rajendra Nayak
2021-07-16  5:13 ` [PATCH v3 2/2] arm64: dts: sc7180: Add required-opps for i2c Rajendra Nayak

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.