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;