diff options
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h | 6 |
7 files changed, 65 insertions, 38 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h index 2cd5a06673a1..75d095048b67 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h @@ -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 **); diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c index 1cf6453fdd70..f0d28985f055 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c @@ -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; diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c index 303f9faf3423..7f84a5ef7905 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c @@ -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 @@ close: 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 { diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h index 4cfa6b21d3df..542ecae806ee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h @@ -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 *); diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c index 48a0f0de3453..a8931cd96bca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c index 12d5ad6b7422..92b8351e9e35 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c @@ -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 { diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h b/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h index 35ac2cc85d2c..ca2e71a0e043 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h @@ -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; }; /* |