From patchwork Tue Oct 23 18:53:26 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 1632151 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id C5F103FD85 for ; Tue, 23 Oct 2012 18:57:38 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0C0D69F6BE for ; Tue, 23 Oct 2012 11:57:38 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [143.182.124.37]) by gabe.freedesktop.org (Postfix) with ESMTP id 2EF189F651; Tue, 23 Oct 2012 11:53:37 -0700 (PDT) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 23 Oct 2012 11:53:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.80,637,1344236400"; d="scan'208";a="208099017" Received: from ideak-desk.fi.intel.com (HELO localhost) ([10.237.72.98]) by azsmga001.ch.intel.com with ESMTP; 23 Oct 2012 11:53:34 -0700 From: Imre Deak To: Daniel Vetter , Chris Wilson , krh@freedesktop.org, Mario Kleiner , =?UTF-8?q?Michel=20D=C3=A4nzer?= Subject: [PATCH 2/2] drm: add support for monotonic vblank timestamps Date: Tue, 23 Oct 2012 21:53:26 +0300 Message-Id: <1351018407-7009-3-git-send-email-imre.deak@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1351018407-7009-1-git-send-email-imre.deak@intel.com> References: <1351018407-7009-1-git-send-email-imre.deak@intel.com> In-Reply-To: <1349444222-22274-1-git-send-email-imre.deak@intel.com> References: <1349444222-22274-1-git-send-email-imre.deak@intel.com> Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 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 Jumps in the vblank and page flip event timestamps cause trouble for clients, so we should avoid them. The timestamp we get currently with gettimeofday can jump, so use instead monotonic timestamps. For backward compatibility use a module flag to revert back to using gettimeofday timestamps. Add also a DRM_CAP_TIMESTAMP_MONOTONIC flag that is simply a read only version of the module flag, so that clients can query this without depending on sysfs. Signed-off-by: Imre Deak --- drivers/gpu/drm/drm_ioctl.c | 3 +++ drivers/gpu/drm/drm_irq.c | 25 ++++++++++++++++++++----- drivers/gpu/drm/drm_stub.c | 8 ++++++++ include/drm/drmP.h | 1 + include/uapi/drm/drm.h | 1 + 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 23dd975..e77bd8b 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -287,6 +287,9 @@ int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv) req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0; req->value |= dev->driver->prime_handle_to_fd ? DRM_PRIME_CAP_EXPORT : 0; break; + case DRM_CAP_TIMESTAMP_MONOTONIC: + req->value = drm_timestamp_monotonic; + break; default: return -EINVAL; } diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 7dc203d..37e58df7 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -633,7 +633,8 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, /* Get system timestamp after query. */ etime = ktime_get(); - mono_time_offset = ktime_get_monotonic_offset(); + if (!drm_timestamp_monotonic) + mono_time_offset = ktime_get_monotonic_offset(); preempt_enable(); @@ -691,7 +692,9 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, vbl_status |= 0x8; } - etime = ktime_sub(etime, mono_time_offset); + if (!drm_timestamp_monotonic) + etime = ktime_sub(etime, mono_time_offset); + /* save this only for debugging purposes */ tv_etime = ktime_to_timeval(etime); /* Subtract time delta from raw timestamp to get final @@ -714,6 +717,17 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, } EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); +static struct timeval get_drm_timestamp(void) +{ + ktime_t now; + + now = ktime_get(); + if (!drm_timestamp_monotonic) + now = ktime_sub(now, ktime_get_monotonic_offset()); + + return ktime_to_timeval(now); +} + /** * drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent * vblank interval. @@ -751,9 +765,9 @@ u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, } /* GPU high precision timestamp query unsupported or failed. - * Return gettimeofday timestamp as best estimate. + * Return current monotonic/gettimeofday timestamp as best estimate. */ - do_gettimeofday(tvblank); + *tvblank = get_drm_timestamp(); return 0; } @@ -842,7 +856,8 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc, seq = drm_vblank_count_and_time(dev, crtc, &now); } else { seq = 0; - do_gettimeofday(&now); + + now = get_drm_timestamp(); } send_vblank_event(dev, e, seq, &now); } diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index c236fd2..4433453 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -46,16 +46,24 @@ EXPORT_SYMBOL(drm_vblank_offdelay); unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ EXPORT_SYMBOL(drm_timestamp_precision); +/* + * Default to use monotonic timestamps for wait-for-vblank and page-flip + * complete events. + */ +unsigned int drm_timestamp_monotonic = 1; + MODULE_AUTHOR(CORE_AUTHOR); MODULE_DESCRIPTION(CORE_DESC); MODULE_LICENSE("GPL and additional rights"); MODULE_PARM_DESC(debug, "Enable debug output"); MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]"); MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); +MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps"); module_param_named(debug, drm_debug, int, 0600); module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); +module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); struct idr drm_minors_idr; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 29eb237..fad21c9 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1505,6 +1505,7 @@ extern unsigned int drm_debug; extern unsigned int drm_vblank_offdelay; extern unsigned int drm_timestamp_precision; +extern unsigned int drm_timestamp_monotonic; extern struct class *drm_class; extern struct proc_dir_entry *drm_proc_root; diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 1e3481e..8d1e2bb 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -778,6 +778,7 @@ struct drm_event_vblank { #define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3 #define DRM_CAP_DUMB_PREFER_SHADOW 0x4 #define DRM_CAP_PRIME 0x5 +#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 #define DRM_PRIME_CAP_IMPORT 0x1 #define DRM_PRIME_CAP_EXPORT 0x2