summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/dispnv50
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2018-05-08 20:39:47 +1000
committerBen Skeggs <bskeggs@redhat.com>2018-05-18 15:01:29 +1000
commit859b456b6b19a19761883cf52993dec645a36152 (patch)
tree47491de6b1fed7a33698a00d5fbad88cfd917ccd /drivers/gpu/drm/nouveau/dispnv50
parent45a2945a3759479c08a4aceaee181639c92f9d48 (diff)
drm/nouveau/kms/nv50-: store window visibility in state
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>
Diffstat (limited to 'drivers/gpu/drm/nouveau/dispnv50')
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/atom.h2
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/wndw.c27
2 files changed, 21 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h
index b5b8a12a18f2..fefb9caaf7b8 100644
--- 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_state *state, struct drm_crtc *crtc)
struct nv50_wndw_atom {
struct drm_plane_state state;
+ bool visible;
+
struct {
u32 handle;
u16 offset:12;
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
index 06d1696b7d03..4a685d78ed33 100644
--- 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 *plane, struct drm_plane_state *state)
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 *plane, struct drm_plane_state *state)
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;