Skip to content

Commit e3f3249

Browse files
author
Ben Skeggs
committed
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 <[email protected]> Reviewed-by: Lyude Paul <[email protected]>
1 parent 5728d06 commit e3f3249

File tree

3 files changed

+16
-9
lines changed
  • drivers/gpu/drm/nouveau

3 files changed

+16
-9
lines changed

drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ struct nvkm_fb {
5858
struct nvkm_memory *mmu_wr;
5959
};
6060

61+
int nvkm_fb_mem_unlock(struct nvkm_fb *);
62+
6163
void nvkm_fb_tile_init(struct nvkm_fb *, int region, u32 addr, u32 size,
6264
u32 pitch, u32 flags, struct nvkm_fb_tile *);
6365
void nvkm_fb_tile_fini(struct nvkm_fb *, int region, struct nvkm_fb_tile *);

drivers/gpu/drm/nouveau/nvkm/engine/device/base.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2808,6 +2808,10 @@ nvkm_device_preinit(struct nvkm_device *device)
28082808
if (ret)
28092809
goto fail;
28102810

2811+
ret = nvkm_fb_mem_unlock(device->fb);
2812+
if (ret)
2813+
goto fail;
2814+
28112815
time = ktime_to_us(ktime_get()) - time;
28122816
nvdev_trace(device, "preinit completed in %lldus\n", time);
28132817
return 0;

drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,20 @@ nvkm_fb_oneinit(struct nvkm_subdev *subdev)
134134
return nvkm_mm_init(&fb->tags.mm, 0, 0, tags, 1);
135135
}
136136

137-
static int
138-
nvkm_fb_init_scrub_vpr(struct nvkm_fb *fb)
137+
int
138+
nvkm_fb_mem_unlock(struct nvkm_fb *fb)
139139
{
140140
struct nvkm_subdev *subdev = &fb->subdev;
141141
int ret;
142142

143+
if (!fb->func->vpr.scrub_required)
144+
return 0;
145+
146+
if (!fb->func->vpr.scrub_required(fb)) {
147+
nvkm_debug(subdev, "VPR not locked\n");
148+
return 0;
149+
}
150+
143151
nvkm_debug(subdev, "VPR locked, running scrubber binary\n");
144152

145153
if (!fb->vpr_scrubber.size) {
@@ -194,13 +202,6 @@ nvkm_fb_init(struct nvkm_subdev *subdev)
194202
if (fb->func->init_unkn)
195203
fb->func->init_unkn(fb);
196204

197-
if (fb->func->vpr.scrub_required &&
198-
fb->func->vpr.scrub_required(fb)) {
199-
ret = nvkm_fb_init_scrub_vpr(fb);
200-
if (ret)
201-
return ret;
202-
}
203-
204205
return 0;
205206
}
206207

0 commit comments

Comments
 (0)