Commit e3f32495 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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 *);
+4 −0
Original line number Diff line number Diff line
@@ -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;
+10 −9
Original line number Diff line number Diff line
@@ -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;
}