On Fri, Mar 18, 2011 at 5:58 PM, Ilija Hadzic <ihadzic at 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>
Ilija, please add your signed-off-by. Alex > > 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__ >