Blob Blame History Raw
From: Ben Skeggs <bskeggs@redhat.com>
Date: Tue, 8 May 2018 20:39:47 +1000
Subject: drm/nouveau/kms/gk104-: support additional cursor sizes
Git-commit: 01d380ab4f702fffa6da60c4b006547b8dd66de8
Patch-mainline: v4.18-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/nouveau/dispnv50/atom.h     |    2 +-
 drivers/gpu/drm/nouveau/dispnv50/curs507a.c |   22 +++++++---------------
 drivers/gpu/drm/nouveau/dispnv50/head.h     |    8 ++++++++
 drivers/gpu/drm/nouveau/dispnv50/head507d.c |   28 ++++++++++++++++++++++++++++
 drivers/gpu/drm/nouveau/dispnv50/head827d.c |    2 ++
 drivers/gpu/drm/nouveau/dispnv50/head907d.c |    2 ++
 drivers/gpu/drm/nouveau/dispnv50/head917d.c |   17 +++++++++++++++++
 7 files changed, 65 insertions(+), 16 deletions(-)

--- a/drivers/gpu/drm/nouveau/dispnv50/atom.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h
@@ -76,7 +76,7 @@ struct nv50_head_atom {
 		bool visible;
 		u32 handle;
 		u64 offset:40;
-		u8  layout:1;
+		u8  layout:2;
 		u8  format:1;
 	} curs;
 
--- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c
@@ -21,6 +21,7 @@
  */
 #include "curs.h"
 #include "core.h"
+#include "head.h"
 
 #include <nvif/cl507a.h>
 
@@ -70,6 +71,7 @@ static int
 curs507a_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
 		 struct nv50_head_atom *asyh)
 {
+	struct nv50_head *head = nv50_head(asyw->state.crtc);
 	int ret;
 
 	ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
@@ -80,24 +82,14 @@ curs507a_acquire(struct nv50_wndw *wndw,
 	if (ret || !asyh->curs.visible)
 		return ret;
 
-	switch (asyw->state.fb->width) {
-	case 32: asyh->curs.layout = 0; break;
-	case 64: asyh->curs.layout = 1; break;
-	default:
-		return -EINVAL;
-	}
-
-	if (asyw->state.fb->width != asyw->state.fb->height)
+	if (asyw->image.w != asyw->image.h)
 		return -EINVAL;
 
-	switch (asyw->image.format) {
-	case 0xcf: asyh->curs.format = 1; break;
-	default:
-		WARN_ON(1);
-		return -EINVAL;
-	}
+	ret = head->func->curs_layout(head, asyw, asyh);
+	if (ret)
+		return ret;
 
-	return 0;
+	return head->func->curs_format(head, asyw, asyh);
 }
 
 static const u32
--- a/drivers/gpu/drm/nouveau/dispnv50/head.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/head.h
@@ -26,6 +26,10 @@ struct nv50_head_func {
 	void (*core_calc)(struct nv50_head *, struct nv50_head_atom *);
 	void (*core_set)(struct nv50_head *, struct nv50_head_atom *);
 	void (*core_clr)(struct nv50_head *);
+	int (*curs_layout)(struct nv50_head *, struct nv50_wndw_atom *,
+			   struct nv50_head_atom *);
+	int (*curs_format)(struct nv50_head *, struct nv50_wndw_atom *,
+			   struct nv50_head_atom *);
 	void (*curs_set)(struct nv50_head *, struct nv50_head_atom *);
 	void (*curs_clr)(struct nv50_head *);
 	void (*base)(struct nv50_head *, struct nv50_head_atom *);
@@ -41,6 +45,10 @@ void head507d_mode(struct nv50_head *, s
 void head507d_olut(struct nv50_head *, struct nv50_head_atom *);
 void head507d_core_calc(struct nv50_head *, struct nv50_head_atom *);
 void head507d_core_clr(struct nv50_head *);
+int head507d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *,
+			 struct nv50_head_atom *);
+int head507d_curs_format(struct nv50_head *, struct nv50_wndw_atom *,
+			 struct nv50_head_atom *);
 void head507d_base(struct nv50_head *, struct nv50_head_atom *);
 void head507d_ovly(struct nv50_head *, struct nv50_head_atom *);
 void head507d_dither(struct nv50_head *, struct nv50_head_atom *);
--- a/drivers/gpu/drm/nouveau/dispnv50/head507d.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/head507d.c
@@ -128,6 +128,32 @@ head507d_curs_set(struct nv50_head *head
 	}
 }
 
+int
+head507d_curs_format(struct nv50_head *head, struct nv50_wndw_atom *asyw,
+		     struct nv50_head_atom *asyh)
+{
+	switch (asyw->image.format) {
+	case 0xcf: asyh->curs.format = 1; break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int
+head507d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw,
+		     struct nv50_head_atom *asyh)
+{
+	switch (asyw->image.w) {
+	case 32: asyh->curs.layout = 0; break;
+	case 64: asyh->curs.layout = 1; break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
 void
 head507d_core_clr(struct nv50_head *head)
 {
@@ -287,6 +313,8 @@ head507d = {
 	.core_calc = head507d_core_calc,
 	.core_set = head507d_core_set,
 	.core_clr = head507d_core_clr,
+	.curs_layout = head507d_curs_layout,
+	.curs_format = head507d_curs_format,
 	.curs_set = head507d_curs_set,
 	.curs_clr = head507d_curs_clr,
 	.base = head507d_base,
--- a/drivers/gpu/drm/nouveau/dispnv50/head827d.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/head827d.c
@@ -113,6 +113,8 @@ head827d = {
 	.core_calc = head507d_core_calc,
 	.core_set = head827d_core_set,
 	.core_clr = head507d_core_clr,
+	.curs_layout = head507d_curs_layout,
+	.curs_format = head507d_curs_format,
 	.curs_set = head827d_curs_set,
 	.curs_clr = head827d_curs_clr,
 	.base = head507d_base,
--- a/drivers/gpu/drm/nouveau/dispnv50/head907d.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/head907d.c
@@ -270,6 +270,8 @@ head907d = {
 	.core_calc = head507d_core_calc,
 	.core_set = head907d_core_set,
 	.core_clr = head907d_core_clr,
+	.curs_layout = head507d_curs_layout,
+	.curs_format = head507d_curs_format,
 	.curs_set = head907d_curs_set,
 	.curs_clr = head907d_curs_clr,
 	.base = head907d_base,
--- a/drivers/gpu/drm/nouveau/dispnv50/head917d.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/head917d.c
@@ -63,6 +63,21 @@ head917d_base(struct nv50_head *head, st
 	}
 }
 
+static int
+head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw,
+		     struct nv50_head_atom *asyh)
+{
+	switch (asyw->state.fb->width) {
+	case  32: asyh->curs.layout = 0; break;
+	case  64: asyh->curs.layout = 1; break;
+	case 128: asyh->curs.layout = 2; break;
+	case 256: asyh->curs.layout = 3; break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
 const struct nv50_head_func
 head917d = {
 	.view = head907d_view,
@@ -73,6 +88,8 @@ head917d = {
 	.core_calc = head507d_core_calc,
 	.core_set = head907d_core_set,
 	.core_clr = head907d_core_clr,
+	.curs_layout = head917d_curs_layout,
+	.curs_format = head507d_curs_format,
 	.curs_set = head907d_curs_set,
 	.curs_clr = head907d_curs_clr,
 	.base = head917d_base,