[PATCH] kernel/drm: vblank wait on crtc > 1

Ilija Hadzic ihadzic at research.bell-labs.com
Fri Mar 18 14:58:04 PDT 2011


Hi Dave,

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)

Regards,

Ilija


Reviewed-by: Mario Kleiner <mario.kleiner at tuebingen.mpg.de>
Acked-by: Mario Kleiner <mario.kleiner at tuebingen.mpg.de>

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 7f6912a..3617b4c 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -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;
  	}
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index a34ef97..c725088 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -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;
-	crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
-
+	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;

diff --git a/include/drm/drm.h b/include/drm/drm.h
index 9ac4313..99cd074 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -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__


More information about the dri-devel mailing list