diff options
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c | 9 |
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; |