From 9a99e904cc5b08f8eda2366135404fe72dae16af Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 11 Jun 2019 16:46:13 +1000 Subject: [PATCH] drm/nouveau/kms/gv100-: add support for plane zpos property Has a nice side-effect that we only update HW for this when it changes now, rather than every time we do a page flip. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/atom.h | 5 ++++ drivers/gpu/drm/nouveau/dispnv50/wndw.c | 14 +++++++++- drivers/gpu/drm/nouveau/dispnv50/wndw.h | 2 ++ drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c | 30 +++++++++++++-------- drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c | 1 + 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h index 75bda111da10..3192f067d291 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -221,6 +221,10 @@ struct nv50_wndw_atom { u16 y; } point; + struct { + u8 depth; + } blend; + union nv50_wndw_atom_mask { struct { bool ntfy:1; @@ -230,6 +234,7 @@ struct nv50_wndw_atom { bool image:1; bool scale:1; bool point:1; + bool blend:1; }; u8 mask; } set, clr; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index b347a68eebd0..10fcd4e1e44c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -150,6 +150,7 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock, if (asyw->set.csc ) wndw->func->csc_set (wndw, asyw); if (asyw->set.scale) wndw->func->scale_set(wndw, asyw); + if (asyw->set.blend) wndw->func->blend_set(wndw, asyw); if (asyw->set.point) { if (asyw->set.point = false, asyw->set.mask) interlock[wndw->interlock.type] |= wndw->interlock.data; @@ -285,6 +286,12 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, asyw->set.scale = true; } + if (wndw->func->blend_set) { + asyw->blend.depth = 255 - asyw->state.normalized_zpos; + if (memcmp(&armw->blend, &asyw->blend, sizeof(asyw->blend))) + asyw->set.blend = true; + } + if (wndw->immd) { asyw->point.x = asyw->state.crtc_x; asyw->point.y = asyw->state.crtc_y; @@ -644,7 +651,12 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, wndw->notify.func = nv50_wndw_notify; - if (1) { + if (wndw->func->blend_set) { + ret = drm_plane_create_zpos_property(&wndw->plane, + nv50_wndw_zpos_default(&wndw->plane), 0, 254); + if (ret) + return ret; + } else { ret = drm_plane_create_zpos_immutable_property(&wndw->plane, nv50_wndw_zpos_default(&wndw->plane)); if (ret) diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h index 59ff8f082542..c63bd3bdaf06 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -76,6 +76,7 @@ struct nv50_wndw_func { void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *); void (*image_clr)(struct nv50_wndw *); void (*scale_set)(struct nv50_wndw *, struct nv50_wndw_atom *); + void (*blend_set)(struct nv50_wndw *, struct nv50_wndw_atom *); void (*update)(struct nv50_wndw *, u32 *interlock); }; @@ -110,6 +111,7 @@ void wndwc37e_sema_clr(struct nv50_wndw *); void wndwc37e_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *); void wndwc37e_ntfy_clr(struct nv50_wndw *); void wndwc37e_image_clr(struct nv50_wndw *); +void wndwc37e_blend_set(struct nv50_wndw *, struct nv50_wndw_atom *); void wndwc37e_update(struct nv50_wndw *, u32 *); int wndwc57e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c b/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c index 0d270cd5ac4c..4d2d54a8c659 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c @@ -81,6 +81,23 @@ wndwc37e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) asyw->xlut.i.load = head907d_olut_load; } +void +wndwc37e_blend_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 8))) { + evo_mthd(push, 0x02ec, 7); + evo_data(push, asyw->blend.depth << 4); + evo_data(push, 0x000000ff); + evo_data(push, 0x00007722); + evo_data(push, 0xffff0000); + evo_data(push, 0xffff0000); + evo_data(push, 0xffff0000); + evo_data(push, 0xffff0000); + evo_kick(push, &wndw->wndw); + } +} + void wndwc37e_image_clr(struct nv50_wndw *wndw) { @@ -99,7 +116,7 @@ wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { u32 *push; - if (!(push = evo_wait(&wndw->wndw, 25))) + if (!(push = evo_wait(&wndw->wndw, 17))) return; evo_mthd(push, 0x0308, 1); @@ -124,16 +141,6 @@ wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) evo_mthd(push, 0x02a4, 1); evo_data(push, asyw->state.crtc_h << 16 | asyw->state.crtc_w); - - /*XXX: Composition-related stuff. Need to implement properly. */ - evo_mthd(push, 0x02ec, 7); - evo_data(push, (2 - (wndw->id & 1)) << 4); - evo_data(push, 0x000000ff); - evo_data(push, 0x00007722); - evo_data(push, 0xffff0000); - evo_data(push, 0xffff0000); - evo_data(push, 0xffff0000); - evo_data(push, 0xffff0000); evo_kick(push, &wndw->wndw); } @@ -258,6 +265,7 @@ wndwc37e = { .csc_clr = wndwc37e_csc_clr, .image_set = wndwc37e_image_set, .image_clr = wndwc37e_image_clr, + .blend_set = wndwc37e_blend_set, .update = wndwc37e_update, }; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c b/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c index d5e4b006ae1e..a311c79e5295 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c @@ -190,6 +190,7 @@ wndwc57e = { .csc_clr = wndwc57e_csc_clr, .image_set = wndwc57e_image_set, .image_clr = wndwc37e_image_clr, + .blend_set = wndwc37e_blend_set, .update = wndwc37e_update, };