* [PATCH 0/4] drm/panfrost: Turn off clocks and regulators in PM
@ 2023-10-30 13:22 AngeloGioacchino Del Regno
2023-10-30 13:22 ` [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend AngeloGioacchino Del Regno
` (3 more replies)
0 siblings, 4 replies; 13+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-10-30 13:22 UTC (permalink / raw)
To: boris.brezillon
Cc: robh, steven.price, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, dri-devel, linux-kernel, wenst,
AngeloGioacchino Del Regno, kernel
At least MediaTek platforms are able to get the GPU clocks and regulators
completely off during system suspend, allowing to save a bit of power.
Panfrost is used on more than just MediaTek SoCs and the benefits of this
can be variable across different SoC models and/or different SoCs from
different manufacturers: this means that just adding this ability for all
could result in unexpected issues and breakages on untested SoCs.
For the aforemenetioned reasons, turning off the clocks and/or regulators
was implemented inside of a capabilities barrier that shall be enabled on
a per-SoC basis (in the panfrost_compatible platform data) after testing
of both benefits and feasibility.
In this series, I am adding the ability to switch on/off clocks and
regulators and enabling that on all MediaTek platforms, as I was able
to successfully test that on multiple Chromebooks featuring different
MediaTek SoCs; specifically, I've manually tested on MT8186, MT8192 and
MT8195, while MT8183 got tested only by KernelCI.
Cheers!
AngeloGioacchino Del Regno (4):
drm/panfrost: Implement ability to turn on/off GPU clocks in suspend
drm/panfrost: Set clocks on/off during system sleep on MediaTek SoCs
drm/panfrost: Implement ability to turn on/off regulators in suspend
drm/panfrost: Set regulators on/off during system sleep on MediaTek
SoCs
drivers/gpu/drm/panfrost/panfrost_device.c | 78 ++++++++++++++++++++--
drivers/gpu/drm/panfrost/panfrost_device.h | 13 ++++
drivers/gpu/drm/panfrost/panfrost_drv.c | 3 +
3 files changed, 90 insertions(+), 4 deletions(-)
--
2.42.0
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend 2023-10-30 13:22 [PATCH 0/4] drm/panfrost: Turn off clocks and regulators in PM AngeloGioacchino Del Regno @ 2023-10-30 13:22 ` AngeloGioacchino Del Regno 2023-10-30 14:57 ` Steven Price 2023-10-31 3:18 ` Chen-Yu Tsai 2023-10-30 13:22 ` [PATCH 2/4] drm/panfrost: Set clocks on/off during system sleep on MediaTek SoCs AngeloGioacchino Del Regno ` (2 subsequent siblings) 3 siblings, 2 replies; 13+ messages in thread From: AngeloGioacchino Del Regno @ 2023-10-30 13:22 UTC (permalink / raw) To: boris.brezillon Cc: robh, steven.price, maarten.lankhorst, mripard, tzimmermann, airlied, daniel, dri-devel, linux-kernel, wenst, AngeloGioacchino Del Regno, kernel Currently, the GPU is being internally powered off for runtime suspend and turned back on for runtime resume through commands sent to it, but note that the GPU doesn't need to be clocked during the poweroff state, hence it is possible to save some power on selected platforms. Add suspend and resume handlers for full system sleep and then add a new panfrost_gpu_pm enumeration and a pm_features variable in the panfrost_compatible structure: BIT(GPU_PM_CLK_DIS) will be used to enable this power saving technique only on SoCs that are able to safely use it. Note that this was implemented only for the system sleep case and not for runtime PM because testing on one of my MediaTek platforms showed issues when turning on and off clocks aggressively (in PM runtime), with the GPU locking up and unable to soft reset, eventually resulting in a full system lockup. Doing this only for full system sleep never showed issues in 3 days of testing by suspending and resuming the system continuously. Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> --- drivers/gpu/drm/panfrost/panfrost_device.c | 61 ++++++++++++++++++++-- drivers/gpu/drm/panfrost/panfrost_device.h | 11 ++++ 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c index 28f7046e1b1a..2022ed76a620 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.c +++ b/drivers/gpu/drm/panfrost/panfrost_device.c @@ -403,7 +403,7 @@ void panfrost_device_reset(struct panfrost_device *pfdev) panfrost_job_enable_interrupts(pfdev); } -static int panfrost_device_resume(struct device *dev) +static int panfrost_device_runtime_resume(struct device *dev) { struct panfrost_device *pfdev = dev_get_drvdata(dev); @@ -413,7 +413,7 @@ static int panfrost_device_resume(struct device *dev) return 0; } -static int panfrost_device_suspend(struct device *dev) +static int panfrost_device_runtime_suspend(struct device *dev) { struct panfrost_device *pfdev = dev_get_drvdata(dev); @@ -426,5 +426,58 @@ static int panfrost_device_suspend(struct device *dev) return 0; } -EXPORT_GPL_RUNTIME_DEV_PM_OPS(panfrost_pm_ops, panfrost_device_suspend, - panfrost_device_resume, NULL); +static int panfrost_device_resume(struct device *dev) +{ + struct panfrost_device *pfdev = dev_get_drvdata(dev); + int ret; + + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { + ret = clk_enable(pfdev->clock); + if (ret) + return ret; + + if (pfdev->bus_clock) { + ret = clk_enable(pfdev->bus_clock); + if (ret) + goto err_bus_clk; + } + } + + ret = pm_runtime_force_resume(dev); + if (ret) + goto err_resume; + + return 0; + +err_resume: + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS) && pfdev->bus_clock) + clk_disable(pfdev->bus_clock); +err_bus_clk: + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) + clk_disable(pfdev->clock); + return ret; +} + +static int panfrost_device_suspend(struct device *dev) +{ + struct panfrost_device *pfdev = dev_get_drvdata(dev); + int ret; + + ret = pm_runtime_force_suspend(dev); + if (ret) + return ret; + + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { + clk_disable(pfdev->clock); + + if (pfdev->bus_clock) + clk_disable(pfdev->bus_clock); + } + + return 0; +} + +EXPORT_GPL_DEV_PM_OPS(panfrost_pm_ops) = { + RUNTIME_PM_OPS(panfrost_device_runtime_suspend, panfrost_device_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(panfrost_device_suspend, panfrost_device_resume) +}; diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h index 1ef38f60d5dc..d7f179eb8ea3 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.h +++ b/drivers/gpu/drm/panfrost/panfrost_device.h @@ -25,6 +25,14 @@ struct panfrost_perfcnt; #define NUM_JOB_SLOTS 3 #define MAX_PM_DOMAINS 5 +/** + * enum panfrost_gpu_pm - Supported kernel power management features + * @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend + */ +enum panfrost_gpu_pm { + GPU_PM_CLK_DIS, +}; + struct panfrost_features { u16 id; u16 revision; @@ -75,6 +83,9 @@ struct panfrost_compatible { /* Vendor implementation quirks callback */ void (*vendor_quirk)(struct panfrost_device *pfdev); + + /* Allowed PM features */ + u8 pm_features; }; struct panfrost_device { -- 2.42.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend 2023-10-30 13:22 ` [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend AngeloGioacchino Del Regno @ 2023-10-30 14:57 ` Steven Price 2023-10-31 8:59 ` AngeloGioacchino Del Regno 2023-10-31 3:18 ` Chen-Yu Tsai 1 sibling, 1 reply; 13+ messages in thread From: Steven Price @ 2023-10-30 14:57 UTC (permalink / raw) To: AngeloGioacchino Del Regno, boris.brezillon Cc: robh, maarten.lankhorst, mripard, tzimmermann, airlied, daniel, dri-devel, linux-kernel, wenst, kernel On 30/10/2023 13:22, AngeloGioacchino Del Regno wrote: > Currently, the GPU is being internally powered off for runtime suspend > and turned back on for runtime resume through commands sent to it, but > note that the GPU doesn't need to be clocked during the poweroff state, > hence it is possible to save some power on selected platforms. Looks like a good addition - I suspect some implementations are quite leaky so this could have a meaningful power saving in some cases. > Add suspend and resume handlers for full system sleep and then add > a new panfrost_gpu_pm enumeration and a pm_features variable in the > panfrost_compatible structure: BIT(GPU_PM_CLK_DIS) will be used to > enable this power saving technique only on SoCs that are able to > safely use it. > > Note that this was implemented only for the system sleep case and not > for runtime PM because testing on one of my MediaTek platforms showed > issues when turning on and off clocks aggressively (in PM runtime), > with the GPU locking up and unable to soft reset, eventually resulting > in a full system lockup. I think I know why you saw this - see below. > Doing this only for full system sleep never showed issues in 3 days > of testing by suspending and resuming the system continuously. > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > --- > drivers/gpu/drm/panfrost/panfrost_device.c | 61 ++++++++++++++++++++-- > drivers/gpu/drm/panfrost/panfrost_device.h | 11 ++++ > 2 files changed, 68 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c > index 28f7046e1b1a..2022ed76a620 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_device.c > +++ b/drivers/gpu/drm/panfrost/panfrost_device.c > @@ -403,7 +403,7 @@ void panfrost_device_reset(struct panfrost_device *pfdev) > panfrost_job_enable_interrupts(pfdev); > } > > -static int panfrost_device_resume(struct device *dev) > +static int panfrost_device_runtime_resume(struct device *dev) > { > struct panfrost_device *pfdev = dev_get_drvdata(dev); > > @@ -413,7 +413,7 @@ static int panfrost_device_resume(struct device *dev) > return 0; > } > > -static int panfrost_device_suspend(struct device *dev) > +static int panfrost_device_runtime_suspend(struct device *dev) > { > struct panfrost_device *pfdev = dev_get_drvdata(dev); > So this function calls panfrost_gpu_power_off() which is simply: void panfrost_gpu_power_off(struct panfrost_device *pfdev) { gpu_write(pfdev, TILER_PWROFF_LO, 0); gpu_write(pfdev, SHADER_PWROFF_LO, 0); gpu_write(pfdev, L2_PWROFF_LO, 0); } So we instruct the GPU to turn off, but don't wait for it to complete. > @@ -426,5 +426,58 @@ static int panfrost_device_suspend(struct device *dev) > return 0; > } > > -EXPORT_GPL_RUNTIME_DEV_PM_OPS(panfrost_pm_ops, panfrost_device_suspend, > - panfrost_device_resume, NULL); > +static int panfrost_device_resume(struct device *dev) > +{ > + struct panfrost_device *pfdev = dev_get_drvdata(dev); > + int ret; > + > + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { > + ret = clk_enable(pfdev->clock); > + if (ret) > + return ret; > + > + if (pfdev->bus_clock) { > + ret = clk_enable(pfdev->bus_clock); > + if (ret) > + goto err_bus_clk; > + } > + } > + > + ret = pm_runtime_force_resume(dev); > + if (ret) > + goto err_resume; > + > + return 0; > + > +err_resume: > + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS) && pfdev->bus_clock) > + clk_disable(pfdev->bus_clock); > +err_bus_clk: > + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) > + clk_disable(pfdev->clock); > + return ret; > +} > + > +static int panfrost_device_suspend(struct device *dev) > +{ > + struct panfrost_device *pfdev = dev_get_drvdata(dev); > + int ret; > + > + ret = pm_runtime_force_suspend(dev); > + if (ret) > + return ret; So here we've started shutting down the GPU (pm_runtime_force_suspend eventually calls panfrost_gpu_power_off). But nothing here waits for the GPU to actually finish shutting down. If we're unlucky there's dirty data in the caches (or coherency which can snoop into the caches) so the GPU could be actively making bus cycles... > + > + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { > + clk_disable(pfdev->clock); ... until its clock goes and everything locks up. Something should be waiting for the power down to complete. Either poll the L2_PWRTRANS_LO register to detect that the L2 is no longer transitioning, or wait for the GPU_IRQ_POWER_CHANGED_ALL interrupt to fire. It would be good to test this with the system suspend doing the full power off, it should be safe so it would be a good stress test. Although whether we want the overhead in normal operation is another matter - so I suspect it should just be for testing purposes. I would hope that we don't actually need the GPU_PM_CLK_DIS feature - this should work as long as the GPU is given the time to shutdown. Although note that actually cutting the power (patches 3 & 4) may expose us to implementation errata - there have been issues with designs not resetting correctly. I'm not sure if those made it into real products or if such bugs are confined to test chips. So for the sake of not causing regressions it's probably not a bad thing to have ;) Steve > + > + if (pfdev->bus_clock) > + clk_disable(pfdev->bus_clock); > + } > + > + return 0; > +} > + > +EXPORT_GPL_DEV_PM_OPS(panfrost_pm_ops) = { > + RUNTIME_PM_OPS(panfrost_device_runtime_suspend, panfrost_device_runtime_resume, NULL) > + SYSTEM_SLEEP_PM_OPS(panfrost_device_suspend, panfrost_device_resume) > +}; > diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h > index 1ef38f60d5dc..d7f179eb8ea3 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_device.h > +++ b/drivers/gpu/drm/panfrost/panfrost_device.h > @@ -25,6 +25,14 @@ struct panfrost_perfcnt; > #define NUM_JOB_SLOTS 3 > #define MAX_PM_DOMAINS 5 > > +/** > + * enum panfrost_gpu_pm - Supported kernel power management features > + * @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend > + */ > +enum panfrost_gpu_pm { > + GPU_PM_CLK_DIS, > +}; > + > struct panfrost_features { > u16 id; > u16 revision; > @@ -75,6 +83,9 @@ struct panfrost_compatible { > > /* Vendor implementation quirks callback */ > void (*vendor_quirk)(struct panfrost_device *pfdev); > + > + /* Allowed PM features */ > + u8 pm_features; > }; > > struct panfrost_device { ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend 2023-10-30 14:57 ` Steven Price @ 2023-10-31 8:59 ` AngeloGioacchino Del Regno 2023-10-31 10:33 ` AngeloGioacchino Del Regno 0 siblings, 1 reply; 13+ messages in thread From: AngeloGioacchino Del Regno @ 2023-10-31 8:59 UTC (permalink / raw) To: Steven Price, boris.brezillon Cc: robh, maarten.lankhorst, mripard, tzimmermann, airlied, daniel, dri-devel, linux-kernel, wenst, kernel Il 30/10/23 15:57, Steven Price ha scritto: > On 30/10/2023 13:22, AngeloGioacchino Del Regno wrote: >> Currently, the GPU is being internally powered off for runtime suspend >> and turned back on for runtime resume through commands sent to it, but >> note that the GPU doesn't need to be clocked during the poweroff state, >> hence it is possible to save some power on selected platforms. > > Looks like a good addition - I suspect some implementations are quite > leaky so this could have a meaningful power saving in some cases. > >> Add suspend and resume handlers for full system sleep and then add >> a new panfrost_gpu_pm enumeration and a pm_features variable in the >> panfrost_compatible structure: BIT(GPU_PM_CLK_DIS) will be used to >> enable this power saving technique only on SoCs that are able to >> safely use it. >> >> Note that this was implemented only for the system sleep case and not >> for runtime PM because testing on one of my MediaTek platforms showed >> issues when turning on and off clocks aggressively (in PM runtime), >> with the GPU locking up and unable to soft reset, eventually resulting >> in a full system lockup. > > I think I know why you saw this - see below. > >> Doing this only for full system sleep never showed issues in 3 days >> of testing by suspending and resuming the system continuously. >> >> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> >> --- >> drivers/gpu/drm/panfrost/panfrost_device.c | 61 ++++++++++++++++++++-- >> drivers/gpu/drm/panfrost/panfrost_device.h | 11 ++++ >> 2 files changed, 68 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c >> index 28f7046e1b1a..2022ed76a620 100644 >> --- a/drivers/gpu/drm/panfrost/panfrost_device.c >> +++ b/drivers/gpu/drm/panfrost/panfrost_device.c >> @@ -403,7 +403,7 @@ void panfrost_device_reset(struct panfrost_device *pfdev) >> panfrost_job_enable_interrupts(pfdev); >> } >> >> -static int panfrost_device_resume(struct device *dev) >> +static int panfrost_device_runtime_resume(struct device *dev) >> { >> struct panfrost_device *pfdev = dev_get_drvdata(dev); >> >> @@ -413,7 +413,7 @@ static int panfrost_device_resume(struct device *dev) >> return 0; >> } >> >> -static int panfrost_device_suspend(struct device *dev) >> +static int panfrost_device_runtime_suspend(struct device *dev) >> { >> struct panfrost_device *pfdev = dev_get_drvdata(dev); >> > > So this function calls panfrost_gpu_power_off() which is simply: > > void panfrost_gpu_power_off(struct panfrost_device *pfdev) > { > gpu_write(pfdev, TILER_PWROFF_LO, 0); > gpu_write(pfdev, SHADER_PWROFF_LO, 0); > gpu_write(pfdev, L2_PWROFF_LO, 0); > } > > So we instruct the GPU to turn off, but don't wait for it to complete. > >> @@ -426,5 +426,58 @@ static int panfrost_device_suspend(struct device *dev) >> return 0; >> } >> >> -EXPORT_GPL_RUNTIME_DEV_PM_OPS(panfrost_pm_ops, panfrost_device_suspend, >> - panfrost_device_resume, NULL); >> +static int panfrost_device_resume(struct device *dev) >> +{ >> + struct panfrost_device *pfdev = dev_get_drvdata(dev); >> + int ret; >> + >> + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { >> + ret = clk_enable(pfdev->clock); >> + if (ret) >> + return ret; >> + >> + if (pfdev->bus_clock) { >> + ret = clk_enable(pfdev->bus_clock); >> + if (ret) >> + goto err_bus_clk; >> + } >> + } >> + >> + ret = pm_runtime_force_resume(dev); >> + if (ret) >> + goto err_resume; >> + >> + return 0; >> + >> +err_resume: >> + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS) && pfdev->bus_clock) >> + clk_disable(pfdev->bus_clock); >> +err_bus_clk: >> + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) >> + clk_disable(pfdev->clock); >> + return ret; >> +} >> + >> +static int panfrost_device_suspend(struct device *dev) >> +{ >> + struct panfrost_device *pfdev = dev_get_drvdata(dev); >> + int ret; >> + >> + ret = pm_runtime_force_suspend(dev); >> + if (ret) >> + return ret; > > So here we've started shutting down the GPU (pm_runtime_force_suspend > eventually calls panfrost_gpu_power_off). But nothing here waits for the > GPU to actually finish shutting down. If we're unlucky there's dirty > data in the caches (or coherency which can snoop into the caches) so the > GPU could be actively making bus cycles... > >> + >> + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { >> + clk_disable(pfdev->clock); > > ... until its clock goes and everything locks up. > > Something should be waiting for the power down to complete. Either poll > the L2_PWRTRANS_LO register to detect that the L2 is no longer > transitioning, or wait for the GPU_IRQ_POWER_CHANGED_ALL interrupt to fire. > > It would be good to test this with the system suspend doing the full > power off, it should be safe so it would be a good stress test. Although > whether we want the overhead in normal operation is another matter - so > I suspect it should just be for testing purposes. > > I would hope that we don't actually need the GPU_PM_CLK_DIS feature - > this should work as long as the GPU is given the time to shutdown. > Although note that actually cutting the power (patches 3 & 4) may expose > us to implementation errata - there have been issues with designs not > resetting correctly. I'm not sure if those made it into real products or > if such bugs are confined to test chips. So for the sake of not causing > regressions it's probably not a bad thing to have ;) > Huge thanks for this analysis of that lockup issue. That was highly appreciated. I've seen that anyway disabling the clocks during *runtime* suspend will make us lose only a few nanoseconds (without polling for that register, nor waiting for the interrupt you mentioned).... so I'd say that if L2_PWRTRANS_LO takes as well just nanoseconds, I could put those clk_disable()/clk_enable() calls back to the Runtime PM handlers as per my original idea. I'll go on with checking if it is feasible to poll-wait to do this in runtime pm, otherwise the v2 will still have this in system sleep handlers... Anyway, as for the GPU_PM_CLK_DIS feature - I feel like being extremely careful with this is still a good idea... thing is, even if we're sure that the GPU itself is fine with us turning off/on clocks (even aggressively), I'm not sure that *all* of the SoCs using Mali GPUs don't have any kind of quirk and for safety I don't want to place any bets. My idea is to add this with feature opt-in - then, if after some time we discover that all SoCs want it and can safely use it, we can simplify the flow by removing the feature bit. Cheers, Angelo > Steve > >> + >> + if (pfdev->bus_clock) >> + clk_disable(pfdev->bus_clock); >> + } >> + >> + return 0; >> +} >> + >> +EXPORT_GPL_DEV_PM_OPS(panfrost_pm_ops) = { >> + RUNTIME_PM_OPS(panfrost_device_runtime_suspend, panfrost_device_runtime_resume, NULL) >> + SYSTEM_SLEEP_PM_OPS(panfrost_device_suspend, panfrost_device_resume) >> +}; >> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h >> index 1ef38f60d5dc..d7f179eb8ea3 100644 >> --- a/drivers/gpu/drm/panfrost/panfrost_device.h >> +++ b/drivers/gpu/drm/panfrost/panfrost_device.h >> @@ -25,6 +25,14 @@ struct panfrost_perfcnt; >> #define NUM_JOB_SLOTS 3 >> #define MAX_PM_DOMAINS 5 >> >> +/** >> + * enum panfrost_gpu_pm - Supported kernel power management features >> + * @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend >> + */ >> +enum panfrost_gpu_pm { >> + GPU_PM_CLK_DIS, >> +}; >> + >> struct panfrost_features { >> u16 id; >> u16 revision; >> @@ -75,6 +83,9 @@ struct panfrost_compatible { >> >> /* Vendor implementation quirks callback */ >> void (*vendor_quirk)(struct panfrost_device *pfdev); >> + >> + /* Allowed PM features */ >> + u8 pm_features; >> }; >> >> struct panfrost_device { > > _______________________________________________ > Kernel mailing list -- kernel@mailman.collabora.com > To unsubscribe send an email to kernel-leave@mailman.collabora.com ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend 2023-10-31 8:59 ` AngeloGioacchino Del Regno @ 2023-10-31 10:33 ` AngeloGioacchino Del Regno 2023-11-01 11:28 ` Steven Price 0 siblings, 1 reply; 13+ messages in thread From: AngeloGioacchino Del Regno @ 2023-10-31 10:33 UTC (permalink / raw) To: Steven Price, boris.brezillon Cc: robh, maarten.lankhorst, mripard, tzimmermann, airlied, daniel, dri-devel, linux-kernel, wenst, kernel Il 31/10/23 09:59, AngeloGioacchino Del Regno ha scritto: > Il 30/10/23 15:57, Steven Price ha scritto: >> On 30/10/2023 13:22, AngeloGioacchino Del Regno wrote: >>> Currently, the GPU is being internally powered off for runtime suspend >>> and turned back on for runtime resume through commands sent to it, but >>> note that the GPU doesn't need to be clocked during the poweroff state, >>> hence it is possible to save some power on selected platforms. >> >> Looks like a good addition - I suspect some implementations are quite >> leaky so this could have a meaningful power saving in some cases. >> >>> Add suspend and resume handlers for full system sleep and then add >>> a new panfrost_gpu_pm enumeration and a pm_features variable in the >>> panfrost_compatible structure: BIT(GPU_PM_CLK_DIS) will be used to >>> enable this power saving technique only on SoCs that are able to >>> safely use it. >>> >>> Note that this was implemented only for the system sleep case and not >>> for runtime PM because testing on one of my MediaTek platforms showed >>> issues when turning on and off clocks aggressively (in PM runtime), >>> with the GPU locking up and unable to soft reset, eventually resulting >>> in a full system lockup. >> >> I think I know why you saw this - see below. >> >>> Doing this only for full system sleep never showed issues in 3 days >>> of testing by suspending and resuming the system continuously. >>> >>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> >>> --- >>> drivers/gpu/drm/panfrost/panfrost_device.c | 61 ++++++++++++++++++++-- >>> drivers/gpu/drm/panfrost/panfrost_device.h | 11 ++++ >>> 2 files changed, 68 insertions(+), 4 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c >>> b/drivers/gpu/drm/panfrost/panfrost_device.c >>> index 28f7046e1b1a..2022ed76a620 100644 >>> --- a/drivers/gpu/drm/panfrost/panfrost_device.c >>> +++ b/drivers/gpu/drm/panfrost/panfrost_device.c >>> @@ -403,7 +403,7 @@ void panfrost_device_reset(struct panfrost_device *pfdev) >>> panfrost_job_enable_interrupts(pfdev); >>> } >>> -static int panfrost_device_resume(struct device *dev) >>> +static int panfrost_device_runtime_resume(struct device *dev) >>> { >>> struct panfrost_device *pfdev = dev_get_drvdata(dev); >>> @@ -413,7 +413,7 @@ static int panfrost_device_resume(struct device *dev) >>> return 0; >>> } >>> -static int panfrost_device_suspend(struct device *dev) >>> +static int panfrost_device_runtime_suspend(struct device *dev) >>> { >>> struct panfrost_device *pfdev = dev_get_drvdata(dev); >> >> So this function calls panfrost_gpu_power_off() which is simply: >> >> void panfrost_gpu_power_off(struct panfrost_device *pfdev) >> { >> gpu_write(pfdev, TILER_PWROFF_LO, 0); >> gpu_write(pfdev, SHADER_PWROFF_LO, 0); >> gpu_write(pfdev, L2_PWROFF_LO, 0); >> } >> >> So we instruct the GPU to turn off, but don't wait for it to complete. >> >>> @@ -426,5 +426,58 @@ static int panfrost_device_suspend(struct device *dev) >>> return 0; >>> } >>> -EXPORT_GPL_RUNTIME_DEV_PM_OPS(panfrost_pm_ops, panfrost_device_suspend, >>> - panfrost_device_resume, NULL); >>> +static int panfrost_device_resume(struct device *dev) >>> +{ >>> + struct panfrost_device *pfdev = dev_get_drvdata(dev); >>> + int ret; >>> + >>> + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { >>> + ret = clk_enable(pfdev->clock); >>> + if (ret) >>> + return ret; >>> + >>> + if (pfdev->bus_clock) { >>> + ret = clk_enable(pfdev->bus_clock); >>> + if (ret) >>> + goto err_bus_clk; >>> + } >>> + } >>> + >>> + ret = pm_runtime_force_resume(dev); >>> + if (ret) >>> + goto err_resume; >>> + >>> + return 0; >>> + >>> +err_resume: >>> + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS) && pfdev->bus_clock) >>> + clk_disable(pfdev->bus_clock); >>> +err_bus_clk: >>> + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) >>> + clk_disable(pfdev->clock); >>> + return ret; >>> +} >>> + >>> +static int panfrost_device_suspend(struct device *dev) >>> +{ >>> + struct panfrost_device *pfdev = dev_get_drvdata(dev); >>> + int ret; >>> + >>> + ret = pm_runtime_force_suspend(dev); >>> + if (ret) >>> + return ret; >> >> So here we've started shutting down the GPU (pm_runtime_force_suspend >> eventually calls panfrost_gpu_power_off). But nothing here waits for the >> GPU to actually finish shutting down. If we're unlucky there's dirty >> data in the caches (or coherency which can snoop into the caches) so the >> GPU could be actively making bus cycles... >> >>> + >>> + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { >>> + clk_disable(pfdev->clock); >> >> ... until its clock goes and everything locks up. >> >> Something should be waiting for the power down to complete. Either poll >> the L2_PWRTRANS_LO register to detect that the L2 is no longer >> transitioning, or wait for the GPU_IRQ_POWER_CHANGED_ALL interrupt to fire. >> >> It would be good to test this with the system suspend doing the full >> power off, it should be safe so it would be a good stress test. Although >> whether we want the overhead in normal operation is another matter - so >> I suspect it should just be for testing purposes. >> >> I would hope that we don't actually need the GPU_PM_CLK_DIS feature - >> this should work as long as the GPU is given the time to shutdown. >> Although note that actually cutting the power (patches 3 & 4) may expose >> us to implementation errata - there have been issues with designs not >> resetting correctly. I'm not sure if those made it into real products or >> if such bugs are confined to test chips. So for the sake of not causing >> regressions it's probably not a bad thing to have ;) >> > > Huge thanks for this analysis of that lockup issue. That was highly appreciated. > > I've seen that anyway disabling the clocks during *runtime* suspend will make us > lose only a few nanoseconds (without polling for that register, nor waiting for > the interrupt you mentioned).... so I'd say that if L2_PWRTRANS_LO takes as well > just nanoseconds, I could put those clk_disable()/clk_enable() calls back to the > Runtime PM handlers as per my original idea. > > I'll go on with checking if it is feasible to poll-wait to do this in runtime pm, > otherwise the v2 will still have this in system sleep handlers... > > Anyway, as for the GPU_PM_CLK_DIS feature - I feel like being extremely careful > with this is still a good idea... thing is, even if we're sure that the GPU itself > is fine with us turning off/on clocks (even aggressively), I'm not sure that *all* > of the SoCs using Mali GPUs don't have any kind of quirk and for safety I don't > want to place any bets. > > My idea is to add this with feature opt-in - then, if after some time we discover > that all SoCs want it and can safely use it, we can simplify the flow by removing > the feature bit. > Sorry for the double email - after some analysis and some trials of your wait solution, I've just seen that... well, panfrost_gpu_power_off() is, and has always been entirely broken, as in it has never done any poweroff! What it does is: gpu_write(pfdev, TILER_PWROFF_LO, 0); gpu_write(pfdev, SHADER_PWROFF_LO, 0); gpu_write(pfdev, L2_PWROFF_LO, 0); ...but the {TILER,SHADER,L2}_PWROFF_LO register is a bitmap and in order to request poweroff of tiler/shader cores and cache we shall flip bits to 1, but this is doing the *exact opposite* of what it's supposed to do. It's doing nothing, at all. I've just fixed that locally (running some tests on MT8195 as we speak) like so: gpu_write(pfdev, TILER_PWROFF_LO, pfdev->features.tiler_present); gpu_write(pfdev, SHADER_PWROFF_LO, pfdev->features.shader_present & core_mask); gpu_write(pfdev, L2_PWROFF_LO, pfdev->features.l2_present & core_mask); ...and now it appears that I can actually manage clocks aggressively during runtime power management without any side issues. Apparently, v2 of this series will have "more juice" than initially intended... Angelo > Cheers, > Angelo > >> Steve >> >>> + >>> + if (pfdev->bus_clock) >>> + clk_disable(pfdev->bus_clock); >>> + } >>> + >>> + return 0; >>> +} >>> + >>> +EXPORT_GPL_DEV_PM_OPS(panfrost_pm_ops) = { >>> + RUNTIME_PM_OPS(panfrost_device_runtime_suspend, >>> panfrost_device_runtime_resume, NULL) >>> + SYSTEM_SLEEP_PM_OPS(panfrost_device_suspend, panfrost_device_resume) >>> +}; >>> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h >>> b/drivers/gpu/drm/panfrost/panfrost_device.h >>> index 1ef38f60d5dc..d7f179eb8ea3 100644 >>> --- a/drivers/gpu/drm/panfrost/panfrost_device.h >>> +++ b/drivers/gpu/drm/panfrost/panfrost_device.h >>> @@ -25,6 +25,14 @@ struct panfrost_perfcnt; >>> #define NUM_JOB_SLOTS 3 >>> #define MAX_PM_DOMAINS 5 >>> +/** >>> + * enum panfrost_gpu_pm - Supported kernel power management features >>> + * @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend >>> + */ >>> +enum panfrost_gpu_pm { >>> + GPU_PM_CLK_DIS, >>> +}; >>> + >>> struct panfrost_features { >>> u16 id; >>> u16 revision; >>> @@ -75,6 +83,9 @@ struct panfrost_compatible { >>> /* Vendor implementation quirks callback */ >>> void (*vendor_quirk)(struct panfrost_device *pfdev); >>> + >>> + /* Allowed PM features */ >>> + u8 pm_features; >>> }; >>> struct panfrost_device { >> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend 2023-10-31 10:33 ` AngeloGioacchino Del Regno @ 2023-11-01 11:28 ` Steven Price 0 siblings, 0 replies; 13+ messages in thread From: Steven Price @ 2023-11-01 11:28 UTC (permalink / raw) To: AngeloGioacchino Del Regno, boris.brezillon Cc: robh, maarten.lankhorst, mripard, tzimmermann, airlied, daniel, dri-devel, linux-kernel, wenst, kernel On 31/10/2023 10:33, AngeloGioacchino Del Regno wrote: <snip> >> Anyway, as for the GPU_PM_CLK_DIS feature - I feel like being >> extremely careful >> with this is still a good idea... thing is, even if we're sure that >> the GPU itself >> is fine with us turning off/on clocks (even aggressively), I'm not >> sure that *all* >> of the SoCs using Mali GPUs don't have any kind of quirk and for >> safety I don't >> want to place any bets. >> >> My idea is to add this with feature opt-in - then, if after some time >> we discover >> that all SoCs want it and can safely use it, we can simplify the flow >> by removing >> the feature bit. Yeah I agree it's best to start with opt-in that way we can avoid regressions and focus the changes on platforms where this matters. > > Sorry for the double email - after some analysis and some trials of your > wait > solution, I've just seen that... well, panfrost_gpu_power_off() is, and > has always > been entirely broken, as in it has never done any poweroff! > > What it does is: > > gpu_write(pfdev, TILER_PWROFF_LO, 0); > gpu_write(pfdev, SHADER_PWROFF_LO, 0); > gpu_write(pfdev, L2_PWROFF_LO, 0); > > ...but the {TILER,SHADER,L2}_PWROFF_LO register is a bitmap and in order > to request > poweroff of tiler/shader cores and cache we shall flip bits to 1, but > this is doing > the *exact opposite* of what it's supposed to do. > > It's doing nothing, at all. Doh! I'd looked at that function when replying to your email and still not spotted that it is broken as you point out! I guess I always get a little distracted by the fact that it's technically "broken" in two other ways: first only the _LO registers are used (but equally there are no implementations with > 32 cores so this doesn't matter) and secondly we shouldn't really trigger the L2 power off while the tiler/shader are powering down. Although it doesn't matter here because the L2 power down will coordinate with the tiler and shader and do the right thing. In reality a single write is sufficient as the L2 power down will trigger the dependent cores to power down: gpu_write(pfdev, L2_PWROFF_LO, pfdev->features.l2_present); > I've just fixed that locally (running some tests on MT8195 as we speak) > like so: > > gpu_write(pfdev, TILER_PWROFF_LO, pfdev->features.tiler_present); > gpu_write(pfdev, SHADER_PWROFF_LO, pfdev->features.shader_present & > core_mask); > gpu_write(pfdev, L2_PWROFF_LO, pfdev->features.l2_present & core_mask); But this should be fine too - as above the L2 transition will just wait. Please can you include a fix (as a separate patch) for that in your next posting? I think that should be worthy of a backport. > ...and now it appears that I can actually manage clocks aggressively > during runtime > power management without any side issues. > > Apparently, v2 of this series will have "more juice" than initially > intended... Thanks for looking in to this! Thanks, Steve ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend 2023-10-30 13:22 ` [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend AngeloGioacchino Del Regno 2023-10-30 14:57 ` Steven Price @ 2023-10-31 3:18 ` Chen-Yu Tsai 2023-10-31 13:20 ` AngeloGioacchino Del Regno 1 sibling, 1 reply; 13+ messages in thread From: Chen-Yu Tsai @ 2023-10-31 3:18 UTC (permalink / raw) To: AngeloGioacchino Del Regno Cc: boris.brezillon, robh, steven.price, maarten.lankhorst, mripard, tzimmermann, airlied, daniel, dri-devel, linux-kernel, kernel On Mon, Oct 30, 2023 at 9:23 PM AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> wrote: > > Currently, the GPU is being internally powered off for runtime suspend > and turned back on for runtime resume through commands sent to it, but > note that the GPU doesn't need to be clocked during the poweroff state, > hence it is possible to save some power on selected platforms. > > Add suspend and resume handlers for full system sleep and then add > a new panfrost_gpu_pm enumeration and a pm_features variable in the > panfrost_compatible structure: BIT(GPU_PM_CLK_DIS) will be used to > enable this power saving technique only on SoCs that are able to > safely use it. > > Note that this was implemented only for the system sleep case and not > for runtime PM because testing on one of my MediaTek platforms showed > issues when turning on and off clocks aggressively (in PM runtime), > with the GPU locking up and unable to soft reset, eventually resulting > in a full system lockup. > > Doing this only for full system sleep never showed issues in 3 days > of testing by suspending and resuming the system continuously. > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > --- > drivers/gpu/drm/panfrost/panfrost_device.c | 61 ++++++++++++++++++++-- > drivers/gpu/drm/panfrost/panfrost_device.h | 11 ++++ > 2 files changed, 68 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c > index 28f7046e1b1a..2022ed76a620 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_device.c > +++ b/drivers/gpu/drm/panfrost/panfrost_device.c > @@ -403,7 +403,7 @@ void panfrost_device_reset(struct panfrost_device *pfdev) > panfrost_job_enable_interrupts(pfdev); > } > > -static int panfrost_device_resume(struct device *dev) > +static int panfrost_device_runtime_resume(struct device *dev) > { > struct panfrost_device *pfdev = dev_get_drvdata(dev); > > @@ -413,7 +413,7 @@ static int panfrost_device_resume(struct device *dev) > return 0; > } > > -static int panfrost_device_suspend(struct device *dev) > +static int panfrost_device_runtime_suspend(struct device *dev) > { > struct panfrost_device *pfdev = dev_get_drvdata(dev); > > @@ -426,5 +426,58 @@ static int panfrost_device_suspend(struct device *dev) > return 0; > } > > -EXPORT_GPL_RUNTIME_DEV_PM_OPS(panfrost_pm_ops, panfrost_device_suspend, > - panfrost_device_resume, NULL); > +static int panfrost_device_resume(struct device *dev) > +{ > + struct panfrost_device *pfdev = dev_get_drvdata(dev); > + int ret; > + > + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { > + ret = clk_enable(pfdev->clock); > + if (ret) > + return ret; > + > + if (pfdev->bus_clock) { > + ret = clk_enable(pfdev->bus_clock); > + if (ret) > + goto err_bus_clk; > + } > + } > + > + ret = pm_runtime_force_resume(dev); > + if (ret) > + goto err_resume; > + > + return 0; > + > +err_resume: > + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS) && pfdev->bus_clock) > + clk_disable(pfdev->bus_clock); > +err_bus_clk: > + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) > + clk_disable(pfdev->clock); > + return ret; > +} > + > +static int panfrost_device_suspend(struct device *dev) > +{ > + struct panfrost_device *pfdev = dev_get_drvdata(dev); > + int ret; > + > + ret = pm_runtime_force_suspend(dev); > + if (ret) > + return ret; > + > + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { > + clk_disable(pfdev->clock); > + > + if (pfdev->bus_clock) > + clk_disable(pfdev->bus_clock); > + } > + > + return 0; > +} > + > +EXPORT_GPL_DEV_PM_OPS(panfrost_pm_ops) = { > + RUNTIME_PM_OPS(panfrost_device_runtime_suspend, panfrost_device_runtime_resume, NULL) > + SYSTEM_SLEEP_PM_OPS(panfrost_device_suspend, panfrost_device_resume) > +}; > diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h > index 1ef38f60d5dc..d7f179eb8ea3 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_device.h > +++ b/drivers/gpu/drm/panfrost/panfrost_device.h > @@ -25,6 +25,14 @@ struct panfrost_perfcnt; > #define NUM_JOB_SLOTS 3 > #define MAX_PM_DOMAINS 5 > > +/** > + * enum panfrost_gpu_pm - Supported kernel power management features > + * @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend > + */ > +enum panfrost_gpu_pm { > + GPU_PM_CLK_DIS, > +}; > + > struct panfrost_features { > u16 id; > u16 revision; > @@ -75,6 +83,9 @@ struct panfrost_compatible { > > /* Vendor implementation quirks callback */ > void (*vendor_quirk)(struct panfrost_device *pfdev); > + > + /* Allowed PM features */ > + u8 pm_features; Nit: I'd just use bitfields. They are easier to set and get without extra macros, and the naming would be self-explanatory. Unless you expect a need to do mask checking (though the compiler might be able to optimize this). ChenYu > }; > > struct panfrost_device { > -- > 2.42.0 > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend 2023-10-31 3:18 ` Chen-Yu Tsai @ 2023-10-31 13:20 ` AngeloGioacchino Del Regno 0 siblings, 0 replies; 13+ messages in thread From: AngeloGioacchino Del Regno @ 2023-10-31 13:20 UTC (permalink / raw) To: Chen-Yu Tsai Cc: boris.brezillon, robh, steven.price, maarten.lankhorst, mripard, tzimmermann, airlied, daniel, dri-devel, linux-kernel, kernel Il 31/10/23 04:18, Chen-Yu Tsai ha scritto: > On Mon, Oct 30, 2023 at 9:23 PM AngeloGioacchino Del Regno > <angelogioacchino.delregno@collabora.com> wrote: >> >> Currently, the GPU is being internally powered off for runtime suspend >> and turned back on for runtime resume through commands sent to it, but >> note that the GPU doesn't need to be clocked during the poweroff state, >> hence it is possible to save some power on selected platforms. >> >> Add suspend and resume handlers for full system sleep and then add >> a new panfrost_gpu_pm enumeration and a pm_features variable in the >> panfrost_compatible structure: BIT(GPU_PM_CLK_DIS) will be used to >> enable this power saving technique only on SoCs that are able to >> safely use it. >> >> Note that this was implemented only for the system sleep case and not >> for runtime PM because testing on one of my MediaTek platforms showed >> issues when turning on and off clocks aggressively (in PM runtime), >> with the GPU locking up and unable to soft reset, eventually resulting >> in a full system lockup. >> >> Doing this only for full system sleep never showed issues in 3 days >> of testing by suspending and resuming the system continuously. >> >> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> >> --- >> drivers/gpu/drm/panfrost/panfrost_device.c | 61 ++++++++++++++++++++-- >> drivers/gpu/drm/panfrost/panfrost_device.h | 11 ++++ >> 2 files changed, 68 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c >> index 28f7046e1b1a..2022ed76a620 100644 >> --- a/drivers/gpu/drm/panfrost/panfrost_device.c >> +++ b/drivers/gpu/drm/panfrost/panfrost_device.c >> @@ -403,7 +403,7 @@ void panfrost_device_reset(struct panfrost_device *pfdev) >> panfrost_job_enable_interrupts(pfdev); >> } >> >> -static int panfrost_device_resume(struct device *dev) >> +static int panfrost_device_runtime_resume(struct device *dev) >> { >> struct panfrost_device *pfdev = dev_get_drvdata(dev); >> >> @@ -413,7 +413,7 @@ static int panfrost_device_resume(struct device *dev) >> return 0; >> } >> >> -static int panfrost_device_suspend(struct device *dev) >> +static int panfrost_device_runtime_suspend(struct device *dev) >> { >> struct panfrost_device *pfdev = dev_get_drvdata(dev); >> >> @@ -426,5 +426,58 @@ static int panfrost_device_suspend(struct device *dev) >> return 0; >> } >> >> -EXPORT_GPL_RUNTIME_DEV_PM_OPS(panfrost_pm_ops, panfrost_device_suspend, >> - panfrost_device_resume, NULL); >> +static int panfrost_device_resume(struct device *dev) >> +{ >> + struct panfrost_device *pfdev = dev_get_drvdata(dev); >> + int ret; >> + >> + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { >> + ret = clk_enable(pfdev->clock); >> + if (ret) >> + return ret; >> + >> + if (pfdev->bus_clock) { >> + ret = clk_enable(pfdev->bus_clock); >> + if (ret) >> + goto err_bus_clk; >> + } >> + } >> + >> + ret = pm_runtime_force_resume(dev); >> + if (ret) >> + goto err_resume; >> + >> + return 0; >> + >> +err_resume: >> + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS) && pfdev->bus_clock) >> + clk_disable(pfdev->bus_clock); >> +err_bus_clk: >> + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) >> + clk_disable(pfdev->clock); >> + return ret; >> +} >> + >> +static int panfrost_device_suspend(struct device *dev) >> +{ >> + struct panfrost_device *pfdev = dev_get_drvdata(dev); >> + int ret; >> + >> + ret = pm_runtime_force_suspend(dev); >> + if (ret) >> + return ret; >> + >> + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { >> + clk_disable(pfdev->clock); >> + >> + if (pfdev->bus_clock) >> + clk_disable(pfdev->bus_clock); >> + } >> + >> + return 0; >> +} >> + >> +EXPORT_GPL_DEV_PM_OPS(panfrost_pm_ops) = { >> + RUNTIME_PM_OPS(panfrost_device_runtime_suspend, panfrost_device_runtime_resume, NULL) >> + SYSTEM_SLEEP_PM_OPS(panfrost_device_suspend, panfrost_device_resume) >> +}; >> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h >> index 1ef38f60d5dc..d7f179eb8ea3 100644 >> --- a/drivers/gpu/drm/panfrost/panfrost_device.h >> +++ b/drivers/gpu/drm/panfrost/panfrost_device.h >> @@ -25,6 +25,14 @@ struct panfrost_perfcnt; >> #define NUM_JOB_SLOTS 3 >> #define MAX_PM_DOMAINS 5 >> >> +/** >> + * enum panfrost_gpu_pm - Supported kernel power management features >> + * @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend >> + */ >> +enum panfrost_gpu_pm { >> + GPU_PM_CLK_DIS, >> +}; >> + >> struct panfrost_features { >> u16 id; >> u16 revision; >> @@ -75,6 +83,9 @@ struct panfrost_compatible { >> >> /* Vendor implementation quirks callback */ >> void (*vendor_quirk)(struct panfrost_device *pfdev); >> + >> + /* Allowed PM features */ >> + u8 pm_features; > > Nit: I'd just use bitfields. They are easier to set and get without > extra macros, and the naming would be self-explanatory. Unless you > expect a need to do mask checking (though the compiler might be able > to optimize this). > I don't expect a need to do mask checking, but I don't expect the opposite either.. ...this could happen in the future, or maybe not, and this becomes a bool, even. That's why I went with a u8 :-) Let's keep it flexible. Thanks, Angelo > ChenYu > >> }; >> >> struct panfrost_device { >> -- >> 2.42.0 >> ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/4] drm/panfrost: Set clocks on/off during system sleep on MediaTek SoCs 2023-10-30 13:22 [PATCH 0/4] drm/panfrost: Turn off clocks and regulators in PM AngeloGioacchino Del Regno 2023-10-30 13:22 ` [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend AngeloGioacchino Del Regno @ 2023-10-30 13:22 ` AngeloGioacchino Del Regno 2023-10-30 13:22 ` [PATCH 3/4] drm/panfrost: Implement ability to turn on/off regulators in suspend AngeloGioacchino Del Regno 2023-10-30 13:22 ` [PATCH 4/4] drm/panfrost: Set regulators on/off during system sleep on MediaTek SoCs AngeloGioacchino Del Regno 3 siblings, 0 replies; 13+ messages in thread From: AngeloGioacchino Del Regno @ 2023-10-30 13:22 UTC (permalink / raw) To: boris.brezillon Cc: robh, steven.price, maarten.lankhorst, mripard, tzimmermann, airlied, daniel, dri-devel, linux-kernel, wenst, AngeloGioacchino Del Regno, kernel All of the MediaTek SoCs supported by Panfrost can switch the clocks off and on during system sleep to save some power without any user experience penalty. Measurements taken on multiple MediaTek SoCs show that adding this will not prolong the time that is required to resume the system in any meaningful way. As an example, for MT8195 - a "before" with only runtime PM operations (so, without turning on/off GPU clocks), and an "after" executing full system sleep .resume() handler (.resume() -> .runtime_resume() -> done): Average Panfrost-only system sleep resume time, before: 110372ns Average Panfrost-only system sleep resume time, after: 114186ns Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> --- drivers/gpu/drm/panfrost/panfrost_drv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 7cabf4e3d1f2..82f3c5fe9c58 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -734,6 +734,7 @@ static const struct panfrost_compatible mediatek_mt8183_b_data = { .supply_names = mediatek_mt8183_b_supplies, .num_pm_domains = ARRAY_SIZE(mediatek_mt8183_pm_domains), .pm_domain_names = mediatek_mt8183_pm_domains, + .pm_features = BIT(GPU_PM_CLK_DIS), }; static const char * const mediatek_mt8186_pm_domains[] = { "core0", "core1" }; @@ -742,6 +743,7 @@ static const struct panfrost_compatible mediatek_mt8186_data = { .supply_names = mediatek_mt8183_b_supplies, .num_pm_domains = ARRAY_SIZE(mediatek_mt8186_pm_domains), .pm_domain_names = mediatek_mt8186_pm_domains, + .pm_features = BIT(GPU_PM_CLK_DIS), }; static const char * const mediatek_mt8192_supplies[] = { "mali", NULL }; @@ -752,6 +754,7 @@ static const struct panfrost_compatible mediatek_mt8192_data = { .supply_names = mediatek_mt8192_supplies, .num_pm_domains = ARRAY_SIZE(mediatek_mt8192_pm_domains), .pm_domain_names = mediatek_mt8192_pm_domains, + .pm_features = BIT(GPU_PM_CLK_DIS), }; static const struct of_device_id dt_match[] = { -- 2.42.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/4] drm/panfrost: Implement ability to turn on/off regulators in suspend 2023-10-30 13:22 [PATCH 0/4] drm/panfrost: Turn off clocks and regulators in PM AngeloGioacchino Del Regno 2023-10-30 13:22 ` [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend AngeloGioacchino Del Regno 2023-10-30 13:22 ` [PATCH 2/4] drm/panfrost: Set clocks on/off during system sleep on MediaTek SoCs AngeloGioacchino Del Regno @ 2023-10-30 13:22 ` AngeloGioacchino Del Regno 2023-10-30 14:57 ` Steven Price 2023-10-30 13:22 ` [PATCH 4/4] drm/panfrost: Set regulators on/off during system sleep on MediaTek SoCs AngeloGioacchino Del Regno 3 siblings, 1 reply; 13+ messages in thread From: AngeloGioacchino Del Regno @ 2023-10-30 13:22 UTC (permalink / raw) To: boris.brezillon Cc: robh, steven.price, maarten.lankhorst, mripard, tzimmermann, airlied, daniel, dri-devel, linux-kernel, wenst, AngeloGioacchino Del Regno, kernel Some platforms/SoCs can power off the GPU entirely by completely cutting off power, greatly enhancing battery time during system suspend: add a new pm_feature GPU_PM_VREG_OFF to allow turning off the GPU regulators during full suspend only on selected platforms. Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> --- drivers/gpu/drm/panfrost/panfrost_device.c | 19 ++++++++++++++++++- drivers/gpu/drm/panfrost/panfrost_device.h | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c index 2022ed76a620..51b22eb0971d 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.c +++ b/drivers/gpu/drm/panfrost/panfrost_device.c @@ -431,10 +431,21 @@ static int panfrost_device_resume(struct device *dev) struct panfrost_device *pfdev = dev_get_drvdata(dev); int ret; + if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) { + unsigned long freq = pfdev->pfdevfreq.fast_rate; + struct dev_pm_opp *opp; + + opp = dev_pm_opp_find_freq_ceil(dev, &freq); + if (IS_ERR(opp)) + return PTR_ERR(opp); + dev_pm_opp_put(opp); + dev_pm_opp_set_opp(dev, opp); + } + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { ret = clk_enable(pfdev->clock); if (ret) - return ret; + goto err_clk; if (pfdev->bus_clock) { ret = clk_enable(pfdev->bus_clock); @@ -455,6 +466,9 @@ static int panfrost_device_resume(struct device *dev) err_bus_clk: if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) clk_disable(pfdev->clock); +err_clk: + if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) + dev_pm_opp_set_opp(dev, NULL); return ret; } @@ -474,6 +488,9 @@ static int panfrost_device_suspend(struct device *dev) clk_disable(pfdev->bus_clock); } + if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) + dev_pm_opp_set_opp(dev, NULL); + return 0; } diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h index d7f179eb8ea3..0fc558db6bfd 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.h +++ b/drivers/gpu/drm/panfrost/panfrost_device.h @@ -28,9 +28,11 @@ struct panfrost_perfcnt; /** * enum panfrost_gpu_pm - Supported kernel power management features * @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend + * @GPU_PM_VREG_OFF: Allow turning off regulators during system suspend */ enum panfrost_gpu_pm { GPU_PM_CLK_DIS, + GPU_PM_VREG_OFF, }; struct panfrost_features { -- 2.42.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 3/4] drm/panfrost: Implement ability to turn on/off regulators in suspend 2023-10-30 13:22 ` [PATCH 3/4] drm/panfrost: Implement ability to turn on/off regulators in suspend AngeloGioacchino Del Regno @ 2023-10-30 14:57 ` Steven Price 2023-10-31 9:00 ` AngeloGioacchino Del Regno 0 siblings, 1 reply; 13+ messages in thread From: Steven Price @ 2023-10-30 14:57 UTC (permalink / raw) To: AngeloGioacchino Del Regno, boris.brezillon Cc: robh, maarten.lankhorst, mripard, tzimmermann, airlied, daniel, dri-devel, linux-kernel, wenst, kernel On 30/10/2023 13:22, AngeloGioacchino Del Regno wrote: > Some platforms/SoCs can power off the GPU entirely by completely cutting > off power, greatly enhancing battery time during system suspend: add a > new pm_feature GPU_PM_VREG_OFF to allow turning off the GPU regulators > during full suspend only on selected platforms. > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > --- > drivers/gpu/drm/panfrost/panfrost_device.c | 19 ++++++++++++++++++- > drivers/gpu/drm/panfrost/panfrost_device.h | 2 ++ > 2 files changed, 20 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c > index 2022ed76a620..51b22eb0971d 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_device.c > +++ b/drivers/gpu/drm/panfrost/panfrost_device.c > @@ -431,10 +431,21 @@ static int panfrost_device_resume(struct device *dev) > struct panfrost_device *pfdev = dev_get_drvdata(dev); > int ret; > > + if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) { > + unsigned long freq = pfdev->pfdevfreq.fast_rate; > + struct dev_pm_opp *opp; > + > + opp = dev_pm_opp_find_freq_ceil(dev, &freq); > + if (IS_ERR(opp)) > + return PTR_ERR(opp); > + dev_pm_opp_put(opp); > + dev_pm_opp_set_opp(dev, opp); These lines look the wrong way round - surely we want to hang onto the reference until the set_opp call is made? Steve > + } > + > if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { > ret = clk_enable(pfdev->clock); > if (ret) > - return ret; > + goto err_clk; > > if (pfdev->bus_clock) { > ret = clk_enable(pfdev->bus_clock); > @@ -455,6 +466,9 @@ static int panfrost_device_resume(struct device *dev) > err_bus_clk: > if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) > clk_disable(pfdev->clock); > +err_clk: > + if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) > + dev_pm_opp_set_opp(dev, NULL); > return ret; > } > > @@ -474,6 +488,9 @@ static int panfrost_device_suspend(struct device *dev) > clk_disable(pfdev->bus_clock); > } > > + if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) > + dev_pm_opp_set_opp(dev, NULL); > + > return 0; > } > > diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h > index d7f179eb8ea3..0fc558db6bfd 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_device.h > +++ b/drivers/gpu/drm/panfrost/panfrost_device.h > @@ -28,9 +28,11 @@ struct panfrost_perfcnt; > /** > * enum panfrost_gpu_pm - Supported kernel power management features > * @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend > + * @GPU_PM_VREG_OFF: Allow turning off regulators during system suspend > */ > enum panfrost_gpu_pm { > GPU_PM_CLK_DIS, > + GPU_PM_VREG_OFF, > }; > > struct panfrost_features { ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/4] drm/panfrost: Implement ability to turn on/off regulators in suspend 2023-10-30 14:57 ` Steven Price @ 2023-10-31 9:00 ` AngeloGioacchino Del Regno 0 siblings, 0 replies; 13+ messages in thread From: AngeloGioacchino Del Regno @ 2023-10-31 9:00 UTC (permalink / raw) To: Steven Price, boris.brezillon Cc: robh, maarten.lankhorst, mripard, tzimmermann, airlied, daniel, dri-devel, linux-kernel, wenst, kernel Il 30/10/23 15:57, Steven Price ha scritto: > On 30/10/2023 13:22, AngeloGioacchino Del Regno wrote: >> Some platforms/SoCs can power off the GPU entirely by completely cutting >> off power, greatly enhancing battery time during system suspend: add a >> new pm_feature GPU_PM_VREG_OFF to allow turning off the GPU regulators >> during full suspend only on selected platforms. >> >> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> >> --- >> drivers/gpu/drm/panfrost/panfrost_device.c | 19 ++++++++++++++++++- >> drivers/gpu/drm/panfrost/panfrost_device.h | 2 ++ >> 2 files changed, 20 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c >> index 2022ed76a620..51b22eb0971d 100644 >> --- a/drivers/gpu/drm/panfrost/panfrost_device.c >> +++ b/drivers/gpu/drm/panfrost/panfrost_device.c >> @@ -431,10 +431,21 @@ static int panfrost_device_resume(struct device *dev) >> struct panfrost_device *pfdev = dev_get_drvdata(dev); >> int ret; >> >> + if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) { >> + unsigned long freq = pfdev->pfdevfreq.fast_rate; >> + struct dev_pm_opp *opp; >> + >> + opp = dev_pm_opp_find_freq_ceil(dev, &freq); >> + if (IS_ERR(opp)) >> + return PTR_ERR(opp); >> + dev_pm_opp_put(opp); >> + dev_pm_opp_set_opp(dev, opp); > > These lines look the wrong way round - surely we want to hang onto the > reference until the set_opp call is made? > Whoops! Yes, thanks, this happened during a cleanup for whatever reason. I'll invert those for v2. Angelo > Steve > >> + } >> + >> if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { >> ret = clk_enable(pfdev->clock); >> if (ret) >> - return ret; >> + goto err_clk; >> >> if (pfdev->bus_clock) { >> ret = clk_enable(pfdev->bus_clock); >> @@ -455,6 +466,9 @@ static int panfrost_device_resume(struct device *dev) >> err_bus_clk: >> if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) >> clk_disable(pfdev->clock); >> +err_clk: >> + if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) >> + dev_pm_opp_set_opp(dev, NULL); >> return ret; >> } >> >> @@ -474,6 +488,9 @@ static int panfrost_device_suspend(struct device *dev) >> clk_disable(pfdev->bus_clock); >> } >> >> + if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) >> + dev_pm_opp_set_opp(dev, NULL); >> + >> return 0; >> } >> >> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h >> index d7f179eb8ea3..0fc558db6bfd 100644 >> --- a/drivers/gpu/drm/panfrost/panfrost_device.h >> +++ b/drivers/gpu/drm/panfrost/panfrost_device.h >> @@ -28,9 +28,11 @@ struct panfrost_perfcnt; >> /** >> * enum panfrost_gpu_pm - Supported kernel power management features >> * @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend >> + * @GPU_PM_VREG_OFF: Allow turning off regulators during system suspend >> */ >> enum panfrost_gpu_pm { >> GPU_PM_CLK_DIS, >> + GPU_PM_VREG_OFF, >> }; >> >> struct panfrost_features { > > _______________________________________________ > Kernel mailing list -- kernel@mailman.collabora.com > To unsubscribe send an email to kernel-leave@mailman.collabora.com ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/4] drm/panfrost: Set regulators on/off during system sleep on MediaTek SoCs 2023-10-30 13:22 [PATCH 0/4] drm/panfrost: Turn off clocks and regulators in PM AngeloGioacchino Del Regno ` (2 preceding siblings ...) 2023-10-30 13:22 ` [PATCH 3/4] drm/panfrost: Implement ability to turn on/off regulators in suspend AngeloGioacchino Del Regno @ 2023-10-30 13:22 ` AngeloGioacchino Del Regno 3 siblings, 0 replies; 13+ messages in thread From: AngeloGioacchino Del Regno @ 2023-10-30 13:22 UTC (permalink / raw) To: boris.brezillon Cc: robh, steven.price, maarten.lankhorst, mripard, tzimmermann, airlied, daniel, dri-devel, linux-kernel, wenst, AngeloGioacchino Del Regno, kernel All of the MediaTek SoCs supported by Panfrost can completely cut power to the GPU during full system sleep without any user-noticeable delay in the resume operation, as shown by measurements taken on multiple MediaTek SoCs. As an example, for MT8195 - a "before" with only runtime PM operations (so, without turning on/off regulators), and an "after" executing full system sleep .resume() handler (.resume() -> .runtime_resume() -> done): Average Panfrost-only system sleep resume time, before: 114186ns Average Panfrost-only system sleep resume time, after: 189684ns Keep in mind that this additional ~0,075ms delay happens only in resume from a full system suspend, and not in runtime PM operations, hence it is acceptable. Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> --- drivers/gpu/drm/panfrost/panfrost_drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 82f3c5fe9c58..f63382d9ab04 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -734,7 +734,7 @@ static const struct panfrost_compatible mediatek_mt8183_b_data = { .supply_names = mediatek_mt8183_b_supplies, .num_pm_domains = ARRAY_SIZE(mediatek_mt8183_pm_domains), .pm_domain_names = mediatek_mt8183_pm_domains, - .pm_features = BIT(GPU_PM_CLK_DIS), + .pm_features = BIT(GPU_PM_CLK_DIS) | BIT(GPU_PM_VREG_OFF), }; static const char * const mediatek_mt8186_pm_domains[] = { "core0", "core1" }; @@ -743,7 +743,7 @@ static const struct panfrost_compatible mediatek_mt8186_data = { .supply_names = mediatek_mt8183_b_supplies, .num_pm_domains = ARRAY_SIZE(mediatek_mt8186_pm_domains), .pm_domain_names = mediatek_mt8186_pm_domains, - .pm_features = BIT(GPU_PM_CLK_DIS), + .pm_features = BIT(GPU_PM_CLK_DIS) | BIT(GPU_PM_VREG_OFF), }; static const char * const mediatek_mt8192_supplies[] = { "mali", NULL }; @@ -754,7 +754,7 @@ static const struct panfrost_compatible mediatek_mt8192_data = { .supply_names = mediatek_mt8192_supplies, .num_pm_domains = ARRAY_SIZE(mediatek_mt8192_pm_domains), .pm_domain_names = mediatek_mt8192_pm_domains, - .pm_features = BIT(GPU_PM_CLK_DIS), + .pm_features = BIT(GPU_PM_CLK_DIS) | BIT(GPU_PM_VREG_OFF), }; static const struct of_device_id dt_match[] = { -- 2.42.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2023-11-01 11:28 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-10-30 13:22 [PATCH 0/4] drm/panfrost: Turn off clocks and regulators in PM AngeloGioacchino Del Regno 2023-10-30 13:22 ` [PATCH 1/4] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend AngeloGioacchino Del Regno 2023-10-30 14:57 ` Steven Price 2023-10-31 8:59 ` AngeloGioacchino Del Regno 2023-10-31 10:33 ` AngeloGioacchino Del Regno 2023-11-01 11:28 ` Steven Price 2023-10-31 3:18 ` Chen-Yu Tsai 2023-10-31 13:20 ` AngeloGioacchino Del Regno 2023-10-30 13:22 ` [PATCH 2/4] drm/panfrost: Set clocks on/off during system sleep on MediaTek SoCs AngeloGioacchino Del Regno 2023-10-30 13:22 ` [PATCH 3/4] drm/panfrost: Implement ability to turn on/off regulators in suspend AngeloGioacchino Del Regno 2023-10-30 14:57 ` Steven Price 2023-10-31 9:00 ` AngeloGioacchino Del Regno 2023-10-30 13:22 ` [PATCH 4/4] drm/panfrost: Set regulators on/off during system sleep on MediaTek SoCs AngeloGioacchino Del Regno
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox