drm/nouveau/kms/nv50-: simplify tracking of channel interlocks
authorBen Skeggs <bskeggs@redhat.com>
Tue, 8 May 2018 10:39:47 +0000 (20:39 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 18 May 2018 05:01:29 +0000 (15:01 +1000)
Instead of windows returning their core channel interlock mask if they
know core has been modified, it's recorded unconditionally and used if
required when update methods are emitted.

This will be required to support Volta.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
20 files changed:
drivers/gpu/drm/nouveau/dispnv50/Kbuild
drivers/gpu/drm/nouveau/dispnv50/base.h
drivers/gpu/drm/nouveau/dispnv50/base507c.c
drivers/gpu/drm/nouveau/dispnv50/base827c.c
drivers/gpu/drm/nouveau/dispnv50/base907c.c
drivers/gpu/drm/nouveau/dispnv50/core.h
drivers/gpu/drm/nouveau/dispnv50/core507d.c
drivers/gpu/drm/nouveau/dispnv50/curs.c
drivers/gpu/drm/nouveau/dispnv50/curs.h
drivers/gpu/drm/nouveau/dispnv50/curs507a.c
drivers/gpu/drm/nouveau/dispnv50/curs907a.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/dispnv50/disp.h
drivers/gpu/drm/nouveau/dispnv50/ovly.c
drivers/gpu/drm/nouveau/dispnv50/ovly.h
drivers/gpu/drm/nouveau/dispnv50/ovly507e.c
drivers/gpu/drm/nouveau/dispnv50/ovly827e.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/dispnv50/ovly907e.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/dispnv50/wndw.c
drivers/gpu/drm/nouveau/dispnv50/wndw.h

index 674221dea7a1130c964adc822bf08d7416ba8095..3e53484b4589d34935b1deafbf7ac7f64bf323d1 100644 (file)
@@ -29,9 +29,12 @@ nouveau-y += dispnv50/base907c.o
 
 nouveau-y += dispnv50/curs.o
 nouveau-y += dispnv50/curs507a.o
+nouveau-y += dispnv50/curs907a.o
 
 nouveau-y += dispnv50/oimm.o
 nouveau-y += dispnv50/oimm507b.o
 
 nouveau-y += dispnv50/ovly.o
 nouveau-y += dispnv50/ovly507e.o
+nouveau-y += dispnv50/ovly827e.o
+nouveau-y += dispnv50/ovly907e.o
index edf96a8d645f2e5250678efca753e302ea443852..71fc10369b3731fc878bba10a11f0fe600a2be2a 100644 (file)
@@ -5,7 +5,7 @@
 int base507c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
 int base507c_new_(const struct nv50_wndw_func *, const u32 *format,
                  struct nouveau_drm *, int head, s32 oclass,
-                 struct nv50_wndw **);
+                 u32 interlock_data, struct nv50_wndw **);
 extern const u32 base507c_format[];
 int base507c_acquire(struct nv50_wndw *, struct nv50_wndw_atom *,
                     struct nv50_head_atom *);
@@ -19,7 +19,7 @@ void base507c_ntfy_clr(struct nv50_wndw *);
 int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *);
 void base507c_image_clr(struct nv50_wndw *);
 void base507c_lut(struct nv50_wndw *, struct nv50_wndw_atom *);
-u32 base507c_update(struct nv50_wndw *, u32);
+void base507c_update(struct nv50_wndw *, u32 *);
 
 int base827c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
 
index 1c65ddc4747e06e8821ada0e33c7b8ad6289e645..819403f4b958d0ad9caa6114c0d69309b1713b0c 100644 (file)
 #include <drm/drm_plane_helper.h>
 #include "nouveau_bo.h"
 
-u32
-base507c_update(struct nv50_wndw *wndw, u32 interlock)
+void
+base507c_update(struct nv50_wndw *wndw, u32 *interlock)
 {
        u32 *push;
        if ((push = evo_wait(&wndw->wndw, 2))) {
                evo_mthd(push, 0x0080, 1);
-               evo_data(push, interlock);
+               evo_data(push, interlock[NV50_DISP_INTERLOCK_CORE]);
                evo_kick(push, &wndw->wndw);
-               return interlock ? 2 << (wndw->id * 8) : 0;
        }
-       return 0;
 }
 
 void
@@ -224,7 +222,7 @@ base507c = {
 
 int
 base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
-             struct nouveau_drm *drm, int head, s32 oclass,
+             struct nouveau_drm *drm, int head, s32 oclass, u32 interlock_data,
              struct nv50_wndw **pwndw)
 {
        struct nv50_disp_base_channel_dma_v0 args = {
@@ -235,7 +233,8 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
        int ret;
 
        ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_PRIMARY,
-                            "base", head, format, BIT(head), &wndw);
+                            "base", head, format, BIT(head),
+                            NV50_DISP_INTERLOCK_BASE, interlock_data, &wndw);
        if (*pwndw = wndw, ret)
                return ret;
 
@@ -266,5 +265,6 @@ int
 base507c_new(struct nouveau_drm *drm, int head, s32 oclass,
             struct nv50_wndw **pwndw)
 {
-       return base507c_new_(&base507c, base507c_format, drm, head, oclass, pwndw);
+       return base507c_new_(&base507c, base507c_format, drm, head, oclass,
+                            0x00000002 << (head * 8), pwndw);
 }
index 9dc968c83c66779f7b34f0e339ef9e6bb4e561cc..240a6409329d22aef1d82cd63664a7c3c90533f2 100644 (file)
@@ -63,5 +63,6 @@ int
 base827c_new(struct nouveau_drm *drm, int head, s32 oclass,
             struct nv50_wndw **pwndw)
 {
-       return base507c_new_(&base827c, base507c_format, drm, head, oclass, pwndw);
+       return base507c_new_(&base827c, base507c_format, drm, head, oclass,
+                            0x00000002 << (head * 8), pwndw);
 }
index 5321c55951b91eb34d5bf304a0e4277eb637b1b7..6c32a4e5cb7d9c1e8b9267ce4bcd5837b81dfc5d 100644 (file)
  */
 #include "base.h"
 
-static u32
-base907c_update(struct nv50_wndw *wndw, u32 interlock)
-{
-       u32 *push;
-       if ((push = evo_wait(&wndw->wndw, 2))) {
-               evo_mthd(push, 0x0080, 1);
-               evo_data(push, interlock);
-               evo_kick(push, &wndw->wndw);
-               return interlock ? 2 << (wndw->id * 4) : 0;
-       }
-       return 0;
-}
-
 static void
 base907c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
 {
@@ -69,12 +56,13 @@ base907c = {
        .image_set = base907c_image_set,
        .image_clr = base507c_image_clr,
        .lut = base507c_lut,
-       .update = base907c_update,
+       .update = base507c_update,
 };
 
 int
 base907c_new(struct nouveau_drm *drm, int head, s32 oclass,
             struct nv50_wndw **pwndw)
 {
-       return base507c_new_(&base907c, base507c_format, drm, head, oclass, pwndw);
+       return base507c_new_(&base907c, base507c_format, drm, head, oclass,
+                            0x00000002 << (head * 4), pwndw);
 }
index 5fd7ddd31e5e44840210c5725796bbd930ae5b0f..c490d7d497b2e697feabbcde5b6115f0aeb718e4 100644 (file)
@@ -16,7 +16,7 @@ struct nv50_core_func {
        void (*ntfy_init)(struct nouveau_bo *, u32 offset);
        int (*ntfy_wait_done)(struct nouveau_bo *, u32 offset,
                              struct nvif_device *);
-       void (*update)(struct nv50_core *, u32 interlock, bool ntfy);
+       void (*update)(struct nv50_core *, u32 *interlock, bool ntfy);
 
        const struct nv50_head_func *head;
        const struct nv50_outp_func {
@@ -31,7 +31,8 @@ int core507d_new_(const struct nv50_core_func *, struct nouveau_drm *, s32,
 void core507d_init(struct nv50_core *);
 void core507d_ntfy_init(struct nouveau_bo *, u32);
 int core507d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *);
-void core507d_update(struct nv50_core *, u32, bool);
+void core507d_update(struct nv50_core *, u32 *, bool);
+
 extern const struct nv50_outp_func dac507d;
 extern const struct nv50_outp_func sor507d;
 extern const struct nv50_outp_func pior507d;
index 96d7d8fde669c6b1dae6baac12a55b885c4a334b..e7fcfa6e646766beafd127db6b17f5753259b520 100644 (file)
@@ -27,7 +27,7 @@
 #include "nouveau_bo.h"
 
 void
-core507d_update(struct nv50_core *core, u32 interlock, bool ntfy)
+core507d_update(struct nv50_core *core, u32 *interlock, bool ntfy)
 {
        u32 *push;
        if ((push = evo_wait(&core->chan, 5))) {
@@ -36,7 +36,8 @@ core507d_update(struct nv50_core *core, u32 interlock, bool ntfy)
                        evo_data(push, 0x80000000 | NV50_DISP_CORE_NTFY);
                }
                evo_mthd(push, 0x0080, 2);
-               evo_data(push, interlock);
+               evo_data(push, interlock[NV50_DISP_INTERLOCK_BASE] |
+                              interlock[NV50_DISP_INTERLOCK_OVLY]);
                evo_data(push, 0x00000000);
                evo_kick(push, &core->chan);
        }
index 6d60e978db69d031afa8b4a50c1496e954ac1747..fb842ed2592f1da7d013be9434e003d1528c83d5 100644 (file)
@@ -31,8 +31,8 @@ nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
                int version;
                int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **);
        } curses[] = {
-               { GK104_DISP_CURSOR, 0, curs507a_new },
-               { GF110_DISP_CURSOR, 0, curs507a_new },
+               { GK104_DISP_CURSOR, 0, curs907a_new },
+               { GF110_DISP_CURSOR, 0, curs907a_new },
                { GT214_DISP_CURSOR, 0, curs507a_new },
                {   G82_DISP_CURSOR, 0, curs507a_new },
                {  NV50_DISP_CURSOR, 0, curs507a_new },
index b85ca9fa419c7ee4b5dac6b14665df9e5846ac5a..2285247dc2a3a823f3a8cc8105bcee41cc4b5c05 100644 (file)
@@ -3,6 +3,12 @@
 #include "wndw.h"
 
 int curs507a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
+int curs507a_new_(const struct nv50_wimm_func *, struct nouveau_drm *,
+                 int head, s32 oclass, u32 interlock_data,
+                 struct nv50_wndw **);
+extern const struct nv50_wimm_func curs507a;
+
+int curs907a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
 
 int nv50_curs_new(struct nouveau_drm *, int head, struct nv50_wndw **);
 #endif
index 589c75c22b3a2df7bcd791a953a673c2d6fde7b3..ba05bcb13ae794767a5656483ff3b8429baab775 100644 (file)
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_plane_helper.h>
 
-static u32
-curs507a_update(struct nv50_wndw *wndw, u32 interlock)
+static void
+curs507a_update(struct nv50_wndw *wndw, u32 *interlock)
 {
        nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000);
-       return 0;
 }
 
 static void
@@ -41,7 +40,7 @@ curs507a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
                                                 asyw->point.x);
 }
 
-static const struct nv50_wimm_func
+const struct nv50_wimm_func
 curs507a = {
        .point = curs507a_point,
        .update = curs507a_update,
@@ -114,9 +113,10 @@ curs507a_wndw = {
        .prepare = curs507a_prepare,
 };
 
-static int
+int
 curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
-             int head, s32 oclass, struct nv50_wndw **pwndw)
+             int head, s32 oclass, u32 interlock_data,
+             struct nv50_wndw **pwndw)
 {
        struct nv50_disp_cursor_v0 args = {
                .head = head,
@@ -126,7 +126,8 @@ curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
        int ret;
 
        ret = nv50_wndw_new_(&curs507a_wndw, drm->dev, DRM_PLANE_TYPE_CURSOR,
-                            "curs", head, curs507a_format, BIT(head), &wndw);
+                            "curs", head, curs507a_format, BIT(head),
+                            NV50_DISP_INTERLOCK_CURS, interlock_data, &wndw);
        if (*pwndw = wndw, ret)
                return ret;
 
@@ -147,5 +148,6 @@ int
 curs507a_new(struct nouveau_drm *drm, int head, s32 oclass,
             struct nv50_wndw **pwndw)
 {
-       return curs507a_new_(&curs507a, drm, head, oclass, pwndw);
+       return curs507a_new_(&curs507a, drm, head, oclass,
+                            0x00000001 << (head * 8), pwndw);
 }
diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs907a.c b/drivers/gpu/drm/nouveau/dispnv50/curs907a.c
new file mode 100644 (file)
index 0000000..d742362
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "curs.h"
+
+int
+curs907a_new(struct nouveau_drm *drm, int head, s32 oclass,
+            struct nv50_wndw **pwndw)
+{
+       return curs507a_new_(&curs507a, drm, head, oclass,
+                            0x00000001 << (head * 4), pwndw);
+}
index eaa63b43282bf70b70ed7588b9ffa747b09315c0..e80d11c9a456e87b33395488ff65d665eb5a3a31 100644 (file)
@@ -1582,14 +1582,14 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe)
  *****************************************************************************/
 
 static void
-nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 interlock)
+nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 *interlock)
 {
        struct nv50_disp *disp = nv50_disp(drm->dev);
        struct nv50_core *core = disp->core;
        struct nv50_mstm *mstm;
        struct drm_encoder *encoder;
 
-       NV_ATOMIC(drm, "commit core %08x\n", interlock);
+       NV_ATOMIC(drm, "commit core %08x\n", interlock[NV50_DISP_INTERLOCK_BASE]);
 
        drm_for_each_encoder(encoder, drm->dev) {
                if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) {
@@ -1626,8 +1626,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
        struct nv50_disp *disp = nv50_disp(dev);
        struct nv50_atom *atom = nv50_atom(state);
        struct nv50_outp_atom *outp, *outt;
-       u32 interlock_core = 0;
-       u32 interlock_chan = 0;
+       u32 interlock[NV50_DISP_INTERLOCK__SIZE] = {};
        int i;
 
        NV_ATOMIC(drm, "commit %d %d\n", atom->lock_core, atom->flush_disable);
@@ -1650,7 +1649,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
 
                if (asyh->clr.mask) {
                        nv50_head_flush_clr(head, asyh, atom->flush_disable);
-                       interlock_core |= 1;
+                       interlock[NV50_DISP_INTERLOCK_CORE] |= 1;
                }
        }
 
@@ -1664,9 +1663,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
                if (!asyw->clr.mask)
                        continue;
 
-               interlock_chan |= nv50_wndw_flush_clr(wndw, interlock_core,
-                                                     atom->flush_disable,
-                                                     asyw);
+               nv50_wndw_flush_clr(wndw, interlock, atom->flush_disable, asyw);
        }
 
        /* Disable output path(s). */
@@ -1682,21 +1679,19 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
 
                if (outp->clr.mask) {
                        help->disable(encoder);
-                       interlock_core |= 1;
+                       interlock[NV50_DISP_INTERLOCK_CORE] |= 1;
                        if (outp->flush_disable) {
-                               nv50_disp_atomic_commit_core(drm, interlock_chan);
-                               interlock_core = 0;
-                               interlock_chan = 0;
+                               nv50_disp_atomic_commit_core(drm, interlock);
+                               memset(interlock, 0x00, sizeof(interlock));
                        }
                }
        }
 
        /* Flush disable. */
-       if (interlock_core) {
+       if (interlock[NV50_DISP_INTERLOCK_CORE]) {
                if (atom->flush_disable) {
-                       nv50_disp_atomic_commit_core(drm, interlock_chan);
-                       interlock_core = 0;
-                       interlock_chan = 0;
+                       nv50_disp_atomic_commit_core(drm, interlock);
+                       memset(interlock, 0x00, sizeof(interlock));
                }
        }
 
@@ -1713,7 +1708,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
 
                if (outp->set.mask) {
                        help->enable(encoder);
-                       interlock_core = 1;
+                       interlock[NV50_DISP_INTERLOCK_CORE] = 1;
                }
 
                list_del(&outp->head);
@@ -1730,7 +1725,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
 
                if (asyh->set.mask) {
                        nv50_head_flush_set(head, asyh);
-                       interlock_core = 1;
+                       interlock[NV50_DISP_INTERLOCK_CORE] = 1;
                }
 
                if (new_crtc_state->active) {
@@ -1752,15 +1747,16 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
                    (!asyw->clr.mask || atom->flush_disable))
                        continue;
 
-               interlock_chan |= nv50_wndw_flush_set(wndw, interlock_core, asyw);
+               nv50_wndw_flush_set(wndw, interlock, asyw);
        }
 
        /* Flush update. */
-       if (interlock_core) {
-               if (interlock_chan || !atom->state.legacy_cursor_update)
-                       nv50_disp_atomic_commit_core(drm, interlock_chan);
+       if (interlock[NV50_DISP_INTERLOCK_CORE]) {
+               if (interlock[NV50_DISP_INTERLOCK_BASE] ||
+                   !atom->state.legacy_cursor_update)
+                       nv50_disp_atomic_commit_core(drm, interlock);
                else
-                       disp->core->func->update(disp->core, 0, false);
+                       disp->core->func->update(disp->core, interlock, false);
        }
 
        if (atom->lock_core)
index 7cbd6684974368b0668cbdcc154b6733451599a0..f3a963b0ab77e5fe7f9bdd84091d50a821e8bc9c 100644 (file)
@@ -27,6 +27,17 @@ nv50_disp(struct drm_device *dev)
        return nouveau_display(dev)->priv;
 }
 
+struct nv50_disp_interlock {
+       enum nv50_disp_interlock_type {
+               NV50_DISP_INTERLOCK_CORE = 0,
+               NV50_DISP_INTERLOCK_CURS,
+               NV50_DISP_INTERLOCK_BASE,
+               NV50_DISP_INTERLOCK_OVLY,
+               NV50_DISP_INTERLOCK__SIZE
+       } type;
+       u32 data;
+};
+
 struct nv50_chan {
        struct nvif_object user;
        struct nvif_device *device;
index ac2d3b64f1863f8337154c574fcf182d39728a23..be0f16fdcd5bd4a46beabaaf0305d60fa5a8dad8 100644 (file)
@@ -32,11 +32,11 @@ nv50_ovly_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
                int version;
                int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **);
        } ovlys[] = {
-               { GK104_DISP_OVERLAY_CONTROL_DMA, 0, ovly507e_new },
-               { GF110_DISP_OVERLAY_CONTROL_DMA, 0, ovly507e_new },
-               { GT214_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new },
-               { GT200_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new },
-               {   G82_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new },
+               { GK104_DISP_OVERLAY_CONTROL_DMA, 0, ovly907e_new },
+               { GF110_DISP_OVERLAY_CONTROL_DMA, 0, ovly907e_new },
+               { GT214_DISP_OVERLAY_CHANNEL_DMA, 0, ovly827e_new },
+               { GT200_DISP_OVERLAY_CHANNEL_DMA, 0, ovly827e_new },
+               {   G82_DISP_OVERLAY_CHANNEL_DMA, 0, ovly827e_new },
                {  NV50_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new },
                {}
        };
index 90af1f2f0aa012684fb2768eaa73ca5e70c6cff2..d149ef6f957e633df3790edc95c8b63ce53dfc68 100644 (file)
@@ -3,6 +3,14 @@
 #include "wndw.h"
 
 int ovly507e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
+int ovly507e_new_(const struct nv50_wndw_func *, const u32 *format,
+                 struct nouveau_drm *, int head, s32 oclass,
+                 u32 interlock_data, struct nv50_wndw **);
+
+extern const u32 ovly827e_format[];
+
+int ovly827e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
+int ovly907e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
 
 int nv50_ovly_new(struct nouveau_drm *, int head, struct nv50_wndw **);
 #endif
index 1b85262bf23bbef2fea8a1f1a14241763b82a9a0..732eea39e4de76e6ed6ae0ba2e43928a5431690f 100644 (file)
@@ -34,9 +34,9 @@ ovly507e_format[] = {
        0
 };
 
-static int
+int
 ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format,
-             struct nouveau_drm *drm, int head, s32 oclass,
+             struct nouveau_drm *drm, int head, s32 oclass, u32 interlock_data,
              struct nv50_wndw **pwndw)
 {
        struct nv50_disp_overlay_channel_dma_v0 args = {
@@ -47,7 +47,9 @@ ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format,
        int ret;
 
        ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_OVERLAY,
-                            "ovly", head, format, BIT(head), &wndw);
+                            "ovly", head, format, BIT(head),
+                            NV50_DISP_INTERLOCK_OVLY, interlock_data,
+                            &wndw);
        if (*pwndw = wndw, ret)
                return ret;
 
@@ -66,5 +68,6 @@ int
 ovly507e_new(struct nouveau_drm *drm, int head, s32 oclass,
             struct nv50_wndw **pwndw)
 {
-       return ovly507e_new_(&ovly507e, ovly507e_format, drm, head, oclass, pwndw);
+       return ovly507e_new_(&ovly507e, ovly507e_format, drm, head, oclass,
+                            0x00000004 << (head * 8), pwndw);
 }
diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c
new file mode 100644 (file)
index 0000000..a8115f1
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "ovly.h"
+
+#include <nouveau_bo.h>
+
+#include <nvif/cl507e.h>
+
+static const struct nv50_wndw_func
+ovly827e = {
+};
+
+const u32
+ovly827e_format[] = {
+       0
+};
+
+int
+ovly827e_new(struct nouveau_drm *drm, int head, s32 oclass,
+            struct nv50_wndw **pwndw)
+{
+       return ovly507e_new_(&ovly827e, ovly827e_format, drm, head, oclass,
+                            0x00000004 << (head * 8), pwndw);
+}
diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c
new file mode 100644 (file)
index 0000000..f50da64
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "ovly.h"
+
+static const struct nv50_wndw_func
+ovly907e = {
+};
+
+int
+ovly907e_new(struct nouveau_drm *drm, int head, s32 oclass,
+            struct nv50_wndw **pwndw)
+{
+       return ovly507e_new_(&ovly907e, ovly827e_format, drm, head, oclass,
+                            0x00000004 << (head * 4), pwndw);
+}
index 4b64f64b7891083d521f8289c9b3f2ea96d21ae1..8f62c2a811ffb2abdb87832d14f9fb6b532c2b66 100644 (file)
@@ -107,8 +107,8 @@ nv50_wndw_wait_armed(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
        return 0;
 }
 
-u32
-nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 interlock, bool flush,
+void
+nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 *interlock, bool flush,
                    struct nv50_wndw_atom *asyw)
 {
        union nv50_wndw_atom_mask clr = {
@@ -118,11 +118,13 @@ nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 interlock, bool flush,
        if (clr.ntfy ) wndw->func-> ntfy_clr(wndw);
        if (clr.image) wndw->func->image_clr(wndw);
 
-       return flush ? wndw->func->update(wndw, interlock) : 0;
+       interlock[wndw->interlock.type] |= wndw->interlock.data;
+       if (flush)
+               wndw->func->update(wndw, interlock);
 }
 
-u32
-nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 interlock,
+void
+nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
                    struct nv50_wndw_atom *asyw)
 {
        if (interlock) {
@@ -139,7 +141,9 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 interlock,
                wndw->immd->update(wndw, interlock);
        }
 
-       return wndw->func->update ? wndw->func->update(wndw, interlock) : 0;
+       interlock[wndw->interlock.type] |= wndw->interlock.data;
+       if (wndw->func->update)
+               wndw->func->update(wndw, interlock);
 }
 
 void
@@ -445,7 +449,9 @@ nv50_wndw_init(struct nv50_wndw *wndw)
 int
 nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
               enum drm_plane_type type, const char *name, int index,
-              const u32 *format, u32 heads, struct nv50_wndw **pwndw)
+              const u32 *format, u32 heads,
+              enum nv50_disp_interlock_type interlock_type, u32 interlock_data,
+              struct nv50_wndw **pwndw)
 {
        struct nv50_wndw *wndw;
        int nformat;
@@ -455,6 +461,9 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
                return -ENOMEM;
        wndw->func = func;
        wndw->id = index;
+       wndw->interlock.type = interlock_type;
+       wndw->interlock.data = interlock_data;
+       wndw->ctxdma.parent = &wndw->wndw.base.user;
 
        wndw->ctxdma.parent = &wndw->wndw.base.user;
        INIT_LIST_HEAD(&wndw->ctxdma.list);
index 8672c280a6a422040293d82f8e6b72a5a18451f1..c26796c612f6b7c40bcededf810ce3b4bff2a3a5 100644 (file)
@@ -15,6 +15,7 @@ struct nv50_wndw {
        const struct nv50_wndw_func *func;
        const struct nv50_wimm_func *immd;
        int id;
+       struct nv50_disp_interlock interlock;
 
        struct {
                struct nvif_object *parent;
@@ -34,13 +35,14 @@ struct nv50_wndw {
 
 int nv50_wndw_new_(const struct nv50_wndw_func *, struct drm_device *,
                   enum drm_plane_type, const char *name, int index,
-                  const u32 *format, u32 heads, struct nv50_wndw **);
+                  const u32 *format, enum nv50_disp_interlock_type,
+                  u32 interlock_data, u32 heads, struct nv50_wndw **);
 void nv50_wndw_init(struct nv50_wndw *);
 void nv50_wndw_fini(struct nv50_wndw *);
-u32 nv50_wndw_flush_set(struct nv50_wndw *, u32 interlock,
-                       struct nv50_wndw_atom *);
-u32 nv50_wndw_flush_clr(struct nv50_wndw *, u32 interlock, bool flush,
-                       struct nv50_wndw_atom *);
+void nv50_wndw_flush_set(struct nv50_wndw *, u32 *interlock,
+                        struct nv50_wndw_atom *);
+void nv50_wndw_flush_clr(struct nv50_wndw *, u32 *interlock, bool flush,
+                        struct nv50_wndw_atom *);
 void nv50_wndw_ntfy_enable(struct nv50_wndw *, struct nv50_wndw_atom *);
 int nv50_wndw_wait_armed(struct nv50_wndw *, struct nv50_wndw_atom *);
 
@@ -63,7 +65,7 @@ struct nv50_wndw_func {
        void (*image_clr)(struct nv50_wndw *);
        void (*lut)(struct nv50_wndw *, struct nv50_wndw_atom *);
 
-       u32 (*update)(struct nv50_wndw *, u32 interlock);
+       void (*update)(struct nv50_wndw *, u32 *interlock);
 };
 
 extern const struct drm_plane_funcs nv50_wndw;
@@ -71,6 +73,6 @@ extern const struct drm_plane_funcs nv50_wndw;
 struct nv50_wimm_func {
        void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *);
 
-       u32 (*update)(struct nv50_wndw *, u32 interlock);
+       void (*update)(struct nv50_wndw *, u32 *interlock);
 };
 #endif