mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/3] genpd: imx8: support multiple states
@ 2023-09-13  2:05 Peng Fan (OSS)
  2023-09-13  2:05 ` [PATCH 1/3] PM / Domains: Support enter deepest state for multiple states domains Peng Fan (OSS)
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Peng Fan (OSS) @ 2023-09-13  2:05 UTC (permalink / raw)
  To: Rafael J. Wysocki, Kevin Hilman, Ulf Hansson, Len Brown,
	Pavel Machek, Greg Kroah-Hartman, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team
  Cc: linux-pm, linux-kernel, linux-arm-kernel, Dong Aisheng, Peng Fan

Patch 1 & 2 are for common code.
Patch 3 is almost same as https://lore.kernel.org/all/20230814104127.1929-8-peng.fan@oss.nxp.com/
For patch 3, I thought of using QoS constraint in the clk-scu driver,
but the clk-scu not support runtime pm, and using simple_qos_governer
would introduce complexity for current SCU Power domain, and the SCU
power domain not only used by clk-scu, but also used by other devices.
So keep current design as NXP downstream which has passed several
rounds LTS releases.

Patch 1&2 has been in NXP LTS for quite some time and pass through
several releases. patch 3 is an update of NXP downstream patch.

---
Dong Aisheng (2):
      PM / Domains: Support enter deepest state for multiple states domains
      PM / Domains: Choose the deepest state to enter if no devices using it

Peng Fan (1):
      genpd: imx: scu-pd: add multi states support

 drivers/base/power/domain.c | 22 +++++++++++++++++++++-
 drivers/genpd/imx/scu-pd.c  | 42 ++++++++++++++++++++++++++++++++++++++++--
 include/linux/pm_domain.h   |  1 +
 3 files changed, 62 insertions(+), 3 deletions(-)
---
base-commit: 3c13c772fc233a10342c8e1605ff0855dfdf0c89
change-id: 20230913-multiple-state-scu-8ddcb0373d3c

Best regards,
-- 
Peng Fan <peng.fan@nxp.com>


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

* [PATCH 1/3] PM / Domains: Support enter deepest state for multiple states domains
  2023-09-13  2:05 [PATCH 0/3] genpd: imx8: support multiple states Peng Fan (OSS)
@ 2023-09-13  2:05 ` Peng Fan (OSS)
  2023-09-13  2:05 ` [PATCH 2/3] PM / Domains: Choose the deepest state to enter if no devices using it Peng Fan (OSS)
  2023-09-13  2:05 ` [PATCH 3/3] genpd: imx: scu-pd: add multi states support Peng Fan (OSS)
  2 siblings, 0 replies; 4+ messages in thread
From: Peng Fan (OSS) @ 2023-09-13  2:05 UTC (permalink / raw)
  To: Rafael J. Wysocki, Kevin Hilman, Ulf Hansson, Len Brown,
	Pavel Machek, Greg Kroah-Hartman, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team
  Cc: linux-pm, linux-kernel, linux-arm-kernel, Dong Aisheng, Peng Fan

From: Dong Aisheng <aisheng.dong@nxp.com>

Currently the generic power domain will power off the domain if all
devices in it have been stopped during system suspend.

It is done by checking if the domain is active in genpd_sync_power_off,
then disable it. However, for power domains supporting multiple low power
states, it may have already entered an intermediate low power state by
runtime PM before system suspend and the status is already
GPD_STATE_POWER_OFF which results in then the power domain stay at an
intermediate low power state during system suspend.
Then genpd_sync_power_off will keep it at the low power state instead
of completely gate off it.

Let's give the power domain a chance to switch to the deepest state in
case it's already off but in an intermediate low power state.

Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/base/power/domain.c | 18 +++++++++++++++++-
 include/linux/pm_domain.h   |  1 +
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 5cb2023581d4..22cfa3020b18 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1124,7 +1124,17 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
 {
 	struct gpd_link *link;
 
-	if (!genpd_status_on(genpd) || genpd_is_always_on(genpd))
+	/*
+	 * Give the power domain a chance to switch to the deepest state in
+	 * case it's already off but in an intermediate low power state.
+	 */
+	genpd->state_idx_saved = genpd->state_idx;
+
+	if (genpd_is_always_on(genpd))
+		return;
+
+	if (!genpd_status_on(genpd) &&
+	    genpd->state_idx == (genpd->state_count - 1))
 		return;
 
 	if (genpd->suspended_count != genpd->device_count
@@ -1143,6 +1153,9 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
 	if (_genpd_power_off(genpd, false))
 		return;
 
+	if (genpd->status == GENPD_STATE_OFF)
+		return;
+
 	genpd->status = GENPD_STATE_OFF;
 
 	list_for_each_entry(link, &genpd->child_links, child_node) {
@@ -1189,6 +1202,9 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock,
 	}
 
 	_genpd_power_on(genpd, false);
+	/* restore save power domain state after resume */
+	genpd->state_idx = genpd->state_idx_saved;
+
 	genpd->status = GENPD_STATE_ON;
 }
 
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index f776fb93eaa0..bbd08115a1fc 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -167,6 +167,7 @@ struct generic_pm_domain {
 		};
 	};
 
+	unsigned int state_idx_saved; /* saved power state for recovery after system suspend/resume */
 };
 
 static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)

-- 
2.37.1


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

* [PATCH 2/3] PM / Domains: Choose the deepest state to enter if no devices using it
  2023-09-13  2:05 [PATCH 0/3] genpd: imx8: support multiple states Peng Fan (OSS)
  2023-09-13  2:05 ` [PATCH 1/3] PM / Domains: Support enter deepest state for multiple states domains Peng Fan (OSS)
@ 2023-09-13  2:05 ` Peng Fan (OSS)
  2023-09-13  2:05 ` [PATCH 3/3] genpd: imx: scu-pd: add multi states support Peng Fan (OSS)
  2 siblings, 0 replies; 4+ messages in thread
From: Peng Fan (OSS) @ 2023-09-13  2:05 UTC (permalink / raw)
  To: Rafael J. Wysocki, Kevin Hilman, Ulf Hansson, Len Brown,
	Pavel Machek, Greg Kroah-Hartman, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team
  Cc: linux-pm, linux-kernel, linux-arm-kernel, Dong Aisheng, Peng Fan

From: Dong Aisheng <aisheng.dong@nxp.com>

For a domain has no working devices anymore, let's choose the deepest state
to enter to save power. e.g. driver probe failure.

Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/base/power/domain.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 22cfa3020b18..1887eb1b3130 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -730,6 +730,10 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
 	if (atomic_read(&genpd->sd_count) > 0)
 		return -EBUSY;
 
+	/* Choose the deepest state if no devices using this domain */
+	if (!genpd->device_count)
+		genpd->state_idx = genpd->state_count - 1;
+
 	ret = _genpd_power_off(genpd, true);
 	if (ret) {
 		genpd->states[genpd->state_idx].rejected++;

-- 
2.37.1


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

* [PATCH 3/3] genpd: imx: scu-pd: add multi states support
  2023-09-13  2:05 [PATCH 0/3] genpd: imx8: support multiple states Peng Fan (OSS)
  2023-09-13  2:05 ` [PATCH 1/3] PM / Domains: Support enter deepest state for multiple states domains Peng Fan (OSS)
  2023-09-13  2:05 ` [PATCH 2/3] PM / Domains: Choose the deepest state to enter if no devices using it Peng Fan (OSS)
@ 2023-09-13  2:05 ` Peng Fan (OSS)
  2 siblings, 0 replies; 4+ messages in thread
From: Peng Fan (OSS) @ 2023-09-13  2:05 UTC (permalink / raw)
  To: Rafael J. Wysocki, Kevin Hilman, Ulf Hansson, Len Brown,
	Pavel Machek, Greg Kroah-Hartman, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team
  Cc: linux-pm, linux-kernel, linux-arm-kernel, Peng Fan

From: Peng Fan <peng.fan@nxp.com>

Add multi states support, this is to support devices could run in LP mode
when runtime suspend, and OFF mode when system suspend.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/genpd/imx/scu-pd.c | 42 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/genpd/imx/scu-pd.c b/drivers/genpd/imx/scu-pd.c
index 2f693b67ddb4..f1a43cb0bf79 100644
--- a/drivers/genpd/imx/scu-pd.c
+++ b/drivers/genpd/imx/scu-pd.c
@@ -368,7 +368,8 @@ static int imx_sc_pd_power(struct generic_pm_domain *domain, bool power_on)
 	hdr->size = 2;
 
 	msg.resource = pd->rsrc;
-	msg.mode = power_on ? IMX_SC_PM_PW_MODE_ON : IMX_SC_PM_PW_MODE_LP;
+	msg.mode = power_on ? IMX_SC_PM_PW_MODE_ON : pd->pd.state_idx ?
+		   IMX_SC_PM_PW_MODE_OFF : IMX_SC_PM_PW_MODE_LP;
 
 	/* keep uart console power on for no_console_suspend */
 	if (imx_con_rsrc == pd->rsrc && !console_suspend_enabled && !power_on)
@@ -412,11 +413,33 @@ static struct generic_pm_domain *imx_scu_pd_xlate(struct of_phandle_args *spec,
 	return domain;
 }
 
+static bool imx_sc_pd_suspend_ok(struct device *dev)
+{
+	/* Always true */
+	return true;
+}
+
+static bool imx_sc_pd_power_down_ok(struct dev_pm_domain *pd)
+{
+	struct generic_pm_domain *genpd = pd_to_genpd(pd);
+
+	/* For runtime suspend, choose LP mode */
+	genpd->state_idx = 0;
+
+	return true;
+}
+
+struct dev_power_governor imx_sc_pd_qos_governor = {
+	.suspend_ok = imx_sc_pd_suspend_ok,
+	.power_down_ok = imx_sc_pd_power_down_ok,
+};
+
 static struct imx_sc_pm_domain *
 imx_scu_add_pm_domain(struct device *dev, int idx,
 		      const struct imx_sc_pd_range *pd_ranges)
 {
 	struct imx_sc_pm_domain *sc_pd;
+	struct genpd_power_state *states;
 	bool is_off;
 	int mode, ret;
 
@@ -427,9 +450,22 @@ imx_scu_add_pm_domain(struct device *dev, int idx,
 	if (!sc_pd)
 		return ERR_PTR(-ENOMEM);
 
+	states = devm_kcalloc(dev, PD_STATE_MAX, sizeof(*states), GFP_KERNEL);
+	if (!states) {
+		devm_kfree(dev, sc_pd);
+		return ERR_PTR(-ENOMEM);
+	}
+
 	sc_pd->rsrc = pd_ranges->rsrc + idx;
 	sc_pd->pd.power_off = imx_sc_pd_power_off;
 	sc_pd->pd.power_on = imx_sc_pd_power_on;
+	states[PD_STATE_LP].power_off_latency_ns = 25000;
+	states[PD_STATE_LP].power_on_latency_ns =  25000;
+	states[PD_STATE_OFF].power_off_latency_ns = 2500000;
+	states[PD_STATE_OFF].power_on_latency_ns =  2500000;
+
+	sc_pd->pd.states = states;
+	sc_pd->pd.state_count = PD_STATE_MAX;
 
 	if (pd_ranges->postfix)
 		snprintf(sc_pd->name, sizeof(sc_pd->name),
@@ -455,14 +491,16 @@ imx_scu_add_pm_domain(struct device *dev, int idx,
 			 sc_pd->name, sc_pd->rsrc);
 
 		devm_kfree(dev, sc_pd);
+		devm_kfree(dev, states);
 		return NULL;
 	}
 
-	ret = pm_genpd_init(&sc_pd->pd, NULL, is_off);
+	ret = pm_genpd_init(&sc_pd->pd, &imx_sc_pd_qos_governor, is_off);
 	if (ret) {
 		dev_warn(dev, "failed to init pd %s rsrc id %d",
 			 sc_pd->name, sc_pd->rsrc);
 		devm_kfree(dev, sc_pd);
+		devm_kfree(dev, states);
 		return NULL;
 	}
 

-- 
2.37.1


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

end of thread, other threads:[~2023-09-13  2:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-13  2:05 [PATCH 0/3] genpd: imx8: support multiple states Peng Fan (OSS)
2023-09-13  2:05 ` [PATCH 1/3] PM / Domains: Support enter deepest state for multiple states domains Peng Fan (OSS)
2023-09-13  2:05 ` [PATCH 2/3] PM / Domains: Choose the deepest state to enter if no devices using it Peng Fan (OSS)
2023-09-13  2:05 ` [PATCH 3/3] genpd: imx: scu-pd: add multi states support Peng Fan (OSS)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®