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
#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;
struct nvkm_falcon falcon;
struct nvkm_falcon_qmgr *qmgr;
+ struct nvkm_falcon_cmdq *cmdq;
struct nvkm_msgqueue *queue;
struct work_struct work;
};
struct nvkm_falcon falcon;
struct nvkm_falcon_qmgr *qmgr;
+ struct nvkm_falcon_cmdq *hpq;
+ struct nvkm_falcon_cmdq *lpq;
struct nvkm_msgqueue *queue;
struct {
{
struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
flush_work(&sec2->work);
+ nvkm_falcon_cmdq_fini(sec2->cmdq);
return 0;
}
{
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;
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);
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;
+}
*/
struct nvkm_msgqueue_queue {
struct nvkm_falcon_qmgr *qmgr;
+ const char *name;
struct mutex mutex;
u32 index;
u32 offset;
*/
#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,
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);
} *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) {
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;
}
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);
}
#include "msgqueue.h"
#include <engine/falcon.h>
+#include <engine/sec2.h>
#include <subdev/secboot.h>
/*
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
} *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) {
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,
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
pmu->func->fini(pmu);
flush_work(&pmu->recv.work);
+
+ nvkm_falcon_cmdq_fini(pmu->lpq);
+ nvkm_falcon_cmdq_fini(pmu->hpq);
return 0;
}
{
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);
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;