Skip to content

Commit

Permalink
drm/nouveau/fb/gp102-: unlock VPR right after devinit
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ben Skeggs committed Nov 9, 2022
1 parent 5728d06 commit e3f3249
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 9 deletions.
2 changes: 2 additions & 0 deletions drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
19 changes: 10 additions & 9 deletions drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit e3f3249

Please sign in to comment.