drm/nouveau/flcn/qmgr: support syncronous command submission from common code
authorBen Skeggs <bskeggs@redhat.com>
Tue, 14 Jan 2020 20:34:22 +0000 (06:34 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 15 Jan 2020 00:50:28 +0000 (10:50 +1000)
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>
drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c
drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.c
drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h

index f0d2898..d6e84a6 100644 (file)
@@ -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;
index 7f84a5e..7e9e82d 100644 (file)
@@ -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;
 }
 
index a8931cd..164722f 100644 (file)
@@ -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
index 92b8351..2891796 100644 (file)
@@ -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
index 0cc192b..b67e85b 100644 (file)
@@ -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;
 }
index ca2e71a..905a625 100644 (file)
@@ -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;
 };