Commit 1f6d2de2 authored by Francisco Jerez's avatar Francisco Jerez Committed by Ben Skeggs
Browse files

drm/nv50: Keep track of the head a channel is vsync'ing to.



In a multihead setup vblank interrupts may end up enabled in both
heads. In that case we want to ignore the vblank interrupts coming
from the wrong CRTC to avoid tearing and unbalanced calls to
drm_vblank_get/put (fdo bug 31074).

Reported-by: default avatarFelix Leimbach <felix.leimbach@gmx.net>
Signed-off-by: default avatarFrancisco Jerez <currojerez@riseup.net>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 1c180fa5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -257,6 +257,7 @@ struct nouveau_channel {

	struct {
		struct nouveau_gpuobj *vblsem;
		uint32_t vblsem_head;
		uint32_t vblsem_offset;
		uint32_t vblsem_rval;
		struct list_head vbl_wait;
+3 −0
Original line number Diff line number Diff line
@@ -432,6 +432,9 @@ nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc)

	list_for_each_entry_safe(chan, tmp, &dev_priv->vbl_waiting,
				 nvsw.vbl_wait) {
		if (chan->nvsw.vblsem_head != crtc)
			continue;

		nouveau_bo_wr32(chan->notifier_bo, chan->nvsw.vblsem_offset,
						chan->nvsw.vblsem_rval);
		list_del(&chan->nvsw.vbl_wait);
+3 −0
Original line number Diff line number Diff line
@@ -387,7 +387,10 @@ nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan,
		return -EINVAL;

	drm_vblank_get(dev, data);

	chan->nvsw.vblsem_head = data;
	list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting);

	return 0;
}