Commit c80157a2 authored by Ben Skeggs's avatar Ben Skeggs

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: default avatarBen Skeggs <bskeggs@redhat.com>
parent 0ae59432
...@@ -30,10 +30,28 @@ int gp102_sec2_flcn_enable(struct nvkm_falcon *); ...@@ -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_DBG(f,fmt,a...) FLCN_PRINTK(debug, (f), fmt, ##a)
#define FLCN_ERR(f,fmt,a...) FLCN_PRINTK(error, (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; struct nvkm_falcon_qmgr;
int nvkm_falcon_qmgr_new(struct nvkm_falcon *, 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 **); 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; struct nvkm_falcon_cmdq;
int nvkm_falcon_cmdq_new(struct nvkm_falcon_qmgr *, const char *name, int nvkm_falcon_cmdq_new(struct nvkm_falcon_qmgr *, const char *name,
struct nvkm_falcon_cmdq **); struct nvkm_falcon_cmdq **);
......
...@@ -149,7 +149,7 @@ cmd_write(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_hdr *cmd, ...@@ -149,7 +149,7 @@ cmd_write(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_hdr *cmd,
int int
nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio, 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 completion *completion, bool wait_init)
{ {
struct nvkm_msgqueue_seq *seq; struct nvkm_msgqueue_seq *seq;
...@@ -172,6 +172,7 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio, ...@@ -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; cmd->ctrl_flags = CMD_FLAGS_STATUS | CMD_FLAGS_INTR;
seq->callback = cb; seq->callback = cb;
seq->priv = priv;
seq->state = SEQ_STATE_USED; seq->state = SEQ_STATE_USED;
seq->completion = completion; seq->completion = completion;
......
...@@ -86,7 +86,7 @@ msg_queue_pop(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_queue *queue, ...@@ -86,7 +86,7 @@ msg_queue_pop(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_queue *queue,
static int static int
msg_queue_read(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_queue *queue, 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; const struct nvkm_subdev *subdev = priv->falcon->owner;
int ret; int ret;
...@@ -136,7 +136,7 @@ msg_queue_read(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_queue *queue, ...@@ -136,7 +136,7 @@ msg_queue_read(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_queue *queue,
static int static int
msgqueue_msg_handle(struct nvkm_msgqueue *priv, msgqueue_msg_handle(struct nvkm_msgqueue *priv,
struct nvkm_falcon_msgq *msgq, struct nvkm_falcon_msgq *msgq,
struct nvkm_msgqueue_hdr *hdr) struct nv_falcon_msg *hdr)
{ {
const struct nvkm_subdev *subdev = priv->falcon->owner; const struct nvkm_subdev *subdev = priv->falcon->owner;
struct nvkm_msgqueue_seq *seq; struct nvkm_msgqueue_seq *seq;
...@@ -149,7 +149,7 @@ msgqueue_msg_handle(struct nvkm_msgqueue *priv, ...@@ -149,7 +149,7 @@ msgqueue_msg_handle(struct nvkm_msgqueue *priv,
if (seq->state == SEQ_STATE_USED) { if (seq->state == SEQ_STATE_USED) {
if (seq->callback) if (seq->callback)
seq->callback(priv, hdr); seq->result = seq->callback(seq->priv, hdr);
} }
if (seq->completion) if (seq->completion)
...@@ -160,12 +160,13 @@ msgqueue_msg_handle(struct nvkm_msgqueue *priv, ...@@ -160,12 +160,13 @@ msgqueue_msg_handle(struct nvkm_msgqueue *priv,
} }
static int static int
msgqueue_handle_init_msg(struct nvkm_msgqueue *priv, msgqueue_handle_init_msg(struct nvkm_msgqueue *priv)
struct nvkm_msgqueue_hdr *hdr)
{ {
struct nvkm_falcon *falcon = priv->falcon; struct nvkm_falcon *falcon = priv->falcon;
const struct nvkm_subdev *subdev = falcon->owner; const struct nvkm_subdev *subdev = falcon->owner;
const u32 tail_reg = falcon->func->msgq.tail; const u32 tail_reg = falcon->func->msgq.tail;
u8 msg_buffer[MSG_BUF_SIZE];
struct nvkm_msgqueue_hdr *hdr = (void *)msg_buffer;
u32 tail; u32 tail;
int ret; int ret;
...@@ -203,12 +204,12 @@ nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *priv, ...@@ -203,12 +204,12 @@ nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *priv,
* stack space to work with. * stack space to work with.
*/ */
u8 msg_buffer[MSG_BUF_SIZE]; u8 msg_buffer[MSG_BUF_SIZE];
struct nvkm_msgqueue_hdr *hdr = (void *)msg_buffer; struct nv_falcon_msg *hdr = (void *)msg_buffer;
int ret; int ret;
/* the first message we receive must be the init message */ /* the first message we receive must be the init message */
if ((!priv->init_msg_received)) { if ((!priv->init_msg_received)) {
ret = msgqueue_handle_init_msg(priv, hdr); ret = msgqueue_handle_init_msg(priv);
if (!ret) if (!ret)
priv->init_msg_received = true; priv->init_msg_received = true;
} else { } else {
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#ifndef __NVKM_CORE_FALCON_MSGQUEUE_H #ifndef __NVKM_CORE_FALCON_MSGQUEUE_H
#define __NVKM_CORE_FALCON_MSGQUEUE_H #define __NVKM_CORE_FALCON_MSGQUEUE_H
#include <core/falcon.h>
#include <core/msgqueue.h> #include <core/msgqueue.h>
/* /*
...@@ -83,8 +83,6 @@ struct nvkm_msgqueue_msg { ...@@ -83,8 +83,6 @@ struct nvkm_msgqueue_msg {
}; };
struct nvkm_msgqueue; 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 * struct nvkm_msgqueue_init_func - msgqueue functions related to initialization
...@@ -163,7 +161,7 @@ struct nvkm_msgqueue { ...@@ -163,7 +161,7 @@ struct nvkm_msgqueue {
void nvkm_msgqueue_ctor(const struct nvkm_msgqueue_func *, struct nvkm_falcon *, void nvkm_msgqueue_ctor(const struct nvkm_msgqueue_func *, struct nvkm_falcon *,
struct nvkm_msgqueue *); struct nvkm_msgqueue *);
int nvkm_msgqueue_post(struct nvkm_msgqueue *, enum msgqueue_msg_priority, 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); struct completion *, bool);
void nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *, void nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *,
struct nvkm_msgqueue_queue *); struct nvkm_msgqueue_queue *);
......
...@@ -169,12 +169,13 @@ enum { ...@@ -169,12 +169,13 @@ enum {
ACR_CMD_BOOTSTRAP_MULTIPLE_FALCONS = 0x03, ACR_CMD_BOOTSTRAP_MULTIPLE_FALCONS = 0x03,
}; };
static void static int
acr_init_wpr_callback(struct nvkm_msgqueue *queue, acr_init_wpr_callback(void *priv, struct nv_falcon_msg *hdr)
struct nvkm_msgqueue_hdr *hdr)
{ {
struct nvkm_msgqueue *queue = priv;
struct { struct {
struct nvkm_msgqueue_msg base; struct nv_falcon_msg base;
u8 msg_type;
u32 error_code; u32 error_code;
} *msg = (void *)hdr; } *msg = (void *)hdr;
const struct nvkm_subdev *subdev = queue->falcon->owner; const struct nvkm_subdev *subdev = queue->falcon->owner;
...@@ -182,11 +183,12 @@ acr_init_wpr_callback(struct nvkm_msgqueue *queue, ...@@ -182,11 +183,12 @@ acr_init_wpr_callback(struct nvkm_msgqueue *queue,
if (msg->error_code) { if (msg->error_code) {
nvkm_error(subdev, "ACR WPR init failure: %d\n", nvkm_error(subdev, "ACR WPR init failure: %d\n",
msg->error_code); msg->error_code);
return; return -EINVAL;
} }
nvkm_debug(subdev, "ACR WPR init complete\n"); nvkm_debug(subdev, "ACR WPR init complete\n");
complete_all(&queue->init_done); complete_all(&queue->init_done);
return 0;
} }
static int static int
...@@ -217,13 +219,13 @@ acr_init_wpr(struct nvkm_msgqueue *queue) ...@@ -217,13 +219,13 @@ acr_init_wpr(struct nvkm_msgqueue *queue)
} }
static void static int
acr_boot_falcon_callback(struct nvkm_msgqueue *priv, acr_boot_falcon_callback(void *_priv, struct nv_falcon_msg *hdr)
struct nvkm_msgqueue_hdr *hdr)
{ {
struct nvkm_msgqueue *priv = _priv;
struct acr_bootstrap_falcon_msg { struct acr_bootstrap_falcon_msg {
struct nvkm_msgqueue_msg base; struct nv_falcon_msg base;
u8 msg_type;
u32 falcon_id; u32 falcon_id;
} *msg = (void *)hdr; } *msg = (void *)hdr;
const struct nvkm_subdev *subdev = priv->falcon->owner; const struct nvkm_subdev *subdev = priv->falcon->owner;
...@@ -232,9 +234,11 @@ acr_boot_falcon_callback(struct nvkm_msgqueue *priv, ...@@ -232,9 +234,11 @@ acr_boot_falcon_callback(struct nvkm_msgqueue *priv,
if (falcon_id >= NVKM_SECBOOT_FALCON_END) { if (falcon_id >= NVKM_SECBOOT_FALCON_END) {
nvkm_error(subdev, "in bootstrap falcon callback:\n"); nvkm_error(subdev, "in bootstrap falcon callback:\n");
nvkm_error(subdev, "invalid falcon ID 0x%x\n", falcon_id); 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]); nvkm_debug(subdev, "%s booted\n", nvkm_secboot_falcon_name[falcon_id]);
return 0;
} }
enum { enum {
...@@ -273,13 +277,13 @@ acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon) ...@@ -273,13 +277,13 @@ acr_boot_falcon(struct nvkm_msgqueue *priv, enum nvkm_secboot_falcon falcon)
return 0; return 0;
} }
static void static int
acr_boot_multiple_falcons_callback(struct nvkm_msgqueue *priv, acr_boot_multiple_falcons_callback(void *_priv, struct nv_falcon_msg *hdr)
struct nvkm_msgqueue_hdr *hdr)
{ {
struct nvkm_msgqueue *priv = _priv;
struct acr_bootstrap_falcon_msg { struct acr_bootstrap_falcon_msg {
struct nvkm_msgqueue_msg base; struct nv_falcon_msg base;
u8 msg_type;
u32 falcon_mask; u32 falcon_mask;
} *msg = (void *)hdr; } *msg = (void *)hdr;
const struct nvkm_subdev *subdev = priv->falcon->owner; const struct nvkm_subdev *subdev = priv->falcon->owner;
...@@ -296,8 +300,10 @@ acr_boot_multiple_falcons_callback(struct nvkm_msgqueue *priv, ...@@ -296,8 +300,10 @@ acr_boot_multiple_falcons_callback(struct nvkm_msgqueue *priv,
nvkm_error(subdev, "in bootstrap falcon callback:\n"); nvkm_error(subdev, "in bootstrap falcon callback:\n");
nvkm_error(subdev, "invalid falcon mask 0x%x\n", nvkm_error(subdev, "invalid falcon mask 0x%x\n",
msg->falcon_mask); msg->falcon_mask);
return; return -EINVAL;
} }
return 0;
} }
static int static int
......
...@@ -147,13 +147,13 @@ enum { ...@@ -147,13 +147,13 @@ enum {
ACR_CMD_BOOTSTRAP_FALCON = 0x00, ACR_CMD_BOOTSTRAP_FALCON = 0x00,
}; };
static void static int
acr_boot_falcon_callback(struct nvkm_msgqueue *priv, acr_boot_falcon_callback(void *_priv, struct nv_falcon_msg *hdr)
struct nvkm_msgqueue_hdr *hdr)
{ {
struct nvkm_msgqueue *priv = _priv;
struct acr_bootstrap_falcon_msg { struct acr_bootstrap_falcon_msg {
struct nvkm_msgqueue_msg base; struct nv_falcon_msg base;
u8 msg_type;
u32 error_code; u32 error_code;
u32 falcon_id; u32 falcon_id;
} *msg = (void *)hdr; } *msg = (void *)hdr;
...@@ -164,16 +164,17 @@ acr_boot_falcon_callback(struct nvkm_msgqueue *priv, ...@@ -164,16 +164,17 @@ acr_boot_falcon_callback(struct nvkm_msgqueue *priv,
nvkm_error(subdev, "in bootstrap falcon callback:\n"); nvkm_error(subdev, "in bootstrap falcon callback:\n");
nvkm_error(subdev, "expected error code 0x%x\n", nvkm_error(subdev, "expected error code 0x%x\n",
msg->error_code); msg->error_code);
return; return -EINVAL;
} }
if (falcon_id >= NVKM_SECBOOT_FALCON_END) { if (falcon_id >= NVKM_SECBOOT_FALCON_END) {
nvkm_error(subdev, "in bootstrap falcon callback:\n"); nvkm_error(subdev, "in bootstrap falcon callback:\n");
nvkm_error(subdev, "invalid falcon ID 0x%x\n", falcon_id); 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]); nvkm_debug(subdev, "%s booted\n", nvkm_secboot_falcon_name[falcon_id]);
return 0;
} }
enum { enum {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <core/falcon.h> #include <core/falcon.h>
#include "msgqueue.h" #include "msgqueue.h"
#define HDR_SIZE sizeof(struct nvkm_msgqueue_hdr) #define HDR_SIZE sizeof(struct nv_falcon_msg)
#define QUEUE_ALIGNMENT 4 #define QUEUE_ALIGNMENT 4
/* max size of the messages we can receive */ /* max size of the messages we can receive */
#define MSG_BUF_SIZE 128 #define MSG_BUF_SIZE 128
...@@ -29,8 +29,10 @@ struct nvkm_msgqueue_seq { ...@@ -29,8 +29,10 @@ struct nvkm_msgqueue_seq {
SEQ_STATE_USED, SEQ_STATE_USED,
SEQ_STATE_CANCELLED SEQ_STATE_CANCELLED
} state; } state;
nvkm_msgqueue_callback callback; nvkm_falcon_qmgr_callback callback;
void *priv;
struct completion *completion; struct completion *completion;
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