diff mbox series

[v2,RESEND,22/24] drm/exynos/decon5433: wait for finish previous update

Message ID 20190320130707.25161-23-a.hajda@samsung.com (mailing list archive)
State Not Applicable
Headers show
Series drm/exynos: add support for GSCALER planes on Exynos5433 | expand

Commit Message

Andrzej Hajda March 20, 2019, 1:07 p.m. UTC
DECON should wait for previous update before starting new one. Otherwise
internal registers can be updated in non-atomic, error prone way.
This patch fixes occasional occurrences of vblank timeouts on tm2 platform:
[ 3167.968742] [CRTC:55:crtc-0] vblank wait timed out
[ 3167.987440] WARNING: CPU: 1 PID: 194 at ../drivers/gpu/drm/drm_atomic_helper.c:1423 drm_atomic_helper_wait_for_vblanks.part.9+0x2c0/0x2c8
[ 3168.029990] Modules linked in:
[ 3168.047240] CPU: 1 PID: 194 Comm: modetest Tainted: G        W         5.0.0-rc1+ #694
[ 3168.069539] Hardware name: Samsung TM2 board (DT)
...
[ 3168.453566] Call trace:
[ 3168.469705]  drm_atomic_helper_wait_for_vblanks.part.9+0x2c0/0x2c8
[ 3168.489983]  drm_atomic_helper_commit_tail_rpm+0x60/0x78
[ 3168.509463]  commit_tail+0x44/0x78
[ 3168.527053]  drm_atomic_helper_commit+0xe8/0x160
[ 3168.546010]  drm_atomic_commit+0x48/0x58
[ 3168.564304]  drm_atomic_helper_update_plane+0x11c/0x140
[ 3168.584080]  __setplane_atomic+0x130/0x150
[ 3168.602799]  setplane_internal+0xb0/0x1a8
[ 3168.621493]  drm_mode_setplane+0xc4/0x1b8
[ 3168.640219]  drm_ioctl_kernel+0x94/0x110
[ 3168.658920]  drm_ioctl+0x1c8/0x428
...

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 5 +++++
 1 file changed, 5 insertions(+)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index b0332763594e..09f035f52444 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -406,6 +406,11 @@  static void decon_set_gscl_mode(struct decon_context *ctx)
 static void decon_atomic_begin(struct exynos_drm_crtc *crtc)
 {
 	struct decon_context *ctx = to_decon(crtc);
+	u32 val;
+
+	/* wait for finish previous updates */
+	if (readl_poll_timeout(ctx->addr + DECON_UPDATE, val, !val, 1000, 20000) < 0)
+		dev_err(ctx->dev, "DECON_UPDATE timeout\n");
 
 	decon_shadow_protect(ctx, true);
 	decon_set_gscl_mode(ctx);