From 8e90a98dfb804f4a86a9bc40706e9f00e870a2ba Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 15 Jan 2020 06:34:22 +1000 Subject: [PATCH] drm/nouveau/flcn/qmgr: support syncronous command submission from 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 --- drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c | 13 +++++++++-- drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c | 8 ++++--- .../drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c | 26 ++++++---------------- .../drm/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 f0d2898..d6e84a6 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 7f84a5e..7e9e82d 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 a8931cd..164722f 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 92b8351..2891796 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 0cc192b..b67e85b 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 ca2e71a0..905a625 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.7.4