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