summaryrefslogtreecommitdiffstats
path: root/arm64-drm-msm-fix-missing-CTL-flush.patch
diff options
context:
space:
mode:
Diffstat (limited to 'arm64-drm-msm-fix-missing-CTL-flush.patch')
-rw-r--r--arm64-drm-msm-fix-missing-CTL-flush.patch42
1 files changed, 42 insertions, 0 deletions
diff --git a/arm64-drm-msm-fix-missing-CTL-flush.patch b/arm64-drm-msm-fix-missing-CTL-flush.patch
new file mode 100644
index 000000000..607102077
--- /dev/null
+++ b/arm64-drm-msm-fix-missing-CTL-flush.patch
@@ -0,0 +1,42 @@
+From 6e8bed6a3e2fd6f1e82ea9b1f705bbc82060a2b7 Mon Sep 17 00:00:00 2001
+From: Rob Clark <robdclark@gmail.com>
+Date: Tue, 3 Jul 2018 08:14:32 -0400
+Subject: [PATCH] drm/msm/mdp5: fix missing CTL flush
+
+f9cb8d8d836e fixed various race conditions with CTL flush, in particular
+flushing and sending the START signal before encoder state was updated.
+But it did this a little too well in some cases that don't trigger
+encoder->enable(), and CTL[n].FLUSH would never be set. When page flips
+happen it would paper over the bug, since the first plag flip would
+flush out the state to the hardware.
+
+The issue could be reproduced with, for example, modetest (without the
+'-v' argument).
+
+Fixes: f9cb8d8d836e drm/msm/mdp5: rework CTL START signal handling
+Signed-off-by: Rob Clark <robdclark@gmail.com>
+Reviewed-by: Sean Paul <seanpaul@chromium.org>
+
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c
+index 9af94e35f678..fcd44d1d1068 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c
+@@ -319,7 +319,17 @@ static int mdp5_encoder_atomic_check(struct drm_encoder *encoder,
+
+ mdp5_cstate->ctl = ctl;
+ mdp5_cstate->pipeline.intf = intf;
+- mdp5_cstate->defer_start = true;
++
++ /*
++ * This is a bit awkward, but we want to flush the CTL and hit the
++ * START bit at most once for an atomic update. In the non-full-
++ * modeset case, this is done from crtc->atomic_flush(), but that
++ * is too early in the case of full modeset, in which case we
++ * defer to encoder->enable(). But we need to *know* whether
++ * encoder->enable() will be called to do this:
++ */
++ if (drm_atomic_crtc_needs_modeset(crtc_state))
++ mdp5_cstate->defer_start = true;
+
+ return 0;
+ }