On Sat, 19 Mar 2011, Alex Deucher wrote:
On Fri, Mar 18, 2011 at 5:58 PM, Ilija Hadzic ihadzic@research.bell-labs.com wrote:
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>
Looks good to me.
Reviewed-by: Alex Deucher alexdeucher@gmail.com Tested-by: Alex Deucher alexdeucher@gmail.com
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com
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__