Blob Blame History Raw
From e3d16892e2281e81197a2e66329233505325e4e2 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Wed, 1 Jun 2022 20:46:31 +1000
Subject: drm/nouveau/disp: move DAC load detection method
Git-commit: dfc4005f8c172eea359f9db08c3b2b0ff0153699
Patch-mainline: v6.0-rc1
References: jsc#PED-1166 jsc#PED-1168 jsc#PED-1170 jsc#PED-1218 jsc#PED-1220 jsc#PED-1222 jsc#PED-1223 jsc#PED-1225 jsc#PED-2849

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c       | 21 +++++-----------
 drivers/gpu/drm/nouveau/include/nvif/cl5070.h |  8 ------
 drivers/gpu/drm/nouveau/include/nvif/if0012.h | 11 ++++++++
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |  1 +
 drivers/gpu/drm/nouveau/nvif/outp.c           | 14 +++++++++++
 .../drm/nouveau/nvkm/engine/disp/rootnv50.c   | 21 ----------------
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 25 +++++++++++++++++++
 7 files changed, 57 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index e094fb074105..a53d685a77eb 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -529,24 +529,15 @@ static enum drm_connector_status
 nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
 {
 	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-	struct nv50_disp *disp = nv50_disp(encoder->dev);
-	struct {
-		struct nv50_disp_mthd_v1 base;
-		struct nv50_disp_dac_load_v0 load;
-	} args = {
-		.base.version = 1,
-		.base.method = NV50_DISP_MTHD_V1_DAC_LOAD,
-		.base.hasht  = nv_encoder->dcb->hasht,
-		.base.hashm  = nv_encoder->dcb->hashm,
-	};
+	u32 loadval;
 	int ret;
 
-	args.load.data = nouveau_drm(encoder->dev)->vbios.dactestval;
-	if (args.load.data == 0)
-		args.load.data = 340;
+	loadval = nouveau_drm(encoder->dev)->vbios.dactestval;
+	if (loadval == 0)
+		loadval = 340;
 
-	ret = nvif_mthd(&disp->disp->object, 0, &args, sizeof(args));
-	if (ret || !args.load.load)
+	ret = nvif_outp_load_detect(&nv_encoder->outp, loadval);
+	if (ret <= 0)
 		return connector_status_disconnected;
 
 	return connector_status_connected;
diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl5070.h b/drivers/gpu/drm/nouveau/include/nvif/cl5070.h
index 53800fb46582..56affb606adf 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/cl5070.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/cl5070.h
@@ -30,7 +30,6 @@ struct nv50_disp_mthd_v1 {
 	__u8  version;
 #define NV50_DISP_MTHD_V1_ACQUIRE                                          0x01
 #define NV50_DISP_MTHD_V1_RELEASE                                          0x02
-#define NV50_DISP_MTHD_V1_DAC_LOAD                                         0x11
 #define NV50_DISP_MTHD_V1_SOR_HDA_ELD                                      0x21
 #define NV50_DISP_MTHD_V1_SOR_HDMI_PWR                                     0x22
 #define NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT                                  0x23
@@ -50,13 +49,6 @@ struct nv50_disp_acquire_v0 {
 	__u8  pad04[4];
 };
 
-struct nv50_disp_dac_load_v0 {
-	__u8  version;
-	__u8  load;
-	__u8  pad02[2];
-	__u32 data;
-};
-
 struct nv50_disp_sor_hda_eld_v0 {
 	__u8  version;
 	__u8  pad01[7];
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index c0793e0f902f..243bd35d942f 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -9,4 +9,15 @@ union nvif_outp_args {
 		__u8 pad02[6];
 	} v0;
 };
+
+#define NVIF_OUTP_V0_LOAD_DETECT 0x00
+
+union nvif_outp_load_detect_args {
+	struct nvif_outp_load_detect_v0 {
+		__u8  version;
+		__u8  load;
+		__u8  pad02[2];
+		__u32 data; /*TODO: move vbios loadval parsing into nvkm */
+	} v0;
+};
 #endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h b/drivers/gpu/drm/nouveau/include/nvif/outp.h
index 64d2131058d5..0d6aa07a9184 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
@@ -10,4 +10,5 @@ struct nvif_outp {
 
 int nvif_outp_ctor(struct nvif_disp *, const char *name, int id, struct nvif_outp *);
 void nvif_outp_dtor(struct nvif_outp *);
+int nvif_outp_load_detect(struct nvif_outp *, u32 loadval);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvif/outp.c b/drivers/gpu/drm/nouveau/nvif/outp.c
index 5a231bf7db96..7bfe91a8d6f9 100644
--- a/drivers/gpu/drm/nouveau/nvif/outp.c
+++ b/drivers/gpu/drm/nouveau/nvif/outp.c
@@ -26,6 +26,20 @@
 #include <nvif/class.h>
 #include <nvif/if0012.h>
 
+int
+nvif_outp_load_detect(struct nvif_outp *outp, u32 loadval)
+{
+	struct nvif_outp_load_detect_v0 args;
+	int ret;
+
+	args.version = 0;
+	args.data = loadval;
+
+	ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_LOAD_DETECT, &args, sizeof(args));
+	NVIF_ERRON(ret, &outp->object, "[LOAD_DETECT data:%08x] load:%02x", args.data, args.load);
+	return ret < 0 ? ret : args.load;
+}
+
 void
 nvif_outp_dtor(struct nvif_outp *outp)
 {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
index 0a28db5b75e7..0af45ccd140c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
@@ -109,27 +109,6 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 	case NV50_DISP_MTHD_V1_RELEASE:
 		nvkm_outp_release(outp, NVKM_OUTP_USER);
 		return 0;
-	case NV50_DISP_MTHD_V1_DAC_LOAD: {
-		union {
-			struct nv50_disp_dac_load_v0 v0;
-		} *args = data;
-		int ret = -ENOSYS;
-		if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
-			if (args->v0.data & 0xfff00000)
-				return -EINVAL;
-			ret = nvkm_outp_acquire(outp, NVKM_OUTP_PRIV, false);
-			if (ret)
-				return ret;
-			ret = outp->ior->func->sense(outp->ior, args->v0.data);
-			nvkm_outp_release(outp, NVKM_OUTP_PRIV);
-			if (ret < 0)
-				return ret;
-			args->v0.load = ret;
-			return 0;
-		} else
-			return ret;
-	}
-		break;
 	case NV50_DISP_MTHD_V1_SOR_HDA_ELD: {
 		union {
 			struct nv50_disp_sor_hda_eld_v0 v0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index 1ea144ecdb31..abedb3e86361 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -21,13 +21,38 @@
  */
 #define nvkm_uoutp(p) container_of((p), struct nvkm_outp, object)
 #include "outp.h"
+#include "ior.h"
 
 #include <nvif/if0012.h>
 
+static int
+nvkm_uoutp_mthd_load_detect(struct nvkm_outp *outp, void *argv, u32 argc)
+{
+	union nvif_outp_load_detect_args *args = argv;
+	int ret;
+
+	if (argc != sizeof(args->v0) || args->v0.version != 0)
+		return -ENOSYS;
+
+	ret = nvkm_outp_acquire(outp, NVKM_OUTP_PRIV, false);
+	if (ret == 0) {
+		if (outp->ior->func->sense) {
+			ret = outp->ior->func->sense(outp->ior, args->v0.data);
+			args->v0.load = ret < 0 ? 0 : ret;
+		} else {
+			ret = -EINVAL;
+		}
+		nvkm_outp_release(outp, NVKM_OUTP_PRIV);
+	}
+
+	return ret;
+}
+
 static int
 nvkm_uoutp_mthd_noacquire(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc)
 {
 	switch (mthd) {
+	case NVIF_OUTP_V0_LOAD_DETECT: return nvkm_uoutp_mthd_load_detect(outp, argv, argc);
 	default:
 		break;
 	}
-- 
2.38.1