From patchwork Thu Mar 3 23:34:53 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilija Hadzic X-Patchwork-Id: 607491 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p23NggVK014430 for ; Thu, 3 Mar 2011 23:43:02 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C19D09E988 for ; Thu, 3 Mar 2011 15:42:36 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 03 Mar 2011 23:43:02 +0000 (UTC) X-Greylist: delayed 453 seconds by postgrey-1.31 at gabe; Thu, 03 Mar 2011 15:42:28 PST Received: from ihemail2.lucent.com (ihemail2.lucent.com [135.245.0.35]) by gabe.freedesktop.org (Postfix) with ESMTP id 30AA79E744 for ; Thu, 3 Mar 2011 15:42:28 -0800 (PST) Received: from umail.lucent.com (h135-3-40-63.lucent.com [135.3.40.63]) by ihemail2.lucent.com (8.13.8/IER-o) with ESMTP id p23NYrLc018157 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 3 Mar 2011 17:34:53 -0600 (CST) Received: from umail-ce2 (umail-ce2 [135.3.40.63]) by umail.lucent.com (8.13.8/TPES) with ESMTP id p23NYrRR018272 for ; Thu, 3 Mar 2011 17:34:53 -0600 (CST) Date: Thu, 3 Mar 2011 17:34:53 -0600 (CST) From: Ilija Hadzic X-X-Sender: ihadzic@umail To: dri-devel@lists.freedesktop.org Subject: vblank problem (and proposed fix) on crtc > 1 Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.57 on 135.245.2.35 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 16d5155..3b0abae 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -668,7 +668,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; @@ -677,16 +677,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 e5f7061..d950581 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 | \ ------------------------------- libdrm patch ----------------------------------- diff --git a/xf86drm.h b/xf86drm.h index 9b89f56..65a68bf 100644 --- a/xf86drm.h +++ b/xf86drm.h @@ -302,6 +302,8 @@ typedef enum { DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */ } drmVBlankSeqType; +#define DRM_VBLANK_HIGH_CRTC_SHIFT 16 +#define DRM_VBLANK_HIGH_CRTC_MASK 0x001F0000 typedef struct _drmVBlankReq { drmVBlankSeqType type; ------------------------------- xf86-video-ati (DDX) patch --------------------- diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 66df03c..5cbe544 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -783,6 +783,7 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) drmVBlank vbl; int ret; int crtc = radeon_dri2_drawable_crtc(draw); + int high_crtc = 0; /* Drawable not displayed, make up a value */ if (crtc == -1) { @@ -791,8 +792,12 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) return TRUE; } vbl.request.type = DRM_VBLANK_RELATIVE; - if (crtc > 0) + if (crtc == 1) vbl.request.type |= DRM_VBLANK_SECONDARY; + else if (crtc > 1) + high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK; + vbl.request.type |= high_crtc; vbl.request.sequence = 0; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); @@ -825,6 +830,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, drmVBlank vbl; int ret, crtc = radeon_dri2_drawable_crtc(draw); CARD64 current_msc; + int high_crtc = 0; /* Truncate to match kernel interfaces; means occasional overflow * misses, but that's generally not a big deal */ @@ -855,8 +861,12 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, /* Get current count */ vbl.request.type = DRM_VBLANK_RELATIVE; - if (crtc > 0) + if (crtc == 1) vbl.request.type |= DRM_VBLANK_SECONDARY; + else if (crtc > 1) + high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK; + vbl.request.type |= high_crtc; vbl.request.sequence = 0; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { @@ -882,8 +892,12 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, if (current_msc >= target_msc) target_msc = current_msc; vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; - if (crtc > 0) + if (crtc == 1) vbl.request.type |= DRM_VBLANK_SECONDARY; + else if (crtc > 1) + high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK; + vbl.request.type |= high_crtc; vbl.request.sequence = target_msc; vbl.request.signal = (unsigned long)wait_info; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); @@ -903,8 +917,12 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, * so we queue an event that will satisfy the divisor/remainder equation. */ vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; - if (crtc > 0) + if (crtc == 1) vbl.request.type |= DRM_VBLANK_SECONDARY; + else if (crtc > 1) + high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK; + vbl.request.type |= high_crtc; vbl.request.sequence = current_msc - (current_msc % divisor) + remainder; @@ -1029,6 +1047,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, CARD64 current_msc; BoxRec box; RegionRec region; + int high_crtc = 0; /* Truncate to match kernel interfaces; means occasional overflow * misses, but that's generally not a big deal */ @@ -1068,8 +1087,12 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, /* Get current count */ vbl.request.type = DRM_VBLANK_RELATIVE; - if (crtc > 0) + if (crtc == 1) vbl.request.type |= DRM_VBLANK_SECONDARY; + else if (crtc > 1) + high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK; + vbl.request.type |= high_crtc; vbl.request.sequence = 0; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { @@ -1111,8 +1134,12 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, */ if (flip == 0) vbl.request.type |= DRM_VBLANK_NEXTONMISS; - if (crtc > 0) + if (crtc == 1) vbl.request.type |= DRM_VBLANK_SECONDARY; + else if (crtc > 1) + high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK; + vbl.request.type |= high_crtc; /* If target_msc already reached or passed, set it to * current_msc to ensure we return a reasonable value back @@ -1145,8 +1172,12 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; if (flip == 0) vbl.request.type |= DRM_VBLANK_NEXTONMISS; - if (crtc > 0) + if (crtc == 1) vbl.request.type |= DRM_VBLANK_SECONDARY; + else if (crtc > 1) + high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK; + vbl.request.type |= high_crtc; vbl.request.sequence = current_msc - (current_msc % divisor) + remainder;