Blob Blame History Raw
From c6ccdd7ba5be35a4d6bfc06149f88f2c0814f8c4 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/cmdq: implement a more explicit send() interface
Git-commit: 149745252c65b0abc13e5ac4aa8c9e5f78d54783
Patch-mainline: v5.6-rc1
References: jsc#SLE-12680, jsc#SLE-12880, jsc#SLE-12882, jsc#SLE-12883, jsc#SLE-13496, jsc#SLE-15322

Takes the command queue pointer directly instead of requiring a function to
lookup based on an queue type, as well as an explicit timeout value.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 .../drm/nouveau/include/nvkm/core/falcon.h    |  5 ++
 drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c    | 21 +++----
 .../gpu/drm/nouveau/nvkm/falcon/msgqueue.h    | 10 ----
 .../nouveau/nvkm/falcon/msgqueue_0137c63d.c   | 60 ++++++-------------
 .../nouveau/nvkm/falcon/msgqueue_0148cdec.c   | 23 +++----
 5 files changed, 40 insertions(+), 79 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h
index 75d095048b67..da7b6766f04f 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h
@@ -45,6 +45,8 @@ struct nv_falcon_msg {
 	u8 seq_id;
 };
 
+#define nv_falcon_cmd nv_falcon_msg
+
 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 **);
@@ -59,6 +61,9 @@ void nvkm_falcon_cmdq_del(struct nvkm_falcon_cmdq **);
 void nvkm_falcon_cmdq_init(struct nvkm_falcon_cmdq *,
 			   u32 index, u32 offset, u32 size);
 void nvkm_falcon_cmdq_fini(struct nvkm_falcon_cmdq *);
+int nvkm_falcon_cmdq_send(struct nvkm_falcon_cmdq *, struct nv_falcon_cmd *,
+			  nvkm_falcon_qmgr_callback, void *priv,
+			  unsigned long timeout_jiffies);
 
 struct nvkm_falcon_msgq;
 int nvkm_falcon_msgq_new(struct nvkm_falcon_qmgr *, const char *name,
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
index 64884a99500f..e41ceac54f48 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
@@ -61,7 +61,7 @@ cmd_queue_push(struct nvkm_msgqueue_queue *queue, void *data, u32 size)
 static void
 cmd_queue_rewind(struct nvkm_msgqueue_queue *queue)
 {
-	struct nvkm_msgqueue_hdr cmd;
+	struct nv_falcon_cmd cmd;
 
 	cmd.unit_id = MSGQUEUE_UNIT_REWIND;
 	cmd.size = sizeof(cmd);
@@ -100,7 +100,7 @@ cmd_queue_close(struct nvkm_msgqueue_queue *queue)
 }
 
 static int
-cmd_write(struct nvkm_msgqueue_queue *queue, struct nvkm_msgqueue_hdr *cmd)
+cmd_write(struct nvkm_msgqueue_queue *queue, struct nv_falcon_cmd *cmd)
 {
 	static unsigned timeout = 2000;
 	unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout);
@@ -124,18 +124,14 @@ cmd_write(struct nvkm_msgqueue_queue *queue, struct nvkm_msgqueue_hdr *cmd)
 #define CMD_FLAGS_INTR BIT(1)
 
 int
-nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
-		   struct nvkm_msgqueue_hdr *cmd, nvkm_falcon_qmgr_callback cb,
-		   struct completion *completion, bool wait_init)
+nvkm_falcon_cmdq_send(struct nvkm_falcon_cmdq *queue,
+		      struct nv_falcon_cmd *cmd,
+		      nvkm_falcon_qmgr_callback cb, void *priv,
+		      unsigned long timeout)
 {
 	struct nvkm_falcon_qmgr_seq *seq;
-	struct nvkm_msgqueue_queue *queue;
 	int ret;
 
-	queue = priv->func->cmd_queue(priv, prio);
-	if (IS_ERR(queue))
-		return PTR_ERR(queue);
-
 	if (!wait_for_completion_timeout(&queue->ready,
 					 msecs_to_jiffies(1000))) {
 		FLCNQ_ERR(queue, "timeout waiting for queue ready");
@@ -150,7 +146,7 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
 	cmd->ctrl_flags = CMD_FLAGS_STATUS | CMD_FLAGS_INTR;
 
 	seq->state = SEQ_STATE_USED;
-	seq->async = !completion;
+	seq->async = !timeout;
 	seq->callback = cb;
 	seq->priv = priv;
 
@@ -162,8 +158,7 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
 	}
 
 	if (!seq->async) {
-		if (!wait_for_completion_timeout(&seq->done,
-						 msecs_to_jiffies(1000))) {
+		if (!wait_for_completion_timeout(&seq->done, timeout)) {
 			FLCNQ_ERR(queue, "timeout waiting for reply");
 			return -ETIMEDOUT;
 		}
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
index 98ace0d8465a..65a2a045fae7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
@@ -52,11 +52,6 @@
  *
  */
 
-enum msgqueue_msg_priority {
-	MSGQUEUE_MSG_PRIORITY_HIGH,
-	MSGQUEUE_MSG_PRIORITY_LOW,
-};
-
 /**
  * struct nvkm_msgqueue_hdr - header for all commands/messages
  * @unit_id:	id of firmware using receiving the command/sending the message
@@ -110,8 +105,6 @@ struct nvkm_msgqueue_func {
 	const struct nvkm_msgqueue_init_func *init_func;
 	const struct nvkm_msgqueue_acr_func *acr_func;
 	void (*dtor)(struct nvkm_msgqueue *);
-	struct nvkm_msgqueue_queue *(*cmd_queue)(struct nvkm_msgqueue *,
-						 enum msgqueue_msg_priority);
 	void (*recv)(struct nvkm_msgqueue *queue);
 };
 
@@ -160,9 +153,6 @@ 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_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 3bd98262f16e..b8c0fcdff156 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
@@ -45,24 +45,6 @@ struct msgqueue_0137bca5 {
 	container_of(container_of(q, struct msgqueue_0137c63d, base), \
 		     struct msgqueue_0137bca5, base);
 
-static struct nvkm_msgqueue_queue *
-msgqueue_0137c63d_cmd_queue(struct nvkm_msgqueue *queue,
-			    enum msgqueue_msg_priority priority)
-{
-	struct msgqueue_0137c63d *priv = msgqueue_0137c63d(queue);
-	const struct nvkm_subdev *subdev = priv->base.falcon->owner;
-
-	switch (priority) {
-	case MSGQUEUE_MSG_PRIORITY_HIGH:
-		return subdev->device->pmu->hpq;
-	case MSGQUEUE_MSG_PRIORITY_LOW:
-		return subdev->device->pmu->lpq;
-	default:
-		nvkm_error(subdev, "invalid command queue!\n");
-		return ERR_PTR(-EINVAL);
-	}
-}
-
 static void
 msgqueue_0137c63d_process_msgs(struct nvkm_msgqueue *queue)
 {
@@ -172,13 +154,13 @@ enum {
 static int
 acr_init_wpr_callback(void *priv, struct nv_falcon_msg *hdr)
 {
-	struct nvkm_msgqueue *queue = priv;
+	struct nvkm_pmu *pmu = priv;
+	struct nvkm_subdev *subdev = &pmu->subdev;
 	struct {
 		struct nv_falcon_msg base;
 		u8 msg_type;
 		u32 error_code;
 	} *msg = (void *)hdr;
-	const struct nvkm_subdev *subdev = queue->falcon->owner;
 
 	if (msg->error_code) {
 		nvkm_error(subdev, "ACR WPR init failure: %d\n",
@@ -187,19 +169,20 @@ acr_init_wpr_callback(void *priv, struct nv_falcon_msg *hdr)
 	}
 
 	nvkm_debug(subdev, "ACR WPR init complete\n");
-	complete_all(&subdev->device->pmu->wpr_ready);
+	complete_all(&pmu->wpr_ready);
 	return 0;
 }
 
 static int
 acr_init_wpr(struct nvkm_msgqueue *queue)
 {
+	struct nvkm_pmu *pmu = queue->falcon->owner->device->pmu;
 	/*
 	 * region_id:	region ID in WPR region
 	 * wpr_offset:	offset in WPR region
 	 */
 	struct {
-		struct nvkm_msgqueue_hdr hdr;
+		struct nv_falcon_cmd hdr;
 		u8 cmd_type;
 		u32 region_id;
 		u32 wpr_offset;
@@ -211,21 +194,20 @@ acr_init_wpr(struct nvkm_msgqueue *queue)
 	cmd.cmd_type = ACR_CMD_INIT_WPR_REGION;
 	cmd.region_id = 0x01;
 	cmd.wpr_offset = 0x00;
-	return nvkm_msgqueue_post(queue, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
-				  acr_init_wpr_callback, NULL, false);
+	return nvkm_falcon_cmdq_send(pmu->hpq, &cmd.hdr, acr_init_wpr_callback,
+				     pmu, 0);
 }
 
 
 static int
-acr_boot_falcon_callback(void *_priv, struct nv_falcon_msg *hdr)
+acr_boot_falcon_callback(void *priv, struct nv_falcon_msg *hdr)
 {
-	struct nvkm_msgqueue *priv = _priv;
 	struct acr_bootstrap_falcon_msg {
 		struct nv_falcon_msg base;
 		u8 msg_type;
 		u32 falcon_id;
 	} *msg = (void *)hdr;
-	const struct nvkm_subdev *subdev = priv->falcon->owner;
+	struct nvkm_subdev *subdev = priv;
 	u32 falcon_id = msg->falcon_id;
 
 	if (falcon_id >= NVKM_SECBOOT_FALCON_END) {
@@ -247,13 +229,12 @@ static int
 acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon)
 {
 	struct nvkm_pmu *pmu = priv->falcon->owner->device->pmu;
-	DECLARE_COMPLETION_ONSTACK(completed);
 	/*
 	 * flags      - Flag specifying RESET or no RESET.
 	 * falcon id  - Falcon id specifying falcon to bootstrap.
 	 */
 	struct {
-		struct nvkm_msgqueue_hdr hdr;
+		struct nv_falcon_cmd hdr;
 		u8 cmd_type;
 		u32 flags;
 		u32 falcon_id;
@@ -272,20 +253,20 @@ acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon)
 	cmd.cmd_type = ACR_CMD_BOOTSTRAP_FALCON;
 	cmd.flags = ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES;
 	cmd.falcon_id = falcon;
-	return nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
-				  acr_boot_falcon_callback, &completed, true);
+	return nvkm_falcon_cmdq_send(pmu->hpq, &cmd.hdr,
+				     acr_boot_falcon_callback, &pmu->subdev,
+				     msecs_to_jiffies(1000));
 }
 
 static int
-acr_boot_multiple_falcons_callback(void *_priv, struct nv_falcon_msg *hdr)
+acr_boot_multiple_falcons_callback(void *priv, struct nv_falcon_msg *hdr)
 {
-	struct nvkm_msgqueue *priv = _priv;
 	struct acr_bootstrap_falcon_msg {
 		struct nv_falcon_msg base;
 		u8 msg_type;
 		u32 falcon_mask;
 	} *msg = (void *)hdr;
-	const struct nvkm_subdev *subdev = priv->falcon->owner;
+	const struct nvkm_subdev *subdev = priv;
 	unsigned long falcon_mask = msg->falcon_mask;
 	u32 falcon_id, falcon_treated = 0;
 
@@ -309,13 +290,12 @@ static int
 acr_boot_multiple_falcons(struct nvkm_msgqueue *priv, unsigned long falcon_mask)
 {
 	struct nvkm_pmu *pmu = priv->falcon->owner->device->pmu;
-	DECLARE_COMPLETION_ONSTACK(completed);
 	/*
 	 * flags      - Flag specifying RESET or no RESET.
 	 * falcon id  - Falcon id specifying falcon to bootstrap.
 	 */
 	struct {
-		struct nvkm_msgqueue_hdr hdr;
+		struct nv_falcon_cmd hdr;
 		u8 cmd_type;
 		u32 flags;
 		u32 falcon_mask;
@@ -340,9 +320,9 @@ acr_boot_multiple_falcons(struct nvkm_msgqueue *priv, unsigned long falcon_mask)
 	cmd.falcon_mask = falcon_mask;
 	cmd.wpr_lo = lower_32_bits(queue->wpr_addr);
 	cmd.wpr_hi = upper_32_bits(queue->wpr_addr);
-	return nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
-				  acr_boot_multiple_falcons_callback,
-				  &completed, true);
+	return nvkm_falcon_cmdq_send(pmu->hpq, &cmd.hdr,
+				     acr_boot_multiple_falcons_callback,
+				     &pmu->subdev, msecs_to_jiffies(1000));
 }
 
 static const struct nvkm_msgqueue_acr_func
@@ -366,7 +346,6 @@ static const struct nvkm_msgqueue_func
 msgqueue_0137c63d_func = {
 	.init_func = &msgqueue_0137c63d_init_func,
 	.acr_func = &msgqueue_0137c63d_acr_func,
-	.cmd_queue = msgqueue_0137c63d_cmd_queue,
 	.recv = msgqueue_0137c63d_process_msgs,
 	.dtor = msgqueue_0137c63d_dtor,
 };
@@ -392,7 +371,6 @@ static const struct nvkm_msgqueue_func
 msgqueue_0137bca5_func = {
 	.init_func = &msgqueue_0137c63d_init_func,
 	.acr_func = &msgqueue_0137bca5_acr_func,
-	.cmd_queue = msgqueue_0137c63d_cmd_queue,
 	.recv = msgqueue_0137c63d_process_msgs,
 	.dtor = msgqueue_0137c63d_dtor,
 };
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
index 1c6077cea865..2826822cd0fc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
@@ -43,13 +43,6 @@ struct msgqueue_0148cdec {
 #define msgqueue_0148cdec(q) \
 	container_of(q, struct msgqueue_0148cdec, base)
 
-static struct nvkm_msgqueue_queue *
-msgqueue_0148cdec_cmd_queue(struct nvkm_msgqueue *queue,
-			    enum msgqueue_msg_priority priority)
-{
-	return queue->falcon->owner->device->sec2->cmdq;
-}
-
 static void
 msgqueue_0148cdec_process_msgs(struct nvkm_msgqueue *queue)
 {
@@ -146,16 +139,15 @@ enum {
 };
 
 static int
-acr_boot_falcon_callback(void *_priv, struct nv_falcon_msg *hdr)
+acr_boot_falcon_callback(void *priv, struct nv_falcon_msg *hdr)
 {
-	struct nvkm_msgqueue *priv = _priv;
 	struct acr_bootstrap_falcon_msg {
 		struct nv_falcon_msg base;
 		u8 msg_type;
 		u32 error_code;
 		u32 falcon_id;
 	} *msg = (void *)hdr;
-	const struct nvkm_subdev *subdev = priv->falcon->owner;
+	const struct nvkm_subdev *subdev = priv;
 	u32 falcon_id = msg->falcon_id;
 
 	if (msg->error_code) {
@@ -183,13 +175,13 @@ enum {
 static int
 acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon)
 {
-	DECLARE_COMPLETION_ONSTACK(completed);
+	struct nvkm_sec2 *sec2 = priv->falcon->owner->device->sec2;
 	/*
 	 * flags      - Flag specifying RESET or no RESET.
 	 * falcon id  - Falcon id specifying falcon to bootstrap.
 	 */
 	struct {
-		struct nvkm_msgqueue_hdr hdr;
+		struct nv_falcon_cmd hdr;
 		u8 cmd_type;
 		u32 flags;
 		u32 falcon_id;
@@ -202,8 +194,10 @@ acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon)
 	cmd.cmd_type = ACR_CMD_BOOTSTRAP_FALCON;
 	cmd.flags = ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES;
 	cmd.falcon_id = falcon;
-	return nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
-				  acr_boot_falcon_callback, &completed, true);
+	return nvkm_falcon_cmdq_send(sec2->cmdq, &cmd.hdr,
+				     acr_boot_falcon_callback,
+				     &sec2->engine.subdev,
+				     msecs_to_jiffies(1000));
 }
 
 const struct nvkm_msgqueue_acr_func
@@ -221,7 +215,6 @@ const struct nvkm_msgqueue_func
 msgqueue_0148cdec_func = {
 	.init_func = &msgqueue_0148cdec_init_func,
 	.acr_func = &msgqueue_0148cdec_acr_func,
-	.cmd_queue = msgqueue_0148cdec_cmd_queue,
 	.recv = msgqueue_0148cdec_process_msgs,
 	.dtor = msgqueue_0148cdec_dtor,
 };
-- 
2.28.0