drm/nouveau/flcn/qmgr: allow arbtrary priv + return code for callbacks

Code to interface with LS firmwares is being moved to the subdevs where it
belongs, rather than living in the common falcon code.

Arbitrary private data passed to callbacks is to allow for something other
than struct nvkm_msgqueue to be passed into the callback (like the pointer
to the subdev itself, for example), and the return code will be used where
we'd like to detect failure from synchronous messages.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Ben Skeggs 2020-01-15 06:34:22 +10:00
parent 0ae59432ba
commit c80157a25e
7 changed files with 65 additions and 38 deletions

View file

@ -30,10 +30,28 @@ int gp102_sec2_flcn_enable(struct nvkm_falcon *);
#define FLCN_DBG(f,fmt,a...) FLCN_PRINTK(debug, (f), fmt, ##a)
#define FLCN_ERR(f,fmt,a...) FLCN_PRINTK(error, (f), fmt, ##a)
/**
* struct nv_falcon_msg - header for all messages
*
* @unit_id: id of firmware process that sent the message
* @size: total size of message
* @ctrl_flags: control flags
* @seq_id: used to match a message from its corresponding command
*/
struct nv_falcon_msg {
u8 unit_id;
u8 size;
u8 ctrl_flags;
u8 seq_id;
};
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 **);
typedef int
(*nvkm_falcon_qmgr_callback)(void *priv, struct nv_falcon_msg *);
struct nvkm_falcon_cmdq;
int nvkm_falcon_cmdq_new(struct nvkm_falcon_qmgr *, const char *name,
struct nvkm_falcon_cmdq **);

View file

@ -149,7 +149,7 @@ cmd_write(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_hdr *cmd,
int
nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
struct nvkm_msgqueue_hdr *cmd, nvkm_msgqueue_callback cb,
struct nvkm_msgqueue_hdr *cmd, nvkm_falcon_qmgr_callback cb,
struct completion *completion, bool wait_init)
{
struct nvkm_msgqueue_seq *seq;
@ -172,6 +172,7 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
cmd->ctrl_flags = CMD_FLAGS_STATUS | CMD_FLAGS_INTR;
seq->callback = cb;
seq->priv = priv;
seq->state = SEQ_STATE_USED;
seq->completion = completion;

View file

@ -86,7 +86,7 @@ msg_queue_pop(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_queue *queue,
static int
msg_queue_read(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_queue *queue,
struct nvkm_msgqueue_hdr *hdr)
struct nv_falcon_msg *hdr)
{
const struct nvkm_subdev *subdev = priv->falcon->owner;
int ret;
@ -136,7 +136,7 @@ msg_queue_read(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_queue *queue,
static int
msgqueue_msg_handle(struct nvkm_msgqueue *priv,
struct nvkm_falcon_msgq *msgq,
struct nvkm_msgqueue_hdr *hdr)
struct nv_falcon_msg *hdr)
{
const struct nvkm_subdev *subdev = priv->falcon->owner;
struct nvkm_msgqueue_seq *seq;
@ -149,7 +149,7 @@ msgqueue_msg_handle(struct nvkm_msgqueue *priv,
if (seq->state == SEQ_STATE_USED) {
if (seq->callback)
seq->callback(priv, hdr);
seq->result = seq->callback(seq->priv, hdr);
}
if (seq->completion)
@ -160,12 +160,13 @@ msgqueue_msg_handle(struct nvkm_msgqueue *priv,
}
static int
msgqueue_handle_init_msg(struct nvkm_msgqueue *priv,
struct nvkm_msgqueue_hdr *hdr)
msgqueue_handle_init_msg(struct nvkm_msgqueue *priv)
{
struct nvkm_falcon *falcon = priv->falcon;
const struct nvkm_subdev *subdev = falcon->owner;
const u32 tail_reg = falcon->func->msgq.tail;
u8 msg_buffer[MSG_BUF_SIZE];
struct nvkm_msgqueue_hdr *hdr = (void *)msg_buffer;
u32 tail;
int ret;
@ -203,12 +204,12 @@ nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *priv,
* stack space to work with.
*/
u8 msg_buffer[MSG_BUF_SIZE];
struct nvkm_msgqueue_hdr *hdr = (void *)msg_buffer;
struct nv_falcon_msg *hdr = (void *)msg_buffer;
int ret;
/* the first message we receive must be the init message */
if ((!priv->init_msg_received)) {
ret = msgqueue_handle_init_msg(priv, hdr);
ret = msgqueue_handle_init_msg(priv);
if (!ret)
priv->init_msg_received = true;
} else {

View file

@ -23,7 +23,7 @@
#ifndef __NVKM_CORE_FALCON_MSGQUEUE_H
#define __NVKM_CORE_FALCON_MSGQUEUE_H
#include <core/falcon.h>
#include <core/msgqueue.h>
/*
@ -83,8 +83,6 @@ struct nvkm_msgqueue_msg {
};
struct nvkm_msgqueue;
typedef void
(*nvkm_msgqueue_callback)(struct nvkm_msgqueue *, struct nvkm_msgqueue_hdr *);
/**
* struct nvkm_msgqueue_init_func - msgqueue functions related to initialization
@ -163,7 +161,7 @@ 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_msgqueue_callback,
struct nvkm_msgqueue_hdr *, nvkm_falcon_qmgr_callback,
struct completion *, bool);
void nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *,
struct nvkm_msgqueue_queue *);

View file

@ -169,12 +169,13 @@ enum {
ACR_CMD_BOOTSTRAP_MULTIPLE_FALCONS = 0x03,
};
static void
acr_init_wpr_callback(struct nvkm_msgqueue *queue,
struct nvkm_msgqueue_hdr *hdr)
static int
acr_init_wpr_callback(void *priv, struct nv_falcon_msg *hdr)
{
struct nvkm_msgqueue *queue = priv;
struct {
struct nvkm_msgqueue_msg base;
struct nv_falcon_msg base;
u8 msg_type;
u32 error_code;
} *msg = (void *)hdr;
const struct nvkm_subdev *subdev = queue->falcon->owner;
@ -182,11 +183,12 @@ acr_init_wpr_callback(struct nvkm_msgqueue *queue,
if (msg->error_code) {
nvkm_error(subdev, "ACR WPR init failure: %d\n",
msg->error_code);
return;
return -EINVAL;
}
nvkm_debug(subdev, "ACR WPR init complete\n");
complete_all(&queue->init_done);
return 0;
}
static int
@ -217,13 +219,13 @@ acr_init_wpr(struct nvkm_msgqueue *queue)
}
static void
acr_boot_falcon_callback(struct nvkm_msgqueue *priv,
struct nvkm_msgqueue_hdr *hdr)
static int
acr_boot_falcon_callback(void *_priv, struct nv_falcon_msg *hdr)
{
struct nvkm_msgqueue *priv = _priv;
struct acr_bootstrap_falcon_msg {
struct nvkm_msgqueue_msg base;
struct nv_falcon_msg base;
u8 msg_type;
u32 falcon_id;
} *msg = (void *)hdr;
const struct nvkm_subdev *subdev = priv->falcon->owner;
@ -232,9 +234,11 @@ acr_boot_falcon_callback(struct nvkm_msgqueue *priv,
if (falcon_id >= NVKM_SECBOOT_FALCON_END) {
nvkm_error(subdev, "in bootstrap falcon callback:\n");
nvkm_error(subdev, "invalid falcon ID 0x%x\n", falcon_id);
return;
return -EINVAL;
}
nvkm_debug(subdev, "%s booted\n", nvkm_secboot_falcon_name[falcon_id]);
return 0;
}
enum {
@ -273,13 +277,13 @@ acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon)
return 0;
}
static void
acr_boot_multiple_falcons_callback(struct nvkm_msgqueue *priv,
struct nvkm_msgqueue_hdr *hdr)
static int
acr_boot_multiple_falcons_callback(void *_priv, struct nv_falcon_msg *hdr)
{
struct nvkm_msgqueue *priv = _priv;
struct acr_bootstrap_falcon_msg {
struct nvkm_msgqueue_msg base;
struct nv_falcon_msg base;
u8 msg_type;
u32 falcon_mask;
} *msg = (void *)hdr;
const struct nvkm_subdev *subdev = priv->falcon->owner;
@ -296,8 +300,10 @@ acr_boot_multiple_falcons_callback(struct nvkm_msgqueue *priv,
nvkm_error(subdev, "in bootstrap falcon callback:\n");
nvkm_error(subdev, "invalid falcon mask 0x%x\n",
msg->falcon_mask);
return;
return -EINVAL;
}
return 0;
}
static int

View file

@ -147,13 +147,13 @@ enum {
ACR_CMD_BOOTSTRAP_FALCON = 0x00,
};
static void
acr_boot_falcon_callback(struct nvkm_msgqueue *priv,
struct nvkm_msgqueue_hdr *hdr)
static int
acr_boot_falcon_callback(void *_priv, struct nv_falcon_msg *hdr)
{
struct nvkm_msgqueue *priv = _priv;
struct acr_bootstrap_falcon_msg {
struct nvkm_msgqueue_msg base;
struct nv_falcon_msg base;
u8 msg_type;
u32 error_code;
u32 falcon_id;
} *msg = (void *)hdr;
@ -164,16 +164,17 @@ acr_boot_falcon_callback(struct nvkm_msgqueue *priv,
nvkm_error(subdev, "in bootstrap falcon callback:\n");
nvkm_error(subdev, "expected error code 0x%x\n",
msg->error_code);
return;
return -EINVAL;
}
if (falcon_id >= NVKM_SECBOOT_FALCON_END) {
nvkm_error(subdev, "in bootstrap falcon callback:\n");
nvkm_error(subdev, "invalid falcon ID 0x%x\n", falcon_id);
return;
return -EINVAL;
}
nvkm_debug(subdev, "%s booted\n", nvkm_secboot_falcon_name[falcon_id]);
return 0;
}
enum {

View file

@ -4,7 +4,7 @@
#include <core/falcon.h>
#include "msgqueue.h"
#define HDR_SIZE sizeof(struct nvkm_msgqueue_hdr)
#define HDR_SIZE sizeof(struct nv_falcon_msg)
#define QUEUE_ALIGNMENT 4
/* max size of the messages we can receive */
#define MSG_BUF_SIZE 128
@ -29,8 +29,10 @@ struct nvkm_msgqueue_seq {
SEQ_STATE_USED,
SEQ_STATE_CANCELLED
} state;
nvkm_msgqueue_callback callback;
nvkm_falcon_qmgr_callback callback;
void *priv;
struct completion *completion;
int result;
};
/*