public inbox for linux-pm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC v2] pmdomain: ti-sci: Set PD on/off state according to the HW state
@ 2025-09-08  8:34 Tomi Valkeinen
  2025-09-11 14:38 ` Ulf Hansson
  0 siblings, 1 reply; 3+ messages in thread
From: Tomi Valkeinen @ 2025-09-08  8:34 UTC (permalink / raw)
  To: Nishanth Menon, Tero Kristo, Santosh Shilimkar, Ulf Hansson
  Cc: linux-arm-kernel, linux-pm, linux-kernel, Kevin Hilman, vishalm,
	sebin.francis, d-gole, Devarsh Thakkar, Vignesh Raghavendra,
	Tomi Valkeinen

At the moment the driver sets the power state of all the PDs it creates
to off, regardless of the actual HW state. This has two drawbacks:

1) The kernel cannot disable unused PDs automatically for power saving,
   as it thinks they are off already

2) A more specific case (but perhaps applicable to other scenarios
   also): bootloader enabled splash-screen cannot be kept on the screen.

The issue in 2) is that the driver framework automatically enables the
device's PD before calling probe() and disables it after the probe().
This means that when the display subsystem (DSS) driver probes, but e.g.
fails due to deferred probing, the DSS PD gets turned off and the driver
cannot do anything to affect that.

Solving the 2) requires more changes to actually keep the PD on during
the boot, but a prerequisite for it is to have the correct power state
for the PD.

The downside with this patch is that it takes time to call the 'is_on'
op, and we need to call it for each PD. In my tests with AM62 SK, using
defconfig, I see an increase from ~3.5ms to ~7ms. However, the added
feature is valuable, so in my opinion it's worth it.

The performance could probably be improved with a new firmware API which
returns the power states of all the PDs.

There's also a related HW issue at play here: if the DSS IP is enabled
and active, and its PD is turned off without first disabling the DSS
display outputs, the DSS IP will hang and causes the kernel to halt if
and when the DSS driver accesses the DSS registers the next time.

With the current upstream kernel, with this patch applied, this means
that if the bootloader enables the display, and the DSS driver is
compiled as a module, the kernel will at some point disable unused PDs,
including the DSS PD. When the DSS module is later loaded, it will hang
the kernel.

The same issue is already there, even without this patch, as the DSS
driver may hit deferred probing, which causes the PD to be turned off,
and leading to kernel halt when the DSS driver is probed again. This
issue has been made quite rare with some arrangements in the DSS
driver's probe, but it's still there.

With recent change from Ulf (e.g. commit 13a4b7fb6260 ("pmdomain: core:
Leave powered-on genpds on until late_initcall_sync")), the sync state
mechanism comes to rescue. It will keep the power domains enabled, until
the drivers have probed, or the sync-state is triggered via some other
mechanism (e.g. manually by the boot scripts).

Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Tested-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
Changes in v2:
- Clarify the current state wrt. sync state in the patch description
- Rebase to current upstream
- No other changes
- Link to v1: https://lore.kernel.org/r/20241022-tisci-pd-boot-state-v1-1-849a6384131b@ideasonboard.com
---
 drivers/pmdomain/ti/ti_sci_pm_domains.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c
index 82df7e44250b..e5d1934f78d9 100644
--- a/drivers/pmdomain/ti/ti_sci_pm_domains.c
+++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c
@@ -200,6 +200,23 @@ static bool ti_sci_pm_idx_exists(struct ti_sci_genpd_provider *pd_provider, u32
 	return false;
 }
 
+static bool ti_sci_pm_pd_is_on(struct ti_sci_genpd_provider *pd_provider,
+			       int pd_idx)
+{
+	bool is_on;
+	int ret;
+
+	if (!pd_provider->ti_sci->ops.dev_ops.is_on)
+		return false;
+
+	ret = pd_provider->ti_sci->ops.dev_ops.is_on(pd_provider->ti_sci,
+						     pd_idx, NULL, &is_on);
+	if (ret)
+		return false;
+
+	return is_on;
+}
+
 static int ti_sci_pm_domain_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -231,6 +248,8 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
 						   index, &args)) {
 
 			if (args.args_count >= 1 && args.np == dev->of_node) {
+				bool is_on;
+
 				of_node_put(args.np);
 				if (args.args[0] > max_id) {
 					max_id = args.args[0];
@@ -264,7 +283,10 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
 				    pd_provider->ti_sci->ops.pm_ops.set_latency_constraint)
 					pd->pd.domain.ops.suspend = ti_sci_pd_suspend;
 
-				pm_genpd_init(&pd->pd, NULL, true);
+				is_on = ti_sci_pm_pd_is_on(pd_provider,
+							   pd->idx);
+
+				pm_genpd_init(&pd->pd, NULL, !is_on);
 
 				list_add(&pd->node, &pd_provider->pd_list);
 			} else {

---
base-commit: 76eeb9b8de9880ca38696b2fb56ac45ac0a25c6c
change-id: 20241022-tisci-pd-boot-state-33cf02efd378

Best regards,
-- 
Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>


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

* Re: [PATCH RFC v2] pmdomain: ti-sci: Set PD on/off state according to the HW state
  2025-09-08  8:34 [PATCH RFC v2] pmdomain: ti-sci: Set PD on/off state according to the HW state Tomi Valkeinen
@ 2025-09-11 14:38 ` Ulf Hansson
  2025-09-16  9:14   ` Tomi Valkeinen
  0 siblings, 1 reply; 3+ messages in thread
From: Ulf Hansson @ 2025-09-11 14:38 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Nishanth Menon, Tero Kristo, Santosh Shilimkar, linux-arm-kernel,
	linux-pm, linux-kernel, Kevin Hilman, vishalm, sebin.francis,
	d-gole, Devarsh Thakkar, Vignesh Raghavendra

On Mon, 8 Sept 2025 at 10:35, Tomi Valkeinen
<tomi.valkeinen@ideasonboard.com> wrote:
>
> At the moment the driver sets the power state of all the PDs it creates
> to off, regardless of the actual HW state. This has two drawbacks:
>
> 1) The kernel cannot disable unused PDs automatically for power saving,
>    as it thinks they are off already
>
> 2) A more specific case (but perhaps applicable to other scenarios
>    also): bootloader enabled splash-screen cannot be kept on the screen.
>
> The issue in 2) is that the driver framework automatically enables the
> device's PD before calling probe() and disables it after the probe().
> This means that when the display subsystem (DSS) driver probes, but e.g.
> fails due to deferred probing, the DSS PD gets turned off and the driver
> cannot do anything to affect that.
>
> Solving the 2) requires more changes to actually keep the PD on during
> the boot, but a prerequisite for it is to have the correct power state
> for the PD.
>
> The downside with this patch is that it takes time to call the 'is_on'
> op, and we need to call it for each PD. In my tests with AM62 SK, using
> defconfig, I see an increase from ~3.5ms to ~7ms. However, the added
> feature is valuable, so in my opinion it's worth it.
>
> The performance could probably be improved with a new firmware API which
> returns the power states of all the PDs.
>
> There's also a related HW issue at play here: if the DSS IP is enabled
> and active, and its PD is turned off without first disabling the DSS
> display outputs, the DSS IP will hang and causes the kernel to halt if
> and when the DSS driver accesses the DSS registers the next time.
>
> With the current upstream kernel, with this patch applied, this means
> that if the bootloader enables the display, and the DSS driver is
> compiled as a module, the kernel will at some point disable unused PDs,
> including the DSS PD. When the DSS module is later loaded, it will hang
> the kernel.
>
> The same issue is already there, even without this patch, as the DSS
> driver may hit deferred probing, which causes the PD to be turned off,
> and leading to kernel halt when the DSS driver is probed again. This
> issue has been made quite rare with some arrangements in the DSS
> driver's probe, but it's still there.
>
> With recent change from Ulf (e.g. commit 13a4b7fb6260 ("pmdomain: core:
> Leave powered-on genpds on until late_initcall_sync")), the sync state
> mechanism comes to rescue. It will keep the power domains enabled, until
> the drivers have probed, or the sync-state is triggered via some other
> mechanism (e.g. manually by the boot scripts).
>
> Reviewed-by: Kevin Hilman <khilman@baylibre.com>
> Tested-by: Kevin Hilman <khilman@baylibre.com>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>

Makes perfect sense to me! Applied for next, thanks!

Kind regards
Uffe


> ---
> Changes in v2:
> - Clarify the current state wrt. sync state in the patch description
> - Rebase to current upstream
> - No other changes
> - Link to v1: https://lore.kernel.org/r/20241022-tisci-pd-boot-state-v1-1-849a6384131b@ideasonboard.com
> ---
>  drivers/pmdomain/ti/ti_sci_pm_domains.c | 24 +++++++++++++++++++++++-
>  1 file changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c
> index 82df7e44250b..e5d1934f78d9 100644
> --- a/drivers/pmdomain/ti/ti_sci_pm_domains.c
> +++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c
> @@ -200,6 +200,23 @@ static bool ti_sci_pm_idx_exists(struct ti_sci_genpd_provider *pd_provider, u32
>         return false;
>  }
>
> +static bool ti_sci_pm_pd_is_on(struct ti_sci_genpd_provider *pd_provider,
> +                              int pd_idx)
> +{
> +       bool is_on;
> +       int ret;
> +
> +       if (!pd_provider->ti_sci->ops.dev_ops.is_on)
> +               return false;
> +
> +       ret = pd_provider->ti_sci->ops.dev_ops.is_on(pd_provider->ti_sci,
> +                                                    pd_idx, NULL, &is_on);
> +       if (ret)
> +               return false;
> +
> +       return is_on;
> +}
> +
>  static int ti_sci_pm_domain_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
> @@ -231,6 +248,8 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
>                                                    index, &args)) {
>
>                         if (args.args_count >= 1 && args.np == dev->of_node) {
> +                               bool is_on;
> +
>                                 of_node_put(args.np);
>                                 if (args.args[0] > max_id) {
>                                         max_id = args.args[0];
> @@ -264,7 +283,10 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
>                                     pd_provider->ti_sci->ops.pm_ops.set_latency_constraint)
>                                         pd->pd.domain.ops.suspend = ti_sci_pd_suspend;
>
> -                               pm_genpd_init(&pd->pd, NULL, true);
> +                               is_on = ti_sci_pm_pd_is_on(pd_provider,
> +                                                          pd->idx);
> +
> +                               pm_genpd_init(&pd->pd, NULL, !is_on);
>
>                                 list_add(&pd->node, &pd_provider->pd_list);
>                         } else {
>
> ---
> base-commit: 76eeb9b8de9880ca38696b2fb56ac45ac0a25c6c
> change-id: 20241022-tisci-pd-boot-state-33cf02efd378
>
> Best regards,
> --
> Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
>

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

* Re: [PATCH RFC v2] pmdomain: ti-sci: Set PD on/off state according to the HW state
  2025-09-11 14:38 ` Ulf Hansson
@ 2025-09-16  9:14   ` Tomi Valkeinen
  0 siblings, 0 replies; 3+ messages in thread
From: Tomi Valkeinen @ 2025-09-16  9:14 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Nishanth Menon, Tero Kristo, Santosh Shilimkar, linux-arm-kernel,
	linux-pm, linux-kernel, Kevin Hilman, vishalm, sebin.francis,
	d-gole, Devarsh Thakkar, Vignesh Raghavendra

Hi,

On 11/09/2025 17:38, Ulf Hansson wrote:
> On Mon, 8 Sept 2025 at 10:35, Tomi Valkeinen
> <tomi.valkeinen@ideasonboard.com> wrote:
>>
>> At the moment the driver sets the power state of all the PDs it creates
>> to off, regardless of the actual HW state. This has two drawbacks:
>>
>> 1) The kernel cannot disable unused PDs automatically for power saving,
>>    as it thinks they are off already
>>
>> 2) A more specific case (but perhaps applicable to other scenarios
>>    also): bootloader enabled splash-screen cannot be kept on the screen.
>>
>> The issue in 2) is that the driver framework automatically enables the
>> device's PD before calling probe() and disables it after the probe().
>> This means that when the display subsystem (DSS) driver probes, but e.g.
>> fails due to deferred probing, the DSS PD gets turned off and the driver
>> cannot do anything to affect that.
>>
>> Solving the 2) requires more changes to actually keep the PD on during
>> the boot, but a prerequisite for it is to have the correct power state
>> for the PD.
>>
>> The downside with this patch is that it takes time to call the 'is_on'
>> op, and we need to call it for each PD. In my tests with AM62 SK, using
>> defconfig, I see an increase from ~3.5ms to ~7ms. However, the added
>> feature is valuable, so in my opinion it's worth it.
>>
>> The performance could probably be improved with a new firmware API which
>> returns the power states of all the PDs.
>>
>> There's also a related HW issue at play here: if the DSS IP is enabled
>> and active, and its PD is turned off without first disabling the DSS
>> display outputs, the DSS IP will hang and causes the kernel to halt if
>> and when the DSS driver accesses the DSS registers the next time.
>>
>> With the current upstream kernel, with this patch applied, this means
>> that if the bootloader enables the display, and the DSS driver is
>> compiled as a module, the kernel will at some point disable unused PDs,
>> including the DSS PD. When the DSS module is later loaded, it will hang
>> the kernel.
>>
>> The same issue is already there, even without this patch, as the DSS
>> driver may hit deferred probing, which causes the PD to be turned off,
>> and leading to kernel halt when the DSS driver is probed again. This
>> issue has been made quite rare with some arrangements in the DSS
>> driver's probe, but it's still there.
>>
>> With recent change from Ulf (e.g. commit 13a4b7fb6260 ("pmdomain: core:
>> Leave powered-on genpds on until late_initcall_sync")), the sync state
>> mechanism comes to rescue. It will keep the power domains enabled, until
>> the drivers have probed, or the sync-state is triggered via some other
>> mechanism (e.g. manually by the boot scripts).
>>
>> Reviewed-by: Kevin Hilman <khilman@baylibre.com>
>> Tested-by: Kevin Hilman <khilman@baylibre.com>
>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> 
> Makes perfect sense to me! Applied for next, thanks!

Thanks!

I just noticed that the patch was marked RFC. Just for the record, the
v1 was RFC, this wasn't.

 Tomi


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

end of thread, other threads:[~2025-09-16  9:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-08  8:34 [PATCH RFC v2] pmdomain: ti-sci: Set PD on/off state according to the HW state Tomi Valkeinen
2025-09-11 14:38 ` Ulf Hansson
2025-09-16  9:14   ` Tomi Valkeinen

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