drm/nouveau/flcn/cmdq: implement a more explicit send() interface
Takes the command queue pointer directly instead of requiring a function to lookup based on an queue type, as well as an explicit timeout value. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Родитель
2b287aebb4
Коммит
149745252c
|
@ -45,6 +45,8 @@ struct nv_falcon_msg {
|
|||
u8 seq_id;
|
||||
};
|
||||
|
||||
#define nv_falcon_cmd nv_falcon_msg
|
||||
|
||||
struct nvkm_falcon_qmgr;
|
||||
int nvkm_falcon_qmgr_new(struct nvkm_falcon *, struct nvkm_falcon_qmgr **);
|
||||
void nvkm_falcon_qmgr_del(struct nvkm_falcon_qmgr **);
|
||||
|
@ -59,6 +61,9 @@ void nvkm_falcon_cmdq_del(struct nvkm_falcon_cmdq **);
|
|||
void nvkm_falcon_cmdq_init(struct nvkm_falcon_cmdq *,
|
||||
u32 index, u32 offset, u32 size);
|
||||
void nvkm_falcon_cmdq_fini(struct nvkm_falcon_cmdq *);
|
||||
int nvkm_falcon_cmdq_send(struct nvkm_falcon_cmdq *, struct nv_falcon_cmd *,
|
||||
nvkm_falcon_qmgr_callback, void *priv,
|
||||
unsigned long timeout_jiffies);
|
||||
|
||||
struct nvkm_falcon_msgq;
|
||||
int nvkm_falcon_msgq_new(struct nvkm_falcon_qmgr *, const char *name,
|
||||
|
|
|
@ -61,7 +61,7 @@ cmd_queue_push(struct nvkm_msgqueue_queue *queue, void *data, u32 size)
|
|||
static void
|
||||
cmd_queue_rewind(struct nvkm_msgqueue_queue *queue)
|
||||
{
|
||||
struct nvkm_msgqueue_hdr cmd;
|
||||
struct nv_falcon_cmd cmd;
|
||||
|
||||
cmd.unit_id = MSGQUEUE_UNIT_REWIND;
|
||||
cmd.size = sizeof(cmd);
|
||||
|
@ -100,7 +100,7 @@ cmd_queue_close(struct nvkm_msgqueue_queue *queue)
|
|||
}
|
||||
|
||||
static int
|
||||
cmd_write(struct nvkm_msgqueue_queue *queue, struct nvkm_msgqueue_hdr *cmd)
|
||||
cmd_write(struct nvkm_msgqueue_queue *queue, struct nv_falcon_cmd *cmd)
|
||||
{
|
||||
static unsigned timeout = 2000;
|
||||
unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout);
|
||||
|
@ -124,18 +124,14 @@ cmd_write(struct nvkm_msgqueue_queue *queue, struct nvkm_msgqueue_hdr *cmd)
|
|||
#define CMD_FLAGS_INTR BIT(1)
|
||||
|
||||
int
|
||||
nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
|
||||
struct nvkm_msgqueue_hdr *cmd, nvkm_falcon_qmgr_callback cb,
|
||||
struct completion *completion, bool wait_init)
|
||||
nvkm_falcon_cmdq_send(struct nvkm_falcon_cmdq *queue,
|
||||
struct nv_falcon_cmd *cmd,
|
||||
nvkm_falcon_qmgr_callback cb, void *priv,
|
||||
unsigned long timeout)
|
||||
{
|
||||
struct nvkm_falcon_qmgr_seq *seq;
|
||||
struct nvkm_msgqueue_queue *queue;
|
||||
int ret;
|
||||
|
||||
queue = priv->func->cmd_queue(priv, prio);
|
||||
if (IS_ERR(queue))
|
||||
return PTR_ERR(queue);
|
||||
|
||||
if (!wait_for_completion_timeout(&queue->ready,
|
||||
msecs_to_jiffies(1000))) {
|
||||
FLCNQ_ERR(queue, "timeout waiting for queue ready");
|
||||
|
@ -150,7 +146,7 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
|
|||
cmd->ctrl_flags = CMD_FLAGS_STATUS | CMD_FLAGS_INTR;
|
||||
|
||||
seq->state = SEQ_STATE_USED;
|
||||
seq->async = !completion;
|
||||
seq->async = !timeout;
|
||||
seq->callback = cb;
|
||||
seq->priv = priv;
|
||||
|
||||
|
@ -162,8 +158,7 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
|
|||
}
|
||||
|
||||
if (!seq->async) {
|
||||
if (!wait_for_completion_timeout(&seq->done,
|
||||
msecs_to_jiffies(1000))) {
|
||||
if (!wait_for_completion_timeout(&seq->done, timeout)) {
|
||||
FLCNQ_ERR(queue, "timeout waiting for reply");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
|
|
@ -52,11 +52,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
enum msgqueue_msg_priority {
|
||||
MSGQUEUE_MSG_PRIORITY_HIGH,
|
||||
MSGQUEUE_MSG_PRIORITY_LOW,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nvkm_msgqueue_hdr - header for all commands/messages
|
||||
* @unit_id: id of firmware using receiving the command/sending the message
|
||||
|
@ -110,8 +105,6 @@ struct nvkm_msgqueue_func {
|
|||
const struct nvkm_msgqueue_init_func *init_func;
|
||||
const struct nvkm_msgqueue_acr_func *acr_func;
|
||||
void (*dtor)(struct nvkm_msgqueue *);
|
||||
struct nvkm_msgqueue_queue *(*cmd_queue)(struct nvkm_msgqueue *,
|
||||
enum msgqueue_msg_priority);
|
||||
void (*recv)(struct nvkm_msgqueue *queue);
|
||||
};
|
||||
|
||||
|
@ -160,9 +153,6 @@ struct nvkm_msgqueue {
|
|||
|
||||
void nvkm_msgqueue_ctor(const struct nvkm_msgqueue_func *, struct nvkm_falcon *,
|
||||
struct nvkm_msgqueue *);
|
||||
int nvkm_msgqueue_post(struct nvkm_msgqueue *, enum msgqueue_msg_priority,
|
||||
struct nvkm_msgqueue_hdr *, nvkm_falcon_qmgr_callback,
|
||||
struct completion *, bool);
|
||||
void nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *,
|
||||
struct nvkm_msgqueue_queue *);
|
||||
|
||||
|
|
|
@ -45,24 +45,6 @@ struct msgqueue_0137bca5 {
|
|||
container_of(container_of(q, struct msgqueue_0137c63d, base), \
|
||||
struct msgqueue_0137bca5, base);
|
||||
|
||||
static struct nvkm_msgqueue_queue *
|
||||
msgqueue_0137c63d_cmd_queue(struct nvkm_msgqueue *queue,
|
||||
enum msgqueue_msg_priority priority)
|
||||
{
|
||||
struct msgqueue_0137c63d *priv = msgqueue_0137c63d(queue);
|
||||
const struct nvkm_subdev *subdev = priv->base.falcon->owner;
|
||||
|
||||
switch (priority) {
|
||||
case MSGQUEUE_MSG_PRIORITY_HIGH:
|
||||
return subdev->device->pmu->hpq;
|
||||
case MSGQUEUE_MSG_PRIORITY_LOW:
|
||||
return subdev->device->pmu->lpq;
|
||||
default:
|
||||
nvkm_error(subdev, "invalid command queue!\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
msgqueue_0137c63d_process_msgs(struct nvkm_msgqueue *queue)
|
||||
{
|
||||
|
@ -172,13 +154,13 @@ enum {
|
|||
static int
|
||||
acr_init_wpr_callback(void *priv, struct nv_falcon_msg *hdr)
|
||||
{
|
||||
struct nvkm_msgqueue *queue = priv;
|
||||
struct nvkm_pmu *pmu = priv;
|
||||
struct nvkm_subdev *subdev = &pmu->subdev;
|
||||
struct {
|
||||
struct nv_falcon_msg base;
|
||||
u8 msg_type;
|
||||
u32 error_code;
|
||||
} *msg = (void *)hdr;
|
||||
const struct nvkm_subdev *subdev = queue->falcon->owner;
|
||||
|
||||
if (msg->error_code) {
|
||||
nvkm_error(subdev, "ACR WPR init failure: %d\n",
|
||||
|
@ -187,19 +169,20 @@ acr_init_wpr_callback(void *priv, struct nv_falcon_msg *hdr)
|
|||
}
|
||||
|
||||
nvkm_debug(subdev, "ACR WPR init complete\n");
|
||||
complete_all(&subdev->device->pmu->wpr_ready);
|
||||
complete_all(&pmu->wpr_ready);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
acr_init_wpr(struct nvkm_msgqueue *queue)
|
||||
{
|
||||
struct nvkm_pmu *pmu = queue->falcon->owner->device->pmu;
|
||||
/*
|
||||
* region_id: region ID in WPR region
|
||||
* wpr_offset: offset in WPR region
|
||||
*/
|
||||
struct {
|
||||
struct nvkm_msgqueue_hdr hdr;
|
||||
struct nv_falcon_cmd hdr;
|
||||
u8 cmd_type;
|
||||
u32 region_id;
|
||||
u32 wpr_offset;
|
||||
|
@ -211,21 +194,20 @@ acr_init_wpr(struct nvkm_msgqueue *queue)
|
|||
cmd.cmd_type = ACR_CMD_INIT_WPR_REGION;
|
||||
cmd.region_id = 0x01;
|
||||
cmd.wpr_offset = 0x00;
|
||||
return nvkm_msgqueue_post(queue, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
|
||||
acr_init_wpr_callback, NULL, false);
|
||||
return nvkm_falcon_cmdq_send(pmu->hpq, &cmd.hdr, acr_init_wpr_callback,
|
||||
pmu, 0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
acr_boot_falcon_callback(void *_priv, struct nv_falcon_msg *hdr)
|
||||
acr_boot_falcon_callback(void *priv, struct nv_falcon_msg *hdr)
|
||||
{
|
||||
struct nvkm_msgqueue *priv = _priv;
|
||||
struct acr_bootstrap_falcon_msg {
|
||||
struct nv_falcon_msg base;
|
||||
u8 msg_type;
|
||||
u32 falcon_id;
|
||||
} *msg = (void *)hdr;
|
||||
const struct nvkm_subdev *subdev = priv->falcon->owner;
|
||||
struct nvkm_subdev *subdev = priv;
|
||||
u32 falcon_id = msg->falcon_id;
|
||||
|
||||
if (falcon_id >= NVKM_SECBOOT_FALCON_END) {
|
||||
|
@ -247,13 +229,12 @@ static int
|
|||
acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon)
|
||||
{
|
||||
struct nvkm_pmu *pmu = priv->falcon->owner->device->pmu;
|
||||
DECLARE_COMPLETION_ONSTACK(completed);
|
||||
/*
|
||||
* flags - Flag specifying RESET or no RESET.
|
||||
* falcon id - Falcon id specifying falcon to bootstrap.
|
||||
*/
|
||||
struct {
|
||||
struct nvkm_msgqueue_hdr hdr;
|
||||
struct nv_falcon_cmd hdr;
|
||||
u8 cmd_type;
|
||||
u32 flags;
|
||||
u32 falcon_id;
|
||||
|
@ -272,20 +253,20 @@ 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;
|
||||
return nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
|
||||
acr_boot_falcon_callback, &completed, true);
|
||||
return nvkm_falcon_cmdq_send(pmu->hpq, &cmd.hdr,
|
||||
acr_boot_falcon_callback, &pmu->subdev,
|
||||
msecs_to_jiffies(1000));
|
||||
}
|
||||
|
||||
static int
|
||||
acr_boot_multiple_falcons_callback(void *_priv, struct nv_falcon_msg *hdr)
|
||||
acr_boot_multiple_falcons_callback(void *priv, struct nv_falcon_msg *hdr)
|
||||
{
|
||||
struct nvkm_msgqueue *priv = _priv;
|
||||
struct acr_bootstrap_falcon_msg {
|
||||
struct nv_falcon_msg base;
|
||||
u8 msg_type;
|
||||
u32 falcon_mask;
|
||||
} *msg = (void *)hdr;
|
||||
const struct nvkm_subdev *subdev = priv->falcon->owner;
|
||||
const struct nvkm_subdev *subdev = priv;
|
||||
unsigned long falcon_mask = msg->falcon_mask;
|
||||
u32 falcon_id, falcon_treated = 0;
|
||||
|
||||
|
@ -309,13 +290,12 @@ static int
|
|||
acr_boot_multiple_falcons(struct nvkm_msgqueue *priv, unsigned long falcon_mask)
|
||||
{
|
||||
struct nvkm_pmu *pmu = priv->falcon->owner->device->pmu;
|
||||
DECLARE_COMPLETION_ONSTACK(completed);
|
||||
/*
|
||||
* flags - Flag specifying RESET or no RESET.
|
||||
* falcon id - Falcon id specifying falcon to bootstrap.
|
||||
*/
|
||||
struct {
|
||||
struct nvkm_msgqueue_hdr hdr;
|
||||
struct nv_falcon_cmd hdr;
|
||||
u8 cmd_type;
|
||||
u32 flags;
|
||||
u32 falcon_mask;
|
||||
|
@ -340,9 +320,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);
|
||||
return nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
|
||||
acr_boot_multiple_falcons_callback,
|
||||
&completed, true);
|
||||
return nvkm_falcon_cmdq_send(pmu->hpq, &cmd.hdr,
|
||||
acr_boot_multiple_falcons_callback,
|
||||
&pmu->subdev, msecs_to_jiffies(1000));
|
||||
}
|
||||
|
||||
static const struct nvkm_msgqueue_acr_func
|
||||
|
@ -366,7 +346,6 @@ static const struct nvkm_msgqueue_func
|
|||
msgqueue_0137c63d_func = {
|
||||
.init_func = &msgqueue_0137c63d_init_func,
|
||||
.acr_func = &msgqueue_0137c63d_acr_func,
|
||||
.cmd_queue = msgqueue_0137c63d_cmd_queue,
|
||||
.recv = msgqueue_0137c63d_process_msgs,
|
||||
.dtor = msgqueue_0137c63d_dtor,
|
||||
};
|
||||
|
@ -392,7 +371,6 @@ static const struct nvkm_msgqueue_func
|
|||
msgqueue_0137bca5_func = {
|
||||
.init_func = &msgqueue_0137c63d_init_func,
|
||||
.acr_func = &msgqueue_0137bca5_acr_func,
|
||||
.cmd_queue = msgqueue_0137c63d_cmd_queue,
|
||||
.recv = msgqueue_0137c63d_process_msgs,
|
||||
.dtor = msgqueue_0137c63d_dtor,
|
||||
};
|
||||
|
|
|
@ -43,13 +43,6 @@ struct msgqueue_0148cdec {
|
|||
#define msgqueue_0148cdec(q) \
|
||||
container_of(q, struct msgqueue_0148cdec, base)
|
||||
|
||||
static struct nvkm_msgqueue_queue *
|
||||
msgqueue_0148cdec_cmd_queue(struct nvkm_msgqueue *queue,
|
||||
enum msgqueue_msg_priority priority)
|
||||
{
|
||||
return queue->falcon->owner->device->sec2->cmdq;
|
||||
}
|
||||
|
||||
static void
|
||||
msgqueue_0148cdec_process_msgs(struct nvkm_msgqueue *queue)
|
||||
{
|
||||
|
@ -146,16 +139,15 @@ enum {
|
|||
};
|
||||
|
||||
static int
|
||||
acr_boot_falcon_callback(void *_priv, struct nv_falcon_msg *hdr)
|
||||
acr_boot_falcon_callback(void *priv, struct nv_falcon_msg *hdr)
|
||||
{
|
||||
struct nvkm_msgqueue *priv = _priv;
|
||||
struct acr_bootstrap_falcon_msg {
|
||||
struct nv_falcon_msg base;
|
||||
u8 msg_type;
|
||||
u32 error_code;
|
||||
u32 falcon_id;
|
||||
} *msg = (void *)hdr;
|
||||
const struct nvkm_subdev *subdev = priv->falcon->owner;
|
||||
const struct nvkm_subdev *subdev = priv;
|
||||
u32 falcon_id = msg->falcon_id;
|
||||
|
||||
if (msg->error_code) {
|
||||
|
@ -183,13 +175,13 @@ enum {
|
|||
static int
|
||||
acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon)
|
||||
{
|
||||
DECLARE_COMPLETION_ONSTACK(completed);
|
||||
struct nvkm_sec2 *sec2 = priv->falcon->owner->device->sec2;
|
||||
/*
|
||||
* flags - Flag specifying RESET or no RESET.
|
||||
* falcon id - Falcon id specifying falcon to bootstrap.
|
||||
*/
|
||||
struct {
|
||||
struct nvkm_msgqueue_hdr hdr;
|
||||
struct nv_falcon_cmd hdr;
|
||||
u8 cmd_type;
|
||||
u32 flags;
|
||||
u32 falcon_id;
|
||||
|
@ -202,8 +194,10 @@ 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;
|
||||
return nvkm_msgqueue_post(priv, MSGQUEUE_MSG_PRIORITY_HIGH, &cmd.hdr,
|
||||
acr_boot_falcon_callback, &completed, true);
|
||||
return nvkm_falcon_cmdq_send(sec2->cmdq, &cmd.hdr,
|
||||
acr_boot_falcon_callback,
|
||||
&sec2->engine.subdev,
|
||||
msecs_to_jiffies(1000));
|
||||
}
|
||||
|
||||
const struct nvkm_msgqueue_acr_func
|
||||
|
@ -221,7 +215,6 @@ const struct nvkm_msgqueue_func
|
|||
msgqueue_0148cdec_func = {
|
||||
.init_func = &msgqueue_0148cdec_init_func,
|
||||
.acr_func = &msgqueue_0148cdec_acr_func,
|
||||
.cmd_queue = msgqueue_0148cdec_cmd_queue,
|
||||
.recv = msgqueue_0148cdec_process_msgs,
|
||||
.dtor = msgqueue_0148cdec_dtor,
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче