1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Copyright 2016 Intel Corp. 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a 5*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"), 6*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation 7*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the 9*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions: 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun * The above copyright notice and this permission notice (including the next 12*4882a593Smuzhiyun * paragraph) shall be included in all copies or substantial portions of the 13*4882a593Smuzhiyun * Software. 14*4882a593Smuzhiyun * 15*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18*4882a593Smuzhiyun * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 19*4882a593Smuzhiyun * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20*4882a593Smuzhiyun * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21*4882a593Smuzhiyun * OTHER DEALINGS IN THE SOFTWARE. 22*4882a593Smuzhiyun */ 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun #ifndef _DRM_VBLANK_H_ 25*4882a593Smuzhiyun #define _DRM_VBLANK_H_ 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun #include <linux/seqlock.h> 28*4882a593Smuzhiyun #include <linux/idr.h> 29*4882a593Smuzhiyun #include <linux/poll.h> 30*4882a593Smuzhiyun #include <linux/kthread.h> 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun #include <drm/drm_file.h> 33*4882a593Smuzhiyun #include <drm/drm_modes.h> 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun struct drm_device; 36*4882a593Smuzhiyun struct drm_crtc; 37*4882a593Smuzhiyun struct drm_vblank_work; 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun /** 40*4882a593Smuzhiyun * struct drm_pending_vblank_event - pending vblank event tracking 41*4882a593Smuzhiyun */ 42*4882a593Smuzhiyun struct drm_pending_vblank_event { 43*4882a593Smuzhiyun /** 44*4882a593Smuzhiyun * @base: Base structure for tracking pending DRM events. 45*4882a593Smuzhiyun */ 46*4882a593Smuzhiyun struct drm_pending_event base; 47*4882a593Smuzhiyun /** 48*4882a593Smuzhiyun * @pipe: drm_crtc_index() of the &drm_crtc this event is for. 49*4882a593Smuzhiyun */ 50*4882a593Smuzhiyun unsigned int pipe; 51*4882a593Smuzhiyun /** 52*4882a593Smuzhiyun * @sequence: frame event should be triggered at 53*4882a593Smuzhiyun */ 54*4882a593Smuzhiyun u64 sequence; 55*4882a593Smuzhiyun /** 56*4882a593Smuzhiyun * @event: Actual event which will be sent to userspace. 57*4882a593Smuzhiyun */ 58*4882a593Smuzhiyun union { 59*4882a593Smuzhiyun /** 60*4882a593Smuzhiyun * @event.base: DRM event base class. 61*4882a593Smuzhiyun */ 62*4882a593Smuzhiyun struct drm_event base; 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /** 65*4882a593Smuzhiyun * @event.vbl: 66*4882a593Smuzhiyun * 67*4882a593Smuzhiyun * Event payload for vblank events, requested through 68*4882a593Smuzhiyun * either the MODE_PAGE_FLIP or MODE_ATOMIC IOCTL. Also 69*4882a593Smuzhiyun * generated by the legacy WAIT_VBLANK IOCTL, but new userspace 70*4882a593Smuzhiyun * should use MODE_QUEUE_SEQUENCE and &event.seq instead. 71*4882a593Smuzhiyun */ 72*4882a593Smuzhiyun struct drm_event_vblank vbl; 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun /** 75*4882a593Smuzhiyun * @event.seq: Event payload for the MODE_QUEUEU_SEQUENCE IOCTL. 76*4882a593Smuzhiyun */ 77*4882a593Smuzhiyun struct drm_event_crtc_sequence seq; 78*4882a593Smuzhiyun } event; 79*4882a593Smuzhiyun }; 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun /** 82*4882a593Smuzhiyun * struct drm_vblank_crtc - vblank tracking for a CRTC 83*4882a593Smuzhiyun * 84*4882a593Smuzhiyun * This structure tracks the vblank state for one CRTC. 85*4882a593Smuzhiyun * 86*4882a593Smuzhiyun * Note that for historical reasons - the vblank handling code is still shared 87*4882a593Smuzhiyun * with legacy/non-kms drivers - this is a free-standing structure not directly 88*4882a593Smuzhiyun * connected to &struct drm_crtc. But all public interface functions are taking 89*4882a593Smuzhiyun * a &struct drm_crtc to hide this implementation detail. 90*4882a593Smuzhiyun */ 91*4882a593Smuzhiyun struct drm_vblank_crtc { 92*4882a593Smuzhiyun /** 93*4882a593Smuzhiyun * @dev: Pointer to the &drm_device. 94*4882a593Smuzhiyun */ 95*4882a593Smuzhiyun struct drm_device *dev; 96*4882a593Smuzhiyun /** 97*4882a593Smuzhiyun * @queue: Wait queue for vblank waiters. 98*4882a593Smuzhiyun */ 99*4882a593Smuzhiyun wait_queue_head_t queue; 100*4882a593Smuzhiyun /** 101*4882a593Smuzhiyun * @disable_timer: Disable timer for the delayed vblank disabling 102*4882a593Smuzhiyun * hysteresis logic. Vblank disabling is controlled through the 103*4882a593Smuzhiyun * drm_vblank_offdelay module option and the setting of the 104*4882a593Smuzhiyun * &drm_device.max_vblank_count value. 105*4882a593Smuzhiyun */ 106*4882a593Smuzhiyun struct timer_list disable_timer; 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun /** 109*4882a593Smuzhiyun * @seqlock: Protect vblank count and time. 110*4882a593Smuzhiyun */ 111*4882a593Smuzhiyun seqlock_t seqlock; 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun /** 114*4882a593Smuzhiyun * @count: 115*4882a593Smuzhiyun * 116*4882a593Smuzhiyun * Current software vblank counter. 117*4882a593Smuzhiyun * 118*4882a593Smuzhiyun * Note that for a given vblank counter value drm_crtc_handle_vblank() 119*4882a593Smuzhiyun * and drm_crtc_vblank_count() or drm_crtc_vblank_count_and_time() 120*4882a593Smuzhiyun * provide a barrier: Any writes done before calling 121*4882a593Smuzhiyun * drm_crtc_handle_vblank() will be visible to callers of the later 122*4882a593Smuzhiyun * functions, iff the vblank count is the same or a later one. 123*4882a593Smuzhiyun * 124*4882a593Smuzhiyun * IMPORTANT: This guarantee requires barriers, therefor never access 125*4882a593Smuzhiyun * this field directly. Use drm_crtc_vblank_count() instead. 126*4882a593Smuzhiyun */ 127*4882a593Smuzhiyun atomic64_t count; 128*4882a593Smuzhiyun /** 129*4882a593Smuzhiyun * @time: Vblank timestamp corresponding to @count. 130*4882a593Smuzhiyun */ 131*4882a593Smuzhiyun ktime_t time; 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun /** 134*4882a593Smuzhiyun * @refcount: Number of users/waiters of the vblank interrupt. Only when 135*4882a593Smuzhiyun * this refcount reaches 0 can the hardware interrupt be disabled using 136*4882a593Smuzhiyun * @disable_timer. 137*4882a593Smuzhiyun */ 138*4882a593Smuzhiyun atomic_t refcount; 139*4882a593Smuzhiyun /** 140*4882a593Smuzhiyun * @last: Protected by &drm_device.vbl_lock, used for wraparound handling. 141*4882a593Smuzhiyun */ 142*4882a593Smuzhiyun u32 last; 143*4882a593Smuzhiyun /** 144*4882a593Smuzhiyun * @max_vblank_count: 145*4882a593Smuzhiyun * 146*4882a593Smuzhiyun * Maximum value of the vblank registers for this crtc. This value +1 147*4882a593Smuzhiyun * will result in a wrap-around of the vblank register. It is used 148*4882a593Smuzhiyun * by the vblank core to handle wrap-arounds. 149*4882a593Smuzhiyun * 150*4882a593Smuzhiyun * If set to zero the vblank core will try to guess the elapsed vblanks 151*4882a593Smuzhiyun * between times when the vblank interrupt is disabled through 152*4882a593Smuzhiyun * high-precision timestamps. That approach is suffering from small 153*4882a593Smuzhiyun * races and imprecision over longer time periods, hence exposing a 154*4882a593Smuzhiyun * hardware vblank counter is always recommended. 155*4882a593Smuzhiyun * 156*4882a593Smuzhiyun * This is the runtime configurable per-crtc maximum set through 157*4882a593Smuzhiyun * drm_crtc_set_max_vblank_count(). If this is used the driver 158*4882a593Smuzhiyun * must leave the device wide &drm_device.max_vblank_count at zero. 159*4882a593Smuzhiyun * 160*4882a593Smuzhiyun * If non-zero, &drm_crtc_funcs.get_vblank_counter must be set. 161*4882a593Smuzhiyun */ 162*4882a593Smuzhiyun u32 max_vblank_count; 163*4882a593Smuzhiyun /** 164*4882a593Smuzhiyun * @inmodeset: Tracks whether the vblank is disabled due to a modeset. 165*4882a593Smuzhiyun * For legacy driver bit 2 additionally tracks whether an additional 166*4882a593Smuzhiyun * temporary vblank reference has been acquired to paper over the 167*4882a593Smuzhiyun * hardware counter resetting/jumping. KMS drivers should instead just 168*4882a593Smuzhiyun * call drm_crtc_vblank_off() and drm_crtc_vblank_on(), which explicitly 169*4882a593Smuzhiyun * save and restore the vblank count. 170*4882a593Smuzhiyun */ 171*4882a593Smuzhiyun unsigned int inmodeset; 172*4882a593Smuzhiyun /** 173*4882a593Smuzhiyun * @pipe: drm_crtc_index() of the &drm_crtc corresponding to this 174*4882a593Smuzhiyun * structure. 175*4882a593Smuzhiyun */ 176*4882a593Smuzhiyun unsigned int pipe; 177*4882a593Smuzhiyun /** 178*4882a593Smuzhiyun * @framedur_ns: Frame/Field duration in ns, used by 179*4882a593Smuzhiyun * drm_crtc_vblank_helper_get_vblank_timestamp() and computed by 180*4882a593Smuzhiyun * drm_calc_timestamping_constants(). 181*4882a593Smuzhiyun */ 182*4882a593Smuzhiyun int framedur_ns; 183*4882a593Smuzhiyun /** 184*4882a593Smuzhiyun * @linedur_ns: Line duration in ns, used by 185*4882a593Smuzhiyun * drm_crtc_vblank_helper_get_vblank_timestamp() and computed by 186*4882a593Smuzhiyun * drm_calc_timestamping_constants(). 187*4882a593Smuzhiyun */ 188*4882a593Smuzhiyun int linedur_ns; 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun /** 191*4882a593Smuzhiyun * @hwmode: 192*4882a593Smuzhiyun * 193*4882a593Smuzhiyun * Cache of the current hardware display mode. Only valid when @enabled 194*4882a593Smuzhiyun * is set. This is used by helpers like 195*4882a593Smuzhiyun * drm_crtc_vblank_helper_get_vblank_timestamp(). We can't just access 196*4882a593Smuzhiyun * the hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode, 197*4882a593Smuzhiyun * because that one is really hard to get from interrupt context. 198*4882a593Smuzhiyun */ 199*4882a593Smuzhiyun struct drm_display_mode hwmode; 200*4882a593Smuzhiyun 201*4882a593Smuzhiyun /** 202*4882a593Smuzhiyun * @enabled: Tracks the enabling state of the corresponding &drm_crtc to 203*4882a593Smuzhiyun * avoid double-disabling and hence corrupting saved state. Needed by 204*4882a593Smuzhiyun * drivers not using atomic KMS, since those might go through their CRTC 205*4882a593Smuzhiyun * disabling functions multiple times. 206*4882a593Smuzhiyun */ 207*4882a593Smuzhiyun bool enabled; 208*4882a593Smuzhiyun 209*4882a593Smuzhiyun /** 210*4882a593Smuzhiyun * @worker: The &kthread_worker used for executing vblank works. 211*4882a593Smuzhiyun */ 212*4882a593Smuzhiyun struct kthread_worker *worker; 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun /** 215*4882a593Smuzhiyun * @pending_work: A list of scheduled &drm_vblank_work items that are 216*4882a593Smuzhiyun * waiting for a future vblank. 217*4882a593Smuzhiyun */ 218*4882a593Smuzhiyun struct list_head pending_work; 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun /** 221*4882a593Smuzhiyun * @work_wait_queue: The wait queue used for signaling that a 222*4882a593Smuzhiyun * &drm_vblank_work item has either finished executing, or was 223*4882a593Smuzhiyun * cancelled. 224*4882a593Smuzhiyun */ 225*4882a593Smuzhiyun wait_queue_head_t work_wait_queue; 226*4882a593Smuzhiyun }; 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs); 229*4882a593Smuzhiyun bool drm_dev_has_vblank(const struct drm_device *dev); 230*4882a593Smuzhiyun u64 drm_crtc_vblank_count(struct drm_crtc *crtc); 231*4882a593Smuzhiyun u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, 232*4882a593Smuzhiyun ktime_t *vblanktime); 233*4882a593Smuzhiyun void drm_crtc_send_vblank_event(struct drm_crtc *crtc, 234*4882a593Smuzhiyun struct drm_pending_vblank_event *e); 235*4882a593Smuzhiyun void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, 236*4882a593Smuzhiyun struct drm_pending_vblank_event *e); 237*4882a593Smuzhiyun void drm_vblank_set_event(struct drm_pending_vblank_event *e, 238*4882a593Smuzhiyun u64 *seq, 239*4882a593Smuzhiyun ktime_t *now); 240*4882a593Smuzhiyun bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); 241*4882a593Smuzhiyun bool drm_crtc_handle_vblank(struct drm_crtc *crtc); 242*4882a593Smuzhiyun int drm_crtc_vblank_get(struct drm_crtc *crtc); 243*4882a593Smuzhiyun void drm_crtc_vblank_put(struct drm_crtc *crtc); 244*4882a593Smuzhiyun void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe); 245*4882a593Smuzhiyun void drm_crtc_wait_one_vblank(struct drm_crtc *crtc); 246*4882a593Smuzhiyun void drm_crtc_vblank_off(struct drm_crtc *crtc); 247*4882a593Smuzhiyun void drm_crtc_vblank_reset(struct drm_crtc *crtc); 248*4882a593Smuzhiyun void drm_crtc_vblank_on(struct drm_crtc *crtc); 249*4882a593Smuzhiyun u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc); 250*4882a593Smuzhiyun void drm_vblank_restore(struct drm_device *dev, unsigned int pipe); 251*4882a593Smuzhiyun void drm_crtc_vblank_restore(struct drm_crtc *crtc); 252*4882a593Smuzhiyun 253*4882a593Smuzhiyun void drm_calc_timestamping_constants(struct drm_crtc *crtc, 254*4882a593Smuzhiyun const struct drm_display_mode *mode); 255*4882a593Smuzhiyun wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc); 256*4882a593Smuzhiyun void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc, 257*4882a593Smuzhiyun u32 max_vblank_count); 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun /* 260*4882a593Smuzhiyun * Helpers for struct drm_crtc_funcs 261*4882a593Smuzhiyun */ 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun typedef bool (*drm_vblank_get_scanout_position_func)(struct drm_crtc *crtc, 264*4882a593Smuzhiyun bool in_vblank_irq, 265*4882a593Smuzhiyun int *vpos, int *hpos, 266*4882a593Smuzhiyun ktime_t *stime, 267*4882a593Smuzhiyun ktime_t *etime, 268*4882a593Smuzhiyun const struct drm_display_mode *mode); 269*4882a593Smuzhiyun 270*4882a593Smuzhiyun bool 271*4882a593Smuzhiyun drm_crtc_vblank_helper_get_vblank_timestamp_internal(struct drm_crtc *crtc, 272*4882a593Smuzhiyun int *max_error, 273*4882a593Smuzhiyun ktime_t *vblank_time, 274*4882a593Smuzhiyun bool in_vblank_irq, 275*4882a593Smuzhiyun drm_vblank_get_scanout_position_func get_scanout_position); 276*4882a593Smuzhiyun bool drm_crtc_vblank_helper_get_vblank_timestamp(struct drm_crtc *crtc, 277*4882a593Smuzhiyun int *max_error, 278*4882a593Smuzhiyun ktime_t *vblank_time, 279*4882a593Smuzhiyun bool in_vblank_irq); 280*4882a593Smuzhiyun 281*4882a593Smuzhiyun #endif 282