drm/nouveau/imem: use fast-path for suspend backup
authorBen Skeggs <bskeggs@redhat.com>
Tue, 31 Oct 2017 17:56:19 +0000 (03:56 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 2 Nov 2017 03:32:20 +0000 (13:32 +1000)
Before: "imem: suspend completed in 5540487us"
 After: "imem: suspend completed in 1871526us"

Suspend from Fedora 26 gnome desktop on GP102.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c

index c8cb8b8..190fb73 100644 (file)
@@ -74,7 +74,6 @@ nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend)
 {
        struct nvkm_bar *bar = nvkm_bar(subdev);
        bar->func->bar1.fini(bar);
-       nvkm_bar_bar2_fini(subdev->device);
        return 0;
 }
 
@@ -101,6 +100,7 @@ static void *
 nvkm_bar_dtor(struct nvkm_subdev *subdev)
 {
        struct nvkm_bar *bar = nvkm_bar(subdev);
+       nvkm_bar_bar2_fini(subdev->device);
        return bar->func->dtor(bar);
 }
 
index 8fc63ec..d7df7cb 100644 (file)
@@ -46,15 +46,20 @@ nvkm_instobj_save(struct nvkm_instobj *iobj)
 {
        struct nvkm_memory *memory = &iobj->memory;
        const u64 size = nvkm_memory_size(memory);
+       void __iomem *map;
        int i;
 
        iobj->suspend = kvmalloc(size, GFP_KERNEL);
        if (!iobj->suspend)
                return -ENOMEM;
 
-       for (i = 0; i < size; i += 4)
-               iobj->suspend[i / 4] = nvkm_ro32(memory, i);
-
+       if (!(map = nvkm_kmap(memory))) {
+               for (i = 0; i < size; i += 4)
+                       iobj->suspend[i / 4] = nvkm_ro32(memory, i);
+       } else {
+               memcpy_fromio(iobj->suspend, map, size);
+       }
+       nvkm_done(memory);
        return 0;
 }
 
@@ -157,6 +162,8 @@ nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend)
                                return ret;
                }
 
+               nvkm_bar_bar2_fini(subdev->device);
+
                list_for_each_entry(iobj, &imem->boot, head) {
                        int ret = nvkm_instobj_save(iobj);
                        if (ret)