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: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
This commit is contained in:
Ben Skeggs 2022-06-01 20:47:52 +10:00
parent 5728d06419
commit e3f324956a
3 changed files with 16 additions and 9 deletions

View File

@ -58,6 +58,8 @@ struct nvkm_fb {
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,
u32 pitch, u32 flags, struct nvkm_fb_tile *);
void nvkm_fb_tile_fini(struct nvkm_fb *, int region, struct nvkm_fb_tile *);

View File

@ -2808,6 +2808,10 @@ nvkm_device_preinit(struct nvkm_device *device)
if (ret)
goto fail;
ret = nvkm_fb_mem_unlock(device->fb);
if (ret)
goto fail;
time = ktime_to_us(ktime_get()) - time;
nvdev_trace(device, "preinit completed in %lldus\n", time);
return 0;

View File

@ -134,12 +134,20 @@ nvkm_fb_oneinit(struct nvkm_subdev *subdev)
return nvkm_mm_init(&fb->tags.mm, 0, 0, tags, 1);
}
static int
nvkm_fb_init_scrub_vpr(struct nvkm_fb *fb)
int
nvkm_fb_mem_unlock(struct nvkm_fb *fb)
{
struct nvkm_subdev *subdev = &fb->subdev;
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");
if (!fb->vpr_scrubber.size) {
@ -194,13 +202,6 @@ nvkm_fb_init(struct nvkm_subdev *subdev)
if (fb->func->init_unkn)
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;
}