Blob Blame History Raw
From 38a72243235ecf2c1359ce66ebed29a7dfb680f7 Mon Sep 17 00:00:00 2001
From: Ilia Mirkin <imirkin@alum.mit.edu>
Date: Mon, 27 May 2019 22:58:37 -0400
Subject: drm/nouveau/kms/nv50-: add fp16 scanout support
Git-commit: 38a72243235ecf2c1359ce66ebed29a7dfb680f7
Patch-mainline: v5.4-rc1
References: bsc#1152489

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>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/nouveau/dispnv50/base507c.c | 24 +++++++++++++++----
 drivers/gpu/drm/nouveau/dispnv50/base827c.c | 11 ++++++++-
 drivers/gpu/drm/nouveau/dispnv50/base917c.c |  2 ++
 drivers/gpu/drm/nouveau/dispnv50/ovly907e.c | 17 +++++++++++++-
 drivers/gpu/drm/nouveau/dispnv50/ovly917e.c |  2 ++
 drivers/gpu/drm/nouveau/dispnv50/wndw.c     | 26 +++++++++++----------
 drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c |  2 ++
 7 files changed, 66 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c
index 80e020611bcb..00a85f1e1a4a 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c
@@ -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
 };
 
diff --git a/drivers/gpu/drm/nouveau/dispnv50/base827c.c b/drivers/gpu/drm/nouveau/dispnv50/base827c.c
index 73646819a0d6..f4c05949dd62 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/base827c.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/base827c.c
@@ -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);
diff --git a/drivers/gpu/drm/nouveau/dispnv50/base917c.c b/drivers/gpu/drm/nouveau/dispnv50/base917c.c
index 54d705bb81a5..a1baed4fe0e9 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/base917c.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/base917c.c
@@ -36,6 +36,8 @@ base917c_format[] = {
 	DRM_FORMAT_ABGR8888,
 	DRM_FORMAT_XRGB2101010,
 	DRM_FORMAT_ARGB2101010,
+	DRM_FORMAT_XBGR16161616F,
+	DRM_FORMAT_ABGR16161616F,
 	0
 };
 
diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c
index a3ce53046015..f947117d62b1 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c
@@ -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);
 }
diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly917e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly917e.c
index 505fa7e78523..fab567e258f9 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/ovly917e.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/ovly917e.c
@@ -33,6 +33,8 @@ ovly917e_format[] = {
 	DRM_FORMAT_ABGR2101010,
 	DRM_FORMAT_XRGB2101010,
 	DRM_FORMAT_ARGB2101010,
+	DRM_FORMAT_XBGR16161616F,
+	DRM_FORMAT_ABGR16161616F,
 	0
 };
 
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
index 0aaa7e0013f6..dd01ea21da97 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
@@ -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;
 	}
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c b/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c
index e52a85c83f7a..826d1d760d3a 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c
@@ -216,6 +216,8 @@ wndwc37e_format[] = {
 	DRM_FORMAT_ABGR8888,
 	DRM_FORMAT_XRGB2101010,
 	DRM_FORMAT_ARGB2101010,
+	DRM_FORMAT_XBGR16161616F,
+	DRM_FORMAT_ABGR16161616F,
 	0
 };
 
-- 
2.28.0