13ed4351aSDaniel Vetter /* 23ed4351aSDaniel Vetter * Copyright 2016 Intel Corp. 33ed4351aSDaniel Vetter * 43ed4351aSDaniel Vetter * Permission is hereby granted, free of charge, to any person obtaining a 53ed4351aSDaniel Vetter * copy of this software and associated documentation files (the "Software"), 63ed4351aSDaniel Vetter * to deal in the Software without restriction, including without limitation 73ed4351aSDaniel Vetter * the rights to use, copy, modify, merge, publish, distribute, sublicense, 83ed4351aSDaniel Vetter * and/or sell copies of the Software, and to permit persons to whom the 93ed4351aSDaniel Vetter * Software is furnished to do so, subject to the following conditions: 103ed4351aSDaniel Vetter * 113ed4351aSDaniel Vetter * The above copyright notice and this permission notice (including the next 123ed4351aSDaniel Vetter * paragraph) shall be included in all copies or substantial portions of the 133ed4351aSDaniel Vetter * Software. 143ed4351aSDaniel Vetter * 153ed4351aSDaniel Vetter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 163ed4351aSDaniel Vetter * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 173ed4351aSDaniel Vetter * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 183ed4351aSDaniel Vetter * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 193ed4351aSDaniel Vetter * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 203ed4351aSDaniel Vetter * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 213ed4351aSDaniel Vetter * OTHER DEALINGS IN THE SOFTWARE. 223ed4351aSDaniel Vetter */ 233ed4351aSDaniel Vetter 243ed4351aSDaniel Vetter #ifndef _DRM_VBLANK_H_ 253ed4351aSDaniel Vetter #define _DRM_VBLANK_H_ 263ed4351aSDaniel Vetter 273ed4351aSDaniel Vetter #include <linux/seqlock.h> 283ed4351aSDaniel Vetter #include <linux/idr.h> 293ed4351aSDaniel Vetter #include <linux/poll.h> 303ed4351aSDaniel Vetter 313ed4351aSDaniel Vetter #include <drm/drm_file.h> 323ed4351aSDaniel Vetter #include <drm/drm_modes.h> 333ed4351aSDaniel Vetter 343ed4351aSDaniel Vetter struct drm_device; 353ed4351aSDaniel Vetter struct drm_crtc; 363ed4351aSDaniel Vetter 373ed4351aSDaniel Vetter /** 383ed4351aSDaniel Vetter * struct drm_pending_vblank_event - pending vblank event tracking 393ed4351aSDaniel Vetter */ 403ed4351aSDaniel Vetter struct drm_pending_vblank_event { 413ed4351aSDaniel Vetter /** 423ed4351aSDaniel Vetter * @base: Base structure for tracking pending DRM events. 433ed4351aSDaniel Vetter */ 443ed4351aSDaniel Vetter struct drm_pending_event base; 453ed4351aSDaniel Vetter /** 463ed4351aSDaniel Vetter * @pipe: drm_crtc_index() of the &drm_crtc this event is for. 473ed4351aSDaniel Vetter */ 483ed4351aSDaniel Vetter unsigned int pipe; 493ed4351aSDaniel Vetter /** 50570e8696SKeith Packard * @sequence: frame event should be triggered at 51570e8696SKeith Packard */ 52570e8696SKeith Packard u64 sequence; 53570e8696SKeith Packard /** 543ed4351aSDaniel Vetter * @event: Actual event which will be sent to userspace. 553ed4351aSDaniel Vetter */ 56bd386e51SKeith Packard union { 5783a7dff0SDaniel Vetter /** 5883a7dff0SDaniel Vetter * @event.base: DRM event base class. 5983a7dff0SDaniel Vetter */ 60bd386e51SKeith Packard struct drm_event base; 6183a7dff0SDaniel Vetter 6283a7dff0SDaniel Vetter /** 6383a7dff0SDaniel Vetter * @event.vbl: 6483a7dff0SDaniel Vetter * 6583a7dff0SDaniel Vetter * Event payload for vblank events, requested through 6683a7dff0SDaniel Vetter * either the MODE_PAGE_FLIP or MODE_ATOMIC IOCTL. Also 6783a7dff0SDaniel Vetter * generated by the legacy WAIT_VBLANK IOCTL, but new userspace 6883a7dff0SDaniel Vetter * should use MODE_QUEUE_SEQUENCE and &event.seq instead. 6983a7dff0SDaniel Vetter */ 70bd386e51SKeith Packard struct drm_event_vblank vbl; 7183a7dff0SDaniel Vetter 7283a7dff0SDaniel Vetter /** 7383a7dff0SDaniel Vetter * @event.seq: Event payload for the MODE_QUEUEU_SEQUENCE IOCTL. 7483a7dff0SDaniel Vetter */ 753064abfaSKeith Packard struct drm_event_crtc_sequence seq; 76bd386e51SKeith Packard } event; 773ed4351aSDaniel Vetter }; 783ed4351aSDaniel Vetter 793ed4351aSDaniel Vetter /** 803ed4351aSDaniel Vetter * struct drm_vblank_crtc - vblank tracking for a CRTC 813ed4351aSDaniel Vetter * 823ed4351aSDaniel Vetter * This structure tracks the vblank state for one CRTC. 833ed4351aSDaniel Vetter * 843ed4351aSDaniel Vetter * Note that for historical reasons - the vblank handling code is still shared 853ed4351aSDaniel Vetter * with legacy/non-kms drivers - this is a free-standing structure not directly 863ed4351aSDaniel Vetter * connected to &struct drm_crtc. But all public interface functions are taking 873ed4351aSDaniel Vetter * a &struct drm_crtc to hide this implementation detail. 883ed4351aSDaniel Vetter */ 893ed4351aSDaniel Vetter struct drm_vblank_crtc { 903ed4351aSDaniel Vetter /** 913ed4351aSDaniel Vetter * @dev: Pointer to the &drm_device. 923ed4351aSDaniel Vetter */ 933ed4351aSDaniel Vetter struct drm_device *dev; 943ed4351aSDaniel Vetter /** 953ed4351aSDaniel Vetter * @queue: Wait queue for vblank waiters. 963ed4351aSDaniel Vetter */ 979e37ee79SDaniel Vetter wait_queue_head_t queue; 983ed4351aSDaniel Vetter /** 993ed4351aSDaniel Vetter * @disable_timer: Disable timer for the delayed vblank disabling 1003ed4351aSDaniel Vetter * hysteresis logic. Vblank disabling is controlled through the 1013ed4351aSDaniel Vetter * drm_vblank_offdelay module option and the setting of the 1023ed4351aSDaniel Vetter * &drm_device.max_vblank_count value. 1033ed4351aSDaniel Vetter */ 1043ed4351aSDaniel Vetter struct timer_list disable_timer; 1053ed4351aSDaniel Vetter 1063ed4351aSDaniel Vetter /** 1073ed4351aSDaniel Vetter * @seqlock: Protect vblank count and time. 1083ed4351aSDaniel Vetter */ 1099e37ee79SDaniel Vetter seqlock_t seqlock; 1103ed4351aSDaniel Vetter 1113ed4351aSDaniel Vetter /** 112bd7e3f3bSDaniel Vetter * @count: 113bd7e3f3bSDaniel Vetter * 114bd7e3f3bSDaniel Vetter * Current software vblank counter. 115bd7e3f3bSDaniel Vetter * 116bd7e3f3bSDaniel Vetter * Note that for a given vblank counter value drm_crtc_handle_vblank() 117bd7e3f3bSDaniel Vetter * and drm_crtc_vblank_count() or drm_crtc_vblank_count_and_time() 118bd7e3f3bSDaniel Vetter * provide a barrier: Any writes done before calling 119bd7e3f3bSDaniel Vetter * drm_crtc_handle_vblank() will be visible to callers of the later 120bd7e3f3bSDaniel Vetter * functions, iff the vblank count is the same or a later one. 121bd7e3f3bSDaniel Vetter * 122bd7e3f3bSDaniel Vetter * IMPORTANT: This guarantee requires barriers, therefor never access 123bd7e3f3bSDaniel Vetter * this field directly. Use drm_crtc_vblank_count() instead. 1243ed4351aSDaniel Vetter */ 125bd7e3f3bSDaniel Vetter atomic64_t count; 1263ed4351aSDaniel Vetter /** 1273ed4351aSDaniel Vetter * @time: Vblank timestamp corresponding to @count. 1283ed4351aSDaniel Vetter */ 12967680d3cSArnd Bergmann ktime_t time; 1303ed4351aSDaniel Vetter 1313ed4351aSDaniel Vetter /** 1323ed4351aSDaniel Vetter * @refcount: Number of users/waiters of the vblank interrupt. Only when 1333ed4351aSDaniel Vetter * this refcount reaches 0 can the hardware interrupt be disabled using 1343ed4351aSDaniel Vetter * @disable_timer. 1353ed4351aSDaniel Vetter */ 1369e37ee79SDaniel Vetter atomic_t refcount; 1373ed4351aSDaniel Vetter /** 1383ed4351aSDaniel Vetter * @last: Protected by &drm_device.vbl_lock, used for wraparound handling. 1393ed4351aSDaniel Vetter */ 1403ed4351aSDaniel Vetter u32 last; 1413ed4351aSDaniel Vetter /** 142ed20151aSVille Syrjälä * @max_vblank_count: 143ed20151aSVille Syrjälä * 144ed20151aSVille Syrjälä * Maximum value of the vblank registers for this crtc. This value +1 145ed20151aSVille Syrjälä * will result in a wrap-around of the vblank register. It is used 146ed20151aSVille Syrjälä * by the vblank core to handle wrap-arounds. 147ed20151aSVille Syrjälä * 148ed20151aSVille Syrjälä * If set to zero the vblank core will try to guess the elapsed vblanks 149ed20151aSVille Syrjälä * between times when the vblank interrupt is disabled through 150ed20151aSVille Syrjälä * high-precision timestamps. That approach is suffering from small 151ed20151aSVille Syrjälä * races and imprecision over longer time periods, hence exposing a 152ed20151aSVille Syrjälä * hardware vblank counter is always recommended. 153ed20151aSVille Syrjälä * 154ed20151aSVille Syrjälä * This is the runtime configurable per-crtc maximum set through 155ed20151aSVille Syrjälä * drm_crtc_set_max_vblank_count(). If this is used the driver 156ed20151aSVille Syrjälä * must leave the device wide &drm_device.max_vblank_count at zero. 157ed20151aSVille Syrjälä * 158ed20151aSVille Syrjälä * If non-zero, &drm_crtc_funcs.get_vblank_counter must be set. 159ed20151aSVille Syrjälä */ 160ed20151aSVille Syrjälä u32 max_vblank_count; 161ed20151aSVille Syrjälä /** 1623ed4351aSDaniel Vetter * @inmodeset: Tracks whether the vblank is disabled due to a modeset. 1633ed4351aSDaniel Vetter * For legacy driver bit 2 additionally tracks whether an additional 1643ed4351aSDaniel Vetter * temporary vblank reference has been acquired to paper over the 1653ed4351aSDaniel Vetter * hardware counter resetting/jumping. KMS drivers should instead just 1663ed4351aSDaniel Vetter * call drm_crtc_vblank_off() and drm_crtc_vblank_on(), which explicitly 1673ed4351aSDaniel Vetter * save and restore the vblank count. 1683ed4351aSDaniel Vetter */ 1699e37ee79SDaniel Vetter unsigned int inmodeset; 1703ed4351aSDaniel Vetter /** 1713ed4351aSDaniel Vetter * @pipe: drm_crtc_index() of the &drm_crtc corresponding to this 1723ed4351aSDaniel Vetter * structure. 1733ed4351aSDaniel Vetter */ 1743ed4351aSDaniel Vetter unsigned int pipe; 1753ed4351aSDaniel Vetter /** 1763ed4351aSDaniel Vetter * @framedur_ns: Frame/Field duration in ns, used by 1777fe3f0d1SThomas Zimmermann * drm_crtc_vblank_helper_get_vblank_timestamp() and computed by 1783ed4351aSDaniel Vetter * drm_calc_timestamping_constants(). 1793ed4351aSDaniel Vetter */ 1803ed4351aSDaniel Vetter int framedur_ns; 1813ed4351aSDaniel Vetter /** 1823ed4351aSDaniel Vetter * @linedur_ns: Line duration in ns, used by 1837fe3f0d1SThomas Zimmermann * drm_crtc_vblank_helper_get_vblank_timestamp() and computed by 1843ed4351aSDaniel Vetter * drm_calc_timestamping_constants(). 1853ed4351aSDaniel Vetter */ 1863ed4351aSDaniel Vetter int linedur_ns; 1873ed4351aSDaniel Vetter 1883ed4351aSDaniel Vetter /** 1893ed4351aSDaniel Vetter * @hwmode: 1903ed4351aSDaniel Vetter * 1913ed4351aSDaniel Vetter * Cache of the current hardware display mode. Only valid when @enabled 1923ed4351aSDaniel Vetter * is set. This is used by helpers like 1937fe3f0d1SThomas Zimmermann * drm_crtc_vblank_helper_get_vblank_timestamp(). We can't just access 1947fe3f0d1SThomas Zimmermann * the hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode, 1953ed4351aSDaniel Vetter * because that one is really hard to get from interrupt context. 1963ed4351aSDaniel Vetter */ 1973ed4351aSDaniel Vetter struct drm_display_mode hwmode; 1983ed4351aSDaniel Vetter 1993ed4351aSDaniel Vetter /** 2003ed4351aSDaniel Vetter * @enabled: Tracks the enabling state of the corresponding &drm_crtc to 2013ed4351aSDaniel Vetter * avoid double-disabling and hence corrupting saved state. Needed by 2023ed4351aSDaniel Vetter * drivers not using atomic KMS, since those might go through their CRTC 2033ed4351aSDaniel Vetter * disabling functions multiple times. 2043ed4351aSDaniel Vetter */ 2053ed4351aSDaniel Vetter bool enabled; 2063ed4351aSDaniel Vetter }; 2073ed4351aSDaniel Vetter 2083ed4351aSDaniel Vetter int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs); 2097beb691fSThomas Zimmermann bool drm_dev_has_vblank(const struct drm_device *dev); 210570e8696SKeith Packard u64 drm_crtc_vblank_count(struct drm_crtc *crtc); 211570e8696SKeith Packard u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, 21267680d3cSArnd Bergmann ktime_t *vblanktime); 2133ed4351aSDaniel Vetter void drm_crtc_send_vblank_event(struct drm_crtc *crtc, 2143ed4351aSDaniel Vetter struct drm_pending_vblank_event *e); 2153ed4351aSDaniel Vetter void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, 2163ed4351aSDaniel Vetter struct drm_pending_vblank_event *e); 217bd386e51SKeith Packard void drm_vblank_set_event(struct drm_pending_vblank_event *e, 218bd386e51SKeith Packard u64 *seq, 219bd386e51SKeith Packard ktime_t *now); 2203ed4351aSDaniel Vetter bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); 2213ed4351aSDaniel Vetter bool drm_crtc_handle_vblank(struct drm_crtc *crtc); 2223ed4351aSDaniel Vetter int drm_crtc_vblank_get(struct drm_crtc *crtc); 2233ed4351aSDaniel Vetter void drm_crtc_vblank_put(struct drm_crtc *crtc); 2243ed4351aSDaniel Vetter void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe); 2253ed4351aSDaniel Vetter void drm_crtc_wait_one_vblank(struct drm_crtc *crtc); 2263ed4351aSDaniel Vetter void drm_crtc_vblank_off(struct drm_crtc *crtc); 2273ed4351aSDaniel Vetter void drm_crtc_vblank_reset(struct drm_crtc *crtc); 2283ed4351aSDaniel Vetter void drm_crtc_vblank_on(struct drm_crtc *crtc); 2293b765c0bSDhinakaran Pandiyan u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc); 230d0bb96b4SDhinakaran Pandiyan void drm_vblank_restore(struct drm_device *dev, unsigned int pipe); 231d0bb96b4SDhinakaran Pandiyan void drm_crtc_vblank_restore(struct drm_crtc *crtc); 2323ed4351aSDaniel Vetter 2333ed4351aSDaniel Vetter bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, 2343ed4351aSDaniel Vetter unsigned int pipe, int *max_error, 23567680d3cSArnd Bergmann ktime_t *vblank_time, 2363ed4351aSDaniel Vetter bool in_vblank_irq); 2373ed4351aSDaniel Vetter void drm_calc_timestamping_constants(struct drm_crtc *crtc, 2383ed4351aSDaniel Vetter const struct drm_display_mode *mode); 2393ed4351aSDaniel Vetter wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc); 240ed20151aSVille Syrjälä void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc, 241ed20151aSVille Syrjälä u32 max_vblank_count); 242f1e2b637SThomas Zimmermann 2437fe3f0d1SThomas Zimmermann /* 2447fe3f0d1SThomas Zimmermann * Helpers for struct drm_crtc_funcs 2457fe3f0d1SThomas Zimmermann */ 2467fe3f0d1SThomas Zimmermann 247f1e2b637SThomas Zimmermann typedef bool (*drm_vblank_get_scanout_position_func)(struct drm_crtc *crtc, 248f1e2b637SThomas Zimmermann bool in_vblank_irq, 249f1e2b637SThomas Zimmermann int *vpos, int *hpos, 250f1e2b637SThomas Zimmermann ktime_t *stime, 251f1e2b637SThomas Zimmermann ktime_t *etime, 252f1e2b637SThomas Zimmermann const struct drm_display_mode *mode); 253f1e2b637SThomas Zimmermann 254f1e2b637SThomas Zimmermann typedef bool (*drm_vblank_get_scanout_position_legacy_func)(struct drm_device *dev, 255f1e2b637SThomas Zimmermann unsigned int pipe, 256f1e2b637SThomas Zimmermann bool in_vblank_irq, 257f1e2b637SThomas Zimmermann int *vpos, 258f1e2b637SThomas Zimmermann int *hpos, 259f1e2b637SThomas Zimmermann ktime_t *stime, 260f1e2b637SThomas Zimmermann ktime_t *etime, 261f1e2b637SThomas Zimmermann const struct drm_display_mode *mode); 262f1e2b637SThomas Zimmermann 263f1e2b637SThomas Zimmermann bool 264f1e2b637SThomas Zimmermann drm_crtc_vblank_helper_get_vblank_timestamp_internal(struct drm_crtc *crtc, 265f1e2b637SThomas Zimmermann int *max_error, 266f1e2b637SThomas Zimmermann ktime_t *vblank_time, 267f1e2b637SThomas Zimmermann bool in_vblank_irq, 268f1e2b637SThomas Zimmermann drm_vblank_get_scanout_position_func get_scanout_position, 269f1e2b637SThomas Zimmermann drm_vblank_get_scanout_position_legacy_func get_scanout_position_legacy); 2707fe3f0d1SThomas Zimmermann bool drm_crtc_vblank_helper_get_vblank_timestamp(struct drm_crtc *crtc, 2717fe3f0d1SThomas Zimmermann int *max_error, 2727fe3f0d1SThomas Zimmermann ktime_t *vblank_time, 2737fe3f0d1SThomas Zimmermann bool in_vblank_irq); 274f1e2b637SThomas Zimmermann 2753ed4351aSDaniel Vetter #endif 276