Introduce a variant of drm_atomic_helper_commit_modeset_enables()
which enables CRTC before encoder/bridge. 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. 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.

Fix this by restoring the enable ordering introduced in commit
c9b1150a68d9 ("drm/atomic-helper: Re-order bridge chain pre-enable
and post-disable"), to enable CRTC early.

Fixes: c9b1150a68d9 ("drm/atomic-helper: Re-order bridge chain pre-enable and 
post-disable")
Signed-off-by: Marek Vasut <[email protected]>
---
Cc: Aradhya Bhatia <[email protected]>
Cc: David Airlie <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Cc: Kieran Bingham <[email protected]>
Cc: Laurent Pinchart <[email protected]>
Cc: Maarten Lankhorst <[email protected]>
Cc: Magnus Damm <[email protected]>
Cc: Maxime Ripard <[email protected]>
Cc: Simona Vetter <[email protected]>
Cc: Thomas Zimmermann <[email protected]>
Cc: Tomi Valkeinen <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
 drivers/gpu/drm/drm_atomic_helper.c           | 24 +++++++++++++++++++
 drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c |  2 +-
 include/drm/drm_atomic_helper.h               |  2 ++
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 5a473a274ff06..c0cdd36a03df1 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1692,6 +1692,30 @@ void drm_atomic_helper_commit_modeset_enables(struct 
drm_device *dev,
 }
 EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables);
 
+/**
+ * drm_atomic_helper_commit_modeset_enables_crtc_early - modeset commit to 
enable outputs, start CRTC early
+ * @dev: DRM device
+ * @state: atomic state object being committed
+ *
+ * This function is a variant of drm_atomic_helper_commit_modeset_enables()
+ * which enables CRTC before encoder/bridge. 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. DSI transfer.
+ */
+void
+drm_atomic_helper_commit_modeset_enables_crtc_early(struct drm_device *dev,
+                                                   struct drm_atomic_state 
*state)
+{
+       crtc_enable(dev, state);
+
+       encoder_bridge_pre_enable(dev, state);
+
+       encoder_bridge_enable(dev, state);
+
+       drm_atomic_helper_commit_writebacks(dev, state);
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables_crtc_early);
+
 /*
  * For atomic updates which touch just a single CRTC, calculate the time of the
  * next vblank, and inform all the fences of the deadline.
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 116ad9605704b..b7e2a735a03ae 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
@@ -547,7 +547,7 @@ static void rcar_du_atomic_commit_tail(struct 
drm_atomic_state *old_state)
        drm_atomic_helper_commit_modeset_disables(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);
+       drm_atomic_helper_commit_modeset_enables_crtc_early(dev, old_state);
 
        drm_atomic_helper_commit_hw_done(old_state);
        drm_atomic_helper_wait_for_flip_done(dev, old_state);
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 53382fe93537b..d7fb473db3431 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -93,6 +93,8 @@ void drm_atomic_helper_commit_modeset_disables(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);
+void drm_atomic_helper_commit_modeset_enables_crtc_early(struct drm_device 
*dev,
+                                                        struct 
drm_atomic_state *old_state);
 
 int drm_atomic_helper_prepare_planes(struct drm_device *dev,
                                     struct drm_atomic_state *state);
-- 
2.51.0

Reply via email to