Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4d5907f7 authored by Ben Skeggs's avatar Ben Skeggs Committed by Greg Kroah-Hartman
Browse files

drm/nouveau/kms/nv50-: also flush fb writes when rewinding push buffer



commit 970a5ee41c72df46e3b0f307528c7d8ef7734a2e upstream.

Should hopefully fix a regression some people have been seeing since EVO
push buffers were moved to VRAM by default on Pascal GPUs.

Fixes: d00ddd9d ("drm/nouveau/kms/nv50-: allocate push buffers in vidmem on pascal")
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Cc: <stable@vger.kernel.org> # 4.19+
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d7fde95b
Loading
Loading
Loading
Loading
+18 −11
Original line number Diff line number Diff line
@@ -197,6 +197,22 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
/******************************************************************************
 * EVO channel helpers
 *****************************************************************************/
static void
evo_flush(struct nv50_dmac *dmac)
{
	/* Push buffer fetches are not coherent with BAR1, we need to ensure
	 * writes have been flushed right through to VRAM before writing PUT.
	 */
	if (dmac->push.type & NVIF_MEM_VRAM) {
		struct nvif_device *device = dmac->base.device;
		nvif_wr32(&device->object, 0x070000, 0x00000001);
		nvif_msec(device, 2000,
			if (!(nvif_rd32(&device->object, 0x070000) & 0x00000002))
				break;
		);
	}
}

u32 *
evo_wait(struct nv50_dmac *evoc, int nr)
{
@@ -207,6 +223,7 @@ evo_wait(struct nv50_dmac *evoc, int nr)
	mutex_lock(&dmac->lock);
	if (put + nr >= (PAGE_SIZE / 4) - 8) {
		dmac->ptr[put] = 0x20000000;
		evo_flush(dmac);

		nvif_wr32(&dmac->base.user, 0x0000, 0x00000000);
		if (nvif_msec(device, 2000,
@@ -229,17 +246,7 @@ evo_kick(u32 *push, struct nv50_dmac *evoc)
{
	struct nv50_dmac *dmac = evoc;

	/* Push buffer fetches are not coherent with BAR1, we need to ensure
	 * writes have been flushed right through to VRAM before writing PUT.
	 */
	if (dmac->push.type & NVIF_MEM_VRAM) {
		struct nvif_device *device = dmac->base.device;
		nvif_wr32(&device->object, 0x070000, 0x00000001);
		nvif_msec(device, 2000,
			if (!(nvif_rd32(&device->object, 0x070000) & 0x00000002))
				break;
		);
	}
	evo_flush(dmac);

	nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2);
	mutex_unlock(&dmac->lock);