summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nvkm/engine
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2020-01-15 06:34:22 +1000
committerBen Skeggs <bskeggs@redhat.com>2020-01-15 10:50:29 +1000
commitd114a1393fa01c4034d895072905578319a903f9 (patch)
treeb919222d6234608a07eab974b156945a0cc65ba1 /drivers/gpu/drm/nouveau/nvkm/engine
parent2d063981d710391cdea4e8c6483d94b519b1cde2 (diff)
drm/nouveau/flcn/msgq: move handling of init message to subdevs
When the PMU/SEC2 LS FWs have booted, they'll send a message to the host with various information, including the configuration of message/command queues that are available. Move the handling for this to the relevant subdevs. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c32
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sec2/priv.h1
3 files changed, 51 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c
index d85aeb059c87..f6a453dc75ad 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c
@@ -30,6 +30,17 @@ nvkm_sec2_recv(struct work_struct *work)
{
struct nvkm_sec2 *sec2 = container_of(work, typeof(*sec2), work);
+ if (!sec2->initmsg_received) {
+ int ret = sec2->func->initmsg(sec2);
+ if (ret) {
+ nvkm_error(&sec2->engine.subdev,
+ "error parsing init message: %d\n", ret);
+ return;
+ }
+
+ sec2->initmsg_received = true;
+ }
+
if (!sec2->queue) {
nvkm_warn(&sec2->engine.subdev,
"recv function called while no firmware set!\n");
@@ -50,8 +61,14 @@ static int
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);
+
+ if (suspend) {
+ nvkm_falcon_cmdq_fini(sec2->cmdq);
+ sec2->initmsg_received = false;
+ }
+
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c
index 26f738d1202e..26a468047747 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c
@@ -69,6 +69,37 @@ gp102_sec2_acr_0 = {
.bootstrap_falcon = gp102_sec2_acr_bootstrap_falcon,
};
+int
+gp102_sec2_initmsg(struct nvkm_sec2 *sec2)
+{
+ struct nv_sec2_init_msg msg;
+ int ret, i;
+
+ ret = nvkm_falcon_msgq_recv_initmsg(sec2->msgq, &msg, sizeof(msg));
+ if (ret)
+ return ret;
+
+ if (msg.hdr.unit_id != NV_SEC2_UNIT_INIT ||
+ msg.msg_type != NV_SEC2_INIT_MSG_INIT)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(msg.queue_info); i++) {
+ if (msg.queue_info[i].id == NV_SEC2_INIT_MSG_QUEUE_ID_MSGQ) {
+ nvkm_falcon_msgq_init(sec2->msgq,
+ msg.queue_info[i].index,
+ msg.queue_info[i].offset,
+ msg.queue_info[i].size);
+ } else {
+ nvkm_falcon_cmdq_init(sec2->cmdq,
+ msg.queue_info[i].index,
+ msg.queue_info[i].offset,
+ msg.queue_info[i].size);
+ }
+ }
+
+ return 0;
+}
+
void
gp102_sec2_intr(struct nvkm_sec2 *sec2)
{
@@ -161,6 +192,7 @@ gp102_sec2 = {
.flcn = &gp102_sec2_flcn,
.unit_acr = NV_SEC2_UNIT_ACR,
.intr = gp102_sec2_intr,
+ .initmsg = gp102_sec2_initmsg,
};
MODULE_FIRMWARE("nvidia/gp102/sec2/desc.bin");
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/priv.h
index 9c00e6634499..1992391832a1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/priv.h
@@ -7,6 +7,7 @@ struct nvkm_sec2_func {
const struct nvkm_falcon_func *flcn;
u8 unit_acr;
void (*intr)(struct nvkm_sec2 *);
+ int (*initmsg)(struct nvkm_sec2 *);
};
void gp102_sec2_intr(struct nvkm_sec2 *);