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