Tested and works on samsung-skomer. Signed-off-by: Stefan Hansson <newbyte@postmarketos.org> Part-of: <https://gitlab.postmarketos.org/postmarketOS/pmaports/-/merge_requests/7660>
494 lines
18 KiB
Diff
494 lines
18 KiB
Diff
From git@z Thu Jan 1 00:00:00 1970
|
|
Subject: [PATCH v5 1/3] drm/atomic-helper: Export and namespace some
|
|
functions
|
|
From: Linus Walleij <linusw@kernel.org>
|
|
Date: Sun, 30 Nov 2025 13:11:17 +0100
|
|
Message-Id: <20251130-mcde-drm-regression-thirdfix-v5-1-aed71a32981d@kernel.org>
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset="utf-8"
|
|
Content-Transfer-Encoding: 7bit
|
|
|
|
Export and namespace those not prefixed with drm_* so
|
|
it becomes possible to write custom commit tail functions
|
|
in individual drivers using the helper infrastructure.
|
|
|
|
Tested-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
|
|
Signed-off-by: Linus Walleij <linusw@kernel.org>
|
|
Reviewed-by: Maxime Ripard <mripard@kernel.org>
|
|
Reviewed-by: Aradhya Bhatia <aradhya.bhatia@linux.dev>
|
|
---
|
|
drivers/gpu/drm/drm_atomic_helper.c | 122 +++++++++++++++++++++++++++++-------
|
|
include/drm/drm_atomic_helper.h | 22 +++++++
|
|
2 files changed, 121 insertions(+), 23 deletions(-)
|
|
|
|
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
|
|
index d5ebe6ea0acb..bfbe3a0ee178 100644
|
|
--- a/drivers/gpu/drm/drm_atomic_helper.c
|
|
+++ b/drivers/gpu/drm/drm_atomic_helper.c
|
|
@@ -1162,8 +1162,18 @@ crtc_needs_disable(struct drm_crtc_state *old_state,
|
|
new_state->self_refresh_active;
|
|
}
|
|
|
|
-static void
|
|
-encoder_bridge_disable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
+/**
|
|
+ * drm_atomic_helper_commit_encoder_bridge_disable - disable bridges and encoder
|
|
+ * @dev: DRM device
|
|
+ * @state: the driver state object
|
|
+ *
|
|
+ * Loops over all connectors in the current state and if the CRTC needs
|
|
+ * it, disables the bridge chain all the way, then disables the encoder
|
|
+ * afterwards.
|
|
+ */
|
|
+void
|
|
+drm_atomic_helper_commit_encoder_bridge_disable(struct drm_device *dev,
|
|
+ struct drm_atomic_state *state)
|
|
{
|
|
struct drm_connector *connector;
|
|
struct drm_connector_state *old_conn_state, *new_conn_state;
|
|
@@ -1229,9 +1239,18 @@ encoder_bridge_disable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
}
|
|
}
|
|
}
|
|
+EXPORT_SYMBOL(drm_atomic_helper_commit_encoder_bridge_disable);
|
|
|
|
-static void
|
|
-crtc_disable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
+/**
|
|
+ * drm_atomic_helper_commit_crtc_disable - disable CRTSs
|
|
+ * @dev: DRM device
|
|
+ * @state: the driver state object
|
|
+ *
|
|
+ * Loops over all CRTCs in the current state and if the CRTC needs
|
|
+ * it, disables it.
|
|
+ */
|
|
+void
|
|
+drm_atomic_helper_commit_crtc_disable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
{
|
|
struct drm_crtc *crtc;
|
|
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
|
|
@@ -1282,9 +1301,18 @@ crtc_disable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
drm_crtc_vblank_put(crtc);
|
|
}
|
|
}
|
|
+EXPORT_SYMBOL(drm_atomic_helper_commit_crtc_disable);
|
|
|
|
-static void
|
|
-encoder_bridge_post_disable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
+/**
|
|
+ * drm_atomic_helper_commit_encoder_bridge_post_disable - post-disable encoder bridges
|
|
+ * @dev: DRM device
|
|
+ * @state: the driver state object
|
|
+ *
|
|
+ * Loops over all connectors in the current state and if the CRTC needs
|
|
+ * it, post-disables all encoder bridges.
|
|
+ */
|
|
+void
|
|
+drm_atomic_helper_commit_encoder_bridge_post_disable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
{
|
|
struct drm_connector *connector;
|
|
struct drm_connector_state *old_conn_state, *new_conn_state;
|
|
@@ -1335,15 +1363,16 @@ encoder_bridge_post_disable(struct drm_device *dev, struct drm_atomic_state *sta
|
|
drm_bridge_put(bridge);
|
|
}
|
|
}
|
|
+EXPORT_SYMBOL(drm_atomic_helper_commit_encoder_bridge_post_disable);
|
|
|
|
static void
|
|
disable_outputs(struct drm_device *dev, struct drm_atomic_state *state)
|
|
{
|
|
- encoder_bridge_disable(dev, state);
|
|
+ drm_atomic_helper_commit_encoder_bridge_disable(dev, state);
|
|
|
|
- crtc_disable(dev, state);
|
|
+ drm_atomic_helper_commit_crtc_disable(dev, state);
|
|
|
|
- encoder_bridge_post_disable(dev, state);
|
|
+ drm_atomic_helper_commit_encoder_bridge_post_disable(dev, state);
|
|
}
|
|
|
|
/**
|
|
@@ -1446,8 +1475,17 @@ void drm_atomic_helper_calc_timestamping_constants(struct drm_atomic_state *stat
|
|
}
|
|
EXPORT_SYMBOL(drm_atomic_helper_calc_timestamping_constants);
|
|
|
|
-static void
|
|
-crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *state)
|
|
+/**
|
|
+ * drm_atomic_helper_commit_crtc_set_mode - set the new mode
|
|
+ * @dev: DRM device
|
|
+ * @state: the driver state object
|
|
+ *
|
|
+ * Loops over all connectors in the current state and if the mode has
|
|
+ * changed, change the mode of the CRTC, then call down the bridge
|
|
+ * chain and change the mode in all bridges as well.
|
|
+ */
|
|
+void
|
|
+drm_atomic_helper_commit_crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *state)
|
|
{
|
|
struct drm_crtc *crtc;
|
|
struct drm_crtc_state *new_crtc_state;
|
|
@@ -1508,6 +1546,7 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *state)
|
|
drm_bridge_put(bridge);
|
|
}
|
|
}
|
|
+EXPORT_SYMBOL(drm_atomic_helper_commit_crtc_set_mode);
|
|
|
|
/**
|
|
* drm_atomic_helper_commit_modeset_disables - modeset commit to disable outputs
|
|
@@ -1531,12 +1570,21 @@ void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev,
|
|
drm_atomic_helper_update_legacy_modeset_state(dev, state);
|
|
drm_atomic_helper_calc_timestamping_constants(state);
|
|
|
|
- crtc_set_mode(dev, state);
|
|
+ drm_atomic_helper_commit_crtc_set_mode(dev, state);
|
|
}
|
|
EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_disables);
|
|
|
|
-static void drm_atomic_helper_commit_writebacks(struct drm_device *dev,
|
|
- struct drm_atomic_state *state)
|
|
+/**
|
|
+ * drm_atomic_helper_commit_writebacks - issue writebacks
|
|
+ * @dev: DRM device
|
|
+ * @state: atomic state object being committed
|
|
+ *
|
|
+ * This loops over the connectors, checks if the new state requires
|
|
+ * a writeback job to be issued and in that case issues an atomic
|
|
+ * commit on each connector.
|
|
+ */
|
|
+void drm_atomic_helper_commit_writebacks(struct drm_device *dev,
|
|
+ struct drm_atomic_state *state)
|
|
{
|
|
struct drm_connector *connector;
|
|
struct drm_connector_state *new_conn_state;
|
|
@@ -1555,9 +1603,18 @@ static void drm_atomic_helper_commit_writebacks(struct drm_device *dev,
|
|
}
|
|
}
|
|
}
|
|
+EXPORT_SYMBOL(drm_atomic_helper_commit_writebacks);
|
|
|
|
-static void
|
|
-encoder_bridge_pre_enable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
+/**
|
|
+ * drm_atomic_helper_commit_encoder_bridge_pre_enable - pre-enable bridges
|
|
+ * @dev: DRM device
|
|
+ * @state: atomic state object being committed
|
|
+ *
|
|
+ * This loops over the connectors and if the CRTC needs it, pre-enables
|
|
+ * the entire bridge chain.
|
|
+ */
|
|
+void
|
|
+drm_atomic_helper_commit_encoder_bridge_pre_enable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
{
|
|
struct drm_connector *connector;
|
|
struct drm_connector_state *new_conn_state;
|
|
@@ -1588,9 +1645,18 @@ encoder_bridge_pre_enable(struct drm_device *dev, struct drm_atomic_state *state
|
|
drm_bridge_put(bridge);
|
|
}
|
|
}
|
|
+EXPORT_SYMBOL(drm_atomic_helper_commit_encoder_bridge_pre_enable);
|
|
|
|
-static void
|
|
-crtc_enable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
+/**
|
|
+ * drm_atomic_helper_commit_crtc_enable - enables the CRTCs
|
|
+ * @dev: DRM device
|
|
+ * @state: atomic state object being committed
|
|
+ *
|
|
+ * This loops over CRTCs in the new state, and of the CRTC needs
|
|
+ * it, enables it.
|
|
+ */
|
|
+void
|
|
+drm_atomic_helper_commit_crtc_enable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
{
|
|
struct drm_crtc *crtc;
|
|
struct drm_crtc_state *old_crtc_state;
|
|
@@ -1619,9 +1685,18 @@ crtc_enable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
}
|
|
}
|
|
}
|
|
+EXPORT_SYMBOL(drm_atomic_helper_commit_crtc_enable);
|
|
|
|
-static void
|
|
-encoder_bridge_enable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
+/**
|
|
+ * drm_atomic_helper_commit_encoder_bridge_enable - enables the bridges
|
|
+ * @dev: DRM device
|
|
+ * @state: atomic state object being committed
|
|
+ *
|
|
+ * This loops over all connectors in the new state, and of the CRTC needs
|
|
+ * it, enables the entire bridge chain.
|
|
+ */
|
|
+void
|
|
+drm_atomic_helper_commit_encoder_bridge_enable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
{
|
|
struct drm_connector *connector;
|
|
struct drm_connector_state *new_conn_state;
|
|
@@ -1664,6 +1739,7 @@ encoder_bridge_enable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
drm_bridge_put(bridge);
|
|
}
|
|
}
|
|
+EXPORT_SYMBOL(drm_atomic_helper_commit_encoder_bridge_enable);
|
|
|
|
/**
|
|
* drm_atomic_helper_commit_modeset_enables - modeset commit to enable outputs
|
|
@@ -1682,11 +1758,11 @@ encoder_bridge_enable(struct drm_device *dev, struct drm_atomic_state *state)
|
|
void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
|
|
struct drm_atomic_state *state)
|
|
{
|
|
- encoder_bridge_pre_enable(dev, state);
|
|
+ drm_atomic_helper_commit_encoder_bridge_pre_enable(dev, state);
|
|
|
|
- crtc_enable(dev, state);
|
|
+ drm_atomic_helper_commit_crtc_enable(dev, state);
|
|
|
|
- encoder_bridge_enable(dev, state);
|
|
+ drm_atomic_helper_commit_encoder_bridge_enable(dev, state);
|
|
|
|
drm_atomic_helper_commit_writebacks(dev, state);
|
|
}
|
|
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
|
|
index 53382fe93537..9afc2e1e24c7 100644
|
|
--- a/include/drm/drm_atomic_helper.h
|
|
+++ b/include/drm/drm_atomic_helper.h
|
|
@@ -60,6 +60,12 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
|
|
int drm_atomic_helper_check_planes(struct drm_device *dev,
|
|
struct drm_atomic_state *state);
|
|
int drm_atomic_helper_check_crtc_primary_plane(struct drm_crtc_state *crtc_state);
|
|
+void drm_atomic_helper_commit_encoder_bridge_disable(struct drm_device *dev,
|
|
+ struct drm_atomic_state *state);
|
|
+void drm_atomic_helper_commit_crtc_disable(struct drm_device *dev,
|
|
+ struct drm_atomic_state *state);
|
|
+void drm_atomic_helper_commit_encoder_bridge_post_disable(struct drm_device *dev,
|
|
+ struct drm_atomic_state *state);
|
|
int drm_atomic_helper_check(struct drm_device *dev,
|
|
struct drm_atomic_state *state);
|
|
void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
|
|
@@ -89,8 +95,24 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
|
|
void
|
|
drm_atomic_helper_calc_timestamping_constants(struct drm_atomic_state *state);
|
|
|
|
+void drm_atomic_helper_commit_crtc_set_mode(struct drm_device *dev,
|
|
+ struct drm_atomic_state *state);
|
|
+
|
|
void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev,
|
|
struct drm_atomic_state *state);
|
|
+
|
|
+void drm_atomic_helper_commit_writebacks(struct drm_device *dev,
|
|
+ struct drm_atomic_state *state);
|
|
+
|
|
+void drm_atomic_helper_commit_encoder_bridge_pre_enable(struct drm_device *dev,
|
|
+ struct drm_atomic_state *state);
|
|
+
|
|
+void drm_atomic_helper_commit_crtc_enable(struct drm_device *dev,
|
|
+ struct drm_atomic_state *state);
|
|
+
|
|
+void drm_atomic_helper_commit_encoder_bridge_enable(struct drm_device *dev,
|
|
+ struct drm_atomic_state *state);
|
|
+
|
|
void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
|
|
struct drm_atomic_state *old_state);
|
|
|
|
|
|
--
|
|
2.51.1
|
|
|
|
From git@z Thu Jan 1 00:00:00 1970
|
|
Subject: [PATCH v5 2/3] drm/mcde: Create custom commit tail
|
|
From: Linus Walleij <linusw@kernel.org>
|
|
Date: Sun, 30 Nov 2025 13:11:18 +0100
|
|
Message-Id: <20251130-mcde-drm-regression-thirdfix-v5-2-aed71a32981d@kernel.org>
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset="utf-8"
|
|
Content-Transfer-Encoding: 7bit
|
|
|
|
commit c9b1150a68d9362a0827609fc0dc1664c0d8bfe1
|
|
"drm/atomic-helper: Re-order bridge chain pre-enable and post-disable"
|
|
caused a series of regressions in all panels that send
|
|
DSI commands in their .prepare() and .unprepare()
|
|
callbacks when used with MCDE.
|
|
|
|
As the CRTC is no longer online at bridge_pre_enable()
|
|
and gone at brige_post_disable() which maps to the panel
|
|
bridge .prepare()/.unprepare() callbacks, any CRTC that
|
|
enable/disable the DSI transmitter in it's enable/disable
|
|
callbacks will be unable to send any DSI commands in the
|
|
.prepare() and .unprepare() callbacks.
|
|
|
|
However the MCDE driver definitely need the CRTC to be
|
|
enabled during .prepare()/.unprepare().
|
|
|
|
Solve this by implementing a custom commit tail function
|
|
in the MCDE driver that always enables the CRTC first
|
|
and disables it last, using the newly exported helpers.
|
|
|
|
Link: https://lore.kernel.org/dri-devel/20251026-fix-mcde-drm-regression-v2-0-8d799e488cf9@linaro.org/
|
|
Link: https://lore.kernel.org/all/20251107230517.471894-1-marek.vasut%2Brenesas%40mailbox.org/
|
|
Fixes: c9b1150a68d9 ("drm/atomic-helper: Re-order bridge chain pre-enable and post-disable")
|
|
Tested-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
|
|
Signed-off-by: Linus Walleij <linusw@kernel.org>
|
|
Reviewed-by: Maxime Ripard <mripard@kernel.org>
|
|
Acked-by: Aradhya Bhatia <aradhya.bhatia@linux.dev>
|
|
---
|
|
drivers/gpu/drm/mcde/mcde_drv.c | 45 ++++++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 44 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
|
|
index 5f2c462bad7e..eb3a8bb8766b 100644
|
|
--- a/drivers/gpu/drm/mcde/mcde_drv.c
|
|
+++ b/drivers/gpu/drm/mcde/mcde_drv.c
|
|
@@ -100,13 +100,56 @@ static const struct drm_mode_config_funcs mcde_mode_config_funcs = {
|
|
.atomic_commit = drm_atomic_helper_commit,
|
|
};
|
|
|
|
+/*
|
|
+ * This commit tail explicitly copies and changes the behaviour of
|
|
+ * the related core DRM atomic helper instead of trying to make
|
|
+ * the core helpers overly generic.
|
|
+ */
|
|
+static void mcde_atomic_commit_tail(struct drm_atomic_state *state)
|
|
+{
|
|
+ struct drm_device *dev = state->dev;
|
|
+
|
|
+ /*
|
|
+ * Variant of drm_atomic_helper_commit_modeset_disables()
|
|
+ * that will disable and post-disable all bridges BEFORE
|
|
+ * disabling the CRTC.
|
|
+ */
|
|
+ drm_atomic_helper_commit_encoder_bridge_disable(dev, state);
|
|
+ drm_atomic_helper_commit_encoder_bridge_post_disable(dev, state);
|
|
+ drm_atomic_helper_commit_crtc_disable(dev, state);
|
|
+ drm_atomic_helper_update_legacy_modeset_state(dev, state);
|
|
+ drm_atomic_helper_calc_timestamping_constants(state);
|
|
+ drm_atomic_helper_commit_crtc_set_mode(dev, state);
|
|
+
|
|
+ /*
|
|
+ * Variant of drm_atomic_helper_commit_modeset_enables()
|
|
+ * that will enable the CRTC BEFORE pre-enabling and
|
|
+ * enabling the bridges.
|
|
+ */
|
|
+ drm_atomic_helper_commit_crtc_enable(dev, state);
|
|
+ drm_atomic_helper_commit_encoder_bridge_pre_enable(dev, state);
|
|
+ drm_atomic_helper_commit_encoder_bridge_enable(dev, state);
|
|
+ drm_atomic_helper_commit_writebacks(dev, state);
|
|
+
|
|
+ drm_atomic_helper_commit_planes(dev, state,
|
|
+ DRM_PLANE_COMMIT_ACTIVE_ONLY);
|
|
+
|
|
+ drm_atomic_helper_fake_vblank(state);
|
|
+
|
|
+ drm_atomic_helper_commit_hw_done(state);
|
|
+
|
|
+ drm_atomic_helper_wait_for_vblanks(dev, state);
|
|
+
|
|
+ drm_atomic_helper_cleanup_planes(dev, state);
|
|
+}
|
|
+
|
|
static const struct drm_mode_config_helper_funcs mcde_mode_config_helpers = {
|
|
/*
|
|
* Using this function is necessary to commit atomic updates
|
|
* that need the CRTC to be enabled before a commit, as is
|
|
* the case with e.g. DSI displays.
|
|
*/
|
|
- .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
|
|
+ .atomic_commit_tail = mcde_atomic_commit_tail,
|
|
};
|
|
|
|
static irqreturn_t mcde_irq(int irq, void *data)
|
|
|
|
--
|
|
2.51.1
|
|
|
|
From git@z Thu Jan 1 00:00:00 1970
|
|
Subject: [PATCH v5 3/3] drm/rcar-du: Modify custom commit tail
|
|
From: Linus Walleij <linusw@kernel.org>
|
|
Date: Sun, 30 Nov 2025 13:11:19 +0100
|
|
Message-Id: <20251130-mcde-drm-regression-thirdfix-v5-3-aed71a32981d@kernel.org>
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset="utf-8"
|
|
Content-Transfer-Encoding: 7bit
|
|
|
|
commit c9b1150a68d9362a0827609fc0dc1664c0d8bfe1
|
|
"drm/atomic-helper: Re-order bridge chain pre-enable and post-disable"
|
|
caused regressions in all bridges that e.g. send DSI commands in
|
|
their .prepare() and .unprepare() callbacks when used with R-Car DU.
|
|
|
|
This is needed on R-Car DU, where the CRTC provides clock to LVDS
|
|
and DSI, and has to be started before a bridge may call .prepare,
|
|
which may trigger e.g. a DSI transfer.
|
|
|
|
This specifically fixes the case where ILI9881C is connected to R-Car
|
|
DU DSI. The ILI9881C panel driver does DSI command transfer in its
|
|
struct drm_panel_funcs .prepare function, which is currently called
|
|
before R-Car DU rcar_du_crtc_atomic_enable() rcar_mipi_dsi_pclk_enable()
|
|
and the DSI command transfer times out.
|
|
|
|
Fixes: c9b1150a68d9 ("drm/atomic-helper: Re-order bridge chain pre-enable and post-disable")
|
|
Link: https://lore.kernel.org/all/20251107230517.471894-1-marek.vasut%2Brenesas%40mailbox.org/
|
|
Tested-by: Geert Uytterhoeven <geert@linux-m68k.org>
|
|
Co-developed-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
|
|
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
|
|
Tested-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
|
|
Signed-off-by: Linus Walleij <linusw@kernel.org>
|
|
Reviewed-by: Maxime Ripard <mripard@kernel.org>
|
|
Acked-by: Aradhya Bhatia <aradhya.bhatia@linux.dev>
|
|
---
|
|
This is a modified version of Marek's patch using the approach
|
|
from MCDE. I'm pretty sure this driver also needs the original
|
|
semantic ording during disablement, and it surely doesn't hurt
|
|
to restore it too.
|
|
---
|
|
drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c | 33 ++++++++++++++++++++++++---
|
|
1 file changed, 30 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
|
|
index 216219accfd9..299d14ec486f 100644
|
|
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
|
|
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
|
|
@@ -540,11 +540,38 @@ static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state)
|
|
rcdu->dpad1_source = rcrtc->index;
|
|
}
|
|
|
|
- /* Apply the atomic update. */
|
|
- drm_atomic_helper_commit_modeset_disables(dev, old_state);
|
|
+ /*
|
|
+ * Apply the atomic update.
|
|
+ *
|
|
+ * We need special ordering to make sure the CRTC disabled last
|
|
+ * and enabled first. We do this with modified versions of the
|
|
+ * common modeset_disables/enables functions.
|
|
+ */
|
|
+
|
|
+ /*
|
|
+ * Variant of drm_atomic_helper_commit_modeset_disables()
|
|
+ * that will disable and post-disable all bridges BEFORE
|
|
+ * disabling the CRTC.
|
|
+ */
|
|
+ drm_atomic_helper_commit_encoder_bridge_disable(dev, old_state);
|
|
+ drm_atomic_helper_commit_encoder_bridge_post_disable(dev, old_state);
|
|
+ drm_atomic_helper_commit_crtc_disable(dev, old_state);
|
|
+ drm_atomic_helper_update_legacy_modeset_state(dev, old_state);
|
|
+ drm_atomic_helper_calc_timestamping_constants(old_state);
|
|
+ drm_atomic_helper_commit_crtc_set_mode(dev, old_state);
|
|
+
|
|
drm_atomic_helper_commit_planes(dev, old_state,
|
|
DRM_PLANE_COMMIT_ACTIVE_ONLY);
|
|
- drm_atomic_helper_commit_modeset_enables(dev, old_state);
|
|
+
|
|
+ /*
|
|
+ * Variant of drm_atomic_helper_commit_modeset_enables()
|
|
+ * that will enable the CRTC BEFORE pre-enabling and
|
|
+ * enabling the bridges.
|
|
+ */
|
|
+ drm_atomic_helper_commit_crtc_enable(dev, old_state);
|
|
+ drm_atomic_helper_commit_encoder_bridge_pre_enable(dev, old_state);
|
|
+ drm_atomic_helper_commit_encoder_bridge_enable(dev, old_state);
|
|
+ drm_atomic_helper_commit_writebacks(dev, old_state);
|
|
|
|
drm_atomic_helper_commit_hw_done(old_state);
|
|
drm_atomic_helper_wait_for_flip_done(dev, old_state);
|
|
|
|
--
|
|
2.51.1
|
|
|