drm/nouveau/kms/nv50-: add fp16 scanout support
authorIlia Mirkin <imirkin@alum.mit.edu>
Tue, 28 May 2019 02:58:37 +0000 (22:58 -0400)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 23 Aug 2019 02:55:31 +0000 (12:55 +1000)
Older hardware seems to want 0..1024 values, while new hardware takes
0..1 values. We set the gain to 1024 for the earlier display classes.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/dispnv50/base507c.c
drivers/gpu/drm/nouveau/dispnv50/base827c.c
drivers/gpu/drm/nouveau/dispnv50/base917c.c
drivers/gpu/drm/nouveau/dispnv50/ovly907e.c
drivers/gpu/drm/nouveau/dispnv50/ovly917e.c
drivers/gpu/drm/nouveau/dispnv50/wndw.c
drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c

index 80e020611bcb5c7ccafbf2310546ffa6604825f7..00a85f1e1a4a7e1d32c661100bb4f41c0a3f60e1 100644 (file)
@@ -58,12 +58,21 @@ static void
 base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
 {
        u32 *push;
-       if ((push = evo_wait(&wndw->wndw, 10))) {
+       if ((push = evo_wait(&wndw->wndw, 13))) {
                evo_mthd(push, 0x0084, 1);
                evo_data(push, asyw->image.mode << 8 |
                               asyw->image.interval << 4);
                evo_mthd(push, 0x00c0, 1);
                evo_data(push, asyw->image.handle[0]);
+               if (asyw->image.format == 0xca) {
+                       evo_mthd(push, 0x0110, 2);
+                       evo_data(push, 1);
+                       evo_data(push, 0x6400);
+               } else {
+                       evo_mthd(push, 0x0110, 2);
+                       evo_data(push, 0);
+                       evo_data(push, 0);
+               }
                evo_mthd(push, 0x0800, 5);
                evo_data(push, asyw->image.offset[0] >> 8);
                evo_data(push, 0x00000000);
@@ -181,9 +190,6 @@ base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
        const struct drm_framebuffer *fb = asyw->state.fb;
        int ret;
 
-       if (!fb->format->depth)
-               return -EINVAL;
-
        ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
                                                  DRM_PLANE_HELPER_NO_SCALING,
                                                  DRM_PLANE_HELPER_NO_SCALING,
@@ -202,6 +208,14 @@ base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
        asyh->base.y = asyw->state.src.y1 >> 16;
        asyh->base.w = asyw->state.fb->width;
        asyh->base.h = asyw->state.fb->height;
+
+       /* Some newer formats, esp FP16 ones, don't have a
+        * "depth". There's nothing that really makes sense there
+        * either, so just set it to the implicit bit count.
+        */
+       if (!asyh->base.depth)
+               asyh->base.depth = asyh->base.cpp * 8;
+
        return 0;
 }
 
@@ -217,6 +231,8 @@ base507c_format[] = {
        DRM_FORMAT_ABGR2101010,
        DRM_FORMAT_XBGR8888,
        DRM_FORMAT_ABGR8888,
+       DRM_FORMAT_XBGR16161616F,
+       DRM_FORMAT_ABGR16161616F,
        0
 };
 
index 73646819a0d686c0270b5084f90c3d89ed08bcf3..f4c05949dd6258ca0ba84130097ac7250f8e06a1 100644 (file)
@@ -25,12 +25,21 @@ static void
 base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
 {
        u32 *push;
-       if ((push = evo_wait(&wndw->wndw, 10))) {
+       if ((push = evo_wait(&wndw->wndw, 13))) {
                evo_mthd(push, 0x0084, 1);
                evo_data(push, asyw->image.mode << 8 |
                               asyw->image.interval << 4);
                evo_mthd(push, 0x00c0, 1);
                evo_data(push, asyw->image.handle[0]);
+               if (asyw->image.format == 0xca) {
+                       evo_mthd(push, 0x0110, 2);
+                       evo_data(push, 1);
+                       evo_data(push, 0x6400);
+               } else {
+                       evo_mthd(push, 0x0110, 2);
+                       evo_data(push, 0);
+                       evo_data(push, 0);
+               }
                evo_mthd(push, 0x0800, 5);
                evo_data(push, asyw->image.offset[0] >> 8);
                evo_data(push, 0x00000000);
index 54d705bb81a5dfa3e95fec5d4d7322ae5a44f9df..a1baed4fe0e9f5d434e1f2f3f992ffbf60000379 100644 (file)
@@ -36,6 +36,8 @@ base917c_format[] = {
        DRM_FORMAT_ABGR8888,
        DRM_FORMAT_XRGB2101010,
        DRM_FORMAT_ARGB2101010,
+       DRM_FORMAT_XBGR16161616F,
+       DRM_FORMAT_ABGR16161616F,
        0
 };
 
index a3ce53046015c2f789013cd6456796d24b3dd70c..f947117d62b1168b6dcbede39fc3fd1bff81638c 100644 (file)
@@ -61,10 +61,25 @@ ovly907e = {
        .update = ovly507e_update,
 };
 
+static const u32
+ovly907e_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_XBGR16161616F,
+       DRM_FORMAT_ABGR16161616F,
+       0
+};
+
 int
 ovly907e_new(struct nouveau_drm *drm, int head, s32 oclass,
             struct nv50_wndw **pwndw)
 {
-       return ovly507e_new_(&ovly907e, ovly827e_format, drm, head, oclass,
+       return ovly507e_new_(&ovly907e, ovly907e_format, drm, head, oclass,
                             0x00000004 << (head * 4), pwndw);
 }
index 505fa7e7852309b0446b6268771f87080c274510..fab567e258f9ab16a1bd605022dbaa2761002377 100644 (file)
@@ -33,6 +33,8 @@ ovly917e_format[] = {
        DRM_FORMAT_ABGR2101010,
        DRM_FORMAT_XRGB2101010,
        DRM_FORMAT_ARGB2101010,
+       DRM_FORMAT_XBGR16161616F,
+       DRM_FORMAT_ABGR16161616F,
        0
 };
 
index 0aaa7e0013f61c8705487dcdb6edf3c6fa038893..dd01ea21da97322c67623d33d0da61f934fd8183 100644 (file)
@@ -204,18 +204,20 @@ static int
 nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw)
 {
        switch (asyw->state.fb->format->format) {
-       case DRM_FORMAT_C8         : asyw->image.format = 0x1e; break;
-       case DRM_FORMAT_XRGB8888   :
-       case DRM_FORMAT_ARGB8888   : asyw->image.format = 0xcf; break;
-       case DRM_FORMAT_RGB565     : asyw->image.format = 0xe8; break;
-       case DRM_FORMAT_XRGB1555   :
-       case DRM_FORMAT_ARGB1555   : asyw->image.format = 0xe9; break;
-       case DRM_FORMAT_XBGR2101010:
-       case DRM_FORMAT_ABGR2101010: asyw->image.format = 0xd1; break;
-       case DRM_FORMAT_XBGR8888   :
-       case DRM_FORMAT_ABGR8888   : asyw->image.format = 0xd5; break;
-       case DRM_FORMAT_XRGB2101010:
-       case DRM_FORMAT_ARGB2101010: asyw->image.format = 0xdf; break;
+       case DRM_FORMAT_C8           : asyw->image.format = 0x1e; break;
+       case DRM_FORMAT_XRGB8888     :
+       case DRM_FORMAT_ARGB8888     : asyw->image.format = 0xcf; break;
+       case DRM_FORMAT_RGB565       : asyw->image.format = 0xe8; break;
+       case DRM_FORMAT_XRGB1555     :
+       case DRM_FORMAT_ARGB1555     : asyw->image.format = 0xe9; break;
+       case DRM_FORMAT_XBGR2101010  :
+       case DRM_FORMAT_ABGR2101010  : asyw->image.format = 0xd1; break;
+       case DRM_FORMAT_XBGR8888     :
+       case DRM_FORMAT_ABGR8888     : asyw->image.format = 0xd5; break;
+       case DRM_FORMAT_XRGB2101010  :
+       case DRM_FORMAT_ARGB2101010  : asyw->image.format = 0xdf; break;
+       case DRM_FORMAT_XBGR16161616F:
+       case DRM_FORMAT_ABGR16161616F: asyw->image.format = 0xca; break;
        default:
                return -EINVAL;
        }
index e52a85c83f7a81358981536b419db9e5a475d82e..826d1d760d3a256ece4e38f5c44a78d5939d0e23 100644 (file)
@@ -216,6 +216,8 @@ wndwc37e_format[] = {
        DRM_FORMAT_ABGR8888,
        DRM_FORMAT_XRGB2101010,
        DRM_FORMAT_ARGB2101010,
+       DRM_FORMAT_XBGR16161616F,
+       DRM_FORMAT_ABGR16161616F,
        0
 };