From c4b7d6c966afe784e090fa66d7a7b126c2273a0b Mon Sep 17 00:00:00 2001 From: Hyun Kwon Date: Thu, 28 Mar 2019 22:22:00 -0700 Subject: [PATCH] drm: xlnx: zynqmp_disp: Skip the modeset for same fb Since the async update creates a separate atomic mode set, there can be back to back atomic modeset with same fb. If the mode set is applied twice, it ends up submitting 2 dma transactions, and it results in jitter. This fixes it by adding the check in plane atomic update, and using plane mode set in async update. Signed-off-by: Hyun Kwon Tested-by: Preetesh Parekh --- drivers/gpu/drm/xlnx/zynqmp_disp.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c index 757ee7720eef..ef95173de332 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c @@ -2676,6 +2676,9 @@ zynqmp_disp_plane_atomic_update(struct drm_plane *plane, if (!plane->state->crtc || !plane->state->fb) return; + if (plane->state->fb == old_state->fb) + return; + if (old_state->fb && old_state->fb->format->format != plane->state->fb->format->format) zynqmp_disp_plane_disable(plane); @@ -2712,12 +2715,15 @@ static void zynqmp_disp_plane_atomic_async_update(struct drm_plane *plane, struct drm_plane_state *new_state) { - struct drm_plane_state *old_state = - drm_atomic_get_old_plane_state(new_state->state, plane); + int ret; if (plane->state->fb == new_state->fb) return; + if (plane->state->fb && + plane->state->fb->format->format != new_state->fb->format->format) + zynqmp_disp_plane_disable(plane); + /* Update the current state with new configurations */ drm_atomic_set_fb_for_plane(plane->state, new_state->fb); plane->state->crtc = new_state->crtc; @@ -2731,7 +2737,19 @@ zynqmp_disp_plane_atomic_async_update(struct drm_plane *plane, plane->state->src_h = new_state->src_h; plane->state->state = new_state->state; - zynqmp_disp_plane_atomic_update(plane, old_state); + ret = zynqmp_disp_plane_mode_set(plane, plane->state->fb, + plane->state->crtc_x, + plane->state->crtc_y, + plane->state->crtc_w, + plane->state->crtc_h, + plane->state->src_x >> 16, + plane->state->src_y >> 16, + plane->state->src_w >> 16, + plane->state->src_h >> 16); + if (ret) + return; + + zynqmp_disp_plane_enable(plane); } static const struct drm_plane_helper_funcs zynqmp_disp_plane_helper_funcs = { -- 2.39.2