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> 305e6c2b4fSLyude Paul #include <linux/kthread.h> 313ed4351aSDaniel Vetter 323ed4351aSDaniel Vetter #include <drm/drm_file.h> 333ed4351aSDaniel Vetter #include <drm/drm_modes.h> 343ed4351aSDaniel Vetter 353ed4351aSDaniel Vetter struct drm_device; 363ed4351aSDaniel Vetter struct drm_crtc; 375e6c2b4fSLyude Paul struct drm_vblank_work; 383ed4351aSDaniel Vetter 393ed4351aSDaniel Vetter /** 403ed4351aSDaniel Vetter * struct drm_pending_vblank_event - pending vblank event tracking 413ed4351aSDaniel Vetter */ 423ed4351aSDaniel Vetter struct drm_pending_vblank_event { 433ed4351aSDaniel Vetter /** 443ed4351aSDaniel Vetter * @base: Base structure for tracking pending DRM events. 453ed4351aSDaniel Vetter */ 463ed4351aSDaniel Vetter struct drm_pending_event base; 473ed4351aSDaniel Vetter /** 483ed4351aSDaniel Vetter * @pipe: drm_crtc_index() of the &drm_crtc this event is for. 493ed4351aSDaniel Vetter */ 503ed4351aSDaniel Vetter unsigned int pipe; 513ed4351aSDaniel Vetter /** 52570e8696SKeith Packard * @sequence: frame event should be triggered at 53570e8696SKeith Packard */ 54570e8696SKeith Packard u64 sequence; 55570e8696SKeith Packard /** 563ed4351aSDaniel Vetter * @event: Actual event which will be sent to userspace. 573ed4351aSDaniel Vetter */ 58bd386e51SKeith Packard union { 5983a7dff0SDaniel Vetter /** 6083a7dff0SDaniel Vetter * @event.base: DRM event base class. 6183a7dff0SDaniel Vetter */ 62bd386e51SKeith Packard struct drm_event base; 6383a7dff0SDaniel Vetter 6483a7dff0SDaniel Vetter /** 6583a7dff0SDaniel Vetter * @event.vbl: 6683a7dff0SDaniel Vetter * 6783a7dff0SDaniel Vetter * Event payload for vblank events, requested through 6883a7dff0SDaniel Vetter * either the MODE_PAGE_FLIP or MODE_ATOMIC IOCTL. Also 6983a7dff0SDaniel Vetter * generated by the legacy WAIT_VBLANK IOCTL, but new userspace 7083a7dff0SDaniel Vetter * should use MODE_QUEUE_SEQUENCE and &event.seq instead. 7183a7dff0SDaniel Vetter */ 72bd386e51SKeith Packard struct drm_event_vblank vbl; 7383a7dff0SDaniel Vetter 7483a7dff0SDaniel Vetter /** 7583a7dff0SDaniel Vetter * @event.seq: Event payload for the MODE_QUEUEU_SEQUENCE IOCTL. 7683a7dff0SDaniel Vetter */ 773064abfaSKeith Packard struct drm_event_crtc_sequence seq; 78bd386e51SKeith Packard } event; 793ed4351aSDaniel Vetter }; 803ed4351aSDaniel Vetter 813ed4351aSDaniel Vetter /** 823ed4351aSDaniel Vetter * struct drm_vblank_crtc - vblank tracking for a CRTC 833ed4351aSDaniel Vetter * 843ed4351aSDaniel Vetter * This structure tracks the vblank state for one CRTC. 853ed4351aSDaniel Vetter * 863ed4351aSDaniel Vetter * Note that for historical reasons - the vblank handling code is still shared 873ed4351aSDaniel Vetter * with legacy/non-kms drivers - this is a free-standing structure not directly 883ed4351aSDaniel Vetter * connected to &struct drm_crtc. But all public interface functions are taking 893ed4351aSDaniel Vetter * a &struct drm_crtc to hide this implementation detail. 903ed4351aSDaniel Vetter */ 913ed4351aSDaniel Vetter struct drm_vblank_crtc { 923ed4351aSDaniel Vetter /** 933ed4351aSDaniel Vetter * @dev: Pointer to the &drm_device. 943ed4351aSDaniel Vetter */ 953ed4351aSDaniel Vetter struct drm_device *dev; 963ed4351aSDaniel Vetter /** 973ed4351aSDaniel Vetter * @queue: Wait queue for vblank waiters. 983ed4351aSDaniel Vetter */ 999e37ee79SDaniel Vetter wait_queue_head_t queue; 1003ed4351aSDaniel Vetter /** 1013ed4351aSDaniel Vetter * @disable_timer: Disable timer for the delayed vblank disabling 1023ed4351aSDaniel Vetter * hysteresis logic. Vblank disabling is controlled through the 1033ed4351aSDaniel Vetter * drm_vblank_offdelay module option and the setting of the 1043ed4351aSDaniel Vetter * &drm_device.max_vblank_count value. 1053ed4351aSDaniel Vetter */ 1063ed4351aSDaniel Vetter struct timer_list disable_timer; 1073ed4351aSDaniel Vetter 1083ed4351aSDaniel Vetter /** 1093ed4351aSDaniel Vetter * @seqlock: Protect vblank count and time. 1103ed4351aSDaniel Vetter */ 1119e37ee79SDaniel Vetter seqlock_t seqlock; 1123ed4351aSDaniel Vetter 1133ed4351aSDaniel Vetter /** 114bd7e3f3bSDaniel Vetter * @count: 115bd7e3f3bSDaniel Vetter * 116bd7e3f3bSDaniel Vetter * Current software vblank counter. 117bd7e3f3bSDaniel Vetter * 118bd7e3f3bSDaniel Vetter * Note that for a given vblank counter value drm_crtc_handle_vblank() 119bd7e3f3bSDaniel Vetter * and drm_crtc_vblank_count() or drm_crtc_vblank_count_and_time() 120bd7e3f3bSDaniel Vetter * provide a barrier: Any writes done before calling 121bd7e3f3bSDaniel Vetter * drm_crtc_handle_vblank() will be visible to callers of the later 122bd7e3f3bSDaniel Vetter * functions, iff the vblank count is the same or a later one. 123bd7e3f3bSDaniel Vetter * 124bd7e3f3bSDaniel Vetter * IMPORTANT: This guarantee requires barriers, therefor never access 125bd7e3f3bSDaniel Vetter * this field directly. Use drm_crtc_vblank_count() instead. 1263ed4351aSDaniel Vetter */ 127bd7e3f3bSDaniel Vetter atomic64_t count; 1283ed4351aSDaniel Vetter /** 1293ed4351aSDaniel Vetter * @time: Vblank timestamp corresponding to @count. 1303ed4351aSDaniel Vetter */ 13167680d3cSArnd Bergmann ktime_t time; 1323ed4351aSDaniel Vetter 1333ed4351aSDaniel Vetter /** 1343ed4351aSDaniel Vetter * @refcount: Number of users/waiters of the vblank interrupt. Only when 1353ed4351aSDaniel Vetter * this refcount reaches 0 can the hardware interrupt be disabled using 1363ed4351aSDaniel Vetter * @disable_timer. 1373ed4351aSDaniel Vetter */ 1389e37ee79SDaniel Vetter atomic_t refcount; 1393ed4351aSDaniel Vetter /** 1403ed4351aSDaniel Vetter * @last: Protected by &drm_device.vbl_lock, used for wraparound handling. 1413ed4351aSDaniel Vetter */ 1423ed4351aSDaniel Vetter u32 last; 1433ed4351aSDaniel Vetter /** 144ed20151aSVille Syrjälä * @max_vblank_count: 145ed20151aSVille Syrjälä * 146ed20151aSVille Syrjälä * Maximum value of the vblank registers for this crtc. This value +1 147ed20151aSVille Syrjälä * will result in a wrap-around of the vblank register. It is used 148ed20151aSVille Syrjälä * by the vblank core to handle wrap-arounds. 149ed20151aSVille Syrjälä * 150ed20151aSVille Syrjälä * If set to zero the vblank core will try to guess the elapsed vblanks 151ed20151aSVille Syrjälä * between times when the vblank interrupt is disabled through 152ed20151aSVille Syrjälä * high-precision timestamps. That approach is suffering from small 153ed20151aSVille Syrjälä * races and imprecision over longer time periods, hence exposing a 154ed20151aSVille Syrjälä * hardware vblank counter is always recommended. 155ed20151aSVille Syrjälä * 156ed20151aSVille Syrjälä * This is the runtime configurable per-crtc maximum set through 157ed20151aSVille Syrjälä * drm_crtc_set_max_vblank_count(). If this is used the driver 158ed20151aSVille Syrjälä * must leave the device wide &drm_device.max_vblank_count at zero. 159ed20151aSVille Syrjälä * 160ed20151aSVille Syrjälä * If non-zero, &drm_crtc_funcs.get_vblank_counter must be set. 161ed20151aSVille Syrjälä */ 162ed20151aSVille Syrjälä u32 max_vblank_count; 163ed20151aSVille Syrjälä /** 1643ed4351aSDaniel Vetter * @inmodeset: Tracks whether the vblank is disabled due to a modeset. 1653ed4351aSDaniel Vetter * For legacy driver bit 2 additionally tracks whether an additional 1663ed4351aSDaniel Vetter * temporary vblank reference has been acquired to paper over the 1673ed4351aSDaniel Vetter * hardware counter resetting/jumping. KMS drivers should instead just 1683ed4351aSDaniel Vetter * call drm_crtc_vblank_off() and drm_crtc_vblank_on(), which explicitly 1693ed4351aSDaniel Vetter * save and restore the vblank count. 1703ed4351aSDaniel Vetter */ 1719e37ee79SDaniel Vetter unsigned int inmodeset; 1723ed4351aSDaniel Vetter /** 1733ed4351aSDaniel Vetter * @pipe: drm_crtc_index() of the &drm_crtc corresponding to this 1743ed4351aSDaniel Vetter * structure. 1753ed4351aSDaniel Vetter */ 1763ed4351aSDaniel Vetter unsigned int pipe; 1773ed4351aSDaniel Vetter /** 1783ed4351aSDaniel Vetter * @framedur_ns: Frame/Field duration in ns, used by 1797fe3f0d1SThomas Zimmermann * drm_crtc_vblank_helper_get_vblank_timestamp() and computed by 1803ed4351aSDaniel Vetter * drm_calc_timestamping_constants(). 1813ed4351aSDaniel Vetter */ 1823ed4351aSDaniel Vetter int framedur_ns; 1833ed4351aSDaniel Vetter /** 1843ed4351aSDaniel Vetter * @linedur_ns: Line duration in ns, used by 1857fe3f0d1SThomas Zimmermann * drm_crtc_vblank_helper_get_vblank_timestamp() and computed by 1863ed4351aSDaniel Vetter * drm_calc_timestamping_constants(). 1873ed4351aSDaniel Vetter */ 1883ed4351aSDaniel Vetter int linedur_ns; 1893ed4351aSDaniel Vetter 1903ed4351aSDaniel Vetter /** 1913ed4351aSDaniel Vetter * @hwmode: 1923ed4351aSDaniel Vetter * 1933ed4351aSDaniel Vetter * Cache of the current hardware display mode. Only valid when @enabled 1943ed4351aSDaniel Vetter * is set. This is used by helpers like 1957fe3f0d1SThomas Zimmermann * drm_crtc_vblank_helper_get_vblank_timestamp(). We can't just access 1967fe3f0d1SThomas Zimmermann * the hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode, 1973ed4351aSDaniel Vetter * because that one is really hard to get from interrupt context. 1983ed4351aSDaniel Vetter */ 1993ed4351aSDaniel Vetter struct drm_display_mode hwmode; 2003ed4351aSDaniel Vetter 2013ed4351aSDaniel Vetter /** 2023ed4351aSDaniel Vetter * @enabled: Tracks the enabling state of the corresponding &drm_crtc to 2033ed4351aSDaniel Vetter * avoid double-disabling and hence corrupting saved state. Needed by 2043ed4351aSDaniel Vetter * drivers not using atomic KMS, since those might go through their CRTC 2053ed4351aSDaniel Vetter * disabling functions multiple times. 2063ed4351aSDaniel Vetter */ 2073ed4351aSDaniel Vetter bool enabled; 2085e6c2b4fSLyude Paul 2095e6c2b4fSLyude Paul /** 2105e6c2b4fSLyude Paul * @worker: The &kthread_worker used for executing vblank works. 2115e6c2b4fSLyude Paul */ 2125e6c2b4fSLyude Paul struct kthread_worker *worker; 2135e6c2b4fSLyude Paul 2145e6c2b4fSLyude Paul /** 2155e6c2b4fSLyude Paul * @pending_work: A list of scheduled &drm_vblank_work items that are 2165e6c2b4fSLyude Paul * waiting for a future vblank. 2175e6c2b4fSLyude Paul */ 2185e6c2b4fSLyude Paul struct list_head pending_work; 2195e6c2b4fSLyude Paul 2205e6c2b4fSLyude Paul /** 2215e6c2b4fSLyude Paul * @work_wait_queue: The wait queue used for signaling that a 2225e6c2b4fSLyude Paul * &drm_vblank_work item has either finished executing, or was 2235e6c2b4fSLyude Paul * cancelled. 2245e6c2b4fSLyude Paul */ 2255e6c2b4fSLyude Paul wait_queue_head_t work_wait_queue; 2263ed4351aSDaniel Vetter }; 2273ed4351aSDaniel Vetter 2283ed4351aSDaniel Vetter int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs); 2297beb691fSThomas Zimmermann bool drm_dev_has_vblank(const struct drm_device *dev); 230570e8696SKeith Packard u64 drm_crtc_vblank_count(struct drm_crtc *crtc); 231570e8696SKeith Packard u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, 23267680d3cSArnd Bergmann ktime_t *vblanktime); 233*b2c077d0SRob Clark int drm_crtc_next_vblank_start(struct drm_crtc *crtc, ktime_t *vblanktime); 2343ed4351aSDaniel Vetter void drm_crtc_send_vblank_event(struct drm_crtc *crtc, 2353ed4351aSDaniel Vetter struct drm_pending_vblank_event *e); 2363ed4351aSDaniel Vetter void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, 2373ed4351aSDaniel Vetter struct drm_pending_vblank_event *e); 238bd386e51SKeith Packard void drm_vblank_set_event(struct drm_pending_vblank_event *e, 239bd386e51SKeith Packard u64 *seq, 240bd386e51SKeith Packard ktime_t *now); 2413ed4351aSDaniel Vetter bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); 2423ed4351aSDaniel Vetter bool drm_crtc_handle_vblank(struct drm_crtc *crtc); 2433ed4351aSDaniel Vetter int drm_crtc_vblank_get(struct drm_crtc *crtc); 2443ed4351aSDaniel Vetter void drm_crtc_vblank_put(struct drm_crtc *crtc); 2453ed4351aSDaniel Vetter void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe); 2463ed4351aSDaniel Vetter void drm_crtc_wait_one_vblank(struct drm_crtc *crtc); 2473ed4351aSDaniel Vetter void drm_crtc_vblank_off(struct drm_crtc *crtc); 2483ed4351aSDaniel Vetter void drm_crtc_vblank_reset(struct drm_crtc *crtc); 2493ed4351aSDaniel Vetter void drm_crtc_vblank_on(struct drm_crtc *crtc); 2503b765c0bSDhinakaran Pandiyan u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc); 251d0bb96b4SDhinakaran Pandiyan void drm_crtc_vblank_restore(struct drm_crtc *crtc); 2523ed4351aSDaniel Vetter 2533ed4351aSDaniel Vetter void drm_calc_timestamping_constants(struct drm_crtc *crtc, 2543ed4351aSDaniel Vetter const struct drm_display_mode *mode); 2553ed4351aSDaniel Vetter wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc); 256ed20151aSVille Syrjälä void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc, 257ed20151aSVille Syrjälä u32 max_vblank_count); 258f1e2b637SThomas Zimmermann 2597fe3f0d1SThomas Zimmermann /* 2607fe3f0d1SThomas Zimmermann * Helpers for struct drm_crtc_funcs 2617fe3f0d1SThomas Zimmermann */ 2627fe3f0d1SThomas Zimmermann 263f1e2b637SThomas Zimmermann typedef bool (*drm_vblank_get_scanout_position_func)(struct drm_crtc *crtc, 264f1e2b637SThomas Zimmermann bool in_vblank_irq, 265f1e2b637SThomas Zimmermann int *vpos, int *hpos, 266f1e2b637SThomas Zimmermann ktime_t *stime, 267f1e2b637SThomas Zimmermann ktime_t *etime, 268f1e2b637SThomas Zimmermann const struct drm_display_mode *mode); 269f1e2b637SThomas Zimmermann 270f1e2b637SThomas Zimmermann bool 271f1e2b637SThomas Zimmermann drm_crtc_vblank_helper_get_vblank_timestamp_internal(struct drm_crtc *crtc, 272f1e2b637SThomas Zimmermann int *max_error, 273f1e2b637SThomas Zimmermann ktime_t *vblank_time, 274f1e2b637SThomas Zimmermann bool in_vblank_irq, 27548e67807SThomas Zimmermann drm_vblank_get_scanout_position_func get_scanout_position); 2767fe3f0d1SThomas Zimmermann bool drm_crtc_vblank_helper_get_vblank_timestamp(struct drm_crtc *crtc, 2777fe3f0d1SThomas Zimmermann int *max_error, 2787fe3f0d1SThomas Zimmermann ktime_t *vblank_time, 2797fe3f0d1SThomas Zimmermann bool in_vblank_irq); 280f1e2b637SThomas Zimmermann 2813ed4351aSDaniel Vetter #endif 282