Blob Blame History Raw
From dd0f55d1b610d7f595cdf84d8b6fea89e55b2a6a Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Wed, 15 Jan 2020 06:34:22 +1000
Subject: drm/nouveau/flcn/qmgr: allow arbtrary priv + return code for
Git-commit: c80157a25e712daf69cbba8cafa0463c0895f56c
Patch-mainline: v5.6-rc1
References: jsc#SLE-12680, jsc#SLE-12880, jsc#SLE-12882, jsc#SLE-12883, jsc#SLE-13496, jsc#SLE-15322
 callbacks

Code to interface with LS firmwares is being moved to the subdevs where it
belongs, rather than living in the common falcon code.

Arbitrary private data passed to callbacks is to allow for something other
than struct nvkm_msgqueue to be passed into the callback (like the pointer
to the subdev itself, for example), and the return code will be used where
we'd like to detect failure from synchronous messages.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 .../drm/nouveau/include/nvkm/core/falcon.h    | 18 +++++++++
 drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c    |  3 +-
 drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c    | 15 +++----
 .../gpu/drm/nouveau/nvkm/falcon/msgqueue.h    |  6 +--
 .../nouveau/nvkm/falcon/msgqueue_0137c63d.c   | 40 +++++++++++--------
 .../nouveau/nvkm/falcon/msgqueue_0148cdec.c   | 15 +++----
 drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h    |  6 ++-
 7 files changed, 65 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h
index 2cd5a06673a1..75d095048b67 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h
@@ -30,10 +30,28 @@ int gp102_sec2_flcn_enable(struct nvkm_falcon *);
 #define FLCN_DBG(f,fmt,a...) FLCN_PRINTK(debug, (f), fmt, ##a)
 #define FLCN_ERR(f,fmt,a...) FLCN_PRINTK(error, (f), fmt, ##a)
 
+/**
+ * struct nv_falcon_msg - header for all messages
+ *
+ * @unit_id:	id of firmware process that sent the message
+ * @size:	total size of message
+ * @ctrl_flags:	control flags
+ * @seq_id:	used to match a message from its corresponding command
+ */
+struct nv_falcon_msg {
+	u8 unit_id;
+	u8 size;
+	u8 ctrl_flags;
+	u8 seq_id;
+};
+
 struct nvkm_falcon_qmgr;
 int nvkm_falcon_qmgr_new(struct nvkm_falcon *, struct nvkm_falcon_qmgr **);
 void nvkm_falcon_qmgr_del(struct nvkm_falcon_qmgr **);
 
+typedef int
+(*nvkm_falcon_qmgr_callback)(void *priv, struct nv_falcon_msg *);
+
 struct nvkm_falcon_cmdq;
 int nvkm_falcon_cmdq_new(struct nvkm_falcon_qmgr *, const char *name,
 			 struct nvkm_falcon_cmdq **);
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
index 1cf6453fdd70..f0d28985f055 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
@@ -149,7 +149,7 @@ cmd_write(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_hdr *cmd,
 
 int
 nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
-		   struct nvkm_msgqueue_hdr *cmd, nvkm_msgqueue_callback cb,
+		   struct nvkm_msgqueue_hdr *cmd, nvkm_falcon_qmgr_callback cb,
 		   struct completion *completion, bool wait_init)
 {
 	struct nvkm_msgqueue_seq *seq;
@@ -172,6 +172,7 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
 	cmd->ctrl_flags = CMD_FLAGS_STATUS | CMD_FLAGS_INTR;
 
 	seq->callback = cb;
+	seq->priv = priv;
 	seq->state = SEQ_STATE_USED;
 	seq->completion = completion;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c
index 303f9faf3423..7f84a5ef7905 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c
@@ -86,7 +86,7 @@ msg_queue_pop(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_queue *queue,
 
 static int
 msg_queue_read(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_queue *queue,
-	       struct nvkm_msgqueue_hdr *hdr)
+	       struct nv_falcon_msg *hdr)
 {
 	const struct nvkm_subdev *subdev = priv->falcon->owner;
 	int ret;
@@ -136,7 +136,7 @@ msg_queue_read(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_queue *queue,
 static int
 msgqueue_msg_handle(struct nvkm_msgqueue *priv,
 		    struct nvkm_falcon_msgq *msgq,
-		    struct nvkm_msgqueue_hdr *hdr)
+		    struct nv_falcon_msg *hdr)
 {
 	const struct nvkm_subdev *subdev = priv->falcon->owner;
 	struct nvkm_msgqueue_seq *seq;
@@ -149,7 +149,7 @@ msgqueue_msg_handle(struct nvkm_msgqueue *priv,
 
 	if (seq->state == SEQ_STATE_USED) {
 		if (seq->callback)
-			seq->callback(priv, hdr);
+			seq->result = seq->callback(seq->priv, hdr);
 	}
 
 	if (seq->completion)
@@ -160,12 +160,13 @@ msgqueue_msg_handle(struct nvkm_msgqueue *priv,
 }
 
 static int
-msgqueue_handle_init_msg(struct nvkm_msgqueue *priv,
-			 struct nvkm_msgqueue_hdr *hdr)
+msgqueue_handle_init_msg(struct nvkm_msgqueue *priv)
 {
 	struct nvkm_falcon *falcon = priv->falcon;
 	const struct nvkm_subdev *subdev = falcon->owner;
 	const u32 tail_reg = falcon->func->msgq.tail;
+	u8 msg_buffer[MSG_BUF_SIZE];
+	struct nvkm_msgqueue_hdr *hdr = (void *)msg_buffer;
 	u32 tail;
 	int ret;
 
@@ -203,12 +204,12 @@ nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *priv,
 	 * stack space to work with.
 	 */
 	u8 msg_buffer[MSG_BUF_SIZE];
-	struct nvkm_msgqueue_hdr *hdr = (void *)msg_buffer;
+	struct nv_falcon_msg *hdr = (void *)msg_buffer;
 	int ret;
 
 	/* the first message we receive must be the init message */
 	if ((!priv->init_msg_received)) {
-		ret = msgqueue_handle_init_msg(priv, hdr);
+		ret = msgqueue_handle_init_msg(priv);
 		if (!ret)
 			priv->init_msg_received = true;
 	} else {
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
index 4cfa6b21d3df..542ecae806ee 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
@@ -23,7 +23,7 @@
 
 #ifndef __NVKM_CORE_FALCON_MSGQUEUE_H
 #define __NVKM_CORE_FALCON_MSGQUEUE_H
-
+#include <core/falcon.h>
 #include <core/msgqueue.h>
 
 /*
@@ -83,8 +83,6 @@ struct nvkm_msgqueue_msg {
 };
 
 struct nvkm_msgqueue;
-typedef void
-(*nvkm_msgqueue_callback)(struct nvkm_msgqueue *, struct nvkm_msgqueue_hdr *);
 
 /**
  * struct nvkm_msgqueue_init_func - msgqueue functions related to initialization
@@ -163,7 +161,7 @@ struct nvkm_msgqueue {
 void nvkm_msgqueue_ctor(const struct nvkm_msgqueue_func *, struct nvkm_falcon *,
 			struct nvkm_msgqueue *);
 int nvkm_msgqueue_post(struct nvkm_msgqueue *, enum msgqueue_msg_priority,
-		       struct nvkm_msgqueue_hdr *, nvkm_msgqueue_callback,
+		       struct nvkm_msgqueue_hdr *, nvkm_falcon_qmgr_callback,
 		       struct completion *, bool);
 void nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *,
 				struct nvkm_msgqueue_queue *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
index 48a0f0de3453..a8931cd96bca 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
@@ -169,12 +169,13 @@ enum {
 	ACR_CMD_BOOTSTRAP_MULTIPLE_FALCONS = 0x03,
 };
 
-static void
-acr_init_wpr_callback(struct nvkm_msgqueue *queue,
-		      struct nvkm_msgqueue_hdr *hdr)
+static int
+acr_init_wpr_callback(void *priv, struct nv_falcon_msg *hdr)
 {
+	struct nvkm_msgqueue *queue = priv;
 	struct {
-		struct nvkm_msgqueue_msg base;
+		struct nv_falcon_msg base;
+		u8 msg_type;
 		u32 error_code;
 	} *msg = (void *)hdr;
 	const struct nvkm_subdev *subdev = queue->falcon->owner;
@@ -182,11 +183,12 @@ acr_init_wpr_callback(struct nvkm_msgqueue *queue,
 	if (msg->error_code) {
 		nvkm_error(subdev, "ACR WPR init failure: %d\n",
 			   msg->error_code);
-		return;
+		return -EINVAL;
 	}
 
 	nvkm_debug(subdev, "ACR WPR init complete\n");
 	complete_all(&queue->init_done);
+	return 0;
 }
 
 static int
@@ -217,13 +219,13 @@ acr_init_wpr(struct nvkm_msgqueue *queue)
 }
 
 
-static void
-acr_boot_falcon_callback(struct nvkm_msgqueue *priv,
-			 struct nvkm_msgqueue_hdr *hdr)
+static int
+acr_boot_falcon_callback(void *_priv, struct nv_falcon_msg *hdr)
 {
+	struct nvkm_msgqueue *priv = _priv;
 	struct acr_bootstrap_falcon_msg {
-		struct nvkm_msgqueue_msg base;
-
+		struct nv_falcon_msg base;
+		u8 msg_type;
 		u32 falcon_id;
 	} *msg = (void *)hdr;
 	const struct nvkm_subdev *subdev = priv->falcon->owner;
@@ -232,9 +234,11 @@ acr_boot_falcon_callback(struct nvkm_msgqueue *priv,
 	if (falcon_id >= NVKM_SECBOOT_FALCON_END) {
 		nvkm_error(subdev, "in bootstrap falcon callback:\n");
 		nvkm_error(subdev, "invalid falcon ID 0x%x\n", falcon_id);
-		return;
+		return -EINVAL;
 	}
+
 	nvkm_debug(subdev, "%s booted\n", nvkm_secboot_falcon_name[falcon_id]);
+	return 0;
 }
 
 enum {
@@ -273,13 +277,13 @@ acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon)
 	return 0;
 }
 
-static void
-acr_boot_multiple_falcons_callback(struct nvkm_msgqueue *priv,
-				   struct nvkm_msgqueue_hdr *hdr)
+static int
+acr_boot_multiple_falcons_callback(void *_priv, struct nv_falcon_msg *hdr)
 {
+	struct nvkm_msgqueue *priv = _priv;
 	struct acr_bootstrap_falcon_msg {
-		struct nvkm_msgqueue_msg base;
-
+		struct nv_falcon_msg base;
+		u8 msg_type;
 		u32 falcon_mask;
 	} *msg = (void *)hdr;
 	const struct nvkm_subdev *subdev = priv->falcon->owner;
@@ -296,8 +300,10 @@ acr_boot_multiple_falcons_callback(struct nvkm_msgqueue *priv,
 		nvkm_error(subdev, "in bootstrap falcon callback:\n");
 		nvkm_error(subdev, "invalid falcon mask 0x%x\n",
 			   msg->falcon_mask);
-		return;
+		return -EINVAL;
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
index 12d5ad6b7422..92b8351e9e35 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
@@ -147,13 +147,13 @@ enum {
 	ACR_CMD_BOOTSTRAP_FALCON = 0x00,
 };
 
-static void
-acr_boot_falcon_callback(struct nvkm_msgqueue *priv,
-			 struct nvkm_msgqueue_hdr *hdr)
+static int
+acr_boot_falcon_callback(void *_priv, struct nv_falcon_msg *hdr)
 {
+	struct nvkm_msgqueue *priv = _priv;
 	struct acr_bootstrap_falcon_msg {
-		struct nvkm_msgqueue_msg base;
-
+		struct nv_falcon_msg base;
+		u8 msg_type;
 		u32 error_code;
 		u32 falcon_id;
 	} *msg = (void *)hdr;
@@ -164,16 +164,17 @@ acr_boot_falcon_callback(struct nvkm_msgqueue *priv,
 		nvkm_error(subdev, "in bootstrap falcon callback:\n");
 		nvkm_error(subdev, "expected error code 0x%x\n",
 			   msg->error_code);
-		return;
+		return -EINVAL;
 	}
 
 	if (falcon_id >= NVKM_SECBOOT_FALCON_END) {
 		nvkm_error(subdev, "in bootstrap falcon callback:\n");
 		nvkm_error(subdev, "invalid falcon ID 0x%x\n", falcon_id);
-		return;
+		return -EINVAL;
 	}
 
 	nvkm_debug(subdev, "%s booted\n", nvkm_secboot_falcon_name[falcon_id]);
+	return 0;
 }
 
 enum {
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h b/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h
index 35ac2cc85d2c..ca2e71a0e043 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h
@@ -4,7 +4,7 @@
 #include <core/falcon.h>
 #include "msgqueue.h"
 
-#define HDR_SIZE sizeof(struct nvkm_msgqueue_hdr)
+#define HDR_SIZE sizeof(struct nv_falcon_msg)
 #define QUEUE_ALIGNMENT 4
 /* max size of the messages we can receive */
 #define MSG_BUF_SIZE 128
@@ -29,8 +29,10 @@ struct nvkm_msgqueue_seq {
 		SEQ_STATE_USED,
 		SEQ_STATE_CANCELLED
 	} state;
-	nvkm_msgqueue_callback callback;
+	nvkm_falcon_qmgr_callback callback;
+	void *priv;
 	struct completion *completion;
+	int result;
 };
 
 /*
-- 
2.28.0