diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2020-01-15 06:34:22 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2020-01-15 10:50:28 +1000 |
commit | acc466ab46574f0d9de65606f0796cff07c9a7d5 (patch) | |
tree | 587805bae5fb67680dba9e2ccd90d4d6f44effe1 /drivers/gpu/drm/nouveau/nvkm | |
parent | 8763955ba73807c6f5d38364074c1802d8415172 (diff) | |
download | linux-stable-acc466ab46574f0d9de65606f0796cff07c9a7d5.tar.gz linux-stable-acc466ab46574f0d9de65606f0796cff07c9a7d5.tar.bz2 linux-stable-acc466ab46574f0d9de65606f0796cff07c9a7d5.zip |
drm/nouveau/flcn/cmdq: explicitly create command queue(s) from subdevs
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>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm')
-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 |
7 files changed, 82 insertions, 21 deletions
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; |