Commit 8e90a98d authored by Ben Skeggs's avatar Ben Skeggs

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: default avatarBen Skeggs <bskeggs@redhat.com>
parent c80157a2
...@@ -171,15 +171,24 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio, ...@@ -171,15 +171,24 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
cmd->seq_id = seq->id; cmd->seq_id = seq->id;
cmd->ctrl_flags = CMD_FLAGS_STATUS | CMD_FLAGS_INTR; cmd->ctrl_flags = CMD_FLAGS_STATUS | CMD_FLAGS_INTR;
seq->state = SEQ_STATE_USED;
seq->async = !completion;
seq->callback = cb; seq->callback = cb;
seq->priv = priv; seq->priv = priv;
seq->state = SEQ_STATE_USED;
seq->completion = completion;
ret = cmd_write(priv, cmd, queue); ret = cmd_write(priv, cmd, queue);
if (ret) { if (ret) {
seq->state = SEQ_STATE_PENDING; seq->state = SEQ_STATE_PENDING;
nvkm_falcon_qmgr_seq_release(queue->qmgr, seq); 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; return ret;
......
...@@ -152,11 +152,13 @@ msgqueue_msg_handle(struct nvkm_msgqueue *priv, ...@@ -152,11 +152,13 @@ msgqueue_msg_handle(struct nvkm_msgqueue *priv,
seq->result = seq->callback(seq->priv, hdr); seq->result = seq->callback(seq->priv, hdr);
} }
if (seq->completion) if (seq->async) {
complete(seq->completion);
nvkm_falcon_qmgr_seq_release(msgq->qmgr, seq); nvkm_falcon_qmgr_seq_release(msgq->qmgr, seq);
return 0; return 0;
}
complete_all(&seq->done);
return 0;
} }
static int static int
......
...@@ -211,11 +211,8 @@ acr_init_wpr(struct nvkm_msgqueue *queue) ...@@ -211,11 +211,8 @@ acr_init_wpr(struct nvkm_msgqueue *queue)
cmd.cmd_type = ACR_CMD_INIT_WPR_REGION; cmd.cmd_type = ACR_CMD_INIT_WPR_REGION;
cmd.region_id = 0x01; cmd.region_id = 0x01;
cmd.wpr_offset = 0x00; cmd.wpr_offset = 0x00;
return nvkm_msgqueue_post(queue, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
nvkm_msgqueue_post(queue, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
acr_init_wpr_callback, NULL, false); acr_init_wpr_callback, NULL, false);
return 0;
} }
...@@ -268,13 +265,8 @@ acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon) ...@@ -268,13 +265,8 @@ acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon)
cmd.cmd_type = ACR_CMD_BOOTSTRAP_FALCON; cmd.cmd_type = ACR_CMD_BOOTSTRAP_FALCON;
cmd.flags = ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES; cmd.flags = ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES;
cmd.falcon_id = falcon; cmd.falcon_id = falcon;
nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr, return nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
acr_boot_falcon_callback, &completed, true); acr_boot_falcon_callback, &completed, true);
if (!wait_for_completion_timeout(&completed, msecs_to_jiffies(1000)))
return -ETIMEDOUT;
return 0;
} }
static int static int
...@@ -334,13 +326,9 @@ acr_boot_multiple_falcons(struct nvkm_msgqueue *priv, unsigned long falcon_mask) ...@@ -334,13 +326,9 @@ acr_boot_multiple_falcons(struct nvkm_msgqueue *priv, unsigned long falcon_mask)
cmd.falcon_mask = falcon_mask; cmd.falcon_mask = falcon_mask;
cmd.wpr_lo = lower_32_bits(queue->wpr_addr); cmd.wpr_lo = lower_32_bits(queue->wpr_addr);
cmd.wpr_hi = upper_32_bits(queue->wpr_addr); cmd.wpr_hi = upper_32_bits(queue->wpr_addr);
nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr, return nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
acr_boot_multiple_falcons_callback, &completed, true); acr_boot_multiple_falcons_callback,
&completed, true);
if (!wait_for_completion_timeout(&completed, msecs_to_jiffies(1000)))
return -ETIMEDOUT;
return 0;
} }
static const struct nvkm_msgqueue_acr_func static const struct nvkm_msgqueue_acr_func
......
...@@ -204,13 +204,8 @@ acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon) ...@@ -204,13 +204,8 @@ acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon)
cmd.cmd_type = ACR_CMD_BOOTSTRAP_FALCON; cmd.cmd_type = ACR_CMD_BOOTSTRAP_FALCON;
cmd.flags = ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES; cmd.flags = ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES;
cmd.falcon_id = falcon; cmd.falcon_id = falcon;
nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr, return nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
acr_boot_falcon_callback, &completed, true); acr_boot_falcon_callback, &completed, true);
if (!wait_for_completion_timeout(&completed, msecs_to_jiffies(1000)))
return -ETIMEDOUT;
return 0;
} }
const struct nvkm_msgqueue_acr_func const struct nvkm_msgqueue_acr_func
......
...@@ -52,7 +52,7 @@ nvkm_falcon_qmgr_seq_release(struct nvkm_falcon_qmgr *priv, ...@@ -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 */ /* no need to acquire seq_lock since clear_bit is atomic */
seq->state = SEQ_STATE_FREE; seq->state = SEQ_STATE_FREE;
seq->callback = NULL; seq->callback = NULL;
seq->completion = NULL; reinit_completion(&seq->done);
clear_bit(seq->id, priv->seq_tbl); clear_bit(seq->id, priv->seq_tbl);
} }
...@@ -78,8 +78,10 @@ nvkm_falcon_qmgr_new(struct nvkm_falcon *falcon, ...@@ -78,8 +78,10 @@ nvkm_falcon_qmgr_new(struct nvkm_falcon *falcon,
qmgr->falcon = falcon; qmgr->falcon = falcon;
mutex_init(&qmgr->seq_lock); 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; qmgr->seq[i].id = i;
init_completion(&qmgr->seq[i].done);
}
return 0; return 0;
} }
...@@ -29,9 +29,10 @@ struct nvkm_msgqueue_seq { ...@@ -29,9 +29,10 @@ struct nvkm_msgqueue_seq {
SEQ_STATE_USED, SEQ_STATE_USED,
SEQ_STATE_CANCELLED SEQ_STATE_CANCELLED
} state; } state;
bool async;
nvkm_falcon_qmgr_callback callback; nvkm_falcon_qmgr_callback callback;
void *priv; void *priv;
struct completion *completion; struct completion done;
int result; int result;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment