Blob Blame History Raw
From: Mario Kleiner <mario.kleiner.de@gmail.com>
Date: Mon, 16 Jul 2018 16:47:50 +1000
Subject: drm/nouveau/kms/nv50-: Allow vblank_disable_immediate
Git-commit: 2ae4c5f6ff7310e4dcaca4378ddadd881d176693
Patch-mainline: v4.19-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

With instantaneous high precision vblank timestamping
that updates at leading edge of vblank, the emulated
"hw vblank counter" from vblank timestamping, which
increments at leading edge of vblank, and reliable
page flip execution and completion at leading edge of
vblank, we should meet the requirements for fast/
immediate vblank irq disable/enable.

This is only allowed on nv50+ gpu's, ie. the ones with
atomic modesetting. One requirement for immediate vblank
disable is that high precision vblank timestamping works
reliably all the time on all connectors. This is not the
case on all pre-nv50 parts for analog VGA outputs, where we
currently don't always have support for scanout position
queries and therefore fall back to vblank interrupt
timestamping. The implementation in nv04_head_state() does
not return valid values for vblanks, vtotal, hblanks, htotal
for VGA outputs on all cards, but those are needed for scanout
position queries.

Testing on Linux-4.12-rc5 + drm-next on a GeForce 9500 GT
(NV G96) with timing measurement equipment indicates this
works fine, so allow immediate vblank disable for power
saving.

For debugging in case of unexpected trouble, booting
with kernel cmdline option drm.vblankoffdelay=0
(or echo 0 > /sys/module/drm/parameters/vblankoffdelay)
would keep vblank irqs permanently on to approximate old
behavior.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -2232,6 +2232,9 @@ nv50_display_create(struct drm_device *d
 		connector->funcs->destroy(connector);
 	}
 
+	/* Disable vblank irqs aggressively for power-saving, safe on nv50+ */
+	dev->vblank_disable_immediate = true;
+
 out:
 	if (ret)
 		nv50_display_destroy(dev);