From: "Adrián Larumbe" <adrian.larumbe@collabora.com>
To: Boris Brezillon <boris.brezillon@collabora.com>,
Rob Herring <robh@kernel.org>,
Steven Price <steven.price@arm.com>,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>,
David Airlie <airlied@gmail.com>,
Simona Vetter <simona@ffwll.ch>,
Faith Ekstrand <faith.ekstrand@collabora.com>,
"Marty E. Plummer" <hanetzer@startmail.com>,
Tomeu Vizoso <tomeu@tomeuvizoso.net>,
Eric Anholt <eric@anholt.net>,
Robin Murphy <robin.murphy@arm.com>,
Philipp Zabel <p.zabel@pengutronix.de>
Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
"Collabora Kernel Team" <kernel@collabora.com>,
"Adrián Larumbe" <adrian.larumbe@collabora.com>,
"Neil Armstrong" <neil.armstrong@linaro.org>
Subject: [PATCH v15 05/15] drm/panfrost: Consolidate device clock management and reset
Date: Mon, 12 Oct 2026 15:47:57 +0100 [thread overview]
Message-ID: <20261012-claude-fixes-v15-5-bc0a6c498553@collabora.com> (raw)
In-Reply-To: <20261012-claude-fixes-v15-0-bc0a6c498553@collabora.com>
Gather all clock enables and disables into a single function to avoid
repetitions between driver init/fini and device resume/suspend, since
these clocks are always handled in bulk.
Also do clk (un)prepares and dis/enables at the same time, since the
clk_prepare_* family of functions can simply increase the refcnt of
an already prepared clock.
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
---
drivers/gpu/drm/panfrost/panfrost_device.c | 124 ++++++++++++++++-------------
1 file changed, 69 insertions(+), 55 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c
index b3a53504bd01..50f4713bfcfd 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -34,10 +34,46 @@ static void panfrost_reset_fini(struct panfrost_device *pfdev)
reset_control_assert(pfdev->rstc);
}
-static int panfrost_clk_init(struct panfrost_device *pfdev)
+static int panfrost_clks_enable(struct panfrost_device *pfdev, bool on_resume)
{
int err;
+
+ err = clk_prepare_enable(pfdev->clock);
+ if (err)
+ return err;
+
+ err = clk_prepare_enable(pfdev->bus_clock);
+ if (err)
+ goto disable_clock;
+
+ if (on_resume) {
+ err = clk_prepare_enable(pfdev->bus_ace_clock);
+ if (err)
+ goto disable_bus_clock;
+ }
+
+ return 0;
+
+disable_bus_clock:
+ clk_disable_unprepare(pfdev->bus_clock);
+disable_clock:
+ clk_disable_unprepare(pfdev->clock);
+
+ return err;
+}
+
+static void panfrost_clks_disable(struct panfrost_device *pfdev, bool on_suspend)
+{
+ if (on_suspend)
+ clk_disable_unprepare(pfdev->bus_ace_clock);
+ clk_disable_unprepare(pfdev->bus_clock);
+ clk_disable_unprepare(pfdev->clock);
+}
+
+static int panfrost_clk_init(struct panfrost_device *pfdev)
+{
unsigned long rate;
+ int err;
pfdev->clock = devm_clk_get(pfdev->base.dev, NULL);
if (IS_ERR(pfdev->clock)) {
@@ -48,53 +84,59 @@ static int panfrost_clk_init(struct panfrost_device *pfdev)
rate = clk_get_rate(pfdev->clock);
dev_info(pfdev->base.dev, "clock rate = %lu\n", rate);
- err = clk_prepare_enable(pfdev->clock);
+ err = clk_prepare(pfdev->clock);
if (err)
return err;
pfdev->bus_clock = devm_clk_get_optional(pfdev->base.dev, "bus");
if (IS_ERR(pfdev->bus_clock)) {
- dev_err(pfdev->base.dev, "get bus_clock failed %ld\n",
- PTR_ERR(pfdev->bus_clock));
err = PTR_ERR(pfdev->bus_clock);
- goto disable_clock;
+ dev_err(pfdev->base.dev, "get bus_clock failed %d\n", err);
+ goto unprepare_clock;
}
if (pfdev->bus_clock) {
rate = clk_get_rate(pfdev->bus_clock);
dev_info(pfdev->base.dev, "bus_clock rate = %lu\n", rate);
- err = clk_prepare_enable(pfdev->bus_clock);
+ err = clk_prepare(pfdev->bus_clock);
if (err)
- goto disable_clock;
+ goto unprepare_clock;
}
pfdev->bus_ace_clock = devm_clk_get_optional(pfdev->base.dev, "bus_ace");
if (IS_ERR(pfdev->bus_ace_clock)) {
err = PTR_ERR(pfdev->bus_ace_clock);
dev_err(pfdev->base.dev, "get bus_ace_clock failed %d\n", err);
- goto disable_bus_clock;
+ goto unprepare_bus_clock;
}
- err = clk_prepare_enable(pfdev->bus_ace_clock);
+ err = clk_prepare(pfdev->bus_ace_clock);
+ if (err)
+ goto unprepare_bus_clock;
+
+ err = panfrost_clks_enable(pfdev, true);
if (err)
- goto disable_bus_clock;
+ goto unprepare_bus_ace_clock;
return 0;
-disable_bus_clock:
- clk_disable_unprepare(pfdev->bus_clock);
-disable_clock:
- clk_disable_unprepare(pfdev->clock);
+unprepare_bus_ace_clock:
+ clk_unprepare(pfdev->bus_ace_clock);
+unprepare_bus_clock:
+ clk_unprepare(pfdev->bus_clock);
+unprepare_clock:
+ clk_unprepare(pfdev->clock);
return err;
}
static void panfrost_clk_fini(struct panfrost_device *pfdev)
{
- clk_disable_unprepare(pfdev->bus_ace_clock);
- clk_disable_unprepare(pfdev->bus_clock);
- clk_disable_unprepare(pfdev->clock);
+ panfrost_clks_disable(pfdev, true);
+ clk_unprepare(pfdev->bus_ace_clock);
+ clk_unprepare(pfdev->bus_clock);
+ clk_unprepare(pfdev->clock);
}
static int panfrost_regulator_init(struct panfrost_device *pfdev)
@@ -436,34 +478,17 @@ static int panfrost_device_runtime_resume(struct device *dev)
if (ret)
return ret;
- ret = clk_enable(pfdev->clock);
- if (ret)
- goto err_clk;
-
- ret = clk_enable(pfdev->bus_clock);
- if (ret)
- goto err_bus_clk;
-
- ret = clk_enable(pfdev->bus_ace_clock);
- if (ret)
- goto err_bus_ace_clk;
+ ret = panfrost_clks_enable(pfdev, true);
+ if (ret) {
+ reset_control_assert(pfdev->rstc);
+ return ret;
+ }
}
panfrost_device_reset(pfdev, true);
panfrost_devfreq_resume(pfdev);
return 0;
-
-err_bus_ace_clk:
- if (pfdev->comp->pm_features & BIT(GPU_PM_RT))
- clk_disable(pfdev->bus_clock);
-err_bus_clk:
- if (pfdev->comp->pm_features & BIT(GPU_PM_RT))
- clk_disable(pfdev->clock);
-err_clk:
- if (pfdev->comp->pm_features & BIT(GPU_PM_RT))
- reset_control_assert(pfdev->rstc);
- return ret;
}
static int panfrost_device_runtime_suspend(struct device *dev)
@@ -480,9 +505,7 @@ static int panfrost_device_runtime_suspend(struct device *dev)
panfrost_gpu_power_off(pfdev);
if (pfdev->comp->pm_features & BIT(GPU_PM_RT)) {
- clk_disable(pfdev->bus_ace_clock);
- clk_disable(pfdev->bus_clock);
- clk_disable(pfdev->clock);
+ panfrost_clks_disable(pfdev, true);
reset_control_assert(pfdev->rstc);
}
@@ -506,13 +529,9 @@ static int panfrost_device_resume(struct device *dev)
}
if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) {
- ret = clk_enable(pfdev->clock);
+ ret = panfrost_clks_enable(pfdev, false);
if (ret)
goto err_clk;
-
- ret = clk_enable(pfdev->bus_clock);
- if (ret)
- goto err_bus_clk;
}
ret = pm_runtime_force_resume(dev);
@@ -523,10 +542,7 @@ static int panfrost_device_resume(struct device *dev)
err_resume:
if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS))
- clk_disable(pfdev->bus_clock);
-err_bus_clk:
- if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS))
- clk_disable(pfdev->clock);
+ panfrost_clks_disable(pfdev, false);
err_clk:
if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF))
dev_pm_opp_set_opp(dev, NULL);
@@ -542,10 +558,8 @@ static int panfrost_device_suspend(struct device *dev)
if (ret)
return ret;
- if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) {
- clk_disable(pfdev->bus_clock);
- clk_disable(pfdev->clock);
- }
+ if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS))
+ panfrost_clks_disable(pfdev, false);
if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF))
dev_pm_opp_set_opp(dev, NULL);
--
2.55.0
next prev parent reply other threads:[~2026-10-12 14:48 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-12 14:47 [PATCH v15 00/15] Collection of fixes for Panfrost: Perfcnt, RPM, refactorings Adrián Larumbe
2026-10-12 14:47 ` [PATCH v15 01/15] drm/panfrost: Move shrinker initialization and unplug one level down Adrián Larumbe
2026-10-12 14:47 ` [PATCH v15 02/15] drm/panfrost: Move lock and modparam initialisations into their subsystems Adrián Larumbe
2026-10-12 14:47 ` [PATCH v15 03/15] drm/panfrost: Move debugfs initialisation to relevant subsystems Adrián Larumbe
2026-10-12 14:47 ` [PATCH v15 04/15] drm/panfrost: Skip NULL checks for clock enable/disabling Adrián Larumbe
2026-10-12 14:47 ` Adrián Larumbe [this message]
2026-10-12 14:47 ` [PATCH v15 06/15] drm/panfrost: Fix PM refcnt and autosuspend issues at device probe/remove Adrián Larumbe
2026-10-12 14:47 ` [PATCH v15 07/15] drm/panfrost: Explicitly enable MMU interrupts at device init Adrián Larumbe
2026-10-12 14:48 ` [PATCH v15 08/15] drm/panfrost: Move all DRM device initialisation into device_init() Adrián Larumbe
2026-10-12 14:48 ` [PATCH v15 09/15] drm/panfrost: Warn of RPM get failure at device remove time Adrián Larumbe
2026-10-12 14:48 ` [PATCH v15 10/15] drm/panfrost: Add debugfs knob for manually triggering a GPU reset Adrián Larumbe
2026-10-12 14:48 ` [PATCH v15 11/15] drm/panfrost: Move perfcnt GPU disable sequence into a helper Adrián Larumbe
2026-10-12 14:48 ` [PATCH v15 12/15] drm/panfrost: Skip cache flush/invalidate when enabling perfcnt Adrián Larumbe
2026-10-12 14:48 ` [PATCH v15 13/15] drm/panfrost: Avoid cache flush after perfcnt sample in fully coherent systems Adrián Larumbe
2026-10-12 14:48 ` [PATCH v15 14/15] drm/panfrost: Introduce a reset lock Adrián Larumbe
2026-10-12 14:48 ` [PATCH v15 15/15] drm/panfrost: Fix races between perfcnt and reset sequence Adrián Larumbe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261012-claude-fixes-v15-5-bc0a6c498553@collabora.com \
--to=adrian.larumbe@collabora.com \
--cc=airlied@gmail.com \
--cc=boris.brezillon@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=eric@anholt.net \
--cc=faith.ekstrand@collabora.com \
--cc=hanetzer@startmail.com \
--cc=kernel@collabora.com \
--cc=linux-kernel@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=p.zabel@pengutronix.de \
--cc=robh@kernel.org \
--cc=robin.murphy@arm.com \
--cc=simona@ffwll.ch \
--cc=steven.price@arm.com \
--cc=tomeu@tomeuvizoso.net \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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®