diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c index f0d28985f055c..d6e84a6678454 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 7f84a5ef79056..7e9e82da7ea7d 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 a8931cd96bca0..164722f617a45 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 92b8351e9e351..28917969293e2 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 0cc192b55cc31..b67e85b169aa5 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 ca2e71a0e0434..905a625b33485 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; };