drm/nouveau/flcn/qmgr: allow arbtrary priv + return code for callbacks
authorBen Skeggs <bskeggs@redhat.com>
Tue, 14 Jan 2020 20:34:22 +0000 (06:34 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 15 Jan 2020 00:50:28 +0000 (10:50 +1000)
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>
drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h
drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c
drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h

index 2cd5a06673a14ddf101d8542ea9e701ed1a9c52b..75d095048b67f714be59160c5c67166dc31a2510 100644 (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 **);
index 1cf6453fdd70a09bbe3730ee0abc9bb668e0f54c..f0d28985f055c0b4842414d57d56bfaf2c0f871e 100644 (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;
 
index 303f9faf34237b11ce68b1879c084b1213477eef..7f84a5ef7905630865429c87ba2acc2e982059cc 100644 (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 @@ 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 {
index 4cfa6b21d3df107849cd093fd07fd66bc340a853..542ecae806eeaeb423aca3ea2bcee654ce6ec418 100644 (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 *);
index 48a0f0de34533d9b7e45536f512f865d481bccd0..a8931cd96bca084f7bf177ed6c3ee6ebc6a3ce90 100644 (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
index 12d5ad6b7422d6f484c81d1b0e5bf239c34f1481..92b8351e9e3513cd8aedbcb2dfa57311770d7701 100644 (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 {
index 35ac2cc85d2c14ad571ec04bd79d338ece710d68..ca2e71a0e0434db5c799c0f0a36f215d91569611 100644 (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;
 };
 
 /*