From 5fbb60059d919d04584b8d4b3581479cb8f52fe8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 15 Dec 2011 00:12:10 +0200 Subject: [PATCH] staging: mrst: Fix zorder handling while overlay updates are pending MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Configuring the Z order may potentially need to touch both overlays simultaneosly. So ovl_wait() needs to be performed for both overlays. Do that before touching any state to allow set_plane_opts() to fail in a clean fashion. Signed-off-by: Ville Syrjälä Acked-by: Pauli Nieminen Reviewed-by: Jani Nikula Signed-off-by: Kirill A. Shutemov --- drivers/staging/mrst/drv/mdfld_overlay.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/staging/mrst/drv/mdfld_overlay.c b/drivers/staging/mrst/drv/mdfld_overlay.c index 74a2def..bfa51cc 100644 --- a/drivers/staging/mrst/drv/mdfld_overlay.c +++ b/drivers/staging/mrst/drv/mdfld_overlay.c @@ -1095,11 +1095,8 @@ static void ovl_set_dst_key(struct mfld_overlay *ovl, const struct drm_plane_opt ovl->dirty |= OVL_DIRTY_REGS; } -static void ovl_set_zorder(struct mfld_overlay *ovl) +static void ovl_set_zorder(struct drm_plane *plane_a, struct drm_plane *plane_c) { - struct drm_psb_private *dev_priv = ovl->dev->dev_private; - struct drm_plane *plane_a = dev_priv->overlays[0]; - struct drm_plane *plane_c = dev_priv->overlays[1]; struct mfld_overlay *ovl_a; struct mfld_overlay *ovl_c; struct mfld_overlay_regs *regs_a; @@ -1130,29 +1127,37 @@ static void ovl_set_zorder(struct mfld_overlay *ovl) ovl_a->dirty |= OVL_DIRTY_REGS; ovl_c->dirty |= OVL_DIRTY_REGS; - - /* commit the other overlay */ - if (ovl == ovl_a) - ovl_commit(ovl_c); - else - ovl_commit(ovl_a); } static int mfld_overlay_set_plane_opts(struct drm_plane *plane, uint32_t flags, struct drm_plane_opts *opts) { struct mfld_overlay *ovl = to_mfld_overlay(plane); + struct drm_plane *other_plane = NULL; + struct mfld_overlay *other_ovl = NULL; int r; if (flags & DRM_MODE_PLANE_ZORDER) { + struct drm_psb_private *dev_priv = ovl->dev->dev_private; + if (opts->zorder < 0) return -EINVAL; + + other_plane = dev_priv->overlays[!ovl->id]; + if (other_plane) + other_ovl = to_mfld_overlay(other_plane); } r = ovl_wait(ovl); if (r) return r; + if (other_ovl) { + r = ovl_wait(other_ovl); + if (r) + return r; + } + /* Constant alpha bits live in color key registers */ if (flags & DRM_MODE_PLANE_CONST_ALPHA) flags |= DRM_MODE_PLANE_SRC_KEY | DRM_MODE_PLANE_DST_KEY; @@ -1204,10 +1209,13 @@ mfld_overlay_set_plane_opts(struct drm_plane *plane, uint32_t flags, struct drm_ if (flags & DRM_MODE_PLANE_ZORDER) { plane->opts.zorder = opts->zorder; - ovl_set_zorder(ovl); + ovl_set_zorder(ovl->id == 0 ? plane : other_plane, + ovl->id == 0 ? other_plane : plane); } ovl_commit(ovl); + if (other_ovl) + ovl_commit(other_ovl); return 0; } -- 2.7.4