]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/exynos: fimd: Guard display clock control with runtime PM calls
authorMarek Szyprowski <m.szyprowski@samsung.com>
Wed, 18 Jun 2025 12:06:26 +0000 (14:06 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Jul 2025 16:24:56 +0000 (18:24 +0200)
[ Upstream commit 5d91394f236167ac624b823820faf4aa928b889e ]

Commit c9b1150a68d9 ("drm/atomic-helper: Re-order bridge chain pre-enable
and post-disable") changed the call sequence to the CRTC enable/disable
and bridge pre_enable/post_disable methods, so those bridge methods are
now called when CRTC is not yet enabled.

This causes a lockup observed on Samsung Peach-Pit/Pi Chromebooks. The
source of this lockup is a call to fimd_dp_clock_enable() function, when
FIMD device is not yet runtime resumed. It worked before the mentioned
commit only because the CRTC implemented by the FIMD driver was always
enabled what guaranteed the FIMD device to be runtime resumed.

This patch adds runtime PM guards to the fimd_dp_clock_enable() function
to enable its proper operation also when the CRTC implemented by FIMD is
not yet enabled.

Fixes: 196e059a8a6a ("drm/exynos: convert clock_enable crtc callback to pipeline clock")
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/exynos/exynos_drm_fimd.c

index 4fe4ca41665b35621783de40df876e3575c4fde7..1978491d3f846e2ea50349456f5389f06fe525f5 100644 (file)
@@ -182,6 +182,7 @@ struct fimd_context {
        u32                             i80ifcon;
        bool                            i80_if;
        bool                            suspended;
+       bool                            dp_clk_enabled;
        wait_queue_head_t               wait_vsync_queue;
        atomic_t                        wait_vsync_event;
        atomic_t                        win_updated;
@@ -1003,7 +1004,18 @@ static void fimd_dp_clock_enable(struct exynos_drm_clk *clk, bool enable)
        struct fimd_context *ctx = container_of(clk, struct fimd_context,
                                                dp_clk);
        u32 val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE;
+
+       if (enable == ctx->dp_clk_enabled)
+               return;
+
+       if (enable)
+               pm_runtime_resume_and_get(ctx->dev);
+
+       ctx->dp_clk_enabled = enable;
        writel(val, ctx->regs + DP_MIE_CLKCON);
+
+       if (!enable)
+               pm_runtime_put(ctx->dev);
 }
 
 static const struct exynos_drm_crtc_ops fimd_crtc_ops = {