Blob Blame History Raw
From 1187de39b51f45dfd27b71c97c983cceac670bdb Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Wed, 15 Jan 2020 06:34:21 +1000
Subject: drm/nouveau/flcn: move fetching of configuration until first use
Git-commit: 5a4b98cde434da25ff25171974036a492c023bce
Patch-mainline: v5.6-rc1
References: jsc#SLE-12680, jsc#SLE-12880, jsc#SLE-12882, jsc#SLE-12883, jsc#SLE-13496, jsc#SLE-15322

We want to be able to register falcons with ACR during the constructor for
the subdev it belongs to, however, we may not have access to the falcon's
registers prior to DEVINIT.

Delay touching registers until the first time the falcon is acquired.

This may temporarily break secboot on non-production boards due to not
being able to determine whether the falcon is in debug or production mode,
the new ACR subdev will not have this issue, and it's not a use-case that's
terribly important for bisectability.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 .../drm/nouveau/include/nvkm/engine/falcon.h  |  2 +
 drivers/gpu/drm/nouveau/nvkm/falcon/base.c    | 95 +++++++++++--------
 2 files changed, 55 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
index 23b582d696c6..087ef96fc123 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
@@ -23,6 +23,8 @@ struct nvkm_falcon {
 
 	struct mutex mutex;
 	struct mutex dmem_mutex;
+	bool oneinit;
+
 	const struct nvkm_subdev *user;
 
 	u8 version;
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/base.c b/drivers/gpu/drm/nouveau/nvkm/falcon/base.c
index 366c87de6e72..3ed421058b08 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/base.c
@@ -134,52 +134,13 @@ nvkm_falcon_clear_interrupt(struct nvkm_falcon *falcon, u32 mask)
 	return falcon->func->clear_interrupt(falcon, mask);
 }
 
-void
-nvkm_falcon_put(struct nvkm_falcon *falcon, const struct nvkm_subdev *user)
-{
-	if (unlikely(!falcon))
-		return;
-
-	mutex_lock(&falcon->mutex);
-	if (falcon->user == user) {
-		nvkm_debug(falcon->user, "released %s falcon\n", falcon->name);
-		falcon->user = NULL;
-	}
-	mutex_unlock(&falcon->mutex);
-}
-
-int
-nvkm_falcon_get(struct nvkm_falcon *falcon, const struct nvkm_subdev *user)
-{
-	mutex_lock(&falcon->mutex);
-	if (falcon->user) {
-		nvkm_error(user, "%s falcon already acquired by %s!\n",
-			   falcon->name, nvkm_subdev_name[falcon->user->index]);
-		mutex_unlock(&falcon->mutex);
-		return -EBUSY;
-	}
-
-	nvkm_debug(user, "acquired %s falcon\n", falcon->name);
-	falcon->user = user;
-	mutex_unlock(&falcon->mutex);
-	return 0;
-}
-
-void
-nvkm_falcon_ctor(const struct nvkm_falcon_func *func,
-		 struct nvkm_subdev *subdev, const char *name, u32 addr,
-		 struct nvkm_falcon *falcon)
+static int
+nvkm_falcon_oneinit(struct nvkm_falcon *falcon)
 {
+	const struct nvkm_subdev *subdev = falcon->owner;
 	u32 debug_reg;
 	u32 reg;
 
-	falcon->func = func;
-	falcon->owner = subdev;
-	falcon->name = name;
-	falcon->addr = addr;
-	mutex_init(&falcon->mutex);
-	mutex_init(&falcon->dmem_mutex);
-
 	reg = nvkm_falcon_rd32(falcon, 0x12c);
 	falcon->version = reg & 0xf;
 	falcon->secret = (reg >> 4) & 0x3;
@@ -218,6 +179,56 @@ nvkm_falcon_ctor(const struct nvkm_falcon_func *func,
 		u32 val = nvkm_falcon_rd32(falcon, debug_reg);
 		falcon->debug = (val >> 20) & 0x1;
 	}
+
+	return 0;
+}
+
+void
+nvkm_falcon_put(struct nvkm_falcon *falcon, const struct nvkm_subdev *user)
+{
+	if (unlikely(!falcon))
+		return;
+
+	mutex_lock(&falcon->mutex);
+	if (falcon->user == user) {
+		nvkm_debug(falcon->user, "released %s falcon\n", falcon->name);
+		falcon->user = NULL;
+	}
+	mutex_unlock(&falcon->mutex);
+}
+
+int
+nvkm_falcon_get(struct nvkm_falcon *falcon, const struct nvkm_subdev *user)
+{
+	int ret = 0;
+
+	mutex_lock(&falcon->mutex);
+	if (falcon->user) {
+		nvkm_error(user, "%s falcon already acquired by %s!\n",
+			   falcon->name, nvkm_subdev_name[falcon->user->index]);
+		mutex_unlock(&falcon->mutex);
+		return -EBUSY;
+	}
+
+	nvkm_debug(user, "acquired %s falcon\n", falcon->name);
+	if (!falcon->oneinit)
+		ret = nvkm_falcon_oneinit(falcon);
+	falcon->user = user;
+	mutex_unlock(&falcon->mutex);
+	return ret;
+}
+
+void
+nvkm_falcon_ctor(const struct nvkm_falcon_func *func,
+		 struct nvkm_subdev *subdev, const char *name, u32 addr,
+		 struct nvkm_falcon *falcon)
+{
+	falcon->func = func;
+	falcon->owner = subdev;
+	falcon->name = name;
+	falcon->addr = addr;
+	mutex_init(&falcon->mutex);
+	mutex_init(&falcon->dmem_mutex);
 }
 
 void
-- 
2.28.0