Lines Matching +full:ref +full:- +full:clock +full:- +full:period +full:- +full:ns
57 * For historical reference, the vertical blanking period was designed to
91 * "Physical top of display" is the reference point for the high-precision/
95 * vertical blanking period so that settings like gamma, the image buffer
109 * tear-free display, users must synchronize page flips and/or rendering to
114 * involves filtering out spurious interrupts, keeping race-free blanking
115 * counters, coping with counter wrap-around and resets and keeping use counts.
133 * On many hardware disabling the vblank interrupt cannot be done in a race-free
139 * Drivers for hardware without support for vertical-blanking interrupts
166 MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (0: never disable, <0…
173 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in store_vblank()
175 assert_spin_locked(&dev->vblank_time_lock); in store_vblank()
177 vblank->last = last; in store_vblank()
179 write_seqlock(&vblank->seqlock); in store_vblank()
180 vblank->time = t_vblank; in store_vblank()
181 atomic64_add(vblank_count_inc, &vblank->count); in store_vblank()
182 write_sequnlock(&vblank->seqlock); in store_vblank()
187 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_max_vblank_count()
189 return vblank->max_vblank_count ?: dev->max_vblank_count; in drm_max_vblank_count()
210 if (crtc->funcs->get_vblank_counter) in __get_vblank_counter()
211 return crtc->funcs->get_vblank_counter(crtc); in __get_vblank_counter()
214 else if (dev->driver->get_vblank_counter) { in __get_vblank_counter()
215 return dev->driver->get_vblank_counter(dev, pipe); in __get_vblank_counter()
238 spin_lock(&dev->vblank_time_lock); in drm_reset_vblank_timestamp()
247 } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0); in drm_reset_vblank_timestamp()
250 * Only reinitialize corresponding vblank timestamp if high-precision query in drm_reset_vblank_timestamp()
263 spin_unlock(&dev->vblank_time_lock); in drm_reset_vblank_timestamp()
272 * Only necessary when going from off->on, to account for frames we
281 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_update_vblank_count()
286 int framedur_ns = vblank->framedur_ns; in drm_update_vblank_count()
292 * NOTE! It's possible we lost a full dev->max_vblank_count + 1 events in drm_update_vblank_count()
304 } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0); in drm_update_vblank_count()
308 diff = (cur_vblank - vblank->last) & max_vblank_count; in drm_update_vblank_count()
310 u64 diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time)); in drm_update_vblank_count()
333 * Within a drm_vblank_pre_modeset - drm_vblank_post_modeset in drm_update_vblank_count()
341 if (diff > 1 && (vblank->inmodeset & 0x2)) { in drm_update_vblank_count()
344 " due to pre-modeset.\n", pipe, diff); in drm_update_vblank_count()
350 pipe, (unsigned long long)atomic64_read(&vblank->count), in drm_update_vblank_count()
351 diff, cur_vblank, vblank->last); in drm_update_vblank_count()
354 drm_WARN_ON_ONCE(dev, cur_vblank != vblank->last); in drm_update_vblank_count()
359 * Only reinitialize corresponding vblank timestamp if high-precision query in drm_update_vblank_count()
372 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_vblank_count()
375 if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) in drm_vblank_count()
378 count = atomic64_read(&vblank->count); in drm_vblank_count()
393 * drm_crtc_accurate_vblank_count - retrieve the master vblank counter
405 struct drm_device *dev = crtc->dev; in drm_crtc_accurate_vblank_count()
411 !crtc->funcs->get_vblank_timestamp, in drm_crtc_accurate_vblank_count()
414 spin_lock_irqsave(&dev->vblank_time_lock, flags); in drm_crtc_accurate_vblank_count()
419 spin_unlock_irqrestore(&dev->vblank_time_lock, flags); in drm_crtc_accurate_vblank_count()
433 if (crtc->funcs->disable_vblank) in __disable_vblank()
434 crtc->funcs->disable_vblank(crtc); in __disable_vblank()
438 dev->driver->disable_vblank(dev, pipe); in __disable_vblank()
451 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_vblank_disable_and_save()
454 assert_spin_locked(&dev->vbl_lock); in drm_vblank_disable_and_save()
460 spin_lock_irqsave(&dev->vblank_time_lock, irqflags); in drm_vblank_disable_and_save()
464 * interrupts were enabled. This avoids calling the ->disable_vblank() in drm_vblank_disable_and_save()
468 if (!vblank->enabled) in drm_vblank_disable_and_save()
479 vblank->enabled = false; in drm_vblank_disable_and_save()
482 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); in drm_vblank_disable_and_save()
488 struct drm_device *dev = vblank->dev; in vblank_disable_fn()
489 unsigned int pipe = vblank->pipe; in vblank_disable_fn()
492 spin_lock_irqsave(&dev->vbl_lock, irqflags); in vblank_disable_fn()
493 if (atomic_read(&vblank->refcount) == 0 && vblank->enabled) { in vblank_disable_fn()
497 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); in vblank_disable_fn()
504 drm_WARN_ON(dev, READ_ONCE(vblank->enabled) && in drm_vblank_init_release()
508 del_timer_sync(&vblank->disable_timer); in drm_vblank_init_release()
512 * drm_vblank_init - initialize vblank support
528 spin_lock_init(&dev->vbl_lock); in drm_vblank_init()
529 spin_lock_init(&dev->vblank_time_lock); in drm_vblank_init()
531 dev->vblank = drmm_kcalloc(dev, num_crtcs, sizeof(*dev->vblank), GFP_KERNEL); in drm_vblank_init()
532 if (!dev->vblank) in drm_vblank_init()
533 return -ENOMEM; in drm_vblank_init()
535 dev->num_crtcs = num_crtcs; in drm_vblank_init()
538 struct drm_vblank_crtc *vblank = &dev->vblank[i]; in drm_vblank_init()
540 vblank->dev = dev; in drm_vblank_init()
541 vblank->pipe = i; in drm_vblank_init()
542 init_waitqueue_head(&vblank->queue); in drm_vblank_init()
543 timer_setup(&vblank->disable_timer, vblank_disable_fn, 0); in drm_vblank_init()
544 seqlock_init(&vblank->seqlock); in drm_vblank_init()
561 * drm_dev_has_vblank - test if vblanking has been initialized for
578 return dev->num_crtcs != 0; in drm_dev_has_vblank()
583 * drm_crtc_vblank_waitqueue - get vblank waitqueue for the CRTC
592 return &crtc->dev->vblank[drm_crtc_index(crtc)].queue; in drm_crtc_vblank_waitqueue()
598 * drm_calc_timestamping_constants - calculate vblank timestamp constants
603 * swap-completion timestamping, e.g, by
611 struct drm_device *dev = crtc->dev; in drm_calc_timestamping_constants()
613 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_calc_timestamping_constants()
615 int dotclock = mode->crtc_clock; in drm_calc_timestamping_constants()
620 if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) in drm_calc_timestamping_constants()
625 int frame_size = mode->crtc_htotal * mode->crtc_vtotal; in drm_calc_timestamping_constants()
629 * dot clock to line duration and frame duration in drm_calc_timestamping_constants()
632 linedur_ns = div_u64((u64) mode->crtc_htotal * 1000000, dotclock); in drm_calc_timestamping_constants()
638 if (mode->flags & DRM_MODE_FLAG_INTERLACE) in drm_calc_timestamping_constants()
642 crtc->base.id); in drm_calc_timestamping_constants()
645 vblank->linedur_ns = linedur_ns; in drm_calc_timestamping_constants()
646 vblank->framedur_ns = framedur_ns; in drm_calc_timestamping_constants()
647 drm_mode_copy(&vblank->hwmode, mode); in drm_calc_timestamping_constants()
651 crtc->base.id, mode->crtc_htotal, in drm_calc_timestamping_constants()
652 mode->crtc_vtotal, mode->crtc_vdisplay); in drm_calc_timestamping_constants()
653 drm_dbg_core(dev, "crtc %u: clock %d kHz framedur %d linedur %d\n", in drm_calc_timestamping_constants()
654 crtc->base.id, dotclock, framedur_ns, linedur_ns); in drm_calc_timestamping_constants()
659 * drm_crtc_vblank_helper_get_vblank_timestamp_internal - precise vblank
667 * need to apply some workarounds for gpu-specific vblank irq quirks
696 struct drm_device *dev = crtc->dev; in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
697 unsigned int pipe = crtc->index; in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
698 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
706 if (pipe >= dev->num_crtcs) { in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
718 mode = &vblank->hwmode; in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
720 mode = &crtc->hwmode; in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
722 /* If mode timing undefined, just return as no-op: in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
725 if (mode->crtc_clock == 0) { in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
749 /* Return as no-op if scanout query unsupported or failed. */ in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
758 duration_ns = ktime_to_ns(etime) - ktime_to_ns(stime); in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
779 delta_ns = div_s64(1000000LL * (vpos * mode->crtc_htotal + hpos), in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
780 mode->crtc_clock); in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
794 "crtc %u : v p(%d,%d)@ %lld.%06ld -> %lld.%06ld [e %d us, %d rep]\n", in drm_crtc_vblank_helper_get_vblank_timestamp_internal()
805 * drm_crtc_vblank_helper_get_vblank_timestamp - precise vblank timestamp
813 * need to apply some workarounds for gpu-specific vblank irq quirks
842 crtc->helper_private->get_scanout_position); in drm_crtc_vblank_helper_get_vblank_timestamp()
847 * drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent
854 * need to apply some workarounds for gpu-specific vblank irq quirks
858 * vblank interval on specified CRTC. May call into kms-driver to
859 * compute the timestamp with a high-precision GPU specific method.
878 if (crtc && crtc->funcs->get_vblank_timestamp && max_error > 0) { in drm_get_last_vbltimestamp()
881 ret = crtc->funcs->get_vblank_timestamp(crtc, &max_error, in drm_get_last_vbltimestamp()
895 * drm_crtc_vblank_count - retrieve "cooked" vblank counter value
902 * drm_crtc_accurate_vblank_count() for such use-cases.
917 return drm_vblank_count(crtc->dev, drm_crtc_index(crtc)); in drm_crtc_vblank_count()
922 * drm_vblank_count_and_time - retrieve "cooked" vblank counter value and the
938 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_vblank_count_and_time()
942 if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) { in drm_vblank_count_and_time()
948 seq = read_seqbegin(&vblank->seqlock); in drm_vblank_count_and_time()
949 vblank_count = atomic64_read(&vblank->count); in drm_vblank_count_and_time()
950 *vblanktime = vblank->time; in drm_vblank_count_and_time()
951 } while (read_seqretry(&vblank->seqlock, seq)); in drm_vblank_count_and_time()
957 * drm_crtc_vblank_count_and_time - retrieve "cooked" vblank counter value
978 return drm_vblank_count_and_time(crtc->dev, drm_crtc_index(crtc), in drm_crtc_vblank_count_and_time()
989 switch (e->event.base.type) { in send_vblank_event()
993 e->event.vbl.sequence = seq; in send_vblank_event()
995 * e->event is a user space structure, with hardcoded unsigned in send_vblank_event()
996 * 32-bit seconds/microseconds. This is safe as we always use in send_vblank_event()
997 * monotonic timestamps since linux-4.15 in send_vblank_event()
999 e->event.vbl.tv_sec = tv.tv_sec; in send_vblank_event()
1000 e->event.vbl.tv_usec = tv.tv_nsec / 1000; in send_vblank_event()
1004 e->event.seq.sequence = seq; in send_vblank_event()
1005 e->event.seq.time_ns = ktime_to_ns(now); in send_vblank_event()
1008 trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, seq); in send_vblank_event()
1013 * retire-fence timestamp to match exactly with HW vsync as it uses it in send_vblank_event()
1016 drm_send_event_timestamp_locked(dev, &e->base, now); in send_vblank_event()
1020 * drm_crtc_arm_vblank_event - arm vblank event after pageflip
1027 * period. This helper function implements exactly the required vblank arming
1036 * 1. Driver commits new hardware state into vblank-synchronized registers.
1060 struct drm_device *dev = crtc->dev; in drm_crtc_arm_vblank_event()
1063 assert_spin_locked(&dev->event_lock); in drm_crtc_arm_vblank_event()
1065 e->pipe = pipe; in drm_crtc_arm_vblank_event()
1066 e->sequence = drm_crtc_accurate_vblank_count(crtc) + 1; in drm_crtc_arm_vblank_event()
1067 list_add_tail(&e->base.link, &dev->vblank_event_list); in drm_crtc_arm_vblank_event()
1072 * drm_crtc_send_vblank_event - helper to send vblank event after pageflip
1085 struct drm_device *dev = crtc->dev; in drm_crtc_send_vblank_event()
1097 e->pipe = pipe; in drm_crtc_send_vblank_event()
1110 if (crtc->funcs->enable_vblank) in __enable_vblank()
1111 return crtc->funcs->enable_vblank(crtc); in __enable_vblank()
1114 else if (dev->driver->enable_vblank) { in __enable_vblank()
1115 return dev->driver->enable_vblank(dev, pipe); in __enable_vblank()
1119 return -EINVAL; in __enable_vblank()
1124 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_vblank_enable()
1127 assert_spin_locked(&dev->vbl_lock); in drm_vblank_enable()
1129 spin_lock(&dev->vblank_time_lock); in drm_vblank_enable()
1131 if (!vblank->enabled) { in drm_vblank_enable()
1137 * prevent double-accounting of same vblank interval. in drm_vblank_enable()
1143 atomic_dec(&vblank->refcount); in drm_vblank_enable()
1151 WRITE_ONCE(vblank->enabled, true); in drm_vblank_enable()
1155 spin_unlock(&dev->vblank_time_lock); in drm_vblank_enable()
1162 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_vblank_get()
1167 return -EINVAL; in drm_vblank_get()
1169 if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) in drm_vblank_get()
1170 return -EINVAL; in drm_vblank_get()
1172 spin_lock_irqsave(&dev->vbl_lock, irqflags); in drm_vblank_get()
1173 /* Going from 0->1 means we have to enable interrupts again */ in drm_vblank_get()
1174 if (atomic_add_return(1, &vblank->refcount) == 1) { in drm_vblank_get()
1177 if (!vblank->enabled) { in drm_vblank_get()
1178 atomic_dec(&vblank->refcount); in drm_vblank_get()
1179 ret = -EINVAL; in drm_vblank_get()
1182 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); in drm_vblank_get()
1188 * drm_crtc_vblank_get - get a reference count on vblank events
1199 return drm_vblank_get(crtc->dev, drm_crtc_index(crtc)); in drm_crtc_vblank_get()
1205 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_vblank_put()
1207 if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) in drm_vblank_put()
1210 if (drm_WARN_ON(dev, atomic_read(&vblank->refcount) == 0)) in drm_vblank_put()
1214 if (atomic_dec_and_test(&vblank->refcount)) { in drm_vblank_put()
1218 vblank_disable_fn(&vblank->disable_timer); in drm_vblank_put()
1219 else if (!dev->vblank_disable_immediate) in drm_vblank_put()
1220 mod_timer(&vblank->disable_timer, in drm_vblank_put()
1226 * drm_crtc_vblank_put - give up ownership of vblank events
1234 drm_vblank_put(crtc->dev, drm_crtc_index(crtc)); in drm_crtc_vblank_put()
1239 * drm_wait_one_vblank - wait for one vblank
1251 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_wait_one_vblank()
1255 if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) in drm_wait_one_vblank()
1265 ret = wait_event_timeout(vblank->queue, in drm_wait_one_vblank()
1276 * drm_crtc_wait_one_vblank - wait for one vblank
1285 drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc)); in drm_crtc_wait_one_vblank()
1290 * drm_crtc_vblank_off - disable vblank events on a CRTC
1302 struct drm_device *dev = crtc->dev; in drm_crtc_vblank_off()
1304 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_crtc_vblank_off()
1309 if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) in drm_crtc_vblank_off()
1316 spin_lock_irq(&dev->event_lock); in drm_crtc_vblank_off()
1318 spin_lock(&dev->vbl_lock); in drm_crtc_vblank_off()
1320 pipe, vblank->enabled, vblank->inmodeset); in drm_crtc_vblank_off()
1324 if (drm_core_check_feature(dev, DRIVER_ATOMIC) || !vblank->inmodeset) in drm_crtc_vblank_off()
1327 wake_up(&vblank->queue); in drm_crtc_vblank_off()
1330 * Prevent subsequent drm_vblank_get() from re-enabling in drm_crtc_vblank_off()
1333 if (!vblank->inmodeset) { in drm_crtc_vblank_off()
1334 atomic_inc(&vblank->refcount); in drm_crtc_vblank_off()
1335 vblank->inmodeset = 1; in drm_crtc_vblank_off()
1337 spin_unlock(&dev->vbl_lock); in drm_crtc_vblank_off()
1342 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { in drm_crtc_vblank_off()
1343 if (e->pipe != pipe) in drm_crtc_vblank_off()
1347 e->sequence, seq); in drm_crtc_vblank_off()
1348 list_del(&e->base.link); in drm_crtc_vblank_off()
1356 spin_unlock_irq(&dev->event_lock); in drm_crtc_vblank_off()
1358 /* Will be reset by the modeset helpers when re-enabling the crtc by in drm_crtc_vblank_off()
1360 vblank->hwmode.crtc_clock = 0; in drm_crtc_vblank_off()
1368 * drm_crtc_vblank_reset - reset vblank state to off on a CRTC
1381 struct drm_device *dev = crtc->dev; in drm_crtc_vblank_reset()
1383 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_crtc_vblank_reset()
1385 spin_lock_irq(&dev->vbl_lock); in drm_crtc_vblank_reset()
1390 if (!vblank->inmodeset) { in drm_crtc_vblank_reset()
1391 atomic_inc(&vblank->refcount); in drm_crtc_vblank_reset()
1392 vblank->inmodeset = 1; in drm_crtc_vblank_reset()
1394 spin_unlock_irq(&dev->vbl_lock); in drm_crtc_vblank_reset()
1396 drm_WARN_ON(dev, !list_empty(&dev->vblank_event_list)); in drm_crtc_vblank_reset()
1397 drm_WARN_ON(dev, !list_empty(&vblank->pending_work)); in drm_crtc_vblank_reset()
1402 * drm_crtc_set_max_vblank_count - configure the hw max vblank counter value
1414 * maximum can again be set to the appropriate non-zero value.
1421 struct drm_device *dev = crtc->dev; in drm_crtc_set_max_vblank_count()
1423 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_crtc_set_max_vblank_count()
1425 drm_WARN_ON(dev, dev->max_vblank_count); in drm_crtc_set_max_vblank_count()
1426 drm_WARN_ON(dev, !READ_ONCE(vblank->inmodeset)); in drm_crtc_set_max_vblank_count()
1428 vblank->max_vblank_count = max_vblank_count; in drm_crtc_set_max_vblank_count()
1433 * drm_crtc_vblank_on - enable vblank events on a CRTC
1444 struct drm_device *dev = crtc->dev; in drm_crtc_vblank_on()
1446 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_crtc_vblank_on()
1448 if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) in drm_crtc_vblank_on()
1451 spin_lock_irq(&dev->vbl_lock); in drm_crtc_vblank_on()
1453 pipe, vblank->enabled, vblank->inmodeset); in drm_crtc_vblank_on()
1456 if (vblank->inmodeset) { in drm_crtc_vblank_on()
1457 atomic_dec(&vblank->refcount); in drm_crtc_vblank_on()
1458 vblank->inmodeset = 0; in drm_crtc_vblank_on()
1464 * re-enable interrupts if there are users left, or the in drm_crtc_vblank_on()
1467 if (atomic_read(&vblank->refcount) != 0 || drm_vblank_offdelay == 0) in drm_crtc_vblank_on()
1469 spin_unlock_irq(&dev->vbl_lock); in drm_crtc_vblank_on()
1483 if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) in drm_vblank_restore()
1486 assert_spin_locked(&dev->vbl_lock); in drm_vblank_restore()
1487 assert_spin_locked(&dev->vblank_time_lock); in drm_vblank_restore()
1489 vblank = &dev->vblank[pipe]; in drm_vblank_restore()
1491 drm_debug_enabled(DRM_UT_VBL) && !vblank->framedur_ns, in drm_vblank_restore()
1493 framedur_ns = vblank->framedur_ns; in drm_vblank_restore()
1498 } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0); in drm_vblank_restore()
1500 diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time)); in drm_vblank_restore()
1506 "missed %d vblanks in %lld ns, frame duration=%d ns, hw_diff=%d\n", in drm_vblank_restore()
1507 diff, diff_ns, framedur_ns, cur_vblank - vblank->last); in drm_vblank_restore()
1508 vblank->last = (cur_vblank - diff) & max_vblank_count; in drm_vblank_restore()
1512 * drm_crtc_vblank_restore - estimate missed vblanks and update vblank count.
1521 * Note that drivers must have race-free high-precision timestamping support,
1524 * time-stamping functions are race-free against vblank hardware counter
1529 WARN_ON_ONCE(!crtc->funcs->get_vblank_timestamp); in drm_crtc_vblank_restore()
1530 WARN_ON_ONCE(!crtc->dev->vblank_disable_immediate); in drm_crtc_vblank_restore()
1532 drm_vblank_restore(crtc->dev, drm_crtc_index(crtc)); in drm_crtc_vblank_restore()
1539 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_legacy_vblank_pre_modeset()
1545 if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) in drm_legacy_vblank_pre_modeset()
1555 if (!vblank->inmodeset) { in drm_legacy_vblank_pre_modeset()
1556 vblank->inmodeset = 0x1; in drm_legacy_vblank_pre_modeset()
1558 vblank->inmodeset |= 0x2; in drm_legacy_vblank_pre_modeset()
1565 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_legacy_vblank_post_modeset()
1571 if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) in drm_legacy_vblank_post_modeset()
1574 if (vblank->inmodeset) { in drm_legacy_vblank_post_modeset()
1575 spin_lock_irq(&dev->vbl_lock); in drm_legacy_vblank_post_modeset()
1577 spin_unlock_irq(&dev->vbl_lock); in drm_legacy_vblank_post_modeset()
1579 if (vblank->inmodeset & 0x2) in drm_legacy_vblank_post_modeset()
1582 vblank->inmodeset = 0; in drm_legacy_vblank_post_modeset()
1592 /* If drm_vblank_init() hasn't been called yet, just no-op */ in drm_legacy_modeset_ctl_ioctl()
1600 pipe = modeset->crtc; in drm_legacy_modeset_ctl_ioctl()
1601 if (pipe >= dev->num_crtcs) in drm_legacy_modeset_ctl_ioctl()
1602 return -EINVAL; in drm_legacy_modeset_ctl_ioctl()
1604 switch (modeset->cmd) { in drm_legacy_modeset_ctl_ioctl()
1612 return -EINVAL; in drm_legacy_modeset_ctl_ioctl()
1623 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_queue_vblank_event()
1631 ret = -ENOMEM; in drm_queue_vblank_event()
1635 e->pipe = pipe; in drm_queue_vblank_event()
1636 e->event.base.type = DRM_EVENT_VBLANK; in drm_queue_vblank_event()
1637 e->event.base.length = sizeof(e->event.vbl); in drm_queue_vblank_event()
1638 e->event.vbl.user_data = vblwait->request.signal; in drm_queue_vblank_event()
1639 e->event.vbl.crtc_id = 0; in drm_queue_vblank_event()
1644 e->event.vbl.crtc_id = crtc->base.id; in drm_queue_vblank_event()
1647 spin_lock_irq(&dev->event_lock); in drm_queue_vblank_event()
1655 if (!READ_ONCE(vblank->enabled)) { in drm_queue_vblank_event()
1656 ret = -EINVAL; in drm_queue_vblank_event()
1660 ret = drm_event_reserve_init_locked(dev, file_priv, &e->base, in drm_queue_vblank_event()
1661 &e->event.base); in drm_queue_vblank_event()
1673 e->sequence = req_seq; in drm_queue_vblank_event()
1677 vblwait->reply.sequence = seq; in drm_queue_vblank_event()
1680 list_add_tail(&e->base.link, &dev->vblank_event_list); in drm_queue_vblank_event()
1681 vblwait->reply.sequence = req_seq; in drm_queue_vblank_event()
1684 spin_unlock_irq(&dev->event_lock); in drm_queue_vblank_event()
1689 spin_unlock_irq(&dev->event_lock); in drm_queue_vblank_event()
1698 if (vblwait->request.sequence) in drm_wait_vblank_is_query()
1702 (vblwait->request.type & (_DRM_VBLANK_TYPES_MASK | in drm_wait_vblank_is_query()
1708 * Widen a 32-bit param to 64-bits.
1710 * \param narrow 32-bit value (missing upper 32 bits)
1711 * \param near 64-bit value that should be 'close' to near
1713 * This function returns a 64-bit value using the lower 32-bits from
1714 * 'narrow' and constructing the upper 32-bits so that the result is
1720 return near + (s32) (narrow - near); in widen_32_to_64()
1732 * timestamps since linux-4.15. in drm_wait_vblank_reply()
1734 reply->sequence = drm_vblank_count_and_time(dev, pipe, &now); in drm_wait_vblank_reply()
1736 reply->tval_sec = (u32)ts.tv_sec; in drm_wait_vblank_reply()
1737 reply->tval_usec = ts.tv_nsec / 1000; in drm_wait_vblank_reply()
1744 return dev->irq_enabled; in drm_wait_vblank_supported()
1761 return -EOPNOTSUPP; in drm_wait_vblank_ioctl()
1763 if (vblwait->request.type & _DRM_VBLANK_SIGNAL) in drm_wait_vblank_ioctl()
1764 return -EINVAL; in drm_wait_vblank_ioctl()
1766 if (vblwait->request.type & in drm_wait_vblank_ioctl()
1771 vblwait->request.type, in drm_wait_vblank_ioctl()
1774 return -EINVAL; in drm_wait_vblank_ioctl()
1777 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; in drm_wait_vblank_ioctl()
1778 high_pipe = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK); in drm_wait_vblank_ioctl()
1784 /* Convert lease-relative crtc index into global crtc index */ in drm_wait_vblank_ioctl()
1788 if (drm_lease_held(file_priv, crtc->base.id)) { in drm_wait_vblank_ioctl()
1791 pipe_index--; in drm_wait_vblank_ioctl()
1799 if (pipe >= dev->num_crtcs) in drm_wait_vblank_ioctl()
1800 return -EINVAL; in drm_wait_vblank_ioctl()
1802 vblank = &dev->vblank[pipe]; in drm_wait_vblank_ioctl()
1804 /* If the counter is currently enabled and accurate, short-circuit in drm_wait_vblank_ioctl()
1807 if (dev->vblank_disable_immediate && in drm_wait_vblank_ioctl()
1809 READ_ONCE(vblank->enabled)) { in drm_wait_vblank_ioctl()
1810 drm_wait_vblank_reply(dev, pipe, &vblwait->reply); in drm_wait_vblank_ioctl()
1823 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { in drm_wait_vblank_ioctl()
1825 req_seq = seq + vblwait->request.sequence; in drm_wait_vblank_ioctl()
1826 vblwait->request.sequence = req_seq; in drm_wait_vblank_ioctl()
1827 vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; in drm_wait_vblank_ioctl()
1830 req_seq = widen_32_to_64(vblwait->request.sequence, seq); in drm_wait_vblank_ioctl()
1833 ret = -EINVAL; in drm_wait_vblank_ioctl()
1840 vblwait->request.type &= ~_DRM_VBLANK_NEXTONMISS; in drm_wait_vblank_ioctl()
1841 vblwait->request.sequence = req_seq; in drm_wait_vblank_ioctl()
1845 /* must hold on to the vblank ref until the event fires in drm_wait_vblank_ioctl()
1856 wait = wait_event_interruptible_timeout(vblank->queue, in drm_wait_vblank_ioctl()
1858 !READ_ONCE(vblank->enabled), in drm_wait_vblank_ioctl()
1864 ret = -EBUSY; in drm_wait_vblank_ioctl()
1866 case -ERESTARTSYS: in drm_wait_vblank_ioctl()
1868 ret = -EINTR; in drm_wait_vblank_ioctl()
1876 if (ret != -EINTR) { in drm_wait_vblank_ioctl()
1877 drm_wait_vblank_reply(dev, pipe, &vblwait->reply); in drm_wait_vblank_ioctl()
1880 pipe, vblwait->reply.sequence); in drm_wait_vblank_ioctl()
1899 assert_spin_locked(&dev->event_lock); in drm_handle_vblank_events()
1903 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { in drm_handle_vblank_events()
1904 if (e->pipe != pipe) in drm_handle_vblank_events()
1906 if (!drm_vblank_passed(seq, e->sequence)) in drm_handle_vblank_events()
1910 e->sequence, seq); in drm_handle_vblank_events()
1912 list_del(&e->base.link); in drm_handle_vblank_events()
1917 if (crtc && crtc->funcs->get_vblank_timestamp) in drm_handle_vblank_events()
1924 * drm_handle_vblank - handle a vblank event
1935 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; in drm_handle_vblank()
1942 if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) in drm_handle_vblank()
1945 spin_lock_irqsave(&dev->event_lock, irqflags); in drm_handle_vblank()
1951 spin_lock(&dev->vblank_time_lock); in drm_handle_vblank()
1954 if (!vblank->enabled) { in drm_handle_vblank()
1955 spin_unlock(&dev->vblank_time_lock); in drm_handle_vblank()
1956 spin_unlock_irqrestore(&dev->event_lock, irqflags); in drm_handle_vblank()
1962 spin_unlock(&dev->vblank_time_lock); in drm_handle_vblank()
1964 wake_up(&vblank->queue); in drm_handle_vblank()
1966 /* With instant-off, we defer disabling the interrupt until after in drm_handle_vblank()
1971 disable_irq = (dev->vblank_disable_immediate && in drm_handle_vblank()
1973 !atomic_read(&vblank->refcount)); in drm_handle_vblank()
1978 spin_unlock_irqrestore(&dev->event_lock, irqflags); in drm_handle_vblank()
1981 vblank_disable_fn(&vblank->disable_timer); in drm_handle_vblank()
1988 * drm_crtc_handle_vblank - handle a vblank event
2009 return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc)); in drm_crtc_handle_vblank()
2033 return -EOPNOTSUPP; in drm_crtc_get_sequence_ioctl()
2036 return -EOPNOTSUPP; in drm_crtc_get_sequence_ioctl()
2038 crtc = drm_crtc_find(dev, file_priv, get_seq->crtc_id); in drm_crtc_get_sequence_ioctl()
2040 return -ENOENT; in drm_crtc_get_sequence_ioctl()
2044 vblank = &dev->vblank[pipe]; in drm_crtc_get_sequence_ioctl()
2045 vblank_enabled = dev->vblank_disable_immediate && READ_ONCE(vblank->enabled); in drm_crtc_get_sequence_ioctl()
2056 drm_modeset_lock(&crtc->mutex, NULL); in drm_crtc_get_sequence_ioctl()
2057 if (crtc->state) in drm_crtc_get_sequence_ioctl()
2058 get_seq->active = crtc->state->enable; in drm_crtc_get_sequence_ioctl()
2060 get_seq->active = crtc->enabled; in drm_crtc_get_sequence_ioctl()
2061 drm_modeset_unlock(&crtc->mutex); in drm_crtc_get_sequence_ioctl()
2062 get_seq->sequence = drm_vblank_count_and_time(dev, pipe, &now); in drm_crtc_get_sequence_ioctl()
2063 get_seq->sequence_ns = ktime_to_ns(now); in drm_crtc_get_sequence_ioctl()
2092 return -EOPNOTSUPP; in drm_crtc_queue_sequence_ioctl()
2095 return -EOPNOTSUPP; in drm_crtc_queue_sequence_ioctl()
2097 crtc = drm_crtc_find(dev, file_priv, queue_seq->crtc_id); in drm_crtc_queue_sequence_ioctl()
2099 return -ENOENT; in drm_crtc_queue_sequence_ioctl()
2101 flags = queue_seq->flags; in drm_crtc_queue_sequence_ioctl()
2105 return -EINVAL; in drm_crtc_queue_sequence_ioctl()
2109 vblank = &dev->vblank[pipe]; in drm_crtc_queue_sequence_ioctl()
2113 return -ENOMEM; in drm_crtc_queue_sequence_ioctl()
2124 req_seq = queue_seq->sequence; in drm_crtc_queue_sequence_ioctl()
2132 e->pipe = pipe; in drm_crtc_queue_sequence_ioctl()
2133 e->event.base.type = DRM_EVENT_CRTC_SEQUENCE; in drm_crtc_queue_sequence_ioctl()
2134 e->event.base.length = sizeof(e->event.seq); in drm_crtc_queue_sequence_ioctl()
2135 e->event.seq.user_data = queue_seq->user_data; in drm_crtc_queue_sequence_ioctl()
2137 spin_lock_irq(&dev->event_lock); in drm_crtc_queue_sequence_ioctl()
2145 if (!READ_ONCE(vblank->enabled)) { in drm_crtc_queue_sequence_ioctl()
2146 ret = -EINVAL; in drm_crtc_queue_sequence_ioctl()
2150 ret = drm_event_reserve_init_locked(dev, file_priv, &e->base, in drm_crtc_queue_sequence_ioctl()
2151 &e->event.base); in drm_crtc_queue_sequence_ioctl()
2156 e->sequence = req_seq; in drm_crtc_queue_sequence_ioctl()
2161 queue_seq->sequence = seq; in drm_crtc_queue_sequence_ioctl()
2164 list_add_tail(&e->base.link, &dev->vblank_event_list); in drm_crtc_queue_sequence_ioctl()
2165 queue_seq->sequence = req_seq; in drm_crtc_queue_sequence_ioctl()
2168 spin_unlock_irq(&dev->event_lock); in drm_crtc_queue_sequence_ioctl()
2172 spin_unlock_irq(&dev->event_lock); in drm_crtc_queue_sequence_ioctl()