summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h8
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h2
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c45
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c9
11 files changed, 95 insertions, 21 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h
index 043bd498e5c9..c4d9431fd63b 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h
@@ -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
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
index 1218f28c14ba..5ae6c10f0fa4 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
@@ -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;
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h
index 3b6586e6c8f8..e52ea3b99a4d 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h
@@ -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;
};
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
index 10b3c71ccf4b..6c0cfef2d1fa 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
@@ -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 {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c
index 542f88a6fc39..38ed27fa0d70 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c
@@ -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);
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
index 4785a563c183..8b7796df697a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c
@@ -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;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
index e978fb15d3b6..6729a7b52742 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
@@ -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;
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
index 68de203d80a8..fd6303b62aa4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c
@@ -22,14 +22,11 @@
*/
#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);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
index 651bef2e3270..8193bec3c031 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c
@@ -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,
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h b/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h
index 9c8d77c11fd9..7b89fdd0c13e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h
@@ -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
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
index 850939f7e287..9dc0a002f530 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
@@ -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;
OpenPOWER on IntegriCloud