Lines Matching refs:dev
42 #define vblanktimestamp(dev, crtc, count) ( \ argument
43 (dev)->_vblank_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \
69 int drm_irq_by_busid(struct drm_device *dev, void *data, in drm_irq_by_busid() argument
74 if (!dev->driver->bus->irq_by_busid) in drm_irq_by_busid()
77 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) in drm_irq_by_busid()
80 return dev->driver->bus->irq_by_busid(dev, p); in drm_irq_by_busid()
86 static void clear_vblank_timestamps(struct drm_device *dev, int crtc) in clear_vblank_timestamps() argument
88 memset(&dev->_vblank_time[crtc * DRM_VBLANKTIME_RBSIZE], 0, in clear_vblank_timestamps()
98 static void vblank_disable_and_save(struct drm_device *dev, int crtc) in vblank_disable_and_save() argument
110 mtx_lock(&dev->vblank_time_lock); in vblank_disable_and_save()
112 dev->driver->disable_vblank(dev, crtc); in vblank_disable_and_save()
113 dev->vblank_enabled[crtc] = 0; in vblank_disable_and_save()
128 dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); in vblank_disable_and_save()
129 vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0); in vblank_disable_and_save()
130 …} while (dev->last_vblank[crtc] != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblr… in vblank_disable_and_save()
138 vblcount = atomic_read(&dev->_vblank_count[crtc]); in vblank_disable_and_save()
140 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); in vblank_disable_and_save()
155 atomic_inc(&dev->_vblank_count[crtc]); in vblank_disable_and_save()
160 clear_vblank_timestamps(dev, crtc); in vblank_disable_and_save()
162 mtx_unlock(&dev->vblank_time_lock); in vblank_disable_and_save()
167 struct drm_device *dev = (struct drm_device *)arg; in vblank_disable_fn() local
170 if (!dev->vblank_disable_allowed) in vblank_disable_fn()
173 for (i = 0; i < dev->num_crtcs; i++) { in vblank_disable_fn()
174 mtx_lock(&dev->vbl_lock); in vblank_disable_fn()
175 if (atomic_read(&dev->vblank_refcount[i]) == 0 && in vblank_disable_fn()
176 dev->vblank_enabled[i]) { in vblank_disable_fn()
178 vblank_disable_and_save(dev, i); in vblank_disable_fn()
180 mtx_unlock(&dev->vbl_lock); in vblank_disable_fn()
184 void drm_vblank_cleanup(struct drm_device *dev) in drm_vblank_cleanup() argument
187 if (dev->num_crtcs == 0) in drm_vblank_cleanup()
190 callout_stop(&dev->vblank_disable_callout); in drm_vblank_cleanup()
192 vblank_disable_fn(dev); in drm_vblank_cleanup()
194 free(dev->_vblank_count, DRM_MEM_VBLANK); in drm_vblank_cleanup()
195 free(dev->vblank_refcount, DRM_MEM_VBLANK); in drm_vblank_cleanup()
196 free(dev->vblank_enabled, DRM_MEM_VBLANK); in drm_vblank_cleanup()
197 free(dev->last_vblank, DRM_MEM_VBLANK); in drm_vblank_cleanup()
198 free(dev->last_vblank_wait, DRM_MEM_VBLANK); in drm_vblank_cleanup()
199 free(dev->vblank_inmodeset, DRM_MEM_VBLANK); in drm_vblank_cleanup()
200 free(dev->_vblank_time, DRM_MEM_VBLANK); in drm_vblank_cleanup()
202 mtx_destroy(&dev->vbl_lock); in drm_vblank_cleanup()
203 mtx_destroy(&dev->vblank_time_lock); in drm_vblank_cleanup()
205 dev->num_crtcs = 0; in drm_vblank_cleanup()
209 int drm_vblank_init(struct drm_device *dev, int num_crtcs) in drm_vblank_init() argument
213 callout_init(&dev->vblank_disable_callout, 1); in drm_vblank_init()
214 mtx_init(&dev->vbl_lock, "drmvbl", NULL, MTX_DEF); in drm_vblank_init()
215 mtx_init(&dev->vblank_time_lock, "drmvtl", NULL, MTX_DEF); in drm_vblank_init()
217 dev->num_crtcs = num_crtcs; in drm_vblank_init()
219 dev->_vblank_count = malloc(sizeof(atomic_t) * num_crtcs, in drm_vblank_init()
221 if (!dev->_vblank_count) in drm_vblank_init()
224 dev->vblank_refcount = malloc(sizeof(atomic_t) * num_crtcs, in drm_vblank_init()
226 if (!dev->vblank_refcount) in drm_vblank_init()
229 dev->vblank_enabled = malloc(num_crtcs * sizeof(int), in drm_vblank_init()
231 if (!dev->vblank_enabled) in drm_vblank_init()
234 dev->last_vblank = malloc(num_crtcs * sizeof(u32), in drm_vblank_init()
236 if (!dev->last_vblank) in drm_vblank_init()
239 dev->last_vblank_wait = malloc(num_crtcs * sizeof(u32), in drm_vblank_init()
241 if (!dev->last_vblank_wait) in drm_vblank_init()
244 dev->vblank_inmodeset = malloc(num_crtcs * sizeof(int), in drm_vblank_init()
246 if (!dev->vblank_inmodeset) in drm_vblank_init()
249 dev->_vblank_time = malloc(num_crtcs * DRM_VBLANKTIME_RBSIZE * in drm_vblank_init()
251 if (!dev->_vblank_time) in drm_vblank_init()
257 if (dev->driver->get_vblank_timestamp) in drm_vblank_init()
264 atomic_set(&dev->_vblank_count[i], 0); in drm_vblank_init()
265 atomic_set(&dev->vblank_refcount[i], 0); in drm_vblank_init()
268 dev->vblank_disable_allowed = 0; in drm_vblank_init()
272 drm_vblank_cleanup(dev); in drm_vblank_init()
286 int drm_irq_install(struct drm_device *dev) in drm_irq_install() argument
291 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) in drm_irq_install()
294 if (drm_dev_to_irq(dev) == 0) in drm_irq_install()
297 DRM_LOCK(dev); in drm_irq_install()
300 if (!dev->dev_private) { in drm_irq_install()
301 DRM_UNLOCK(dev); in drm_irq_install()
305 if (dev->irq_enabled) { in drm_irq_install()
306 DRM_UNLOCK(dev); in drm_irq_install()
309 dev->irq_enabled = 1; in drm_irq_install()
310 DRM_UNLOCK(dev); in drm_irq_install()
312 DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); in drm_irq_install()
315 if (dev->driver->irq_preinstall) in drm_irq_install()
316 dev->driver->irq_preinstall(dev); in drm_irq_install()
320 if (!drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) in drm_irq_install()
331 ret = -bus_setup_intr(dev->dev, dev->irqr, sh_flags, NULL, in drm_irq_install()
332 dev->driver->irq_handler, dev, &dev->irqh); in drm_irq_install()
335 device_printf(dev->dev, "Error setting interrupt: %d\n", -ret); in drm_irq_install()
336 DRM_LOCK(dev); in drm_irq_install()
337 dev->irq_enabled = 0; in drm_irq_install()
338 DRM_UNLOCK(dev); in drm_irq_install()
343 if (dev->driver->irq_postinstall) in drm_irq_install()
344 ret = dev->driver->irq_postinstall(dev); in drm_irq_install()
347 DRM_LOCK(dev); in drm_irq_install()
348 dev->irq_enabled = 0; in drm_irq_install()
349 DRM_UNLOCK(dev); in drm_irq_install()
350 bus_teardown_intr(dev->dev, dev->irqr, dev->irqh); in drm_irq_install()
351 dev->driver->bus->free_irq(dev); in drm_irq_install()
365 int drm_irq_uninstall(struct drm_device *dev) in drm_irq_uninstall() argument
369 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) in drm_irq_uninstall()
372 DRM_LOCK(dev); in drm_irq_uninstall()
373 irq_enabled = dev->irq_enabled; in drm_irq_uninstall()
374 dev->irq_enabled = 0; in drm_irq_uninstall()
375 DRM_UNLOCK(dev); in drm_irq_uninstall()
380 if (dev->num_crtcs) { in drm_irq_uninstall()
381 mtx_lock(&dev->vbl_lock); in drm_irq_uninstall()
382 for (i = 0; i < dev->num_crtcs; i++) { in drm_irq_uninstall()
383 DRM_WAKEUP(&dev->_vblank_count[i]); in drm_irq_uninstall()
384 dev->vblank_enabled[i] = 0; in drm_irq_uninstall()
385 dev->last_vblank[i] = in drm_irq_uninstall()
386 dev->driver->get_vblank_counter(dev, i); in drm_irq_uninstall()
388 mtx_unlock(&dev->vbl_lock); in drm_irq_uninstall()
394 DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); in drm_irq_uninstall()
396 if (dev->driver->irq_uninstall) in drm_irq_uninstall()
397 dev->driver->irq_uninstall(dev); in drm_irq_uninstall()
399 bus_teardown_intr(dev->dev, dev->irqr, dev->irqh); in drm_irq_uninstall()
400 dev->driver->bus->free_irq(dev); in drm_irq_uninstall()
417 int drm_control(struct drm_device *dev, void *data, in drm_control() argument
429 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) in drm_control()
431 if (drm_core_check_feature(dev, DRIVER_MODESET)) in drm_control()
433 if (dev->if_version < DRM_IF_VERSION(1, 2) && in drm_control()
434 ctl->irq != drm_dev_to_irq(dev)) in drm_control()
436 return drm_irq_install(dev); in drm_control()
438 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) in drm_control()
440 if (drm_core_check_feature(dev, DRIVER_MODESET)) in drm_control()
442 return drm_irq_uninstall(dev); in drm_control()
545 int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, in drm_calc_vbltimestamp_from_scanoutpos() argument
558 if (crtc < 0 || crtc >= dev->num_crtcs) { in drm_calc_vbltimestamp_from_scanoutpos()
564 if (!dev->driver->get_scanout_position) { in drm_calc_vbltimestamp_from_scanoutpos()
603 vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, &hpos); in drm_calc_vbltimestamp_from_scanoutpos()
726 u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, in drm_get_last_vbltimestamp() argument
735 if (dev->driver->get_vblank_timestamp && (max_error > 0)) { in drm_get_last_vbltimestamp()
736 ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error, in drm_get_last_vbltimestamp()
760 u32 drm_vblank_count(struct drm_device *dev, int crtc) in drm_vblank_count() argument
762 return atomic_read(&dev->_vblank_count[crtc]); in drm_vblank_count()
780 u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, in drm_vblank_count_and_time() argument
791 cur_vblank = atomic_read(&dev->_vblank_count[crtc]); in drm_vblank_count_and_time()
792 *vblanktime = vblanktimestamp(dev, crtc, cur_vblank); in drm_vblank_count_and_time()
794 } while (cur_vblank != atomic_read(&dev->_vblank_count[crtc])); in drm_vblank_count_and_time()
800 static void send_vblank_event(struct drm_device *dev, in send_vblank_event() argument
804 WARN_ON_SMP(!mtx_owned(&dev->event_lock)); in send_vblank_event()
825 void drm_send_vblank_event(struct drm_device *dev, int crtc, in drm_send_vblank_event() argument
831 seq = drm_vblank_count_and_time(dev, crtc, &now); in drm_send_vblank_event()
837 send_vblank_event(dev, e, seq, &now); in drm_send_vblank_event()
857 static void drm_update_vblank_count(struct drm_device *dev, int crtc) in drm_update_vblank_count() argument
875 cur_vblank = dev->driver->get_vblank_counter(dev, crtc); in drm_update_vblank_count()
876 rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0); in drm_update_vblank_count()
877 } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc)); in drm_update_vblank_count()
880 diff = cur_vblank - dev->last_vblank[crtc]; in drm_update_vblank_count()
881 if (cur_vblank < dev->last_vblank[crtc]) { in drm_update_vblank_count()
882 diff += dev->max_vblank_count; in drm_update_vblank_count()
885 crtc, dev->last_vblank[crtc], cur_vblank, diff); in drm_update_vblank_count()
896 tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; in drm_update_vblank_count()
897 vblanktimestamp(dev, crtc, tslot) = t_vblank; in drm_update_vblank_count()
901 atomic_add(diff, &dev->_vblank_count[crtc]); in drm_update_vblank_count()
916 int drm_vblank_get(struct drm_device *dev, int crtc) in drm_vblank_get() argument
920 mtx_lock(&dev->vbl_lock); in drm_vblank_get()
922 if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { in drm_vblank_get()
923 mtx_lock(&dev->vblank_time_lock); in drm_vblank_get()
924 if (!dev->vblank_enabled[crtc]) { in drm_vblank_get()
931 ret = dev->driver->enable_vblank(dev, crtc); in drm_vblank_get()
935 atomic_dec(&dev->vblank_refcount[crtc]); in drm_vblank_get()
937 dev->vblank_enabled[crtc] = 1; in drm_vblank_get()
938 drm_update_vblank_count(dev, crtc); in drm_vblank_get()
941 mtx_unlock(&dev->vblank_time_lock); in drm_vblank_get()
943 if (!dev->vblank_enabled[crtc]) { in drm_vblank_get()
944 atomic_dec(&dev->vblank_refcount[crtc]); in drm_vblank_get()
948 mtx_unlock(&dev->vbl_lock); in drm_vblank_get()
962 void drm_vblank_put(struct drm_device *dev, int crtc) in drm_vblank_put() argument
964 BUG_ON(atomic_read(&dev->vblank_refcount[crtc]) == 0); in drm_vblank_put()
967 if (atomic_dec_and_test(&dev->vblank_refcount[crtc]) && in drm_vblank_put()
969 callout_reset(&dev->vblank_disable_callout, in drm_vblank_put()
971 vblank_disable_fn, dev); in drm_vblank_put()
982 void drm_vblank_off(struct drm_device *dev, int crtc) in drm_vblank_off() argument
988 mtx_lock(&dev->vbl_lock); in drm_vblank_off()
989 vblank_disable_and_save(dev, crtc); in drm_vblank_off()
990 DRM_WAKEUP(&dev->_vblank_count[crtc]); in drm_vblank_off()
993 seq = drm_vblank_count_and_time(dev, crtc, &now); in drm_vblank_off()
995 mtx_lock(&dev->event_lock); in drm_vblank_off()
996 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { in drm_vblank_off()
1003 drm_vblank_put(dev, e->pipe); in drm_vblank_off()
1004 send_vblank_event(dev, e, seq, &now); in drm_vblank_off()
1006 mtx_unlock(&dev->event_lock); in drm_vblank_off()
1008 mtx_unlock(&dev->vbl_lock); in drm_vblank_off()
1020 void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) in drm_vblank_pre_modeset() argument
1023 if (!dev->num_crtcs) in drm_vblank_pre_modeset()
1032 if (!dev->vblank_inmodeset[crtc]) { in drm_vblank_pre_modeset()
1033 dev->vblank_inmodeset[crtc] = 0x1; in drm_vblank_pre_modeset()
1034 if (drm_vblank_get(dev, crtc) == 0) in drm_vblank_pre_modeset()
1035 dev->vblank_inmodeset[crtc] |= 0x2; in drm_vblank_pre_modeset()
1040 void drm_vblank_post_modeset(struct drm_device *dev, int crtc) in drm_vblank_post_modeset() argument
1043 if (!dev->num_crtcs) in drm_vblank_post_modeset()
1046 if (dev->vblank_inmodeset[crtc]) { in drm_vblank_post_modeset()
1047 mtx_lock(&dev->vbl_lock); in drm_vblank_post_modeset()
1048 dev->vblank_disable_allowed = 1; in drm_vblank_post_modeset()
1049 mtx_unlock(&dev->vbl_lock); in drm_vblank_post_modeset()
1051 if (dev->vblank_inmodeset[crtc] & 0x2) in drm_vblank_post_modeset()
1052 drm_vblank_put(dev, crtc); in drm_vblank_post_modeset()
1054 dev->vblank_inmodeset[crtc] = 0; in drm_vblank_post_modeset()
1070 int drm_modeset_ctl(struct drm_device *dev, void *data, in drm_modeset_ctl() argument
1077 if (!dev->num_crtcs) in drm_modeset_ctl()
1081 if (drm_core_check_feature(dev, DRIVER_MODESET)) in drm_modeset_ctl()
1085 if (crtc >= dev->num_crtcs) in drm_modeset_ctl()
1090 drm_vblank_pre_modeset(dev, crtc); in drm_modeset_ctl()
1093 drm_vblank_post_modeset(dev, crtc); in drm_modeset_ctl()
1109 static int drm_queue_vblank_event(struct drm_device *dev, int pipe, in drm_queue_vblank_event() argument
1133 mtx_lock(&dev->event_lock); in drm_queue_vblank_event()
1141 seq = drm_vblank_count_and_time(dev, pipe, &now); in drm_queue_vblank_event()
1157 drm_vblank_put(dev, pipe); in drm_queue_vblank_event()
1158 send_vblank_event(dev, e, seq, &now); in drm_queue_vblank_event()
1162 list_add_tail(&e->base.link, &dev->vblank_event_list); in drm_queue_vblank_event()
1166 mtx_unlock(&dev->event_lock); in drm_queue_vblank_event()
1171 mtx_unlock(&dev->event_lock); in drm_queue_vblank_event()
1174 drm_vblank_put(dev, pipe); in drm_queue_vblank_event()
1192 int drm_wait_vblank(struct drm_device *dev, void *data, in drm_wait_vblank() argument
1199 if (/*(!drm_dev_to_irq(dev)) || */(!dev->irq_enabled)) in drm_wait_vblank()
1221 if (crtc >= dev->num_crtcs) in drm_wait_vblank()
1224 ret = drm_vblank_get(dev, crtc); in drm_wait_vblank()
1229 seq = drm_vblank_count(dev, crtc); in drm_wait_vblank()
1246 return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); in drm_wait_vblank()
1256 dev->last_vblank_wait[crtc] = vblwait->request.sequence; in drm_wait_vblank()
1257 mtx_lock(&dev->vblank_time_lock); in drm_wait_vblank()
1258 while (((drm_vblank_count(dev, crtc) - vblwait->request.sequence) > in drm_wait_vblank()
1259 (1 << 23)) && dev->irq_enabled) { in drm_wait_vblank()
1268 ret = -msleep(&dev->_vblank_count[crtc], &dev->vblank_time_lock, in drm_wait_vblank()
1275 mtx_unlock(&dev->vblank_time_lock); in drm_wait_vblank()
1280 reply_seq = drm_vblank_count_and_time(dev, crtc, &now); in drm_wait_vblank()
1300 drm_vblank_put(dev, crtc); in drm_wait_vblank()
1304 static void drm_handle_vblank_events(struct drm_device *dev, int crtc) in drm_handle_vblank_events() argument
1310 seq = drm_vblank_count_and_time(dev, crtc, &now); in drm_handle_vblank_events()
1312 mtx_lock(&dev->event_lock); in drm_handle_vblank_events()
1314 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { in drm_handle_vblank_events()
1324 drm_vblank_put(dev, e->pipe); in drm_handle_vblank_events()
1325 send_vblank_event(dev, e, seq, &now); in drm_handle_vblank_events()
1328 mtx_unlock(&dev->event_lock); in drm_handle_vblank_events()
1341 bool drm_handle_vblank(struct drm_device *dev, int crtc) in drm_handle_vblank() argument
1347 if (!dev->num_crtcs) in drm_handle_vblank()
1354 mtx_lock(&dev->vblank_time_lock); in drm_handle_vblank()
1357 if (!dev->vblank_enabled[crtc]) { in drm_handle_vblank()
1358 mtx_unlock(&dev->vblank_time_lock); in drm_handle_vblank()
1367 vblcount = atomic_read(&dev->_vblank_count[crtc]); in drm_handle_vblank()
1368 drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ); in drm_handle_vblank()
1372 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); in drm_handle_vblank()
1385 vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; in drm_handle_vblank()
1391 atomic_inc(&dev->_vblank_count[crtc]); in drm_handle_vblank()
1398 DRM_WAKEUP(&dev->_vblank_count[crtc]); in drm_handle_vblank()
1399 drm_handle_vblank_events(dev, crtc); in drm_handle_vblank()
1401 mtx_unlock(&dev->vblank_time_lock); in drm_handle_vblank()