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

Commit 19b01b5f authored by Ilija Hadzic's avatar Ilija Hadzic Committed by Dave Airlie
Browse files

drm/kernel: vblank wait on crtc > 1

Below is a patch against drm-next branch of 2.6.38-rc8+ kernel that adds
the capability to wait on vblank events for CRTCs that are greater than 1
and thus cannot be represented with primary/secondary flags in the legacy
interface. It was discussed on the dri-devel list in these two threads:

http://lists.freedesktop.org/archives/dri-devel/2011-March/009009.html
http://lists.freedesktop.org/archives/dri-devel/2011-March/009025.html



This patch extends the interface to drm_wait_vblank ioctl so that crtc>1
can be represented. It also adds a new capability to drm_getcap ioctl so
that the user space can check whether the new interface to drm_wait_vblank
is supported (and fall back to the legacy interface if not)

Signed-off-by: default avatarIlija Hadzic <ihadzic@research.bell-labs.com>
Reviewed-by: Mario Kleiner <mario.kleiner at tuebingen.mpg.de>
Acked-by: Mario Kleiner <mario.kleiner at tuebingen.mpg.de>
Reviewed-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Tested-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent b74ad5ae
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -280,6 +280,9 @@ int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
		if (dev->driver->dumb_create)
			req->value = 1;
		break;
	case DRM_CAP_HIGH_CRTC:
		req->value = 1;
		break;
	default:
		return -EINVAL;
	}
+10 −5
Original line number Diff line number Diff line
@@ -1125,7 +1125,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
{
	union drm_wait_vblank *vblwait = data;
	int ret = 0;
	unsigned int flags, seq, crtc;
	unsigned int flags, seq, crtc, high_crtc;

	if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled))
		return -EINVAL;
@@ -1134,16 +1134,21 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
		return -EINVAL;

	if (vblwait->request.type &
	    ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) {
	    ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK |
	      _DRM_VBLANK_HIGH_CRTC_MASK)) {
		DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n",
			  vblwait->request.type,
			  (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK));
			  (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK |
			   _DRM_VBLANK_HIGH_CRTC_MASK));
		return -EINVAL;
	}

	flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
	high_crtc = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK);
	if (high_crtc)
		crtc = high_crtc >> _DRM_VBLANK_HIGH_CRTC_SHIFT;
	else
		crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;

	if (crtc >= dev->num_crtcs)
		return -EINVAL;

+3 −0
Original line number Diff line number Diff line
@@ -469,6 +469,8 @@ enum drm_vblank_seq_type {
	_DRM_VBLANK_SECONDARY = 0x20000000,	/**< Secondary display controller */
	_DRM_VBLANK_SIGNAL = 0x40000000	/**< Send signal instead of blocking, unsupported */
};
#define _DRM_VBLANK_HIGH_CRTC_SHIFT 16
#define _DRM_VBLANK_HIGH_CRTC_MASK 0x001F0000

#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \
@@ -753,6 +755,7 @@ struct drm_event_vblank {
};

#define DRM_CAP_DUMB_BUFFER 0x1
#define DRM_CAP_HIGH_CRTC 0x2

/* typedef area */
#ifndef __KERNEL__