]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
drm/nouveau/flcn/cmdq: explicitly create command queue(s) from subdevs
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.

This is an incremental step towards that goal.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h
drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h
drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c
drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.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
drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c

index 043bd498e5c9487f71d3ee4511959c306f006682..c4d9431fd63b8c6132ae3cb00ec4ad8e93d47efe 100644 (file)
@@ -33,4 +33,12 @@ int gp102_sec2_flcn_enable(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 **);
+
+struct nvkm_falcon_cmdq;
+int nvkm_falcon_cmdq_new(struct nvkm_falcon_qmgr *, const char *name,
+                        struct nvkm_falcon_cmdq **);
+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 *);
 #endif
index 1218f28c14baba31cd93e7453de2694cda24e4d1..5ae6c10f0fa446ec557d0ee16e3b051d051c3bb3 100644 (file)
@@ -3,6 +3,8 @@
 #define __NVKM_SUBDEV_H__
 #include <core/device.h>
 
+#define nvkm_falcon_cmdq nvkm_msgqueue_queue
+
 struct nvkm_subdev {
        const struct nvkm_subdev_func *func;
        struct nvkm_device *device;
index 3b6586e6c8f8210bf158474cfa702fa3831919ce..e52ea3b99a4d720973019580251fa7553b08f082 100644 (file)
@@ -11,6 +11,7 @@ struct nvkm_sec2 {
        struct nvkm_falcon falcon;
 
        struct nvkm_falcon_qmgr *qmgr;
+       struct nvkm_falcon_cmdq *cmdq;
        struct nvkm_msgqueue *queue;
        struct work_struct work;
 };
index 10b3c71ccf4bd7f7308a712befcdc6afe5da06ae..6c0cfef2d1fa9bfcad7a3894453435b659b6832c 100644 (file)
@@ -10,6 +10,8 @@ struct nvkm_pmu {
        struct nvkm_falcon falcon;
 
        struct nvkm_falcon_qmgr *qmgr;
+       struct nvkm_falcon_cmdq *hpq;
+       struct nvkm_falcon_cmdq *lpq;
        struct nvkm_msgqueue *queue;
 
        struct {
index 542f88a6fc396b9871e431270067f29bb0bc7874..38ed27fa0d700b11046a9b2b411c662d83566deb 100644 (file)
@@ -51,6 +51,7 @@ nvkm_sec2_fini(struct nvkm_engine *engine, bool suspend)
 {
        struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
        flush_work(&sec2->work);
+       nvkm_falcon_cmdq_fini(sec2->cmdq);
        return 0;
 }
 
@@ -59,6 +60,7 @@ nvkm_sec2_dtor(struct nvkm_engine *engine)
 {
        struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
        nvkm_msgqueue_del(&sec2->queue);
+       nvkm_falcon_cmdq_del(&sec2->cmdq);
        nvkm_falcon_qmgr_del(&sec2->qmgr);
        nvkm_falcon_dtor(&sec2->falcon);
        return sec2;
@@ -96,7 +98,8 @@ nvkm_sec2_new_(const struct nvkm_sec2_fwif *fwif, struct nvkm_device *device,
        if (ret)
                return ret;
 
-       if ((ret = nvkm_falcon_qmgr_new(&sec2->falcon, &sec2->qmgr)))
+       if ((ret = nvkm_falcon_qmgr_new(&sec2->falcon, &sec2->qmgr)) ||
+           (ret = nvkm_falcon_cmdq_new(sec2->qmgr, "cmdq", &sec2->cmdq)))
                return ret;
 
        INIT_WORK(&sec2->work, nvkm_sec2_recv);
index 4785a563c1830646fadc97f9673afc52b9019a54..8b7796df697a6d4be8cef98343051c7887b80634 100644 (file)
@@ -183,3 +183,48 @@ nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
 
        return ret;
 }
+
+void
+nvkm_falcon_cmdq_fini(struct nvkm_falcon_cmdq *cmdq)
+{
+}
+
+void
+nvkm_falcon_cmdq_init(struct nvkm_falcon_cmdq *cmdq,
+                     u32 index, u32 offset, u32 size)
+{
+       const struct nvkm_falcon_func *func = cmdq->qmgr->falcon->func;
+
+       cmdq->head_reg = func->cmdq.head + index * func->cmdq.stride;
+       cmdq->tail_reg = func->cmdq.tail + index * func->cmdq.stride;
+       cmdq->offset = offset;
+       cmdq->size = size;
+
+       FLCNQ_DBG(cmdq, "initialised @ index %d offset 0x%08x size 0x%08x",
+                 index, cmdq->offset, cmdq->size);
+}
+
+void
+nvkm_falcon_cmdq_del(struct nvkm_falcon_cmdq **pcmdq)
+{
+       struct nvkm_falcon_cmdq *cmdq = *pcmdq;
+       if (cmdq) {
+               kfree(*pcmdq);
+               *pcmdq = NULL;
+       }
+}
+
+int
+nvkm_falcon_cmdq_new(struct nvkm_falcon_qmgr *qmgr, const char *name,
+                    struct nvkm_falcon_cmdq **pcmdq)
+{
+       struct nvkm_falcon_cmdq *cmdq = *pcmdq;
+
+       if (!(cmdq = *pcmdq = kzalloc(sizeof(*cmdq), GFP_KERNEL)))
+               return -ENOMEM;
+
+       cmdq->qmgr = qmgr;
+       cmdq->name = name;
+       mutex_init(&cmdq->mutex);
+       return 0;
+}
index e978fb15d3b6d296e35ed1830f2c44df508eabcc..6729a7b52742487921370dfd5c710918e00973c1 100644 (file)
@@ -133,6 +133,7 @@ struct nvkm_msgqueue_func {
  */
 struct nvkm_msgqueue_queue {
        struct nvkm_falcon_qmgr *qmgr;
+       const char *name;
        struct mutex mutex;
        u32 index;
        u32 offset;
index 68de203d80a8084ff877bf712b7c01aedf7b82d7..fd6303b62aa4d895ec9590b5911337c924c541b6 100644 (file)
  */
 #include "msgqueue.h"
 #include <engine/falcon.h>
+#include <subdev/pmu.h>
 #include <subdev/secboot.h>
 
 /* Queues identifiers */
 enum {
-       /* High Priority Command Queue for Host -> PMU communication */
-       MSGQUEUE_0137C63D_COMMAND_QUEUE_HPQ = 0,
-       /* Low Priority Command Queue for Host -> PMU communication */
-       MSGQUEUE_0137C63D_COMMAND_QUEUE_LPQ = 1,
        /* Message queue for PMU -> Host communication */
        MSGQUEUE_0137C63D_MESSAGE_QUEUE = 4,
        MSGQUEUE_0137C63D_NUM_QUEUES = 5,
@@ -61,9 +58,9 @@ msgqueue_0137c63d_cmd_queue(struct nvkm_msgqueue *queue,
 
        switch (priority) {
        case MSGQUEUE_MSG_PRIORITY_HIGH:
-               return &priv->queue[MSGQUEUE_0137C63D_COMMAND_QUEUE_HPQ];
+               return subdev->device->pmu->hpq;
        case MSGQUEUE_MSG_PRIORITY_LOW:
-               return &priv->queue[MSGQUEUE_0137C63D_COMMAND_QUEUE_LPQ];
+               return subdev->device->pmu->lpq;
        default:
                nvkm_error(subdev, "invalid command queue!\n");
                return ERR_PTR(-EINVAL);
@@ -138,6 +135,7 @@ init_callback(struct nvkm_msgqueue *_queue, struct nvkm_msgqueue_hdr *hdr)
        } *init = (void *)hdr;
        const struct nvkm_falcon_func *func = _queue->falcon->func;
        const struct nvkm_subdev *subdev = _queue->falcon->owner;
+       struct nvkm_pmu *pmu = subdev->device->pmu;
        int i;
 
        if (init->base.hdr.unit_id != MSGQUEUE_0137C63D_UNIT_INIT) {
@@ -159,12 +157,7 @@ init_callback(struct nvkm_msgqueue *_queue, struct nvkm_msgqueue_hdr *hdr)
                queue->offset = init->queue_info[i].offset;
                queue->size = init->queue_info[i].size;
 
-               if (i != MSGQUEUE_0137C63D_MESSAGE_QUEUE) {
-                       queue->head_reg = func->cmdq.head + queue->index *
-                                         func->cmdq.stride;
-                       queue->tail_reg = func->cmdq.tail + queue->index *
-                                         func->cmdq.stride;
-               } else {
+               if (i == MSGQUEUE_0137C63D_MESSAGE_QUEUE) {
                        queue->head_reg = func->msgq.head;
                        queue->tail_reg = func->msgq.tail;
                }
@@ -174,6 +167,13 @@ init_callback(struct nvkm_msgqueue *_queue, struct nvkm_msgqueue_hdr *hdr)
                           i, queue->index, queue->offset, queue->size);
        }
 
+       nvkm_falcon_cmdq_init(pmu->hpq, init->queue_info[0].index,
+                                       init->queue_info[0].offset,
+                                       init->queue_info[0].size);
+       nvkm_falcon_cmdq_init(pmu->lpq, init->queue_info[1].index,
+                                       init->queue_info[1].offset,
+                                       init->queue_info[1].size);
+
        /* Complete initialization by initializing WPR region */
        return acr_init_wpr(&priv->base);
 }
index 651bef2e3270c3c09e8fccba11c13a26092e0d6c..8193bec3c031be630d310dc4de3cabe8fbefd77a 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "msgqueue.h"
 #include <engine/falcon.h>
+#include <engine/sec2.h>
 #include <subdev/secboot.h>
 
 /*
@@ -48,9 +49,7 @@ static struct nvkm_msgqueue_queue *
 msgqueue_0148cdec_cmd_queue(struct nvkm_msgqueue *queue,
                            enum msgqueue_msg_priority priority)
 {
-       struct msgqueue_0148cdec *priv = msgqueue_0148cdec(queue);
-
-       return &priv->queue[MSGQUEUE_0148CDEC_COMMAND_QUEUE];
+       return queue->falcon->owner->device->sec2->cmdq;
 }
 
 static void
@@ -107,6 +106,7 @@ init_callback(struct nvkm_msgqueue *_queue, struct nvkm_msgqueue_hdr *hdr)
        } *init = (void *)hdr;
        const struct nvkm_falcon_func *func = _queue->falcon->func;
        const struct nvkm_subdev *subdev = _queue->falcon->owner;
+       struct nvkm_sec2 *sec2 = subdev->device->sec2;
        int i;
 
        if (init->base.hdr.unit_id != MSGQUEUE_0148CDEC_UNIT_INIT) {
@@ -135,10 +135,10 @@ init_callback(struct nvkm_msgqueue *_queue, struct nvkm_msgqueue_hdr *hdr)
                        queue->tail_reg = func->msgq.tail + queue->index *
                                          func->msgq.stride;
                } else {
-                       queue->head_reg = func->cmdq.head + queue->index *
-                                         func->cmdq.stride;
-                       queue->tail_reg = func->cmdq.tail + queue->index *
-                                         func->cmdq.stride;
+                       nvkm_falcon_cmdq_init(sec2->cmdq,
+                                             init->queue_info[i].index,
+                                             init->queue_info[i].offset,
+                                             init->queue_info[i].size);
                }
 
                nvkm_debug(subdev,
index 9c8d77c11fd9997080a5d3c655315ab86203eaf5..7b89fdd0c13e2b80e0a1deb7dc6b10290b914c7c 100644 (file)
@@ -15,4 +15,9 @@ struct nvkm_falcon_qmgr {
 
 struct nvkm_msgqueue_seq *msgqueue_seq_acquire(struct nvkm_msgqueue *);
 void msgqueue_seq_release(struct nvkm_msgqueue *, struct nvkm_msgqueue_seq *);
+
+#define FLCNQ_PRINTK(t,q,f,a...)                                               \
+       FLCN_PRINTK(t, (q)->qmgr->falcon, "%s: "f, (q)->name, ##a)
+#define FLCNQ_DBG(q,f,a...) FLCNQ_PRINTK(debug, (q), f, ##a)
+#define FLCNQ_ERR(q,f,a...) FLCNQ_PRINTK(error, (q), f, ##a)
 #endif
index 850939f7e2878b16fd8837f59ac790d54e339675..9dc0a002f530885608102ba0fdfc5a3223ac2b1b 100644 (file)
@@ -86,6 +86,9 @@ nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend)
                pmu->func->fini(pmu);
 
        flush_work(&pmu->recv.work);
+
+       nvkm_falcon_cmdq_fini(pmu->lpq);
+       nvkm_falcon_cmdq_fini(pmu->hpq);
        return 0;
 }
 
@@ -139,6 +142,8 @@ nvkm_pmu_dtor(struct nvkm_subdev *subdev)
 {
        struct nvkm_pmu *pmu = nvkm_pmu(subdev);
        nvkm_msgqueue_del(&pmu->queue);
+       nvkm_falcon_cmdq_del(&pmu->lpq);
+       nvkm_falcon_cmdq_del(&pmu->hpq);
        nvkm_falcon_qmgr_del(&pmu->qmgr);
        nvkm_falcon_dtor(&pmu->falcon);
        return nvkm_pmu(subdev);
@@ -176,7 +181,9 @@ nvkm_pmu_ctor(const struct nvkm_pmu_fwif *fwif, struct nvkm_device *device,
        if (ret)
                return ret;
 
-       if ((ret = nvkm_falcon_qmgr_new(&pmu->falcon, &pmu->qmgr)))
+       if ((ret = nvkm_falcon_qmgr_new(&pmu->falcon, &pmu->qmgr)) ||
+           (ret = nvkm_falcon_cmdq_new(pmu->qmgr, "hpq", &pmu->hpq)) ||
+           (ret = nvkm_falcon_cmdq_new(pmu->qmgr, "lpq", &pmu->lpq)))
                return ret;
 
        return 0;