Blob Blame History Raw
From 9916f4f005c357aa94691ba1e309c5d7a074e142 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: support syncronous command submission from
Git-commit: 8e90a98dfb804f4a86a9bc40706e9f00e870a2ba
Patch-mainline: v5.6-rc1
References: jsc#SLE-12680, jsc#SLE-12880, jsc#SLE-12882, jsc#SLE-12883, jsc#SLE-13496, jsc#SLE-15322
 common code

Functions implementing FW commands had to implement this themselves, let's
move that to common code and plumb the return code from callbacks through.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c    | 13 ++++++++--
 drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c    |  8 +++---
 .../nouveau/nvkm/falcon/msgqueue_0137c63d.c   | 26 +++++--------------
 .../nouveau/nvkm/falcon/msgqueue_0148cdec.c   |  9 ++-----
 drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.c    |  6 +++--
 drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h    |  3 ++-
 6 files changed, 31 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
index f0d28985f055..d6e84a667845 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
@@ -171,15 +171,24 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
 	cmd->seq_id = seq->id;
 	cmd->ctrl_flags = CMD_FLAGS_STATUS | CMD_FLAGS_INTR;
 
+	seq->state = SEQ_STATE_USED;
+	seq->async = !completion;
 	seq->callback = cb;
 	seq->priv = priv;
-	seq->state = SEQ_STATE_USED;
-	seq->completion = completion;
 
 	ret = cmd_write(priv, cmd, queue);
 	if (ret) {
 		seq->state = SEQ_STATE_PENDING;
 		nvkm_falcon_qmgr_seq_release(queue->qmgr, seq);
+		return ret;
+	}
+
+	if (!seq->async) {
+		if (!wait_for_completion_timeout(&seq->done,
+						 msecs_to_jiffies(1000)))
+			return -ETIMEDOUT;
+		ret = seq->result;
+		nvkm_falcon_qmgr_seq_release(queue->qmgr, seq);
 	}
 
 	return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c
index 7f84a5ef7905..7e9e82da7ea7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c
@@ -152,10 +152,12 @@ msgqueue_msg_handle(struct nvkm_msgqueue *priv,
 			seq->result = seq->callback(seq->priv, hdr);
 	}
 
-	if (seq->completion)
-		complete(seq->completion);
+	if (seq->async) {
+		nvkm_falcon_qmgr_seq_release(msgq->qmgr, seq);
+		return 0;
+	}
 
-	nvkm_falcon_qmgr_seq_release(msgq->qmgr, seq);
+	complete_all(&seq->done);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
index a8931cd96bca..164722f617a4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
@@ -211,11 +211,8 @@ acr_init_wpr(struct nvkm_msgqueue *queue)
 	cmd.cmd_type = ACR_CMD_INIT_WPR_REGION;
 	cmd.region_id = 0x01;
 	cmd.wpr_offset = 0x00;
-
-	nvkm_msgqueue_post(queue, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
-			   acr_init_wpr_callback, NULL, false);
-
-	return 0;
+	return nvkm_msgqueue_post(queue, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
+				  acr_init_wpr_callback, NULL, false);
 }
 
 
@@ -268,13 +265,8 @@ 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;
-	nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
-			acr_boot_falcon_callback, &completed, true);
-
-	if (!wait_for_completion_timeout(&completed, msecs_to_jiffies(1000)))
-		return -ETIMEDOUT;
-
-	return 0;
+	return nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
+				  acr_boot_falcon_callback, &completed, true);
 }
 
 static int
@@ -334,13 +326,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);
-	nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
-			acr_boot_multiple_falcons_callback, &completed, true);
-
-	if (!wait_for_completion_timeout(&completed, msecs_to_jiffies(1000)))
-		return -ETIMEDOUT;
-
-	return 0;
+	return nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
+				  acr_boot_multiple_falcons_callback,
+				  &completed, true);
 }
 
 static const struct nvkm_msgqueue_acr_func
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
index 92b8351e9e35..28917969293e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
@@ -204,13 +204,8 @@ 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;
-	nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
-			   acr_boot_falcon_callback, &completed, true);
-
-	if (!wait_for_completion_timeout(&completed, msecs_to_jiffies(1000)))
-		return -ETIMEDOUT;
-
-	return 0;
+	return nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
+				  acr_boot_falcon_callback, &completed, true);
 }
 
 const struct nvkm_msgqueue_acr_func
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.c b/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.c
index 0cc192b55cc3..b67e85b169aa 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.c
@@ -52,7 +52,7 @@ nvkm_falcon_qmgr_seq_release(struct nvkm_falcon_qmgr *priv,
 	/* no need to acquire seq_lock since clear_bit is atomic */
 	seq->state = SEQ_STATE_FREE;
 	seq->callback = NULL;
-	seq->completion = NULL;
+	reinit_completion(&seq->done);
 	clear_bit(seq->id, priv->seq_tbl);
 }
 
@@ -78,8 +78,10 @@ nvkm_falcon_qmgr_new(struct nvkm_falcon *falcon,
 
 	qmgr->falcon = falcon;
 	mutex_init(&qmgr->seq_lock);
-	for (i = 0; i < NVKM_MSGQUEUE_NUM_SEQUENCES; i++)
+	for (i = 0; i < NVKM_MSGQUEUE_NUM_SEQUENCES; i++) {
 		qmgr->seq[i].id = i;
+		init_completion(&qmgr->seq[i].done);
+	}
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h b/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h
index ca2e71a0e043..905a625b3348 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h
@@ -29,9 +29,10 @@ struct nvkm_msgqueue_seq {
 		SEQ_STATE_USED,
 		SEQ_STATE_CANCELLED
 	} state;
+	bool async;
 	nvkm_falcon_qmgr_callback callback;
 	void *priv;
-	struct completion *completion;
+	struct completion done;
 	int result;
 };
 
-- 
2.28.0