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

Commit ab285d74 authored by Michel Dänzer's avatar Michel Dänzer Committed by airlied
Browse files

drm: Core vsync: Add flag DRM_VBLANK_NEXTONMISS.



When this flag is set and the target sequence is missed, wait for the next
vertical blank instead of returning immediately.

Signed-off-by: default avatarDave Airlie <airlied@linux.ie>
parent 8163e418
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -487,12 +487,14 @@ typedef struct drm_irq_busid {
typedef enum {
	_DRM_VBLANK_ABSOLUTE = 0x0,	/**< Wait for specific vblank sequence number */
	_DRM_VBLANK_RELATIVE = 0x1,	/**< Wait for given number of vblanks */
	_DRM_VBLANK_NEXTONMISS = 0x10000000,	/**< If missed, wait for next vblank */
	_DRM_VBLANK_SECONDARY = 0x20000000,	/**< Secondary display controller */
	_DRM_VBLANK_SIGNAL = 0x40000000	/**< Send signal instead of blocking */
} drm_vblank_seq_type_t;

#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY)
#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \
				_DRM_VBLANK_NEXTONMISS)

struct drm_wait_vblank_request {
	drm_vblank_seq_type_t type;
+10 −6
Original line number Diff line number Diff line
@@ -250,8 +250,7 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
	drm_wait_vblank_t vblwait;
	struct timeval now;
	int ret = 0;
	unsigned int flags;
	atomic_t *seq;
	unsigned int flags, seq;

	if (!dev->irq)
		return -EINVAL;
@@ -273,12 +272,12 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
				    DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
		return -EINVAL;

	seq = (flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 :
	      &dev->vbl_received;
	seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2
			  : &dev->vbl_received);

	switch (vblwait.request.type & _DRM_VBLANK_TYPES_MASK) {
	case _DRM_VBLANK_RELATIVE:
		vblwait.request.sequence += atomic_read(seq);
		vblwait.request.sequence += seq;
		vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
	case _DRM_VBLANK_ABSOLUTE:
		break;
@@ -286,13 +285,18 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
		return -EINVAL;
	}

	if ((flags & _DRM_VBLANK_NEXTONMISS) &&
	    (seq - vblwait.request.sequence) <= (1<<23)) {
		vblwait.request.sequence = seq + 1;
	}

	if (flags & _DRM_VBLANK_SIGNAL) {
		unsigned long irqflags;
		drm_vbl_sig_t *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY)
				      ? &dev->vbl_sigs2 : &dev->vbl_sigs;
		drm_vbl_sig_t *vbl_sig;

		vblwait.reply.sequence = atomic_read(seq);
		vblwait.reply.sequence = seq;

		spin_lock_irqsave(&dev->vbl_lock, irqflags);