drm/nouveau/kms/nv50-: initial overlay support
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:31 +0000 (15:01 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
16 files changed:
drivers/gpu/drm/nouveau/dispnv50/Kbuild
drivers/gpu/drm/nouveau/dispnv50/atom.h
drivers/gpu/drm/nouveau/dispnv50/base.h
drivers/gpu/drm/nouveau/dispnv50/curs.h
drivers/gpu/drm/nouveau/dispnv50/disp.h
drivers/gpu/drm/nouveau/dispnv50/head507d.c
drivers/gpu/drm/nouveau/dispnv50/head907d.c
drivers/gpu/drm/nouveau/dispnv50/oimm507b.c
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
drivers/gpu/drm/nouveau/dispnv50/ovly907e.c
drivers/gpu/drm/nouveau/dispnv50/ovly917e.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/dispnv50/wndw.c
drivers/gpu/drm/nouveau/dispnv50/wndw.h

index 7c337fd8015879e7270b83a489d95b7fa2b31027..ebd18cb9fedac5b3970a5e22ae04c4836129d1e9 100644 (file)
@@ -40,3 +40,4 @@ nouveau-y += dispnv50/ovly.o
 nouveau-y += dispnv50/ovly507e.o
 nouveau-y += dispnv50/ovly827e.o
 nouveau-y += dispnv50/ovly907e.o
+nouveau-y += dispnv50/ovly917e.o
index 3d059df78322b98ea38084314c8a713d62ba73e2..d8337e7996e80f936cfddd120b3c16ffffad866a 100644 (file)
@@ -173,6 +173,7 @@ struct nv50_wndw_atom {
                u8  mode:2;
                u8  interval:4;
 
+               u8  colorspace:2;
                u8  format;
                u8  kind:7;
                u8  layout:1;
@@ -186,6 +187,15 @@ struct nv50_wndw_atom {
                u64 offset[6];
        } image;
 
+       struct {
+               u16 sx;
+               u16 sy;
+               u16 sw;
+               u16 sh;
+               u16 dw;
+               u16 dh;
+       } scale;
+
        struct {
                u16 x;
                u16 y;
@@ -197,6 +207,7 @@ struct nv50_wndw_atom {
                        bool sema:1;
                        bool xlut:1;
                        bool image:1;
+                       bool scale:1;
                        bool point:1;
                };
                u8 mask;
index 7afd9e26f9f96d3aa7d360bb1479086586d84c4a..e7f14f230f35b4789e46d5a33f69c98a5c1b305a 100644 (file)
@@ -13,10 +13,8 @@ void base507c_release(struct nv50_wndw *, struct nv50_wndw_atom *,
                      struct nv50_head_atom *);
 void base507c_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *);
 void base507c_sema_clr(struct nv50_wndw *);
-void base507c_ntfy_reset(struct nouveau_bo *, u32);
 void base507c_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *);
 void base507c_ntfy_clr(struct nv50_wndw *);
-int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *);
 void base507c_xlut_set(struct nv50_wndw *, struct nv50_wndw_atom *);
 void base507c_xlut_clr(struct nv50_wndw *);
 void base507c_image_clr(struct nv50_wndw *);
index 2285247dc2a3a823f3a8cc8105bcee41cc4b5c05..8edac4507ec894057ba8fa0bff76fbaa24200fa5 100644 (file)
@@ -6,7 +6,6 @@ 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 **);
 
index f3a963b0ab77e5fe7f9bdd84091d50a821e8bc9c..a89b83f95187e85f555ff349ce13c3e1613561dd 100644 (file)
@@ -16,6 +16,9 @@ struct nv50_disp {
 #define NV50_DISP_BASE_SEM0(c)                    NV50_DISP_WNDW_SEM0(0 + (c))
 #define NV50_DISP_BASE_SEM1(c)                    NV50_DISP_WNDW_SEM1(0 + (c))
 #define NV50_DISP_BASE_NTFY(c)                    NV50_DISP_WNDW_NTFY(0 + (c))
+#define NV50_DISP_OVLY_SEM0(c)                    NV50_DISP_WNDW_SEM0(4 + (c))
+#define NV50_DISP_OVLY_SEM1(c)                    NV50_DISP_WNDW_SEM1(4 + (c))
+#define NV50_DISP_OVLY_NTFY(c)                    NV50_DISP_WNDW_NTFY(4 + (c))
        struct nouveau_bo *sync;
 
        struct mutex mutex;
index 5b6a280ab804c9b501111f04a2ac25da7097d747..51bc5996fd37a1a85e4e2189995f8d8bdb10f33e 100644 (file)
@@ -58,7 +58,6 @@ head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
 
        if (asyh->ovly.cpp) {
                switch (asyh->ovly.cpp) {
-               case 8: bounds |= 0x00000500; break;
                case 4: bounds |= 0x00000300; break;
                case 2: bounds |= 0x00000100; break;
                default:
@@ -66,6 +65,8 @@ head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
                        break;
                }
                bounds |= 0x00000001;
+       } else {
+               bounds |= 0x00000100;
        }
 
        if ((push = evo_wait(core, 2))) {
index c09620f540f9febf74e8849d9a54c1db193d21d1..633907163eb1f1289b08da747c144649eb17b6f8 100644 (file)
@@ -82,6 +82,8 @@ head907d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
                        break;
                }
                bounds |= 0x00000001;
+       } else {
+               bounds |= 0x00000100;
        }
 
        if ((push = evo_wait(core, 2))) {
index c4baca82de14b53b468d429276cb44baa50011d6..2ee404b3e19ffdcd91ee0680cf204f197bbb71ff 100644 (file)
 
 #include <nvif/cl507b.h>
 
-static const struct nv50_wimm_func
-oimm507b = {
-};
-
 static int
 oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
               s32 oclass, struct nv50_wndw *wndw)
@@ -52,5 +48,5 @@ oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
 int
 oimm507b_init(struct nouveau_drm *drm, s32 oclass, struct nv50_wndw *wndw)
 {
-       return oimm507b_init_(&oimm507b, drm, oclass, wndw);
+       return oimm507b_init_(&curs507a, drm, oclass, wndw);
 }
index be0f16fdcd5bd4a46beabaaf0305d60fa5a8dad8..90c246d47604cb657dbf1b1160f6f70ae405e59b 100644 (file)
@@ -32,7 +32,7 @@ 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, ovly907e_new },
+               { GK104_DISP_OVERLAY_CONTROL_DMA, 0, ovly917e_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 },
index d149ef6f957e633df3790edc95c8b63ce53dfc68..4869d52d17860f4e3b5af1d4f8f44be46f9bac0b 100644 (file)
@@ -6,11 +6,25 @@ 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 **);
+int ovly507e_acquire(struct nv50_wndw *, struct nv50_wndw_atom *,
+                    struct nv50_head_atom *);
+void ovly507e_release(struct nv50_wndw *, struct nv50_wndw_atom *,
+                     struct nv50_head_atom *);
+void ovly507e_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *);
+void ovly507e_ntfy_clr(struct nv50_wndw *);
+void ovly507e_image_clr(struct nv50_wndw *);
+void ovly507e_scale_set(struct nv50_wndw *, struct nv50_wndw_atom *);
+void ovly507e_update(struct nv50_wndw *, u32 *);
 
 extern const u32 ovly827e_format[];
+void ovly827e_ntfy_reset(struct nouveau_bo *, u32);
+int ovly827e_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *);
+
+extern const struct nv50_wndw_func ovly907e;
 
 int ovly827e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
 int ovly907e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
+int ovly917e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
 
 int nv50_ovly_new(struct nouveau_drm *, int head, struct nv50_wndw **);
 #endif
index 732eea39e4de76e6ed6ae0ba2e43928a5431690f..cc417664f8231dba2def603a0e838dfed9c921ef 100644 (file)
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 #include "ovly.h"
+#include "atom.h"
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_plane_helper.h>
 
 #include <nvif/cl507e.h>
+#include <nvif/event.h>
+
+void
+ovly507e_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[NV50_DISP_INTERLOCK_CORE]);
+               evo_kick(push, &wndw->wndw);
+       }
+}
+
+void
+ovly507e_scale_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
+{
+       u32 *push;
+       if ((push = evo_wait(&wndw->wndw, 4))) {
+               evo_mthd(push, 0x00e0, 3);
+               evo_data(push, asyw->scale.sy << 16 | asyw->scale.sx);
+               evo_data(push, asyw->scale.sh << 16 | asyw->scale.sw);
+               evo_data(push, asyw->scale.dw);
+               evo_kick(push, &wndw->wndw);
+       }
+}
+
+void
+ovly507e_image_clr(struct nv50_wndw *wndw)
+{
+       u32 *push;
+       if ((push = evo_wait(&wndw->wndw, 4))) {
+               evo_mthd(push, 0x0084, 1);
+               evo_data(push, 0x00000000);
+               evo_mthd(push, 0x00c0, 1);
+               evo_data(push, 0x00000000);
+               evo_kick(push, &wndw->wndw);
+       }
+}
+
+static void
+ovly507e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
+{
+       u32 *push;
+       if ((push = evo_wait(&wndw->wndw, 12))) {
+               evo_mthd(push, 0x0084, 1);
+               evo_data(push, asyw->image.interval << 4);
+               evo_mthd(push, 0x00c0, 1);
+               evo_data(push, asyw->image.handle[0]);
+               evo_mthd(push, 0x0100, 1);
+               evo_data(push, 0x00000002);
+               evo_mthd(push, 0x0800, 1);
+               evo_data(push, asyw->image.offset[0] >> 8);
+               evo_mthd(push, 0x0808, 3);
+               evo_data(push, asyw->image.h << 16 | asyw->image.w);
+               evo_data(push, asyw->image.layout << 20 |
+                              (asyw->image.pitch[0] >> 8) << 8 |
+                              asyw->image.blocks[0] << 8 |
+                              asyw->image.blockh);
+               evo_data(push, asyw->image.kind << 16 |
+                              asyw->image.format << 8 |
+                              asyw->image.colorspace);
+               evo_kick(push, &wndw->wndw);
+       }
+}
+
+void
+ovly507e_ntfy_clr(struct nv50_wndw *wndw)
+{
+       u32 *push;
+       if ((push = evo_wait(&wndw->wndw, 2))) {
+               evo_mthd(push, 0x00a4, 1);
+               evo_data(push, 0x00000000);
+               evo_kick(push, &wndw->wndw);
+       }
+}
+
+void
+ovly507e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
+{
+       u32 *push;
+       if ((push = evo_wait(&wndw->wndw, 3))) {
+               evo_mthd(push, 0x00a0, 2);
+               evo_data(push, asyw->ntfy.awaken << 30 | asyw->ntfy.offset);
+               evo_data(push, asyw->ntfy.handle);
+               evo_kick(push, &wndw->wndw);
+       }
+}
+
+void
+ovly507e_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
+                struct nv50_head_atom *asyh)
+{
+       asyh->ovly.cpp = 0;
+}
+
+int
+ovly507e_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
+                struct nv50_head_atom *asyh)
+{
+       const struct drm_framebuffer *fb = asyw->state.fb;
+       int ret;
+
+       ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
+                                                 DRM_PLANE_HELPER_NO_SCALING,
+                                                 DRM_PLANE_HELPER_NO_SCALING,
+                                                 true, true);
+       if (ret)
+               return ret;
+
+       asyh->ovly.cpp = fb->format->cpp[0];
+       return 0;
+}
 
 #include "nouveau_bo.h"
 
 static const struct nv50_wndw_func
 ovly507e = {
+       .acquire = ovly507e_acquire,
+       .release = ovly507e_release,
+       .ntfy_set = ovly507e_ntfy_set,
+       .ntfy_clr = ovly507e_ntfy_clr,
+       .ntfy_reset = base507c_ntfy_reset,
+       .ntfy_wait_begun = base507c_ntfy_wait_begun,
+       .image_set = ovly507e_image_set,
+       .image_clr = ovly507e_image_clr,
+       .scale_set = ovly507e_scale_set,
+       .update = ovly507e_update,
 };
 
 static const u32
 ovly507e_format[] = {
+       DRM_FORMAT_YUYV,
+       DRM_FORMAT_UYVY,
+       DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_ARGB8888,
+       DRM_FORMAT_XRGB1555,
+       DRM_FORMAT_ARGB1555,
        0
 };
 
@@ -61,6 +193,18 @@ ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format,
                return ret;
        }
 
+       ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func, false,
+                              NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT,
+                              &(struct nvif_notify_uevent_req) {},
+                              sizeof(struct nvif_notify_uevent_req),
+                              sizeof(struct nvif_notify_uevent_rep),
+                              &wndw->notify);
+       if (ret)
+               return ret;
+
+       wndw->ntfy = NV50_DISP_OVLY_NTFY(wndw->id);
+       wndw->sema = NV50_DISP_OVLY_SEM0(wndw->id);
+       wndw->data = 0x00000000;
        return 0;
 }
 
index a8115f13406ee5231014b71f06b8cb567f4ab335..aaa9fe5a4fc8acab3f5559d20147e187485abb28 100644 (file)
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 #include "ovly.h"
+#include "atom.h"
 
 #include <nouveau_bo.h>
 
-#include <nvif/cl507e.h>
+static void
+ovly827e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
+{
+       u32 *push;
+       if ((push = evo_wait(&wndw->wndw, 12))) {
+               evo_mthd(push, 0x0084, 1);
+               evo_data(push, asyw->image.interval << 4);
+               evo_mthd(push, 0x00c0, 1);
+               evo_data(push, asyw->image.handle[0]);
+               evo_mthd(push, 0x0100, 1);
+               evo_data(push, 0x00000002);
+               evo_mthd(push, 0x0800, 1);
+               evo_data(push, asyw->image.offset[0] >> 8);
+               evo_mthd(push, 0x0808, 3);
+               evo_data(push, asyw->image.h << 16 | asyw->image.w);
+               evo_data(push, asyw->image.layout << 20 |
+                              (asyw->image.pitch[0] >> 8) << 8 |
+                              asyw->image.blocks[0] << 8 |
+                              asyw->image.blockh);
+               evo_data(push, asyw->image.format << 8 |
+                              asyw->image.colorspace);
+               evo_kick(push, &wndw->wndw);
+       }
+}
+
+int
+ovly827e_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset,
+                        struct nvif_device *device)
+{
+       s64 time = nvif_msec(device, 2000ULL,
+               u32 data = nouveau_bo_rd32(bo, offset / 4 + 3);
+               if ((data & 0xffff0000) == 0xffff0000)
+                       break;
+               usleep_range(1, 2);
+       );
+       return time < 0 ? time : 0;
+}
+
+void
+ovly827e_ntfy_reset(struct nouveau_bo *bo, u32 offset)
+{
+       nouveau_bo_wr32(bo, offset / 4 + 0, 0x00000000);
+       nouveau_bo_wr32(bo, offset / 4 + 1, 0x00000000);
+       nouveau_bo_wr32(bo, offset / 4 + 2, 0x00000000);
+       nouveau_bo_wr32(bo, offset / 4 + 3, 0x80000000);
+}
 
 static const struct nv50_wndw_func
 ovly827e = {
+       .acquire = ovly507e_acquire,
+       .release = ovly507e_release,
+       .ntfy_set = ovly507e_ntfy_set,
+       .ntfy_clr = ovly507e_ntfy_clr,
+       .ntfy_reset = ovly827e_ntfy_reset,
+       .ntfy_wait_begun = ovly827e_ntfy_wait_begun,
+       .image_set = ovly827e_image_set,
+       .image_clr = ovly507e_image_clr,
+       .scale_set = ovly507e_scale_set,
+       .update = ovly507e_update,
 };
 
 const u32
 ovly827e_format[] = {
+       DRM_FORMAT_YUYV,
+       DRM_FORMAT_UYVY,
+       DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_ARGB8888,
+       DRM_FORMAT_XRGB1555,
+       DRM_FORMAT_ARGB1555,
+       DRM_FORMAT_XBGR2101010,
+       DRM_FORMAT_ABGR2101010,
        0
 };
 
index f50da6461d41b58c0c8d53ac7ab5a4ec313ba649..a3ce53046015c2f789013cd6456796d24b3dd70c 100644 (file)
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 #include "ovly.h"
+#include "atom.h"
 
-static const struct nv50_wndw_func
+static void
+ovly907e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
+{
+       u32 *push;
+       if ((push = evo_wait(&wndw->wndw, 12))) {
+               evo_mthd(push, 0x0084, 1);
+               evo_data(push, asyw->image.interval << 4);
+               evo_mthd(push, 0x00c0, 1);
+               evo_data(push, asyw->image.handle[0]);
+               evo_mthd(push, 0x0100, 1);
+               evo_data(push, 0x00000002);
+               evo_mthd(push, 0x0400, 1);
+               evo_data(push, asyw->image.offset[0] >> 8);
+               evo_mthd(push, 0x0408, 3);
+               evo_data(push, asyw->image.h << 16 | asyw->image.w);
+               evo_data(push, asyw->image.layout << 24 |
+                              (asyw->image.pitch[0] >> 8) << 8 |
+                              asyw->image.blocks[0] << 8 |
+                              asyw->image.blockh);
+               evo_data(push, asyw->image.format << 8 |
+                              asyw->image.colorspace);
+               evo_kick(push, &wndw->wndw);
+       }
+}
+
+const struct nv50_wndw_func
 ovly907e = {
+       .acquire = ovly507e_acquire,
+       .release = ovly507e_release,
+       .ntfy_set = ovly507e_ntfy_set,
+       .ntfy_clr = ovly507e_ntfy_clr,
+       .ntfy_reset = ovly827e_ntfy_reset,
+       .ntfy_wait_begun = ovly827e_ntfy_wait_begun,
+       .image_set = ovly907e_image_set,
+       .image_clr = ovly507e_image_clr,
+       .scale_set = ovly507e_scale_set,
+       .update = ovly507e_update,
 };
 
 int
diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly917e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly917e.c
new file mode 100644 (file)
index 0000000..505fa7e
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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 u32
+ovly917e_format[] = {
+       DRM_FORMAT_YUYV,
+       DRM_FORMAT_UYVY,
+       DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_ARGB8888,
+       DRM_FORMAT_XRGB1555,
+       DRM_FORMAT_ARGB1555,
+       DRM_FORMAT_XBGR2101010,
+       DRM_FORMAT_ABGR2101010,
+       DRM_FORMAT_XRGB2101010,
+       DRM_FORMAT_ARGB2101010,
+       0
+};
+
+int
+ovly917e_new(struct nouveau_drm *drm, int head, s32 oclass,
+            struct nv50_wndw **pwndw)
+{
+       return ovly507e_new_(&ovly907e, ovly917e_format, drm, head, oclass,
+                            0x00000004 << (head * 4), pwndw);
+}
index 861fb0ec6b615fe018263cdc569f6554051eb846..c7c08fae383f3313558c8a077b33b5473f40defd 100644 (file)
@@ -146,6 +146,7 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
                wndw->func->xlut_set(wndw, asyw);
        }
 
+       if (asyw->set.scale) wndw->func->scale_set(wndw, asyw);
        if (asyw->set.point) {
                wndw->immd->point(wndw, asyw);
                wndw->immd->update(wndw, interlock);
@@ -180,6 +181,20 @@ nv50_wndw_atomic_check_release(struct nv50_wndw *wndw,
        asyw->sema.handle = 0;
 }
 
+static int
+nv50_wndw_atomic_check_acquire_yuv(struct nv50_wndw_atom *asyw)
+{
+       switch (asyw->state.fb->format->format) {
+       case DRM_FORMAT_YUYV: asyw->image.format = 0x28; break;
+       case DRM_FORMAT_UYVY: asyw->image.format = 0x29; break;
+       default:
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       asyw->image.colorspace = 1;
+       return 0;
+}
+
 static int
 nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw)
 {
@@ -197,9 +212,9 @@ nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw)
        case DRM_FORMAT_XRGB2101010:
        case DRM_FORMAT_ARGB2101010: asyw->image.format = 0xdf; break;
        default:
-               WARN_ON(1);
                return -EINVAL;
        }
+       asyw->image.colorspace = 0;
        return 0;
 }
 
@@ -221,8 +236,11 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
                asyw->image.kind = fb->nvbo->kind;
 
                ret = nv50_wndw_atomic_check_acquire_rgb(asyw);
-               if (ret)
-                       return ret;
+               if (ret) {
+                       ret = nv50_wndw_atomic_check_acquire_yuv(asyw);
+                       if (ret)
+                               return ret;
+               }
 
                if (asyw->image.kind) {
                        asyw->image.layout = 0;
@@ -247,6 +265,17 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
                asyw->set.image = wndw->func->image_set != NULL;
        }
 
+       if (wndw->func->scale_set) {
+               asyw->scale.sx = asyw->state.src_x >> 16;
+               asyw->scale.sy = asyw->state.src_y >> 16;
+               asyw->scale.sw = asyw->state.src_w >> 16;
+               asyw->scale.sh = asyw->state.src_h >> 16;
+               asyw->scale.dw = asyw->state.crtc_w;
+               asyw->scale.dh = asyw->state.crtc_h;
+               if (memcmp(&armw->scale, &asyw->scale, sizeof(asyw->scale)))
+                       asyw->set.scale = true;
+       }
+
        if (wndw->immd) {
                asyw->point.x = asyw->state.crtc_x;
                asyw->point.y = asyw->state.crtc_y;
index 223cf3f37dae3316198d430c5218abfe66769a0e..745304d06af1985488e59923db5316f6a1fce8ba 100644 (file)
@@ -70,15 +70,21 @@ struct nv50_wndw_func {
        void (*xlut_clr)(struct nv50_wndw *);
        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 (*update)(struct nv50_wndw *, u32 *interlock);
 };
 
 extern const struct drm_plane_funcs nv50_wndw;
 
+void base507c_ntfy_reset(struct nouveau_bo *, u32);
+int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *);
+
 struct nv50_wimm_func {
        void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *);
 
        void (*update)(struct nv50_wndw *, u32 *interlock);
 };
+
+extern const struct nv50_wimm_func curs507a;
 #endif