drm/nouveau/flcn/msgq: explicitly create message queue 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>
This commit is contained in:
parent
acc466ab46
commit
22431189d6
|
@ -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
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <core/device.h>
|
||||
|
||||
#define nvkm_falcon_cmdq nvkm_msgqueue_queue
|
||||
#define nvkm_falcon_msgq nvkm_msgqueue_queue
|
||||
|
||||
struct nvkm_subdev {
|
||||
const struct nvkm_subdev_func *func;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue