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 <bskeggs@redhat.com>
This commit is contained in:
Ben Skeggs
2020-01-15 06:34:22 +10:00
parent c80157a25e
commit 8e90a98dfb
6 changed files with 31 additions and 34 deletions

View 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;

View 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;
}

View 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

View 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

View 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;
}

View 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;
};