Source
/*
* drm_irq.c IRQ and vblank support
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* DOC: vblank handling
*
* Vertical blanking plays a major role in graphics rendering. To achieve
* tear-free display, users must synchronize page flips and/or rendering to
* vertical blanking. The DRM API offers ioctls to perform page flips
* synchronized to vertical blanking and wait for vertical blanking.
*
* The DRM core handles most of the vertical blanking management logic, which
* involves filtering out spurious interrupts, keeping race-free blanking
* counters, coping with counter wrap-around and resets and keeping use counts.
* It relies on the driver to generate vertical blanking interrupts and
* optionally provide a hardware vertical blanking counter.
*
* Drivers must initialize the vertical blanking handling core with a call to
* drm_vblank_init(). Minimally, a driver needs to implement
* &drm_crtc_funcs.enable_vblank and &drm_crtc_funcs.disable_vblank plus call
* drm_crtc_handle_vblank() in its vblank interrupt handler for working vblank
* support.
*
* Vertical blanking interrupts can be enabled by the DRM core or by drivers
* themselves (for instance to handle page flipping operations). The DRM core
* maintains a vertical blanking use count to ensure that the interrupts are not
* disabled while a user still needs them. To increment the use count, drivers
* call drm_crtc_vblank_get() and release the vblank reference again with
* drm_crtc_vblank_put(). In between these two calls vblank interrupts are
* guaranteed to be enabled.
*
* On many hardware disabling the vblank interrupt cannot be done in a race-free
* manner, see &drm_driver.vblank_disable_immediate and
* &drm_driver.max_vblank_count. In that case the vblank core only disables the
* vblanks after a timer has expired, which can be configured through the
* ``vblankoffdelay`` module parameter.
*/
/* Retry timestamp calculation up to 3 times to satisfy
* drm_timestamp_precision before giving up.
*/
/* Threshold in nanoseconds for detection of redundant
* vblank irq in drm_handle_vblank(). 1 msec should be ok.
*/
static bool
drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
ktime_t *tvblank, bool in_vblank_irq);
static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */
static int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */
module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600);
module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600);
MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (0: never disable, <0: disable immediately)");
MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
static void store_vblank(struct drm_device *dev, unsigned int pipe,