diff options
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 |