Commit e3f32495 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/fb/gp102-: unlock VPR right after devinit

Under memory load, instmem allocations could end up in the regions of
VRAM that are inaccessible right after boot, and be corrupted after a
suspend/resume cycle as a result of being restored before booting the
mem unlock firmware.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent 5728d064
...@@ -58,6 +58,8 @@ struct nvkm_fb { ...@@ -58,6 +58,8 @@ struct nvkm_fb {
struct nvkm_memory *mmu_wr; struct nvkm_memory *mmu_wr;
}; };
int nvkm_fb_mem_unlock(struct nvkm_fb *);
void nvkm_fb_tile_init(struct nvkm_fb *, int region, u32 addr, u32 size, void nvkm_fb_tile_init(struct nvkm_fb *, int region, u32 addr, u32 size,
u32 pitch, u32 flags, struct nvkm_fb_tile *); u32 pitch, u32 flags, struct nvkm_fb_tile *);
void nvkm_fb_tile_fini(struct nvkm_fb *, int region, struct nvkm_fb_tile *); void nvkm_fb_tile_fini(struct nvkm_fb *, int region, struct nvkm_fb_tile *);
......
...@@ -2808,6 +2808,10 @@ nvkm_device_preinit(struct nvkm_device *device) ...@@ -2808,6 +2808,10 @@ nvkm_device_preinit(struct nvkm_device *device)
if (ret) if (ret)
goto fail; goto fail;
ret = nvkm_fb_mem_unlock(device->fb);
if (ret)
goto fail;
time = ktime_to_us(ktime_get()) - time; time = ktime_to_us(ktime_get()) - time;
nvdev_trace(device, "preinit completed in %lldus\n", time); nvdev_trace(device, "preinit completed in %lldus\n", time);
return 0; return 0;
......
...@@ -134,12 +134,20 @@ nvkm_fb_oneinit(struct nvkm_subdev *subdev) ...@@ -134,12 +134,20 @@ nvkm_fb_oneinit(struct nvkm_subdev *subdev)
return nvkm_mm_init(&fb->tags.mm, 0, 0, tags, 1); return nvkm_mm_init(&fb->tags.mm, 0, 0, tags, 1);
} }
static int int
nvkm_fb_init_scrub_vpr(struct nvkm_fb *fb) nvkm_fb_mem_unlock(struct nvkm_fb *fb)
{ {
struct nvkm_subdev *subdev = &fb->subdev; struct nvkm_subdev *subdev = &fb->subdev;
int ret; int ret;
if (!fb->func->vpr.scrub_required)
return 0;
if (!fb->func->vpr.scrub_required(fb)) {
nvkm_debug(subdev, "VPR not locked\n");
return 0;
}
nvkm_debug(subdev, "VPR locked, running scrubber binary\n"); nvkm_debug(subdev, "VPR locked, running scrubber binary\n");
if (!fb->vpr_scrubber.size) { if (!fb->vpr_scrubber.size) {
...@@ -194,13 +202,6 @@ nvkm_fb_init(struct nvkm_subdev *subdev) ...@@ -194,13 +202,6 @@ nvkm_fb_init(struct nvkm_subdev *subdev)
if (fb->func->init_unkn) if (fb->func->init_unkn)
fb->func->init_unkn(fb); fb->func->init_unkn(fb);
if (fb->func->vpr.scrub_required &&
fb->func->vpr.scrub_required(fb)) {
ret = nvkm_fb_init_scrub_vpr(fb);
if (ret)
return ret;
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment