Blob Blame History Raw
From fdb2175e962f29a138a9595af1cd95fdffda37ec 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: split the condition for queue readiness vs pmu
Git-commit: 2e8a65973b9afeebbff5e8a8e51e7cdd14f745a7
Patch-mainline: v5.6-rc1
References: jsc#SLE-12680, jsc#SLE-12880, jsc#SLE-12882, jsc#SLE-12883, jsc#SLE-13496, jsc#SLE-15322
 acr readiness

This is to allow for proper separation of the LS interface code from the
queue handling code.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 .../gpu/drm/nouveau/include/nvkm/subdev/pmu.h    |  2 ++
 drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c       | 13 +++++++++----
 drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c   |  6 ------
 drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h   |  4 ++--
 .../drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c  | 16 +++++++++++++++-
 .../drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c  |  2 --
 drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c   |  3 +++
 7 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
index 39fb218f943e..21607b40aee6 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
@@ -15,6 +15,8 @@ struct nvkm_pmu {
 	struct nvkm_falcon_msgq *msgq;
 	struct nvkm_msgqueue *queue;
 
+	struct completion wpr_ready;
+
 	struct {
 		u32 base;
 		u32 size;
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
index a674548f6168..d32cc0d354ee 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
@@ -156,14 +156,16 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
 	struct nvkm_msgqueue_queue *queue;
 	int ret;
 
-	if (wait_init && !wait_for_completion_timeout(&priv->init_done,
-					 msecs_to_jiffies(1000)))
-		return -ETIMEDOUT;
-
 	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");
+		return -ETIMEDOUT;
+	}
+
 	seq = nvkm_falcon_qmgr_seq_acquire(queue->qmgr);
 	if (IS_ERR(seq))
 		return PTR_ERR(seq);
@@ -197,6 +199,7 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
 void
 nvkm_falcon_cmdq_fini(struct nvkm_falcon_cmdq *cmdq)
 {
+	reinit_completion(&cmdq->ready);
 }
 
 void
@@ -209,6 +212,7 @@ nvkm_falcon_cmdq_init(struct nvkm_falcon_cmdq *cmdq,
 	cmdq->tail_reg = func->cmdq.tail + index * func->cmdq.stride;
 	cmdq->offset = offset;
 	cmdq->size = size;
+	complete_all(&cmdq->ready);
 
 	FLCNQ_DBG(cmdq, "initialised @ index %d offset 0x%08x size 0x%08x",
 		  index, cmdq->offset, cmdq->size);
@@ -236,5 +240,6 @@ nvkm_falcon_cmdq_new(struct nvkm_falcon_qmgr *qmgr, const char *name,
 	cmdq->qmgr = qmgr;
 	cmdq->name = name;
 	mutex_init(&cmdq->mutex);
+	init_completion(&cmdq->ready);
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
index db3e4a3489bf..3e14c7bc3e32 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
@@ -126,8 +126,6 @@ nvkm_msgqueue_reinit(struct nvkm_msgqueue *queue)
 		return 0;
 
 	queue->init_msg_received = false;
-	reinit_completion(&queue->init_done);
-
 	return 0;
 }
 
@@ -138,8 +136,4 @@ nvkm_msgqueue_ctor(const struct nvkm_msgqueue_func *func,
 {
 	queue->func = func;
 	queue->falcon = falcon;
-
-	init_completion(&queue->init_done);
-
-
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
index 542ecae806ee..98ace0d8465a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
@@ -140,6 +140,8 @@ struct nvkm_msgqueue_queue {
 
 	u32 head_reg;
 	u32 tail_reg;
+
+	struct completion ready;
 };
 
 /**
@@ -148,14 +150,12 @@ struct nvkm_msgqueue_queue {
  * @falcon:	falcon to be managed
  * @func:	implementation of the firmware to use
  * @init_msg_received:	whether the init message has already been received
- * @init_done:	whether all init is complete and commands can be processed
   */
 struct nvkm_msgqueue {
 	struct nvkm_falcon *falcon;
 	const struct nvkm_msgqueue_func *func;
 	u32 fw_version;
 	bool init_msg_received;
-	struct completion init_done;
 };
 
 void nvkm_msgqueue_ctor(const struct nvkm_msgqueue_func *, struct nvkm_falcon *,
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
index 164722f617a4..3bd98262f16e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
@@ -187,7 +187,7 @@ acr_init_wpr_callback(void *priv, struct nv_falcon_msg *hdr)
 	}
 
 	nvkm_debug(subdev, "ACR WPR init complete\n");
-	complete_all(&queue->init_done);
+	complete_all(&subdev->device->pmu->wpr_ready);
 	return 0;
 }
 
@@ -246,6 +246,7 @@ enum {
 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.
@@ -258,6 +259,12 @@ acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon)
 		u32 falcon_id;
 	} cmd;
 
+	if (!wait_for_completion_timeout(&pmu->wpr_ready,
+					 msecs_to_jiffies(1000))) {
+		nvkm_error(&pmu->subdev, "timeout waiting for WPR init\n");
+		return -ETIMEDOUT;
+	}
+
 	memset(&cmd, 0, sizeof(cmd));
 
 	cmd.hdr.unit_id = MSGQUEUE_0137C63D_UNIT_ACR;
@@ -301,6 +308,7 @@ acr_boot_multiple_falcons_callback(void *_priv, struct nv_falcon_msg *hdr)
 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.
@@ -317,6 +325,12 @@ acr_boot_multiple_falcons(struct nvkm_msgqueue *priv, unsigned long falcon_mask)
 	} cmd;
 	struct msgqueue_0137bca5 *queue = msgqueue_0137bca5(priv);
 
+	if (!wait_for_completion_timeout(&pmu->wpr_ready,
+					 msecs_to_jiffies(1000))) {
+		nvkm_error(&pmu->subdev, "timeout waiting for WPR init\n");
+		return -ETIMEDOUT;
+	}
+
 	memset(&cmd, 0, sizeof(cmd));
 
 	cmd.hdr.unit_id = MSGQUEUE_0137C63D_UNIT_ACR;
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
index 28917969293e..1c6077cea865 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
@@ -127,8 +127,6 @@ init_callback(struct nvkm_msgqueue *_queue, struct nvkm_msgqueue_hdr *hdr)
 		}
 	}
 
-	complete_all(&_queue->init_done);
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
index 86af2ddb3e78..bc0eb84c2c90 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
@@ -87,6 +87,8 @@ nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend)
 
 	flush_work(&pmu->recv.work);
 
+	reinit_completion(&pmu->wpr_ready);
+
 	nvkm_falcon_cmdq_fini(pmu->lpq);
 	nvkm_falcon_cmdq_fini(pmu->hpq);
 	return 0;
@@ -188,6 +190,7 @@ nvkm_pmu_ctor(const struct nvkm_pmu_fwif *fwif, struct nvkm_device *device,
 	    (ret = nvkm_falcon_msgq_new(pmu->qmgr, "msgq", &pmu->msgq)))
 		return ret;
 
+	init_completion(&pmu->wpr_ready);
 	return 0;
 }
 
-- 
2.28.0