Blob Blame History Raw
From dffa487822d1ff8f44817124d8f2927057a57775 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Tue, 11 Jun 2019 17:46:39 +1000
Subject: drm/nouveau/kms/gv100-: implement csc + enable modern colour
 managment properties
Git-commit: dffa487822d1ff8f44817124d8f2927057a57775
Patch-mainline: v5.4-rc1
References: bsc#1152489

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/nouveau/dispnv50/base907c.c |  2 +-
 drivers/gpu/drm/nouveau/dispnv50/head.c     |  3 +-
 drivers/gpu/drm/nouveau/dispnv50/wndw.h     |  4 +-
 drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c | 26 +++++++-
 drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c | 71 ++++++++++++++++++++-
 5 files changed, 99 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/base907c.c b/drivers/gpu/drm/nouveau/dispnv50/base907c.c
index fd0c1d84730b..5f2de77e0f32 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/base907c.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/base907c.c
@@ -101,7 +101,7 @@ csc_drm_to_base(u64 in)
 	}
 }
 
-static void
+void
 base907c_csc(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
 	     const struct drm_color_ctm *ctm)
 {
diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c
index 46e7f4c51f10..0d1108eadcff 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/head.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/head.c
@@ -512,8 +512,7 @@ nv50_head_create(struct drm_device *dev, int index)
 				  &nv50_head_func, "head-%d", head->base.index);
 	drm_crtc_helper_add(crtc, &nv50_head_help);
 	drm_mode_crtc_set_gamma_size(crtc, 256);
-	if (disp->disp->object.oclass >= GF110_DISP &&
-	    disp->disp->object.oclass < GV100_DISP)
+	if (disp->disp->object.oclass >= GF110_DISP)
 		drm_crtc_enable_color_mgmt(crtc, 256, true, 256);
 	else
 		drm_crtc_enable_color_mgmt(crtc, 0, false, 256);
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h
index 1e781d80c990..59ff8f082542 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h
@@ -85,6 +85,9 @@ 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 *);
 
+void base907c_csc(struct nv50_wndw *, struct nv50_wndw_atom *,
+		  const struct drm_color_ctm *);
+
 struct nv50_wimm_func {
 	void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *);
 
@@ -106,7 +109,6 @@ void wndwc37e_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *);
 void wndwc37e_sema_clr(struct nv50_wndw *);
 void wndwc37e_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *);
 void wndwc37e_ntfy_clr(struct nv50_wndw *);
-void wndwc37e_image_set(struct nv50_wndw *, struct nv50_wndw_atom *);
 void wndwc37e_image_clr(struct nv50_wndw *);
 void wndwc37e_update(struct nv50_wndw *, u32 *);
 
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c b/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c
index 8a4f0e436be6..0d270cd5ac4c 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c
@@ -28,6 +28,23 @@
 
 #include <nvif/clc37e.h>
 
+static void
+wndwc37e_csc_clr(struct nv50_wndw *wndw)
+{
+}
+
+static void
+wndwc37e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
+{
+	u32 *push, i;
+	if ((push = evo_wait(&wndw->wndw, 13))) {
+		 evo_mthd(push, 0x02bc, 12);
+		 for (i = 0; i < 12; i++)
+			  evo_data(push, asyw->csc.matrix[i]);
+		 evo_kick(push, &wndw->wndw);
+	}
+}
+
 static void
 wndwc37e_ilut_clr(struct nv50_wndw *wndw)
 {
@@ -77,7 +94,7 @@ wndwc37e_image_clr(struct nv50_wndw *wndw)
 	}
 }
 
-void
+static void
 wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
 {
 	u32 *push;
@@ -90,7 +107,9 @@ wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
 	evo_mthd(push, 0x0224, 4);
 	evo_data(push, asyw->image.h << 16 | asyw->image.w);
 	evo_data(push, asyw->image.layout << 4 | asyw->image.blockh);
-	evo_data(push, asyw->image.colorspace << 8 | asyw->image.format);
+	evo_data(push, asyw->csc.valid << 17 |
+		       asyw->image.colorspace << 8 |
+		       asyw->image.format);
 	evo_data(push, asyw->image.blocks[0] | (asyw->image.pitch[0] >> 6));
 	evo_mthd(push, 0x0240, 1);
 	evo_data(push, asyw->image.handle[0]);
@@ -234,6 +253,9 @@ wndwc37e = {
 	.ilut = wndwc37e_ilut,
 	.xlut_set = wndwc37e_ilut_set,
 	.xlut_clr = wndwc37e_ilut_clr,
+	.csc = base907c_csc,
+	.csc_set = wndwc37e_csc_set,
+	.csc_clr = wndwc37e_csc_clr,
 	.image_set = wndwc37e_image_set,
 	.image_clr = wndwc37e_image_clr,
 	.update = wndwc37e_update,
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c b/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c
index ba89f1a5fcfa..d5e4b006ae1e 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c
@@ -28,6 +28,72 @@
 
 #include <nvif/clc37e.h>
 
+static void
+wndwc57e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
+{
+	u32 *push;
+
+	if (!(push = evo_wait(&wndw->wndw, 17)))
+		return;
+
+	evo_mthd(push, 0x0308, 1);
+	evo_data(push, asyw->image.mode << 4 | asyw->image.interval);
+	evo_mthd(push, 0x0224, 4);
+	evo_data(push, asyw->image.h << 16 | asyw->image.w);
+	evo_data(push, asyw->image.layout << 4 | asyw->image.blockh);
+	evo_data(push, asyw->image.colorspace << 8 |
+		       asyw->image.format);
+	evo_data(push, asyw->image.blocks[0] | (asyw->image.pitch[0] >> 6));
+	evo_mthd(push, 0x0240, 1);
+	evo_data(push, asyw->image.handle[0]);
+	evo_mthd(push, 0x0260, 1);
+	evo_data(push, asyw->image.offset[0] >> 8);
+	evo_mthd(push, 0x0290, 1);
+	evo_data(push, (asyw->state.src_y >> 16) << 16 |
+		       (asyw->state.src_x >> 16));
+	evo_mthd(push, 0x0298, 1);
+	evo_data(push, (asyw->state.src_h >> 16) << 16 |
+		       (asyw->state.src_w >> 16));
+	evo_mthd(push, 0x02a4, 1);
+	evo_data(push, asyw->state.crtc_h << 16 |
+		       asyw->state.crtc_w);
+	evo_kick(push, &wndw->wndw);
+}
+
+static void
+wndwc57e_csc_clr(struct nv50_wndw *wndw)
+{
+	u32 *push;
+	if ((push = evo_wait(&wndw->wndw, 13))) {
+		 evo_mthd(push, 0x0400, 12);
+		 evo_data(push, 0x00010000);
+		 evo_data(push, 0x00000000);
+		 evo_data(push, 0x00000000);
+		 evo_data(push, 0x00000000);
+		 evo_data(push, 0x00000000);
+		 evo_data(push, 0x00010000);
+		 evo_data(push, 0x00000000);
+		 evo_data(push, 0x00000000);
+		 evo_data(push, 0x00000000);
+		 evo_data(push, 0x00000000);
+		 evo_data(push, 0x00010000);
+		 evo_data(push, 0x00000000);
+		 evo_kick(push, &wndw->wndw);
+	}
+}
+
+static void
+wndwc57e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
+{
+	u32 *push, i;
+	if ((push = evo_wait(&wndw->wndw, 13))) {
+		 evo_mthd(push, 0x0400, 12);
+		 for (i = 0; i < 12; i++)
+			  evo_data(push, asyw->csc.matrix[i]);
+		 evo_kick(push, &wndw->wndw);
+	}
+}
+
 static void
 wndwc57e_ilut_clr(struct nv50_wndw *wndw)
 {
@@ -119,7 +185,10 @@ wndwc57e = {
 	.ilut_identity = true,
 	.xlut_set = wndwc57e_ilut_set,
 	.xlut_clr = wndwc57e_ilut_clr,
-	.image_set = wndwc37e_image_set,
+	.csc = base907c_csc,
+	.csc_set = wndwc57e_csc_set,
+	.csc_clr = wndwc57e_csc_clr,
+	.image_set = wndwc57e_image_set,
 	.image_clr = wndwc37e_image_clr,
 	.update = wndwc37e_update,
 };
-- 
2.28.0