The DRM core exposes two vertical blank related ioctls:
This takes a struct drm_wait_vblank structure as its argument, and it is used to block or request a signal when a specified vblank event occurs.
This should be called by application level drivers before and after mode setting, since on many devices the vertical blank counter is reset at that time. Internally, the DRM snapshots the last vblank count when the ioctl is called with the _DRM_PRE_MODESET command, so that the counter won't go backwards (which is dealt with when _DRM_POST_MODESET is used).
To support the functions above, the DRM core provides several helper functions for tracking vertical blank counters, and requires drivers to provide several callbacks: get_vblank_counter(), enable_vblank() and disable_vblank(). The core uses get_vblank_counter() to keep the counter accurate across interrupt disable periods. It should return the current vertical blank event count, which is often tracked in a device register. The enable and disable vblank callbacks should enable and disable vertical blank interrupts, respectively. In the absence of DRM clients waiting on vblank events, the core DRM code uses the disable_vblank() function to disable interrupts, which saves power. They are re-enabled again when a client calls the vblank wait ioctl above.
A device that doesn't provide a count register may simply use an internal atomic counter incremented on every vertical blank interrupt (and then treat the enable_vblank() and disable_vblank() callbacks as no-ops).