diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h index c4d9431fd63b..2cd5a06673a1 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h @@ -41,4 +41,11 @@ 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 *); + +struct nvkm_falcon_msgq; +int nvkm_falcon_msgq_new(struct nvkm_falcon_qmgr *, const char *name, + struct nvkm_falcon_msgq **); +void nvkm_falcon_msgq_del(struct nvkm_falcon_msgq **); +void nvkm_falcon_msgq_init(struct nvkm_falcon_msgq *, + u32 index, u32 offset, u32 size); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h index 5ae6c10f0fa4..b632a43c16ef 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h @@ -4,6 +4,7 @@ #include #define nvkm_falcon_cmdq nvkm_msgqueue_queue +#define nvkm_falcon_msgq nvkm_msgqueue_queue struct nvkm_subdev { const struct nvkm_subdev_func *func; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h index e52ea3b99a4d..ca1b227a81f9 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h @@ -12,6 +12,7 @@ struct nvkm_sec2 { struct nvkm_falcon_qmgr *qmgr; struct nvkm_falcon_cmdq *cmdq; + struct nvkm_falcon_msgq *msgq; 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 6c0cfef2d1fa..39fb218f943e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h @@ -12,6 +12,7 @@ struct nvkm_pmu { struct nvkm_falcon_qmgr *qmgr; struct nvkm_falcon_cmdq *hpq; struct nvkm_falcon_cmdq *lpq; + struct nvkm_falcon_msgq *msgq; 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 38ed27fa0d70..d85aeb059c87 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c @@ -60,6 +60,7 @@ nvkm_sec2_dtor(struct nvkm_engine *engine) { struct nvkm_sec2 *sec2 = nvkm_sec2(engine); nvkm_msgqueue_del(&sec2->queue); + nvkm_falcon_msgq_del(&sec2->msgq); nvkm_falcon_cmdq_del(&sec2->cmdq); nvkm_falcon_qmgr_del(&sec2->qmgr); nvkm_falcon_dtor(&sec2->falcon); @@ -99,7 +100,8 @@ nvkm_sec2_new_(const struct nvkm_sec2_fwif *fwif, struct nvkm_device *device, return ret; if ((ret = nvkm_falcon_qmgr_new(&sec2->falcon, &sec2->qmgr)) || - (ret = nvkm_falcon_cmdq_new(sec2->qmgr, "cmdq", &sec2->cmdq))) + (ret = nvkm_falcon_cmdq_new(sec2->qmgr, "cmdq", &sec2->cmdq)) || + (ret = nvkm_falcon_msgq_new(sec2->qmgr, "msgq", &sec2->msgq))) return ret; INIT_WORK(&sec2->work, nvkm_sec2_recv); diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c index 5db0b41bc2c8..7be610427eef 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c @@ -214,3 +214,42 @@ nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *priv, msgqueue_msg_handle(priv, hdr); } } + +void +nvkm_falcon_msgq_init(struct nvkm_falcon_msgq *msgq, + u32 index, u32 offset, u32 size) +{ + const struct nvkm_falcon_func *func = msgq->qmgr->falcon->func; + + msgq->head_reg = func->msgq.head + index * func->msgq.stride; + msgq->tail_reg = func->msgq.tail + index * func->msgq.stride; + msgq->offset = offset; + + FLCNQ_DBG(msgq, "initialised @ index %d offset 0x%08x size 0x%08x", + index, msgq->offset, size); +} + +void +nvkm_falcon_msgq_del(struct nvkm_falcon_msgq **pmsgq) +{ + struct nvkm_falcon_msgq *msgq = *pmsgq; + if (msgq) { + kfree(*pmsgq); + *pmsgq = NULL; + } +} + +int +nvkm_falcon_msgq_new(struct nvkm_falcon_qmgr *qmgr, const char *name, + struct nvkm_falcon_msgq **pmsgq) +{ + struct nvkm_falcon_msgq *msgq = *pmsgq; + + if (!(msgq = *pmsgq = kzalloc(sizeof(*msgq), GFP_KERNEL))) + return -ENOMEM; + + msgq->qmgr = qmgr; + msgq->name = name; + mutex_init(&msgq->mutex); + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c index fd6303b62aa4..48a0f0de3453 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0137c63d.c @@ -27,15 +27,11 @@ /* Queues identifiers */ enum { - /* Message queue for PMU -> Host communication */ - MSGQUEUE_0137C63D_MESSAGE_QUEUE = 4, MSGQUEUE_0137C63D_NUM_QUEUES = 5, }; struct msgqueue_0137c63d { struct nvkm_msgqueue base; - - struct nvkm_msgqueue_queue queue[MSGQUEUE_0137C63D_NUM_QUEUES]; }; #define msgqueue_0137c63d(q) \ container_of(q, struct msgqueue_0137c63d, base) @@ -70,11 +66,7 @@ msgqueue_0137c63d_cmd_queue(struct nvkm_msgqueue *queue, static void msgqueue_0137c63d_process_msgs(struct nvkm_msgqueue *queue) { - struct msgqueue_0137c63d *priv = msgqueue_0137c63d(queue); - struct nvkm_msgqueue_queue *q_queue = - &priv->queue[MSGQUEUE_0137C63D_MESSAGE_QUEUE]; - - nvkm_msgqueue_process_msgs(&priv->base, q_queue); + nvkm_msgqueue_process_msgs(queue, queue->falcon->owner->device->pmu->msgq); } /* Init unit */ @@ -133,10 +125,8 @@ init_callback(struct nvkm_msgqueue *_queue, struct nvkm_msgqueue_hdr *hdr) u16 sw_managed_area_offset; u16 sw_managed_area_size; } *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) { nvkm_error(subdev, "expected message from init unit\n"); @@ -148,31 +138,15 @@ init_callback(struct nvkm_msgqueue *_queue, struct nvkm_msgqueue_hdr *hdr) return -EINVAL; } - for (i = 0; i < MSGQUEUE_0137C63D_NUM_QUEUES; i++) { - struct nvkm_msgqueue_queue *queue = &priv->queue[i]; - - mutex_init(&queue->mutex); - - queue->index = init->queue_info[i].index; - queue->offset = init->queue_info[i].offset; - queue->size = init->queue_info[i].size; - - if (i == MSGQUEUE_0137C63D_MESSAGE_QUEUE) { - queue->head_reg = func->msgq.head; - queue->tail_reg = func->msgq.tail; - } - - nvkm_debug(subdev, - "queue %d: index %d, offset 0x%08x, size 0x%08x\n", - 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); + nvkm_falcon_msgq_init(pmu->msgq, init->queue_info[4].index, + init->queue_info[4].offset, + init->queue_info[4].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 8193bec3c031..12d5ad6b7422 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue_0148cdec.c @@ -39,8 +39,6 @@ enum { struct msgqueue_0148cdec { struct nvkm_msgqueue base; - - struct nvkm_msgqueue_queue queue[MSGQUEUE_0148CDEC_NUM_QUEUES]; }; #define msgqueue_0148cdec(q) \ container_of(q, struct msgqueue_0148cdec, base) @@ -55,11 +53,7 @@ msgqueue_0148cdec_cmd_queue(struct nvkm_msgqueue *queue, static void msgqueue_0148cdec_process_msgs(struct nvkm_msgqueue *queue) { - struct msgqueue_0148cdec *priv = msgqueue_0148cdec(queue); - struct nvkm_msgqueue_queue *q_queue = - &priv->queue[MSGQUEUE_0148CDEC_MESSAGE_QUEUE]; - - nvkm_msgqueue_process_msgs(&priv->base, q_queue); + nvkm_msgqueue_process_msgs(queue, queue->falcon->owner->device->sec2->msgq); } @@ -87,7 +81,6 @@ init_gen_cmdline(struct nvkm_msgqueue *queue, void *buf) static int init_callback(struct nvkm_msgqueue *_queue, struct nvkm_msgqueue_hdr *hdr) { - struct msgqueue_0148cdec *priv = msgqueue_0148cdec(_queue); struct { struct nvkm_msgqueue_msg base; @@ -104,7 +97,6 @@ init_callback(struct nvkm_msgqueue *_queue, struct nvkm_msgqueue_hdr *hdr) u16 sw_managed_area_offset; u16 sw_managed_area_size; } *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; @@ -121,29 +113,18 @@ init_callback(struct nvkm_msgqueue *_queue, struct nvkm_msgqueue_hdr *hdr) for (i = 0; i < MSGQUEUE_0148CDEC_NUM_QUEUES; i++) { u8 id = init->queue_info[i].id; - struct nvkm_msgqueue_queue *queue = &priv->queue[id]; - - mutex_init(&queue->mutex); - - queue->index = init->queue_info[i].index; - queue->offset = init->queue_info[i].offset; - queue->size = init->queue_info[i].size; if (id == MSGQUEUE_0148CDEC_MESSAGE_QUEUE) { - queue->head_reg = func->msgq.head + queue->index * - func->msgq.stride; - queue->tail_reg = func->msgq.tail + queue->index * - func->msgq.stride; + nvkm_falcon_msgq_init(sec2->msgq, + init->queue_info[i].index, + init->queue_info[i].offset, + init->queue_info[i].size); } else { nvkm_falcon_cmdq_init(sec2->cmdq, init->queue_info[i].index, init->queue_info[i].offset, init->queue_info[i].size); } - - nvkm_debug(subdev, - "queue %d: index %d, offset 0x%08x, size 0x%08x\n", - id, queue->index, queue->offset, queue->size); } complete_all(&_queue->init_done); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c index 9dc0a002f530..86af2ddb3e78 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c @@ -142,6 +142,7 @@ nvkm_pmu_dtor(struct nvkm_subdev *subdev) { struct nvkm_pmu *pmu = nvkm_pmu(subdev); nvkm_msgqueue_del(&pmu->queue); + nvkm_falcon_msgq_del(&pmu->msgq); nvkm_falcon_cmdq_del(&pmu->lpq); nvkm_falcon_cmdq_del(&pmu->hpq); nvkm_falcon_qmgr_del(&pmu->qmgr); @@ -183,7 +184,8 @@ nvkm_pmu_ctor(const struct nvkm_pmu_fwif *fwif, struct nvkm_device *device, 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))) + (ret = nvkm_falcon_cmdq_new(pmu->qmgr, "lpq", &pmu->lpq)) || + (ret = nvkm_falcon_msgq_new(pmu->qmgr, "msgq", &pmu->msgq))) return ret; return 0;