Lines Matching full:crtc
40 #define vblanktimestamp(dev, crtc, count) ( \ argument
41 (dev)->_vblank_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \
82 * Clear vblank timestamp buffer for a crtc.
84 static void clear_vblank_timestamps(struct drm_device *dev, int crtc) in clear_vblank_timestamps() argument
86 memset(&dev->_vblank_time[crtc * DRM_VBLANKTIME_RBSIZE], 0, in clear_vblank_timestamps()
91 * Disable vblank irq's on crtc, make sure that last vblank count
96 static void vblank_disable_and_save(struct drm_device *dev, int crtc) in vblank_disable_and_save() argument
110 dev->driver->disable_vblank(dev, crtc); in vblank_disable_and_save()
111 dev->vblank_enabled[crtc] = 0; in vblank_disable_and_save()
126 dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); in vblank_disable_and_save()
127 vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0); in vblank_disable_and_save()
128 …} while (dev->last_vblank[crtc] != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblr… in vblank_disable_and_save()
136 vblcount = atomic_read(&dev->_vblank_count[crtc]); in vblank_disable_and_save()
138 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); in vblank_disable_and_save()
153 atomic_inc(&dev->_vblank_count[crtc]); in vblank_disable_and_save()
158 clear_vblank_timestamps(dev, crtc); in vblank_disable_and_save()
175 DRM_DEBUG("disabling vblank on crtc %d\n", i); in vblank_disable_fn()
260 /* Zero per-crtc vblank stuff */ in drm_vblank_init()
451 * They are derived from crtc's true scanout timing,
455 * @crtc drm_crtc whose timestamp constants should be updated.
458 void drm_calc_timestamping_constants(struct drm_crtc *crtc) in drm_calc_timestamping_constants() argument
464 dotclock = (u64) crtc->hwmode.clock * 1000; in drm_calc_timestamping_constants()
469 if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE) in drm_calc_timestamping_constants()
479 linedur_ns = (s64) div64_u64(((u64) crtc->hwmode.crtc_htotal * in drm_calc_timestamping_constants()
481 framedur_ns = (s64) crtc->hwmode.crtc_vtotal * linedur_ns; in drm_calc_timestamping_constants()
483 DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n", in drm_calc_timestamping_constants()
484 crtc->base.id); in drm_calc_timestamping_constants()
486 crtc->pixeldur_ns = pixeldur_ns; in drm_calc_timestamping_constants()
487 crtc->linedur_ns = linedur_ns; in drm_calc_timestamping_constants()
488 crtc->framedur_ns = framedur_ns; in drm_calc_timestamping_constants()
490 DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n", in drm_calc_timestamping_constants()
491 crtc->base.id, crtc->hwmode.crtc_htotal, in drm_calc_timestamping_constants()
492 crtc->hwmode.crtc_vtotal, crtc->hwmode.crtc_vdisplay); in drm_calc_timestamping_constants()
493 DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n", in drm_calc_timestamping_constants()
494 crtc->base.id, (int) dotclock/1000, (int) framedur_ns, in drm_calc_timestamping_constants()
503 * of a crtc. This can be called from within get_vblank_timestamp()
520 * @crtc: Which crtc's vblank timestamp to retrieve.
527 * @refcrtc: drm_crtc* of crtc which defines scanout timing.
532 * -EINVAL - Invalid crtc.
543 int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, in drm_calc_vbltimestamp_from_scanoutpos() argument
556 if (crtc < 0 || crtc >= dev->num_crtcs) { in drm_calc_vbltimestamp_from_scanoutpos()
557 DRM_ERROR("Invalid crtc %d\n", crtc); in drm_calc_vbltimestamp_from_scanoutpos()
577 * Happens during initial modesetting of a crtc. in drm_calc_vbltimestamp_from_scanoutpos()
580 DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); in drm_calc_vbltimestamp_from_scanoutpos()
601 vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, &hpos); in drm_calc_vbltimestamp_from_scanoutpos()
614 DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n", in drm_calc_vbltimestamp_from_scanoutpos()
615 crtc, vbl_status); in drm_calc_vbltimestamp_from_scanoutpos()
628 DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n", in drm_calc_vbltimestamp_from_scanoutpos()
629 crtc, (int) duration_ns/1000, *max_error/1000, i); in drm_calc_vbltimestamp_from_scanoutpos()
678 DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %jd.%jd -> %jd.%jd [e %d us, %d rep]\n", in drm_calc_vbltimestamp_from_scanoutpos()
679 crtc, (int)vbl_status, hpos, vpos, (uintmax_t)raw_time.tv_sec, in drm_calc_vbltimestamp_from_scanoutpos()
709 * @crtc: which crtc's vblank timestamp to retrieve
716 * vblank interval on specified crtc. May call into kms-driver to
724 u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, in drm_get_last_vbltimestamp() argument
734 ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error, in drm_get_last_vbltimestamp()
752 * @crtc: which counter to retrieve
758 u32 drm_vblank_count(struct drm_device *dev, int crtc) in drm_vblank_count() argument
760 return atomic_read(&dev->_vblank_count[crtc]); in drm_vblank_count()
769 * @crtc: which counter to retrieve
778 u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, in drm_vblank_count_and_time() argument
789 cur_vblank = atomic_read(&dev->_vblank_count[crtc]); in drm_vblank_count_and_time()
790 *vblanktime = vblanktimestamp(dev, crtc, cur_vblank); in drm_vblank_count_and_time()
792 } while (cur_vblank != atomic_read(&dev->_vblank_count[crtc])); in drm_vblank_count_and_time()
817 * @crtc: CRTC in question
823 void drm_send_vblank_event(struct drm_device *dev, int crtc, in drm_send_vblank_event() argument
828 if (crtc >= 0) { in drm_send_vblank_event()
829 seq = drm_vblank_count_and_time(dev, crtc, &now); in drm_send_vblank_event()
842 * @crtc: counter to update
845 * (specified by @crtc). Deal with wraparound, if it occurred, and
855 static void drm_update_vblank_count(struct drm_device *dev, int crtc) in drm_update_vblank_count() argument
873 cur_vblank = dev->driver->get_vblank_counter(dev, crtc); in drm_update_vblank_count()
874 rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0); in drm_update_vblank_count()
875 } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc)); in drm_update_vblank_count()
878 diff = cur_vblank - dev->last_vblank[crtc]; in drm_update_vblank_count()
879 if (cur_vblank < dev->last_vblank[crtc]) { in drm_update_vblank_count()
883 crtc, dev->last_vblank[crtc], cur_vblank, diff); in drm_update_vblank_count()
886 DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", in drm_update_vblank_count()
887 crtc, diff); in drm_update_vblank_count()
894 tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; in drm_update_vblank_count()
895 vblanktimestamp(dev, crtc, tslot) = t_vblank; in drm_update_vblank_count()
899 atomic_add(diff, &dev->_vblank_count[crtc]); in drm_update_vblank_count()
906 * @crtc: which CRTC to own
914 int drm_vblank_get(struct drm_device *dev, int crtc) in drm_vblank_get() argument
920 if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { in drm_vblank_get()
922 if (!dev->vblank_enabled[crtc]) { in drm_vblank_get()
929 ret = dev->driver->enable_vblank(dev, crtc); in drm_vblank_get()
930 DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", in drm_vblank_get()
931 crtc, ret); in drm_vblank_get()
933 atomic_dec(&dev->vblank_refcount[crtc]); in drm_vblank_get()
935 dev->vblank_enabled[crtc] = 1; in drm_vblank_get()
936 drm_update_vblank_count(dev, crtc); in drm_vblank_get()
941 if (!dev->vblank_enabled[crtc]) { in drm_vblank_get()
942 atomic_dec(&dev->vblank_refcount[crtc]); in drm_vblank_get()
955 * @crtc: which counter to give up
960 void drm_vblank_put(struct drm_device *dev, int crtc) in drm_vblank_put() argument
962 BUG_ON(atomic_read(&dev->vblank_refcount[crtc]) == 0); in drm_vblank_put()
965 if (atomic_dec_and_test(&dev->vblank_refcount[crtc]) && in drm_vblank_put()
974 * drm_vblank_off - disable vblank events on a CRTC
976 * @crtc: CRTC in question
980 void drm_vblank_off(struct drm_device *dev, int crtc) in drm_vblank_off() argument
987 vblank_disable_and_save(dev, crtc); in drm_vblank_off()
988 DRM_WAKEUP(&dev->_vblank_count[crtc]); in drm_vblank_off()
991 seq = drm_vblank_count_and_time(dev, crtc, &now); in drm_vblank_off()
995 if (e->pipe != crtc) in drm_vblank_off()
1013 * @crtc: CRTC in question
1018 void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) in drm_vblank_pre_modeset() argument
1026 * have the kernel take a reference on the CRTC (just once though in drm_vblank_pre_modeset()
1030 if (!dev->vblank_inmodeset[crtc]) { in drm_vblank_pre_modeset()
1031 dev->vblank_inmodeset[crtc] = 0x1; in drm_vblank_pre_modeset()
1032 if (drm_vblank_get(dev, crtc) == 0) in drm_vblank_pre_modeset()
1033 dev->vblank_inmodeset[crtc] |= 0x2; in drm_vblank_pre_modeset()
1038 void drm_vblank_post_modeset(struct drm_device *dev, int crtc) in drm_vblank_post_modeset() argument
1044 if (dev->vblank_inmodeset[crtc]) { in drm_vblank_post_modeset()
1049 if (dev->vblank_inmodeset[crtc] & 0x2) in drm_vblank_post_modeset()
1050 drm_vblank_put(dev, crtc); in drm_vblank_post_modeset()
1052 dev->vblank_inmodeset[crtc] = 0; in drm_vblank_post_modeset()
1072 unsigned int crtc; in drm_modeset_ctl() local
1082 crtc = modeset->crtc; in drm_modeset_ctl()
1083 if (crtc >= dev->num_crtcs) in drm_modeset_ctl()
1088 drm_vblank_pre_modeset(dev, crtc); in drm_modeset_ctl()
1091 drm_vblank_post_modeset(dev, crtc); in drm_modeset_ctl()
1147 DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n", in drm_queue_vblank_event()
1195 unsigned int flags, seq, crtc, high_crtc; in drm_wait_vblank() local
1216 crtc = high_crtc >> _DRM_VBLANK_HIGH_CRTC_SHIFT; in drm_wait_vblank()
1218 crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; in drm_wait_vblank()
1219 if (crtc >= dev->num_crtcs) in drm_wait_vblank()
1222 ret = drm_vblank_get(dev, crtc); in drm_wait_vblank()
1227 seq = drm_vblank_count(dev, crtc); in drm_wait_vblank()
1244 return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); in drm_wait_vblank()
1252 DRM_DEBUG("waiting on vblank count %d, crtc %d\n", in drm_wait_vblank()
1253 vblwait->request.sequence, crtc); in drm_wait_vblank()
1254 dev->last_vblank_wait[crtc] = vblwait->request.sequence; in drm_wait_vblank()
1256 while (((drm_vblank_count(dev, crtc) - vblwait->request.sequence) > in drm_wait_vblank()
1263 * application when crtc is disabled or irq in drm_wait_vblank()
1266 ret = -msleep(&dev->_vblank_count[crtc], &dev->vblank_time_lock, in drm_wait_vblank()
1278 reply_seq = drm_vblank_count_and_time(dev, crtc, &now); in drm_wait_vblank()
1280 curproc->p_pid, crtc, vblwait->request.type, in drm_wait_vblank()
1291 curproc->p_pid, crtc, vblwait->request.type, ret, in drm_wait_vblank()
1298 drm_vblank_put(dev, crtc); in drm_wait_vblank()
1302 static void drm_handle_vblank_events(struct drm_device *dev, int crtc) in drm_handle_vblank_events() argument
1308 seq = drm_vblank_count_and_time(dev, crtc, &now); in drm_handle_vblank_events()
1313 if (e->pipe != crtc) in drm_handle_vblank_events()
1328 CTR2(KTR_DRM, "drm_handle_vblank_events %d %d", seq, crtc); in drm_handle_vblank_events()
1334 * @crtc: where this event occurred
1339 bool drm_handle_vblank(struct drm_device *dev, int crtc) in drm_handle_vblank() argument
1355 if (!dev->vblank_enabled[crtc]) { in drm_handle_vblank()
1365 vblcount = atomic_read(&dev->_vblank_count[crtc]); in drm_handle_vblank()
1366 drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ); in drm_handle_vblank()
1370 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); in drm_handle_vblank()
1383 vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; in drm_handle_vblank()
1389 atomic_inc(&dev->_vblank_count[crtc]); in drm_handle_vblank()
1392 DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", in drm_handle_vblank()
1393 crtc, (int) diff_ns); in drm_handle_vblank()
1396 DRM_WAKEUP(&dev->_vblank_count[crtc]); in drm_handle_vblank()
1397 drm_handle_vblank_events(dev, crtc); in drm_handle_vblank()