Lines Matching refs:dev
29 __FBSDID("$FreeBSD: releng/11.0/sys/dev/drm/drm_irq.c 283999 2015-06-04 20:36:16Z jhb $");
36 #include "dev/drm/drmP.h"
37 #include "dev/drm/drm.h"
39 int drm_irq_by_busid(struct drm_device *dev, void *data,
44 if ((irq->busnum >> 8) != dev->pci_domain ||
45 (irq->busnum & 0xff) != dev->pci_bus ||
46 irq->devnum != dev->pci_slot ||
47 irq->funcnum != dev->pci_func)
50 irq->irq = dev->irq;
61 struct drm_device *dev = arg;
63 DRM_SPINLOCK(&dev->irq_lock);
64 dev->driver->irq_handler(arg);
65 DRM_SPINUNLOCK(&dev->irq_lock);
70 struct drm_device *dev = (struct drm_device *)arg;
74 mtx_assert(&dev->vbl_lock, MA_OWNED);
76 if (callout_pending(&dev->vblank_disable_timer)) {
80 if (!callout_active(&dev->vblank_disable_timer)) {
84 callout_deactivate(&dev->vblank_disable_timer);
86 DRM_DEBUG("vblank_disable: %s\n", dev->vblank_disable_allowed ?
88 if (!dev->vblank_disable_allowed)
91 for (i = 0; i < dev->num_crtcs; i++) {
92 if (dev->vblank[i].refcount == 0 &&
93 dev->vblank[i].enabled && !dev->vblank[i].inmodeset) {
95 dev->vblank[i].last =
96 dev->driver->get_vblank_counter(dev, i);
97 dev->driver->disable_vblank(dev, i);
98 dev->vblank[i].enabled = 0;
103 void drm_vblank_cleanup(struct drm_device *dev)
106 if (dev->num_crtcs == 0)
109 DRM_SPINLOCK(&dev->vbl_lock);
110 callout_stop(&dev->vblank_disable_timer);
111 DRM_SPINUNLOCK(&dev->vbl_lock);
113 callout_drain(&dev->vblank_disable_timer);
115 DRM_SPINLOCK(&dev->vbl_lock);
116 vblank_disable_fn((void *)dev);
117 DRM_SPINUNLOCK(&dev->vbl_lock);
119 free(dev->vblank, DRM_MEM_DRIVER);
121 dev->num_crtcs = 0;
124 int drm_vblank_init(struct drm_device *dev, int num_crtcs)
128 callout_init_mtx(&dev->vblank_disable_timer, &dev->vbl_lock, 0);
129 dev->num_crtcs = num_crtcs;
131 dev->vblank = malloc(sizeof(struct drm_vblank_info) * num_crtcs,
133 if (!dev->vblank)
139 DRM_SPINLOCK(&dev->vbl_lock);
141 DRM_INIT_WAITQUEUE(&dev->vblank[i].queue);
142 dev->vblank[i].refcount = 0;
143 atomic_store_rel_32(&dev->vblank[i].count, 0);
145 dev->vblank_disable_allowed = 0;
146 DRM_SPINUNLOCK(&dev->vbl_lock);
151 drm_vblank_cleanup(dev);
155 int drm_irq_install(struct drm_device *dev)
159 if (dev->irq == 0 || dev->dev_private == NULL)
162 DRM_DEBUG("irq=%d\n", dev->irq);
165 if (dev->irq_enabled) {
169 dev->irq_enabled = 1;
171 dev->context_flag = 0;
174 dev->driver->irq_preinstall(dev);
178 retcode = bus_setup_intr(dev->device, dev->irqr,
180 NULL, drm_irq_handler_wrap, dev, &dev->irqh);
186 dev->driver->irq_postinstall(dev);
188 if (dev->driver->enable_vblank) {
189 DRM_SPINLOCK(&dev->vbl_lock);
190 for( crtc = 0 ; crtc < dev->num_crtcs ; crtc++) {
191 if (dev->driver->enable_vblank(dev, crtc) == 0) {
192 dev->vblank[crtc].enabled = 1;
195 callout_reset(&dev->vblank_disable_timer, 5 * DRM_HZ,
196 (timeout_t *)vblank_disable_fn, (void *)dev);
197 DRM_SPINUNLOCK(&dev->vbl_lock);
203 dev->irq_enabled = 0;
209 int drm_irq_uninstall(struct drm_device *dev)
213 if (!dev->irq_enabled)
216 dev->irq_enabled = 0;
221 DRM_SPINLOCK(&dev->vbl_lock);
222 for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
223 if (dev->vblank[crtc].enabled) {
224 DRM_WAKEUP(&dev->vblank[crtc].queue);
225 dev->vblank[crtc].last =
226 dev->driver->get_vblank_counter(dev, crtc);
227 dev->vblank[crtc].enabled = 0;
230 DRM_SPINUNLOCK(&dev->vbl_lock);
232 DRM_DEBUG("irq=%d\n", dev->irq);
234 dev->driver->irq_uninstall(dev);
237 bus_teardown_intr(dev->device, dev->irqr, dev->irqh);
243 int drm_control(struct drm_device *dev, void *data, struct drm_file *file_priv)
253 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
255 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
256 ctl->irq != dev->irq)
258 return drm_irq_install(dev);
260 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
263 err = drm_irq_uninstall(dev);
271 u32 drm_vblank_count(struct drm_device *dev, int crtc)
273 return atomic_load_acq_32(&dev->vblank[crtc].count);
276 static void drm_update_vblank_count(struct drm_device *dev, int crtc)
283 * NOTE! It's possible we lost a full dev->max_vblank_count events
287 cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
288 diff = cur_vblank - dev->vblank[crtc].last;
289 if (cur_vblank < dev->vblank[crtc].last) {
290 diff += dev->max_vblank_count;
293 crtc, dev->vblank[crtc].last, cur_vblank, diff);
299 atomic_add_rel_32(&dev->vblank[crtc].count, diff);
302 int drm_vblank_get(struct drm_device *dev, int crtc)
307 mtx_assert(&dev->vbl_lock, MA_OWNED);
310 if (++dev->vblank[crtc].refcount == 1 &&
311 !dev->vblank[crtc].enabled) {
312 ret = dev->driver->enable_vblank(dev, crtc);
315 --dev->vblank[crtc].refcount;
317 dev->vblank[crtc].enabled = 1;
318 drm_update_vblank_count(dev, crtc);
322 if (dev->vblank[crtc].enabled)
323 dev->vblank[crtc].last =
324 dev->driver->get_vblank_counter(dev, crtc);
329 void drm_vblank_put(struct drm_device *dev, int crtc)
332 mtx_assert(&dev->vbl_lock, MA_OWNED);
334 KASSERT(dev->vblank[crtc].refcount > 0,
338 if (--dev->vblank[crtc].refcount == 0)
339 callout_reset(&dev->vblank_disable_timer, 5 * DRM_HZ,
340 (timeout_t *)vblank_disable_fn, (void *)dev);
343 int drm_modeset_ctl(struct drm_device *dev, void *data,
350 if (!dev->num_crtcs)
354 if (crtc >= dev->num_crtcs) {
369 DRM_SPINLOCK(&dev->vbl_lock);
370 if (!dev->vblank[crtc].inmodeset) {
371 dev->vblank[crtc].inmodeset = 0x1;
372 if (drm_vblank_get(dev, crtc) == 0)
373 dev->vblank[crtc].inmodeset |= 0x2;
375 DRM_SPINUNLOCK(&dev->vbl_lock);
379 DRM_SPINLOCK(&dev->vbl_lock);
380 if (dev->vblank[crtc].inmodeset) {
381 if (dev->vblank[crtc].inmodeset & 0x2)
382 drm_vblank_put(dev, crtc);
383 dev->vblank[crtc].inmodeset = 0;
385 dev->vblank_disable_allowed = 1;
386 DRM_SPINUNLOCK(&dev->vbl_lock);
397 int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
403 if (!dev->irq_enabled)
417 if (crtc >= dev->num_crtcs)
420 DRM_SPINLOCK(&dev->vbl_lock);
421 ret = drm_vblank_get(dev, crtc);
422 DRM_SPINUNLOCK(&dev->vbl_lock);
427 seq = drm_vblank_count(dev, crtc);
451 for ( ret = 0 ; !ret && !(((drm_vblank_count(dev, crtc) -
453 !dev->irq_enabled) ; ) {
454 mtx_lock(&dev->irq_lock);
455 if (!(((drm_vblank_count(dev, crtc) -
457 !dev->irq_enabled))
458 ret = mtx_sleep(&dev->vblank[crtc].queue,
459 &dev->irq_lock, PCATCH, "vblwtq",
461 mtx_unlock(&dev->irq_lock);
470 vblwait->reply.sequence = drm_vblank_count(dev, crtc);
472 vblwait->reply.sequence, dev->irq_enabled);
479 DRM_SPINLOCK(&dev->vbl_lock);
480 drm_vblank_put(dev, crtc);
481 DRM_SPINUNLOCK(&dev->vbl_lock);
486 void drm_handle_vblank(struct drm_device *dev, int crtc)
488 atomic_add_rel_32(&dev->vblank[crtc].count, 1);
489 DRM_WAKEUP(&dev->vblank[crtc].queue);