Blob Blame History Raw
From: Ben Skeggs <bskeggs@redhat.com>
Date: Tue, 8 May 2018 20:39:47 +1000
Subject: drm/nouveau/kms/nv50-: store window visibility in state
Git-commit: 859b456b6b19a19761883cf52993dec645a36152
Patch-mainline: v4.18-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Window visibility is going to become a little more complicated with the
upcoming LUT changes, so store the calculated value to avoid needing to
recalculate the armed state again.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/nouveau/dispnv50/atom.h |    2 ++
 drivers/gpu/drm/nouveau/dispnv50/wndw.c |   27 +++++++++++++++++++--------
 2 files changed, 21 insertions(+), 8 deletions(-)

--- a/drivers/gpu/drm/nouveau/dispnv50/atom.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h
@@ -136,6 +136,8 @@ nv50_head_atom_get(struct drm_atomic_sta
 struct nv50_wndw_atom {
 	struct drm_plane_state state;
 
+	bool visible;
+
 	struct {
 		u32  handle;
 		u16  offset:12;
--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
@@ -244,26 +244,33 @@ nv50_wndw_atomic_check(struct drm_plane
 	struct nv50_wndw_atom *armw = nv50_wndw_atom(wndw->plane.state);
 	struct nv50_wndw_atom *asyw = nv50_wndw_atom(state);
 	struct nv50_head_atom *harm = NULL, *asyh = NULL;
-	bool varm = false, asyv = false, asym = false;
+	bool modeset = false;
 	int ret;
 
 	NV_ATOMIC(drm, "%s atomic_check\n", plane->name);
+
+	/* Fetch the assembly state for the head the window will belong to,
+	 * and determine whether the window will be visible.
+	 */
 	if (asyw->state.crtc) {
 		asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc);
 		if (IS_ERR(asyh))
 			return PTR_ERR(asyh);
-		asym = drm_atomic_crtc_needs_modeset(&asyh->state);
-		asyv = asyh->state.active;
+		modeset = drm_atomic_crtc_needs_modeset(&asyh->state);
+		asyw->visible = asyh->state.active;
+	} else {
+		asyw->visible = false;
 	}
 
+	/* Fetch assembly state for the head the window used to belong to. */
 	if (armw->state.crtc) {
 		harm = nv50_head_atom_get(asyw->state.state, armw->state.crtc);
 		if (IS_ERR(harm))
 			return PTR_ERR(harm);
-		varm = harm->state.crtc->state->active;
 	}
 
-	if (asyv) {
+	/* Calculate new window state. */
+	if (asyw->visible) {
 		asyw->point.x = asyw->state.crtc_x;
 		asyw->point.y = asyw->state.crtc_y;
 		if (memcmp(&armw->point, &asyw->point, sizeof(asyw->point)))
@@ -273,18 +280,22 @@ nv50_wndw_atomic_check(struct drm_plane
 		if (ret)
 			return ret;
 	} else
-	if (varm) {
+	if (armw->visible) {
 		nv50_wndw_atomic_check_release(wndw, asyw, harm);
 	} else {
 		return 0;
 	}
 
-	if (!asyv || asym) {
+	/* Aside from the obvious case where the window is actively being
+	 * disabled, we might also need to temporarily disable the window
+	 * when performing certain modeset operations.
+	 */
+	if (!asyw->visible || modeset) {
 		asyw->clr.ntfy = armw->ntfy.handle != 0;
 		asyw->clr.sema = armw->sema.handle != 0;
 		if (wndw->func->image_clr)
 			asyw->clr.image = armw->image.handle[0] != 0;
-		asyw->set.lut = wndw->func->lut && asyv;
+		asyw->set.lut = wndw->func->lut && asyw->visible;
 	}
 
 	return 0;