]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/gpu/drm/nouveau/dispnv50/wndw.c
drm/nouveau/kms/gf119-: add ctm property support
[linux.git] / drivers / gpu / drm / nouveau / dispnv50 / wndw.c
index 027a01b97d1c7e0f1b83781c84777bb5bc79ae10..c8d0786297222e1eec86962dcfb34bec8f0f561f 100644 (file)
@@ -26,6 +26,8 @@
 #include <nvif/cl0002.h>
 
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_fourcc.h>
+
 #include "nouveau_bo.h"
 
 static void
@@ -118,6 +120,7 @@ nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 *interlock, bool flush,
        if (clr.sema ) wndw->func-> sema_clr(wndw);
        if (clr.ntfy ) wndw->func-> ntfy_clr(wndw);
        if (clr.xlut ) wndw->func-> xlut_clr(wndw);
+       if (clr.csc  ) wndw->func->  csc_clr(wndw);
        if (clr.image) wndw->func->image_clr(wndw);
 
        interlock[wndw->interlock.type] |= wndw->interlock.data;
@@ -145,6 +148,7 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
                wndw->func->xlut_set(wndw, asyw);
        }
 
+       if (asyw->set.csc  ) wndw->func->csc_set  (wndw, asyw);
        if (asyw->set.scale) wndw->func->scale_set(wndw, asyw);
        if (asyw->set.point) {
                if (asyw->set.point = false, asyw->set.mask)
@@ -202,18 +206,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;
        }
@@ -320,7 +326,9 @@ nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw,
                asyh->wndw.olut &= ~BIT(wndw->id);
        }
 
-       if (!ilut && wndw->func->ilut_identity) {
+       if (!ilut && wndw->func->ilut_identity &&
+           asyw->state.fb->format->format != DRM_FORMAT_XBGR16161616F &&
+           asyw->state.fb->format->format != DRM_FORMAT_ABGR16161616F) {
                static struct drm_property_blob dummy = {};
                ilut = &dummy;
        }
@@ -332,6 +340,8 @@ nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw,
                asyw->xlut.handle = wndw->wndw.vram.handle;
                asyw->xlut.i.buffer = !asyw->xlut.i.buffer;
                asyw->set.xlut = true;
+       } else {
+               asyw->clr.xlut = armw->xlut.handle != 0;
        }
 
        /* Handle setting base SET_OUTPUT_LUT_LO_ENABLE_USE_CORE_LUT. */
@@ -339,6 +349,16 @@ nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw,
            (!armw->visible || (armw->xlut.handle && !asyw->xlut.handle)))
                asyw->set.xlut = true;
 
+       if (wndw->func->csc && asyh->state.ctm) {
+               const struct drm_color_ctm *ctm = asyh->state.ctm->data;
+               wndw->func->csc(wndw, asyw, ctm);
+               asyw->csc.valid = true;
+               asyw->set.csc = true;
+       } else {
+               asyw->csc.valid = false;
+               asyw->clr.csc = armw->csc.valid;
+       }
+
        /* Can't do an immediate flip while changing the LUT. */
        asyh->state.pageflip_flags &= ~DRM_MODE_PAGE_FLIP_ASYNC;
 }
@@ -408,6 +428,7 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state)
                asyw->clr.ntfy = armw->ntfy.handle != 0;
                asyw->clr.sema = armw->sema.handle != 0;
                asyw->clr.xlut = armw->xlut.handle != 0;
+               asyw->clr.csc  = armw->csc.valid;
                if (wndw->func->image_clr)
                        asyw->clr.image = armw->image.handle[0] != 0;
        }
@@ -499,6 +520,7 @@ nv50_wndw_atomic_duplicate_state(struct drm_plane *plane)
        asyw->ntfy = armw->ntfy;
        asyw->ilut = NULL;
        asyw->xlut = armw->xlut;
+       asyw->csc  = armw->csc;
        asyw->image = armw->image;
        asyw->point = armw->point;
        asyw->clr.mask = 0;