drm/nouveau/gr/gf100-: generate golden context during first object alloc
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Jun 2022 10:48:05 +0000 (20:48 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 9 Nov 2022 00:45:10 +0000 (10:45 +1000)
Needed for GV100 (and only GV100 for some reason) for WFI_GOLDEN_SAVE.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c

index 2979157..45db67d 100644 (file)
@@ -26,6 +26,7 @@
 #include <subdev/fb.h>
 #include <subdev/mc.h>
 #include <subdev/timer.h>
+#include <engine/fifo.h>
 
 /*******************************************************************************
  * PGRAPH context register lists
@@ -1433,14 +1434,12 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
 #define CB_RESERVED 0x80000
 
 int
-gf100_grctx_generate(struct gf100_gr *gr)
+gf100_grctx_generate(struct gf100_gr *gr, struct gf100_gr_chan *chan, struct nvkm_gpuobj *inst)
 {
        const struct gf100_grctx_func *grctx = gr->func->grctx;
        struct nvkm_subdev *subdev = &gr->base.engine.subdev;
        struct nvkm_device *device = subdev->device;
-       struct nvkm_memory *inst = NULL;
        struct nvkm_memory *data = NULL;
-       struct nvkm_vmm *vmm = NULL;
        struct nvkm_vma *ctx = NULL;
        struct gf100_grctx info;
        int ret, i;
@@ -1472,38 +1471,20 @@ gf100_grctx_generate(struct gf100_gr *gr)
        /* Init SCC RAM. */
        nvkm_wr32(device, 0x40802c, 0x00000001);
 
-       /* Allocate memory to for a "channel", which we'll use to generate
-        * the default context values.
-        */
-       ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
-                             0x1000, 0x1000, true, &inst);
-       if (ret)
-               goto done;
-
-       ret = nvkm_vmm_new(device, 0, 0, NULL, 0, NULL, "grctx", &vmm);
-       if (ret)
-               goto done;
-
-       vmm->debug = subdev->debug;
-
-       ret = nvkm_vmm_join(vmm, inst);
-       if (ret)
-               goto done;
-
+       /* Allocate memory to store context, and dummy global context buffers. */
        ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
                              CB_RESERVED + gr->size, 0, true, &data);
        if (ret)
                goto done;
 
-       ret = nvkm_vmm_get(vmm, 0, nvkm_memory_size(data), &ctx);
+       ret = nvkm_vmm_get(chan->vmm, 0, nvkm_memory_size(data), &ctx);
        if (ret)
                goto done;
 
-       ret = nvkm_memory_map(data, 0, vmm, ctx, NULL, 0);
+       ret = nvkm_memory_map(data, 0, chan->vmm, ctx, NULL, 0);
        if (ret)
                goto done;
 
-
        /* Setup context pointer. */
        nvkm_kmap(inst);
        nvkm_wo32(inst, 0x0210, lower_32_bits(ctx->addr + CB_RESERVED) | 4);
@@ -1518,11 +1499,11 @@ gf100_grctx_generate(struct gf100_gr *gr)
        info.buffer_nr = 0;
 
        /* Make channel current. */
-       addr = nvkm_memory_addr(inst) >> 12;
+       addr = inst->addr >> 12;
        if (gr->firmware) {
                ret = gf100_gr_fecs_bind_pointer(gr, 0x80000000 | addr);
                if (ret)
-                       goto done;
+                       goto done_inst;
 
                nvkm_kmap(data);
                nvkm_wo32(data, 0x1c, 1);
@@ -1552,7 +1533,7 @@ gf100_grctx_generate(struct gf100_gr *gr)
                        break;
        ) < 0) {
                ret = -EBUSY;
-               goto done;
+               goto done_inst;
        }
 
        gr->data = kmalloc(gr->size, GFP_KERNEL);
@@ -1566,12 +1547,14 @@ gf100_grctx_generate(struct gf100_gr *gr)
                ret = -ENOMEM;
        }
 
+done_inst:
+       nvkm_kmap(inst);
+       nvkm_wo32(inst, 0x0210, 0);
+       nvkm_wo32(inst, 0x0214, 0);
+       nvkm_done(inst);
 done:
-       nvkm_vmm_put(vmm, &ctx);
+       nvkm_vmm_put(chan->vmm, &ctx);
        nvkm_memory_unref(&data);
-       nvkm_vmm_part(vmm, inst);
-       nvkm_vmm_unref(&vmm);
-       nvkm_memory_unref(&inst);
        return ret;
 }
 
index 32bbddc..7b968ef 100644 (file)
@@ -81,7 +81,7 @@ struct gf100_grctx_func {
 };
 
 extern const struct gf100_grctx_func gf100_grctx;
-int  gf100_grctx_generate(struct gf100_gr *);
+int  gf100_grctx_generate(struct gf100_gr *, struct gf100_gr_chan *, struct nvkm_gpuobj *inst);
 void gf100_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *);
 void gf100_grctx_generate_bundle(struct gf100_grctx *);
 void gf100_grctx_generate_pagepool(struct gf100_grctx *);
index 662d953..310949c 100644 (file)
@@ -394,6 +394,17 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
        chan->vmm = nvkm_vmm_ref(fifoch->vmm);
        *pobject = &chan->object;
 
+       /* Generate golden context image. */
+       mutex_lock(&gr->fecs.mutex);
+       if (gr->data == NULL) {
+               ret = gf100_grctx_generate(gr, chan, fifoch->inst);
+               if (ret) {
+                       nvkm_error(&base->engine.subdev, "failed to construct context\n");
+                       return ret;
+               }
+       }
+       mutex_unlock(&gr->fecs.mutex);
+
        /* allocate memory for a "mmio list" buffer that's used by the HUB
         * fuc to modify some per-context register settings on first load
         * of the context.
@@ -1763,15 +1774,6 @@ gf100_gr_init_ctxctl_ext(struct gf100_gr *gr)
                        return ret;
        }
 
-       /* Generate golden context image. */
-       if (gr->data == NULL) {
-               int ret = gf100_grctx_generate(gr);
-               if (ret) {
-                       nvkm_error(subdev, "failed to construct context\n");
-                       return ret;
-               }
-       }
-
        return 0;
 }
 
@@ -1823,14 +1825,6 @@ gf100_gr_init_ctxctl_int(struct gf100_gr *gr)
        }
 
        gr->size = nvkm_rd32(device, 0x409804);
-       if (gr->data == NULL) {
-               int ret = gf100_grctx_generate(gr);
-               if (ret) {
-                       nvkm_error(subdev, "failed to construct context\n");
-                       return ret;
-               }
-       }
-
        return 0;
 }