summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/dispnv50
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/dispnv50')
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/Kbuild3
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/base.h4
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/base507c.c16
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/base827c.c3
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/base907c.c18
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/core.h5
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/core507d.c5
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/curs.c4
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/curs.h6
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/curs507a.c18
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/curs907a.c30
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/disp.c42
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/disp.h11
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/ovly.c10
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/ovly.h8
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/ovly507e.c11
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/ovly827e.c43
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/ovly907e.c34
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/wndw.c23
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/wndw.h16
20 files changed, 224 insertions, 86 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv50/Kbuild b/drivers/gpu/drm/nouveau/dispnv50/Kbuild
index 674221dea7a1..3e53484b4589 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/Kbuild
+++ b/drivers/gpu/drm/nouveau/dispnv50/Kbuild
@@ -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
diff --git a/drivers/gpu/drm/nouveau/dispnv50/base.h b/drivers/gpu/drm/nouveau/dispnv50/base.h
index edf96a8d645f..71fc10369b37 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/base.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/base.h
@@ -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 **);
diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c
index 1c65ddc4747e..819403f4b958 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c
@@ -28,17 +28,15 @@
#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);
}
diff --git a/drivers/gpu/drm/nouveau/dispnv50/base827c.c b/drivers/gpu/drm/nouveau/dispnv50/base827c.c
index 9dc968c83c66..240a6409329d 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/base827c.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/base827c.c
@@ -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);
}
diff --git a/drivers/gpu/drm/nouveau/dispnv50/base907c.c b/drivers/gpu/drm/nouveau/dispnv50/base907c.c
index 5321c55951b9..6c32a4e5cb7d 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/base907c.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/base907c.c
@@ -21,19 +21,6 @@
*/
#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);
}
diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.h b/drivers/gpu/drm/nouveau/dispnv50/core.h
index 5fd7ddd31e5e..c490d7d497b2 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/core.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/core.h
@@ -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;
diff --git a/drivers/gpu/drm/nouveau/dispnv50/core507d.c b/drivers/gpu/drm/nouveau/dispnv50/core507d.c
index 96d7d8fde669..e7fcfa6e6467 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/core507d.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/core507d.c
@@ -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);
}
diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs.c b/drivers/gpu/drm/nouveau/dispnv50/curs.c
index 6d60e978db69..fb842ed2592f 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/curs.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/curs.c
@@ -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 },
diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs.h b/drivers/gpu/drm/nouveau/dispnv50/curs.h
index b85ca9fa419c..2285247dc2a3 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/curs.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/curs.h
@@ -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
diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c
index 589c75c22b3a..ba05bcb13ae7 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c
@@ -27,11 +27,10 @@
#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
index 000000000000..d742362de03e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/dispnv50/curs907a.c
@@ -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);
+}
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index eaa63b43282b..e80d11c9a456 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -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)
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.h b/drivers/gpu/drm/nouveau/dispnv50/disp.h
index 7cbd66849743..f3a963b0ab77 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h
@@ -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;
diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly.c b/drivers/gpu/drm/nouveau/dispnv50/ovly.c
index ac2d3b64f186..be0f16fdcd5b 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/ovly.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/ovly.c
@@ -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 },
{}
};
diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly.h b/drivers/gpu/drm/nouveau/dispnv50/ovly.h
index 90af1f2f0aa0..d149ef6f957e 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/ovly.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/ovly.h
@@ -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
diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c
index 1b85262bf23b..732eea39e4de 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c
@@ -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
index 000000000000..a8115f13406e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c
@@ -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
index 000000000000..f50da6461d41
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c
@@ -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);
+}
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
index 4b64f64b7891..8f62c2a811ff 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
@@ -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);
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h
index 8672c280a6a4..c26796c612f6 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h
@@ -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