drm/nouveau/gr/gf100-: call FECS WFI_GOLDEN_SAVE method
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Jun 2022 10:48:08 +0000 (20:48 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 9 Nov 2022 00:45:11 +0000 (10:45 +1000)
This won't work on Ampere, and, it's questionable whether we should have
been using our FW's method of storing the golden context image with NV's
firmware to begin with.

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/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h

index 332590f..eef9b3f 100644 (file)
@@ -1496,17 +1496,25 @@ gf100_grctx_generate(struct gf100_gr *gr, struct gf100_gr_chan *chan, struct nvk
 
        grctx->main(chan);
 
-       /* Trigger a context unload by unsetting the "next channel valid" bit
-        * and faking a context switch interrupt.
-        */
-       nvkm_mask(device, 0x409b04, 0x80000000, 0x00000000);
-       nvkm_wr32(device, 0x409000, 0x00000100);
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x409b00) & 0x80000000))
-                       break;
-       ) < 0) {
-               ret = -EBUSY;
-               goto done_inst;
+       if (!gr->firmware) {
+               /* Trigger a context unload by unsetting the "next channel valid" bit
+                * and faking a context switch interrupt.
+                */
+               nvkm_mask(device, 0x409b04, 0x80000000, 0x00000000);
+               nvkm_wr32(device, 0x409000, 0x00000100);
+               if (nvkm_msec(device, 2000,
+                       if (!(nvkm_rd32(device, 0x409b00) & 0x80000000))
+                               break;
+               ) < 0) {
+                       ret = -EBUSY;
+                       goto done_inst;
+               }
+       } else {
+               ret = gf100_gr_fecs_wfi_golden_save(gr, 0x80000000 | addr);
+               if (ret)
+                       goto done_inst;
+
+               nvkm_mask(device, 0x409b00, 0x80000000, 0x00000000);
        }
 
        gr->data = kmalloc(gr->size, GFP_KERNEL);
index 30dce77..22f360d 100644 (file)
@@ -797,6 +797,25 @@ gf100_gr_fecs_stop_ctxsw(struct nvkm_gr *base)
 }
 
 int
+gf100_gr_fecs_wfi_golden_save(struct gf100_gr *gr, u32 inst)
+{
+       struct nvkm_device *device = gr->base.engine.subdev.device;
+
+       nvkm_mask(device, 0x409800, 0x00000003, 0x00000000);
+       nvkm_wr32(device, 0x409500, inst);
+       nvkm_wr32(device, 0x409504, 0x00000009);
+       nvkm_msec(device, 2000,
+               u32 stat = nvkm_rd32(device, 0x409800);
+               if (stat & 0x00000002)
+                       return -EIO;
+               if (stat & 0x00000001)
+                       return 0;
+       );
+
+       return -ETIMEDOUT;
+}
+
+int
 gf100_gr_fecs_bind_pointer(struct gf100_gr *gr, u32 inst)
 {
        struct nvkm_device *device = gr->base.engine.subdev.device;
index 7f467f6..66aefc9 100644 (file)
@@ -129,6 +129,7 @@ struct gf100_gr {
 };
 
 int gf100_gr_fecs_bind_pointer(struct gf100_gr *, u32 inst);
+int gf100_gr_fecs_wfi_golden_save(struct gf100_gr *, u32 inst);
 
 struct gf100_gr_func_zbc {
        void (*clear_color)(struct gf100_gr *, int zbc);