1 /* $OpenBSD: drm_irq.c,v 1.55 2014/09/13 16:06:37 doug Exp $ */ 2 /** 3 * \file drm_irq.c 4 * IRQ support 5 * 6 * \author Rickard E. (Rik) Faith <faith@valinux.com> 7 * \author Gareth Hughes <gareth@valinux.com> 8 */ 9 10 /* 11 * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com 12 * 13 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. 14 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 15 * All Rights Reserved. 16 * 17 * Permission is hereby granted, free of charge, to any person obtaining a 18 * copy of this software and associated documentation files (the "Software"), 19 * to deal in the Software without restriction, including without limitation 20 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 21 * and/or sell copies of the Software, and to permit persons to whom the 22 * Software is furnished to do so, subject to the following conditions: 23 * 24 * The above copyright notice and this permission notice (including the next 25 * paragraph) shall be included in all copies or substantial portions of the 26 * Software. 27 * 28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 31 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 32 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 33 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 34 * OTHER DEALINGS IN THE SOFTWARE. 35 */ 36 37 #include <sys/task.h> 38 39 #include "drmP.h" 40 #include "drm.h" 41 42 /* Access macro for slots in vblank timestamp ringbuffer. */ 43 #define vblanktimestamp(dev, crtc, count) ( \ 44 (dev)->_vblank_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \ 45 ((count) % DRM_VBLANKTIME_RBSIZE)]) 46 47 /* Retry timestamp calculation up to 3 times to satisfy 48 * drm_timestamp_precision before giving up. 49 */ 50 #define DRM_TIMESTAMP_MAXRETRIES 3 51 52 /* Threshold in nanoseconds for detection of redundant 53 * vblank irq in drm_handle_vblank(). 1 msec should be ok. 54 */ 55 #define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000 56 57 int64_t timeval_to_ns(const struct timeval *); 58 struct timeval ns_to_timeval(const int64_t); 59 60 #ifdef DRM_VBLANK_DEBUG 61 #define DPRINTF(x...) do { printf(x); } while(/* CONSTCOND */ 0) 62 #else 63 #define DPRINTF(x...) do { } while(/* CONSTCOND */ 0) 64 #endif 65 66 unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ 67 unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ 68 /* 69 * Default to use monotonic timestamps for wait-for-vblank and page-flip 70 * complete events. 71 */ 72 unsigned int drm_timestamp_monotonic = 1; 73 74 /** 75 * Get interrupt from bus id. 76 * 77 * \param inode device inode. 78 * \param file_priv DRM file private. 79 * \param cmd command. 80 * \param arg user argument, pointing to a drm_irq_busid structure. 81 * \return zero on success or a negative number on failure. 82 * 83 * Finds the PCI device with the specified bus id and gets its IRQ number. 84 * This IOCTL is deprecated, and will now return EINVAL for any busid not equal 85 * to that of the device that this DRM instance attached to. 86 */ 87 int drm_irq_by_busid(struct drm_device *dev, void *data, 88 struct drm_file *file_priv) 89 { 90 struct drm_irq_busid *irq = data; 91 92 /* 93 * This is only ever called by root as part of a stupid interface. 94 * just hand over the irq without checking the busid. If all clients 95 * can be forced to use interface 1.2 then this can die. 96 */ 97 irq->irq = dev->irq; 98 99 DRM_DEBUG("%d:%d:%d => IRQ %d\n", irq->busnum, irq->devnum, 100 irq->funcnum, irq->irq); 101 102 return 0; 103 } 104 105 /* 106 * Clear vblank timestamp buffer for a crtc. 107 */ 108 static void clear_vblank_timestamps(struct drm_device *dev, int crtc) 109 { 110 memset(&dev->_vblank_time[crtc * DRM_VBLANKTIME_RBSIZE], 0, 111 DRM_VBLANKTIME_RBSIZE * sizeof(struct timeval)); 112 } 113 114 #define NSEC_PER_USEC 1000L 115 #define NSEC_PER_SEC 1000000000L 116 117 int64_t 118 timeval_to_ns(const struct timeval *tv) 119 { 120 return ((int64_t)tv->tv_sec * NSEC_PER_SEC) + 121 tv->tv_usec * NSEC_PER_USEC; 122 } 123 124 struct timeval 125 ns_to_timeval(const int64_t nsec) 126 { 127 struct timeval tv; 128 int32_t rem; 129 130 if (nsec == 0) { 131 tv.tv_sec = 0; 132 tv.tv_usec = 0; 133 return (tv); 134 } 135 136 tv.tv_sec = nsec / NSEC_PER_SEC; 137 rem = nsec % NSEC_PER_SEC; 138 if (rem < 0) { 139 tv.tv_sec--; 140 rem += NSEC_PER_SEC; 141 } 142 tv.tv_usec = rem / 1000; 143 return (tv); 144 } 145 146 static inline int64_t 147 abs64(int64_t x) 148 { 149 return (x < 0 ? -x : x); 150 } 151 152 /* 153 * Disable vblank irq's on crtc, make sure that last vblank count 154 * of hardware and corresponding consistent software vblank counter 155 * are preserved, even if there are any spurious vblank irq's after 156 * disable. 157 */ 158 static void vblank_disable_and_save(struct drm_device *dev, int crtc) 159 { 160 u32 vblcount; 161 s64 diff_ns; 162 int vblrc; 163 struct timeval tvblank; 164 int count = DRM_TIMESTAMP_MAXRETRIES; 165 166 /* Prevent vblank irq processing while disabling vblank irqs, 167 * so no updates of timestamps or count can happen after we've 168 * disabled. Needed to prevent races in case of delayed irq's. 169 */ 170 mtx_enter(&dev->vblank_time_lock); 171 172 dev->driver->disable_vblank(dev, crtc); 173 dev->vblank_enabled[crtc] = 0; 174 175 /* No further vblank irq's will be processed after 176 * this point. Get current hardware vblank count and 177 * vblank timestamp, repeat until they are consistent. 178 * 179 * FIXME: There is still a race condition here and in 180 * drm_update_vblank_count() which can cause off-by-one 181 * reinitialization of software vblank counter. If gpu 182 * vblank counter doesn't increment exactly at the leading 183 * edge of a vblank interval, then we can lose 1 count if 184 * we happen to execute between start of vblank and the 185 * delayed gpu counter increment. 186 */ 187 do { 188 dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); 189 vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0); 190 } while (dev->last_vblank[crtc] != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc); 191 192 if (!count) 193 vblrc = 0; 194 195 /* Compute time difference to stored timestamp of last vblank 196 * as updated by last invocation of drm_handle_vblank() in vblank irq. 197 */ 198 vblcount = atomic_read(&dev->_vblank_count[crtc]); 199 diff_ns = timeval_to_ns(&tvblank) - 200 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); 201 202 /* If there is at least 1 msec difference between the last stored 203 * timestamp and tvblank, then we are currently executing our 204 * disable inside a new vblank interval, the tvblank timestamp 205 * corresponds to this new vblank interval and the irq handler 206 * for this vblank didn't run yet and won't run due to our disable. 207 * Therefore we need to do the job of drm_handle_vblank() and 208 * increment the vblank counter by one to account for this vblank. 209 * 210 * Skip this step if there isn't any high precision timestamp 211 * available. In that case we can't account for this and just 212 * hope for the best. 213 */ 214 if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) { 215 atomic_inc(&dev->_vblank_count[crtc]); 216 smp_mb__after_atomic_inc(); 217 } 218 219 /* Invalidate all timestamps while vblank irq's are off. */ 220 clear_vblank_timestamps(dev, crtc); 221 222 mtx_leave(&dev->vblank_time_lock); 223 } 224 225 static void vblank_disable_fn(void *arg) 226 { 227 struct drm_device *dev = (struct drm_device *)arg; 228 int i; 229 230 if (!dev->vblank_disable_allowed) 231 return; 232 233 for (i = 0; i < dev->num_crtcs; i++) { 234 mtx_enter(&dev->vbl_lock); 235 if (atomic_read(&dev->vblank_refcount[i]) == 0 && 236 dev->vblank_enabled[i]) { 237 DPRINTF("disabling vblank on crtc %d\n", i); 238 vblank_disable_and_save(dev, i); 239 } 240 mtx_leave(&dev->vbl_lock); 241 } 242 } 243 244 void drm_vblank_cleanup(struct drm_device *dev) 245 { 246 /* Bail if the driver didn't call drm_vblank_init() */ 247 if (dev->num_crtcs == 0) 248 return; 249 250 timeout_del(&dev->vblank_disable_timer); 251 252 vblank_disable_fn(dev); 253 254 kfree(dev->vbl_queue); 255 kfree(dev->_vblank_count); 256 kfree(dev->vblank_refcount); 257 kfree(dev->vblank_enabled); 258 kfree(dev->last_vblank); 259 kfree(dev->last_vblank_wait); 260 kfree(dev->vblank_inmodeset); 261 kfree(dev->_vblank_time); 262 263 dev->num_crtcs = 0; 264 } 265 EXPORT_SYMBOL(drm_vblank_cleanup); 266 267 int drm_vblank_init(struct drm_device *dev, int num_crtcs) 268 { 269 int i, ret = -ENOMEM; 270 271 timeout_set(&dev->vblank_disable_timer, vblank_disable_fn, 272 dev); 273 mtx_init(&dev->vbl_lock, IPL_TTY); 274 mtx_init(&dev->vblank_time_lock, IPL_TTY); 275 276 dev->num_crtcs = num_crtcs; 277 278 dev->vbl_queue = kmalloc(sizeof(int) * num_crtcs, 279 GFP_KERNEL); 280 if (!dev->vbl_queue) 281 goto err; 282 283 dev->_vblank_count = kmalloc(sizeof(atomic_t) * num_crtcs, GFP_KERNEL); 284 if (!dev->_vblank_count) 285 goto err; 286 287 dev->vblank_refcount = kmalloc(sizeof(atomic_t) * num_crtcs, 288 GFP_KERNEL); 289 if (!dev->vblank_refcount) 290 goto err; 291 292 dev->vblank_enabled = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL); 293 if (!dev->vblank_enabled) 294 goto err; 295 296 dev->last_vblank = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL); 297 if (!dev->last_vblank) 298 goto err; 299 300 dev->last_vblank_wait = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL); 301 if (!dev->last_vblank_wait) 302 goto err; 303 304 dev->vblank_inmodeset = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL); 305 if (!dev->vblank_inmodeset) 306 goto err; 307 308 dev->_vblank_time = kcalloc(num_crtcs * DRM_VBLANKTIME_RBSIZE, 309 sizeof(struct timeval), GFP_KERNEL); 310 if (!dev->_vblank_time) 311 goto err; 312 313 DRM_DEBUG("Supports vblank timestamp caching Rev 1 (10.10.2010).\n"); 314 315 /* Driver specific high-precision vblank timestamping supported? */ 316 if (dev->driver->get_vblank_timestamp) 317 DRM_DEBUG("Driver supports precise vblank timestamp query.\n"); 318 else 319 DRM_DEBUG("No driver support for vblank timestamp query.\n"); 320 321 /* Zero per-crtc vblank stuff */ 322 for (i = 0; i < num_crtcs; i++) { 323 atomic_set(&dev->_vblank_count[i], 0); 324 atomic_set(&dev->vblank_refcount[i], 0); 325 } 326 327 dev->vblank_disable_allowed = 0; 328 return 0; 329 330 err: 331 drm_vblank_cleanup(dev); 332 return ret; 333 } 334 EXPORT_SYMBOL(drm_vblank_init); 335 336 #ifdef notyet 337 static void drm_irq_vgaarb_nokms(void *cookie, bool state) 338 { 339 struct drm_device *dev = cookie; 340 341 #ifdef notyet 342 if (dev->driver->vgaarb_irq) { 343 dev->driver->vgaarb_irq(dev, state); 344 return; 345 } 346 #endif 347 348 if (!dev->irq_enabled) 349 return; 350 351 if (state) { 352 if (dev->driver->irq_uninstall) 353 dev->driver->irq_uninstall(dev); 354 } else { 355 if (dev->driver->irq_preinstall) 356 dev->driver->irq_preinstall(dev); 357 if (dev->driver->irq_postinstall) 358 dev->driver->irq_postinstall(dev); 359 } 360 } 361 #endif 362 363 /** 364 * Install IRQ handler. 365 * 366 * \param dev DRM device. 367 * 368 * Initializes the IRQ related data. Installs the handler, calling the driver 369 * \c irq_preinstall() and \c irq_postinstall() functions 370 * before and after the installation. 371 */ 372 int drm_irq_install(struct drm_device *dev) 373 { 374 int ret; 375 376 if (dev->irq == 0 || dev->dev_private == NULL) 377 return (EINVAL); 378 379 DRM_DEBUG("irq=%d\n", dev->irq); 380 381 DRM_LOCK(); 382 if (dev->irq_enabled) { 383 DRM_UNLOCK(); 384 return (EBUSY); 385 } 386 dev->irq_enabled = 1; 387 DRM_UNLOCK(); 388 389 if (dev->driver->irq_install) { 390 if ((ret = dev->driver->irq_install(dev)) != 0) 391 goto err; 392 } else { 393 if (dev->driver->irq_preinstall) 394 dev->driver->irq_preinstall(dev); 395 if (dev->driver->irq_postinstall) 396 dev->driver->irq_postinstall(dev); 397 } 398 399 return (0); 400 err: 401 DRM_LOCK(); 402 dev->irq_enabled = 0; 403 DRM_UNLOCK(); 404 return (ret); 405 } 406 EXPORT_SYMBOL(drm_irq_install); 407 408 /** 409 * Uninstall the IRQ handler. 410 * 411 * \param dev DRM device. 412 * 413 * Calls the driver's \c irq_uninstall() function, and stops the irq. 414 */ 415 int drm_irq_uninstall(struct drm_device *dev) 416 { 417 int i; 418 419 DRM_LOCK(); 420 if (!dev->irq_enabled) { 421 DRM_UNLOCK(); 422 return (EINVAL); 423 } 424 425 dev->irq_enabled = 0; 426 DRM_UNLOCK(); 427 428 /* 429 * Ick. we're about to turn of vblanks, so make sure anyone waiting 430 * on them gets woken up. Also make sure we update state correctly 431 * so that we can continue refcounting correctly. 432 */ 433 if (dev->num_crtcs) { 434 mtx_enter(&dev->vbl_lock); 435 for (i = 0; i < dev->num_crtcs; i++) { 436 wakeup(&dev->vbl_queue[i]); 437 dev->vblank_enabled[i] = 0; 438 dev->last_vblank[i] = 439 dev->driver->get_vblank_counter(dev, i); 440 } 441 mtx_leave(&dev->vbl_lock); 442 } 443 444 DRM_DEBUG("irq=%d\n", dev->irq); 445 446 dev->driver->irq_uninstall(dev); 447 448 return (0); 449 } 450 EXPORT_SYMBOL(drm_irq_uninstall); 451 452 /** 453 * IRQ control ioctl. 454 * 455 * \param inode device inode. 456 * \param file_priv DRM file private. 457 * \param cmd command. 458 * \param arg user argument, pointing to a drm_control structure. 459 * \return zero on success or a negative number on failure. 460 * 461 * Calls irq_install() or irq_uninstall() according to \p arg. 462 */ 463 int drm_control(struct drm_device *dev, void *data, 464 struct drm_file *file_priv) 465 { 466 struct drm_control *ctl = data; 467 468 /* Handle drivers who used to require IRQ setup no longer does. */ 469 if (!(dev->driver->flags & DRIVER_IRQ)) 470 return (0); 471 472 switch (ctl->func) { 473 case DRM_INST_HANDLER: 474 if (drm_core_check_feature(dev, DRIVER_MODESET)) 475 return 0; 476 if (dev->if_version < DRM_IF_VERSION(1, 2) && 477 ctl->irq != dev->irq) 478 return (EINVAL); 479 return (drm_irq_install(dev)); 480 case DRM_UNINST_HANDLER: 481 if (drm_core_check_feature(dev, DRIVER_MODESET)) 482 return 0; 483 return (drm_irq_uninstall(dev)); 484 default: 485 return (EINVAL); 486 } 487 } 488 489 /** 490 * drm_calc_timestamping_constants - Calculate and 491 * store various constants which are later needed by 492 * vblank and swap-completion timestamping, e.g, by 493 * drm_calc_vbltimestamp_from_scanoutpos(). 494 * They are derived from crtc's true scanout timing, 495 * so they take things like panel scaling or other 496 * adjustments into account. 497 * 498 * @crtc drm_crtc whose timestamp constants should be updated. 499 * 500 */ 501 void drm_calc_timestamping_constants(struct drm_crtc *crtc) 502 { 503 s64 linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0; 504 u64 dotclock; 505 506 /* Dot clock in Hz: */ 507 dotclock = (u64) crtc->hwmode.clock * 1000; 508 509 /* Fields of interlaced scanout modes are only halve a frame duration. 510 * Double the dotclock to get halve the frame-/line-/pixelduration. 511 */ 512 if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE) 513 dotclock *= 2; 514 515 /* Valid dotclock? */ 516 if (dotclock > 0) { 517 /* Convert scanline length in pixels and video dot clock to 518 * line duration, frame duration and pixel duration in 519 * nanoseconds: 520 */ 521 pixeldur_ns = (s64) 1000000000 / dotclock; 522 linedur_ns = (s64) ((u64) crtc->hwmode.crtc_htotal * 523 1000000000) / dotclock; 524 framedur_ns = (s64) crtc->hwmode.crtc_vtotal * linedur_ns; 525 } else 526 DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n", 527 crtc->base.id); 528 529 crtc->pixeldur_ns = pixeldur_ns; 530 crtc->linedur_ns = linedur_ns; 531 crtc->framedur_ns = framedur_ns; 532 533 DPRINTF("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n", 534 crtc->base.id, crtc->hwmode.crtc_htotal, 535 crtc->hwmode.crtc_vtotal, crtc->hwmode.crtc_vdisplay); 536 DPRINTF("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n", 537 crtc->base.id, (int) dotclock/1000, (int) framedur_ns, 538 (int) linedur_ns, (int) pixeldur_ns); 539 } 540 EXPORT_SYMBOL(drm_calc_timestamping_constants); 541 542 /** 543 * drm_calc_vbltimestamp_from_scanoutpos - helper routine for kms 544 * drivers. Implements calculation of exact vblank timestamps from 545 * given drm_display_mode timings and current video scanout position 546 * of a crtc. This can be called from within get_vblank_timestamp() 547 * implementation of a kms driver to implement the actual timestamping. 548 * 549 * Should return timestamps conforming to the OML_sync_control OpenML 550 * extension specification. The timestamp corresponds to the end of 551 * the vblank interval, aka start of scanout of topmost-leftmost display 552 * pixel in the following video frame. 553 * 554 * Requires support for optional dev->driver->get_scanout_position() 555 * in kms driver, plus a bit of setup code to provide a drm_display_mode 556 * that corresponds to the true scanout timing. 557 * 558 * The current implementation only handles standard video modes. It 559 * returns as no operation if a doublescan or interlaced video mode is 560 * active. Higher level code is expected to handle this. 561 * 562 * @dev: DRM device. 563 * @crtc: Which crtc's vblank timestamp to retrieve. 564 * @max_error: Desired maximum allowable error in timestamps (nanosecs). 565 * On return contains true maximum error of timestamp. 566 * @vblank_time: Pointer to struct timeval which should receive the timestamp. 567 * @flags: Flags to pass to driver: 568 * 0 = Default. 569 * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. 570 * @refcrtc: drm_crtc* of crtc which defines scanout timing. 571 * 572 * Returns negative value on error, failure or if not supported in current 573 * video mode: 574 * 575 * -EINVAL - Invalid crtc. 576 * -EAGAIN - Temporary unavailable, e.g., called before initial modeset. 577 * -ENOTSUPP - Function not supported in current display mode. 578 * -EIO - Failed, e.g., due to failed scanout position query. 579 * 580 * Returns or'ed positive status flags on success: 581 * 582 * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. 583 * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. 584 * 585 */ 586 int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, 587 int *max_error, 588 struct timeval *vblank_time, 589 unsigned flags, 590 struct drm_crtc *refcrtc) 591 { 592 struct timeval stime, etime; 593 #ifdef notyet 594 struct timeval mono_time_offset; 595 #endif 596 struct drm_display_mode *mode; 597 int vbl_status, vtotal, vdisplay; 598 int vpos, hpos, i; 599 s64 framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; 600 bool invbl; 601 602 if (crtc < 0 || crtc >= dev->num_crtcs) { 603 DRM_ERROR("Invalid crtc %d\n", crtc); 604 return -EINVAL; 605 } 606 607 /* Scanout position query not supported? Should not happen. */ 608 if (!dev->driver->get_scanout_position) { 609 DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); 610 return -EIO; 611 } 612 613 mode = &refcrtc->hwmode; 614 vtotal = mode->crtc_vtotal; 615 vdisplay = mode->crtc_vdisplay; 616 617 /* Durations of frames, lines, pixels in nanoseconds. */ 618 framedur_ns = refcrtc->framedur_ns; 619 linedur_ns = refcrtc->linedur_ns; 620 pixeldur_ns = refcrtc->pixeldur_ns; 621 622 /* If mode timing undefined, just return as no-op: 623 * Happens during initial modesetting of a crtc. 624 */ 625 if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) { 626 DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); 627 return -EAGAIN; 628 } 629 630 /* Get current scanout position with system timestamp. 631 * Repeat query up to DRM_TIMESTAMP_MAXRETRIES times 632 * if single query takes longer than max_error nanoseconds. 633 * 634 * This guarantees a tight bound on maximum error if 635 * code gets preempted or delayed for some reason. 636 */ 637 for (i = 0; i < DRM_TIMESTAMP_MAXRETRIES; i++) { 638 /* Disable preemption to make it very likely to 639 * succeed in the first iteration even on PREEMPT_RT kernel. 640 */ 641 #ifdef notyet 642 preempt_disable(); 643 #endif 644 645 /* Get system timestamp before query. */ 646 getmicrouptime(&stime); 647 648 /* Get vertical and horizontal scanout pos. vpos, hpos. */ 649 vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, &hpos); 650 651 /* Get system timestamp after query. */ 652 getmicrouptime(&etime); 653 #ifdef notyet 654 if (!drm_timestamp_monotonic) 655 mono_time_offset = ktime_get_monotonic_offset(); 656 657 preempt_enable(); 658 #endif 659 660 /* Return as no-op if scanout query unsupported or failed. */ 661 if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { 662 DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n", 663 crtc, vbl_status); 664 return -EIO; 665 } 666 667 duration_ns = timeval_to_ns(&etime) - timeval_to_ns(&stime); 668 669 /* Accept result with < max_error nsecs timing uncertainty. */ 670 if (duration_ns <= (s64) *max_error) 671 break; 672 } 673 674 /* Noisy system timing? */ 675 if (i == DRM_TIMESTAMP_MAXRETRIES) { 676 DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n", 677 crtc, (int) duration_ns/1000, *max_error/1000, i); 678 } 679 680 /* Return upper bound of timestamp precision error. */ 681 *max_error = (int) duration_ns; 682 683 /* Check if in vblank area: 684 * vpos is >=0 in video scanout area, but negative 685 * within vblank area, counting down the number of lines until 686 * start of scanout. 687 */ 688 invbl = vbl_status & DRM_SCANOUTPOS_INVBL; 689 690 /* Convert scanout position into elapsed time at raw_time query 691 * since start of scanout at first display scanline. delta_ns 692 * can be negative if start of scanout hasn't happened yet. 693 */ 694 delta_ns = (s64) vpos * linedur_ns + (s64) hpos * pixeldur_ns; 695 696 /* Is vpos outside nominal vblank area, but less than 697 * 1/100 of a frame height away from start of vblank? 698 * If so, assume this isn't a massively delayed vblank 699 * interrupt, but a vblank interrupt that fired a few 700 * microseconds before true start of vblank. Compensate 701 * by adding a full frame duration to the final timestamp. 702 * Happens, e.g., on ATI R500, R600. 703 * 704 * We only do this if DRM_CALLED_FROM_VBLIRQ. 705 */ 706 if ((flags & DRM_CALLED_FROM_VBLIRQ) && !invbl && 707 ((vdisplay - vpos) < vtotal / 100)) { 708 delta_ns = delta_ns - framedur_ns; 709 710 /* Signal this correction as "applied". */ 711 vbl_status |= 0x8; 712 } 713 714 #ifdef notyet 715 if (!drm_timestamp_monotonic) 716 etime = ktime_sub(etime, mono_time_offset); 717 #endif 718 719 /* Subtract time delta from raw timestamp to get final 720 * vblank_time timestamp for end of vblank. 721 */ 722 *vblank_time = ns_to_timeval(timeval_to_ns(&etime) - delta_ns); 723 724 DPRINTF("crtc %d : v %d p(%d,%d)@ %lld.%ld -> %lld.%ld [e %d us, %d rep]\n", 725 crtc, (int)vbl_status, hpos, vpos, 726 (long long)etime.tv_sec, (long)etime.tv_usec, 727 (long long)vblank_time->tv_sec, (long)vblank_time->tv_usec, 728 (int)duration_ns/1000, i); 729 730 vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD; 731 if (invbl) 732 vbl_status |= DRM_VBLANKTIME_INVBL; 733 734 return vbl_status; 735 } 736 EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); 737 738 static struct timeval get_drm_timestamp(void) 739 { 740 struct timeval now; 741 742 getmicrouptime(&now); 743 #ifdef notyet 744 if (!drm_timestamp_monotonic) 745 now = ktime_sub(now, ktime_get_monotonic_offset()); 746 #endif 747 748 return (now); 749 } 750 751 /** 752 * drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent 753 * vblank interval. 754 * 755 * @dev: DRM device 756 * @crtc: which crtc's vblank timestamp to retrieve 757 * @tvblank: Pointer to target struct timeval which should receive the timestamp 758 * @flags: Flags to pass to driver: 759 * 0 = Default. 760 * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. 761 * 762 * Fetches the system timestamp corresponding to the time of the most recent 763 * vblank interval on specified crtc. May call into kms-driver to 764 * compute the timestamp with a high-precision GPU specific method. 765 * 766 * Returns zero if timestamp originates from uncorrected do_gettimeofday() 767 * call, i.e., it isn't very precisely locked to the true vblank. 768 * 769 * Returns non-zero if timestamp is considered to be very precise. 770 */ 771 u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, 772 struct timeval *tvblank, unsigned flags) 773 { 774 int ret; 775 776 /* Define requested maximum error on timestamps (nanoseconds). */ 777 int max_error = (int) drm_timestamp_precision * 1000; 778 779 /* Query driver if possible and precision timestamping enabled. */ 780 if (dev->driver->get_vblank_timestamp && (max_error > 0)) { 781 ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error, 782 tvblank, flags); 783 if (ret > 0) 784 return (u32) ret; 785 } 786 787 /* GPU high precision timestamp query unsupported or failed. 788 * Return current monotonic/gettimeofday timestamp as best estimate. 789 */ 790 *tvblank = get_drm_timestamp(); 791 792 return 0; 793 } 794 EXPORT_SYMBOL(drm_get_last_vbltimestamp); 795 796 /** 797 * drm_vblank_count - retrieve "cooked" vblank counter value 798 * @dev: DRM device 799 * @crtc: which counter to retrieve 800 * 801 * Fetches the "cooked" vblank count value that represents the number of 802 * vblank events since the system was booted, including lost events due to 803 * modesetting activity. 804 */ 805 u32 drm_vblank_count(struct drm_device *dev, int crtc) 806 { 807 return atomic_read(&dev->_vblank_count[crtc]); 808 } 809 EXPORT_SYMBOL(drm_vblank_count); 810 811 /** 812 * drm_vblank_count_and_time - retrieve "cooked" vblank counter value 813 * and the system timestamp corresponding to that vblank counter value. 814 * 815 * @dev: DRM device 816 * @crtc: which counter to retrieve 817 * @vblanktime: Pointer to struct timeval to receive the vblank timestamp. 818 * 819 * Fetches the "cooked" vblank count value that represents the number of 820 * vblank events since the system was booted, including lost events due to 821 * modesetting activity. Returns corresponding system timestamp of the time 822 * of the vblank interval that corresponds to the current value vblank counter 823 * value. 824 */ 825 u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, 826 struct timeval *vblanktime) 827 { 828 u32 cur_vblank; 829 830 /* Read timestamp from slot of _vblank_time ringbuffer 831 * that corresponds to current vblank count. Retry if 832 * count has incremented during readout. This works like 833 * a seqlock. 834 */ 835 do { 836 cur_vblank = atomic_read(&dev->_vblank_count[crtc]); 837 *vblanktime = vblanktimestamp(dev, crtc, cur_vblank); 838 DRM_READMEMORYBARRIER(); 839 } while (cur_vblank != atomic_read(&dev->_vblank_count[crtc])); 840 841 return cur_vblank; 842 } 843 EXPORT_SYMBOL(drm_vblank_count_and_time); 844 845 static void send_vblank_event(struct drm_device *dev, 846 struct drm_pending_vblank_event *e, 847 unsigned long seq, struct timeval *now) 848 { 849 struct drm_file *file_priv = e->base.file_priv; 850 MUTEX_ASSERT_LOCKED(&dev->event_lock); 851 e->event.sequence = seq; 852 e->event.tv_sec = now->tv_sec; 853 e->event.tv_usec = now->tv_usec; 854 855 TAILQ_INSERT_TAIL(&file_priv->evlist, &e->base, link); 856 wakeup(&file_priv->evlist); 857 selwakeup(&file_priv->rsel); 858 #if 0 859 trace_drm_vblank_event_delivered(e->base.pid, e->pipe, 860 e->event.sequence); 861 #endif 862 } 863 864 /** 865 * drm_send_vblank_event - helper to send vblank event after pageflip 866 * @dev: DRM device 867 * @crtc: CRTC in question 868 * @e: the event to send 869 * 870 * Updates sequence # and timestamp on event, and sends it to userspace. 871 * Caller must hold event lock. 872 */ 873 void drm_send_vblank_event(struct drm_device *dev, int crtc, 874 struct drm_pending_vblank_event *e) 875 { 876 struct timeval now; 877 unsigned int seq; 878 if (crtc >= 0) { 879 seq = drm_vblank_count_and_time(dev, crtc, &now); 880 } else { 881 seq = 0; 882 883 now = get_drm_timestamp(); 884 } 885 send_vblank_event(dev, e, seq, &now); 886 } 887 EXPORT_SYMBOL(drm_send_vblank_event); 888 889 /** 890 * drm_update_vblank_count - update the master vblank counter 891 * @dev: DRM device 892 * @crtc: counter to update 893 * 894 * Call back into the driver to update the appropriate vblank counter 895 * (specified by @crtc). Deal with wraparound, if it occurred, and 896 * update the last read value so we can deal with wraparound on the next 897 * call if necessary. 898 * 899 * Only necessary when going from off->on, to account for frames we 900 * didn't get an interrupt for. 901 * 902 * Note: caller must hold dev->vbl_lock since this reads & writes 903 * device vblank fields. 904 */ 905 static void drm_update_vblank_count(struct drm_device *dev, int crtc) 906 { 907 u32 cur_vblank, diff, tslot, rc; 908 struct timeval t_vblank; 909 910 /* 911 * Interrupts were disabled prior to this call, so deal with counter 912 * wrap if needed. 913 * NOTE! It's possible we lost a full dev->max_vblank_count events 914 * here if the register is small or we had vblank interrupts off for 915 * a long time. 916 * 917 * We repeat the hardware vblank counter & timestamp query until 918 * we get consistent results. This to prevent races between gpu 919 * updating its hardware counter while we are retrieving the 920 * corresponding vblank timestamp. 921 */ 922 do { 923 cur_vblank = dev->driver->get_vblank_counter(dev, crtc); 924 rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0); 925 } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc)); 926 927 /* Deal with counter wrap */ 928 diff = cur_vblank - dev->last_vblank[crtc]; 929 if (cur_vblank < dev->last_vblank[crtc]) { 930 diff += dev->max_vblank_count; 931 932 DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", 933 crtc, dev->last_vblank[crtc], cur_vblank, diff); 934 } 935 936 DPRINTF("enabling vblank interrupts on crtc %d, missed %d\n", 937 crtc, diff); 938 939 /* Reinitialize corresponding vblank timestamp if high-precision query 940 * available. Skip this step if query unsupported or failed. Will 941 * reinitialize delayed at next vblank interrupt in that case. 942 */ 943 if (rc) { 944 tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; 945 vblanktimestamp(dev, crtc, tslot) = t_vblank; 946 } 947 948 smp_mb__before_atomic_inc(); 949 atomic_add(diff, &dev->_vblank_count[crtc]); 950 smp_mb__after_atomic_inc(); 951 } 952 953 /** 954 * drm_vblank_get - get a reference count on vblank events 955 * @dev: DRM device 956 * @crtc: which CRTC to own 957 * 958 * Acquire a reference count on vblank events to avoid having them disabled 959 * while in use. 960 * 961 * RETURNS 962 * Zero on success, nonzero on failure. 963 */ 964 int drm_vblank_get(struct drm_device *dev, int crtc) 965 { 966 int ret = 0; 967 968 mtx_enter(&dev->vbl_lock); 969 /* Going from 0->1 means we have to enable interrupts again */ 970 if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { 971 mtx_enter(&dev->vblank_time_lock); 972 if (!dev->vblank_enabled[crtc]) { 973 /* Enable vblank irqs under vblank_time_lock protection. 974 * All vblank count & timestamp updates are held off 975 * until we are done reinitializing master counter and 976 * timestamps. Filtercode in drm_handle_vblank() will 977 * prevent double-accounting of same vblank interval. 978 */ 979 ret = dev->driver->enable_vblank(dev, crtc); 980 DPRINTF("enabling vblank on crtc %d, ret: %d\n", 981 crtc, ret); 982 if (ret) 983 atomic_dec(&dev->vblank_refcount[crtc]); 984 else { 985 dev->vblank_enabled[crtc] = 1; 986 drm_update_vblank_count(dev, crtc); 987 } 988 } 989 mtx_leave(&dev->vblank_time_lock); 990 } else { 991 if (!dev->vblank_enabled[crtc]) { 992 atomic_dec(&dev->vblank_refcount[crtc]); 993 ret = -EINVAL; 994 } 995 } 996 mtx_leave(&dev->vbl_lock); 997 998 return ret; 999 } 1000 EXPORT_SYMBOL(drm_vblank_get); 1001 1002 /** 1003 * drm_vblank_put - give up ownership of vblank events 1004 * @dev: DRM device 1005 * @crtc: which counter to give up 1006 * 1007 * Release ownership of a given vblank counter, turning off interrupts 1008 * if possible. Disable interrupts after drm_vblank_offdelay milliseconds. 1009 */ 1010 void drm_vblank_put(struct drm_device *dev, int crtc) 1011 { 1012 BUG_ON(atomic_read(&dev->vblank_refcount[crtc]) == 0); 1013 1014 /* Last user schedules interrupt disable */ 1015 if (atomic_dec_and_test(&dev->vblank_refcount[crtc]) && 1016 (drm_vblank_offdelay > 0)) 1017 timeout_add_msec(&dev->vblank_disable_timer, drm_vblank_offdelay); 1018 } 1019 1020 /** 1021 * drm_vblank_off - disable vblank events on a CRTC 1022 * @dev: DRM device 1023 * @crtc: CRTC in question 1024 * 1025 * Caller must hold event lock. 1026 */ 1027 void drm_vblank_off(struct drm_device *dev, int crtc) 1028 { 1029 struct drmevlist *list; 1030 struct drm_pending_event *ev, *tmp; 1031 struct drm_pending_vblank_event *vev; 1032 struct timeval now; 1033 unsigned int seq; 1034 1035 mtx_enter(&dev->vbl_lock); 1036 vblank_disable_and_save(dev, crtc); 1037 wakeup(&dev->vbl_queue[crtc]); 1038 1039 list = &dev->vbl_events; 1040 /* Send any queued vblank events, lest the natives grow disquiet */ 1041 seq = drm_vblank_count_and_time(dev, crtc, &now); 1042 1043 mtx_enter(&dev->event_lock); 1044 for (ev = TAILQ_FIRST(list); ev != NULL; ev = tmp) { 1045 tmp = TAILQ_NEXT(ev, link); 1046 1047 vev = (struct drm_pending_vblank_event *)ev; 1048 1049 if (vev->pipe != crtc) 1050 continue; 1051 DRM_DEBUG("Sending premature vblank event on disable: \ 1052 wanted %d, current %d\n", 1053 vev->event.sequence, seq); 1054 TAILQ_REMOVE(list, ev, link); 1055 drm_vblank_put(dev, vev->pipe); 1056 send_vblank_event(dev, vev, seq, &now); 1057 } 1058 mtx_leave(&dev->event_lock); 1059 1060 mtx_leave(&dev->vbl_lock); 1061 } 1062 1063 /** 1064 * drm_vblank_pre_modeset - account for vblanks across mode sets 1065 * @dev: DRM device 1066 * @crtc: CRTC in question 1067 * 1068 * Account for vblank events across mode setting events, which will likely 1069 * reset the hardware frame counter. 1070 */ 1071 void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) 1072 { 1073 /* vblank is not initialized (IRQ not installed ?), or has been freed */ 1074 if (!dev->num_crtcs) 1075 return; 1076 /* 1077 * To avoid all the problems that might happen if interrupts 1078 * were enabled/disabled around or between these calls, we just 1079 * have the kernel take a reference on the CRTC (just once though 1080 * to avoid corrupting the count if multiple, mismatch calls occur), 1081 * so that interrupts remain enabled in the interim. 1082 */ 1083 if (!dev->vblank_inmodeset[crtc]) { 1084 dev->vblank_inmodeset[crtc] = 0x1; 1085 if (drm_vblank_get(dev, crtc) == 0) 1086 dev->vblank_inmodeset[crtc] |= 0x2; 1087 } 1088 } 1089 EXPORT_SYMBOL(drm_vblank_pre_modeset); 1090 1091 void drm_vblank_post_modeset(struct drm_device *dev, int crtc) 1092 { 1093 /* vblank is not initialized (IRQ not installed ?), or has been freed */ 1094 if (!dev->num_crtcs) 1095 return; 1096 1097 if (dev->vblank_inmodeset[crtc]) { 1098 mtx_enter(&dev->vbl_lock); 1099 dev->vblank_disable_allowed = 1; 1100 mtx_leave(&dev->vbl_lock); 1101 1102 if (dev->vblank_inmodeset[crtc] & 0x2) 1103 drm_vblank_put(dev, crtc); 1104 1105 dev->vblank_inmodeset[crtc] = 0; 1106 } 1107 } 1108 EXPORT_SYMBOL(drm_vblank_post_modeset); 1109 1110 /** 1111 * drm_modeset_ctl - handle vblank event counter changes across mode switch 1112 * @DRM_IOCTL_ARGS: standard ioctl arguments 1113 * 1114 * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET 1115 * ioctls around modesetting so that any lost vblank events are accounted for. 1116 * 1117 * Generally the counter will reset across mode sets. If interrupts are 1118 * enabled around this call, we don't have to do anything since the counter 1119 * will have already been incremented. 1120 */ 1121 int drm_modeset_ctl(struct drm_device *dev, void *data, 1122 struct drm_file *file_priv) 1123 { 1124 struct drm_modeset_ctl *modeset = data; 1125 unsigned int crtc; 1126 1127 /* If drm_vblank_init() hasn't been called yet, just no-op */ 1128 if (!dev->num_crtcs) 1129 return 0; 1130 1131 /* KMS drivers handle this internally */ 1132 if (drm_core_check_feature(dev, DRIVER_MODESET)) 1133 return 0; 1134 1135 crtc = modeset->crtc; 1136 if (crtc >= dev->num_crtcs) 1137 return -EINVAL; 1138 1139 switch (modeset->cmd) { 1140 case _DRM_PRE_MODESET: 1141 drm_vblank_pre_modeset(dev, crtc); 1142 break; 1143 case _DRM_POST_MODESET: 1144 drm_vblank_post_modeset(dev, crtc); 1145 break; 1146 default: 1147 return -EINVAL; 1148 } 1149 1150 return 0; 1151 } 1152 1153 static int drm_queue_vblank_event(struct drm_device *dev, int pipe, 1154 union drm_wait_vblank *vblwait, 1155 struct drm_file *file_priv) 1156 { 1157 struct drm_pending_vblank_event *e; 1158 struct timeval now; 1159 unsigned int seq; 1160 int ret; 1161 1162 e = kzalloc(sizeof *e, GFP_KERNEL); 1163 if (e == NULL) { 1164 ret = -ENOMEM; 1165 goto err_put; 1166 } 1167 1168 e->pipe = pipe; 1169 e->base.pid = DRM_CURRENTPID; 1170 e->event.base.type = DRM_EVENT_VBLANK; 1171 e->event.base.length = sizeof e->event; 1172 e->event.user_data = vblwait->request.signal; 1173 e->base.event = &e->event.base; 1174 e->base.file_priv = file_priv; 1175 e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; 1176 1177 mtx_enter(&dev->event_lock); 1178 1179 if (file_priv->event_space < sizeof e->event) { 1180 ret = -EBUSY; 1181 goto err_unlock; 1182 } 1183 1184 file_priv->event_space -= sizeof e->event; 1185 seq = drm_vblank_count_and_time(dev, pipe, &now); 1186 1187 if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) && 1188 (seq - vblwait->request.sequence) <= (1 << 23)) { 1189 vblwait->request.sequence = seq + 1; 1190 vblwait->reply.sequence = vblwait->request.sequence; 1191 } 1192 1193 DPRINTF("event on vblank count %d, current %d, crtc %d\n", 1194 vblwait->request.sequence, seq, pipe); 1195 1196 #if 0 1197 trace_drm_vblank_event_queued(current->pid, pipe, 1198 vblwait->request.sequence); 1199 #endif 1200 1201 e->event.sequence = vblwait->request.sequence; 1202 if ((seq - vblwait->request.sequence) <= (1 << 23)) { 1203 drm_vblank_put(dev, pipe); 1204 send_vblank_event(dev, e, seq, &now); 1205 vblwait->reply.sequence = seq; 1206 } else { 1207 /* drm_handle_vblank_events will call drm_vblank_put */ 1208 TAILQ_INSERT_TAIL(&dev->vbl_events, &e->base, link); 1209 vblwait->reply.sequence = vblwait->request.sequence; 1210 } 1211 1212 mtx_leave(&dev->event_lock); 1213 1214 return 0; 1215 1216 err_unlock: 1217 mtx_leave(&dev->event_lock); 1218 kfree(e); 1219 err_put: 1220 drm_vblank_put(dev, pipe); 1221 return ret; 1222 } 1223 1224 /** 1225 * Wait for VBLANK. 1226 * 1227 * \param inode device inode. 1228 * \param file_priv DRM file private. 1229 * \param cmd command. 1230 * \param data user argument, pointing to a drm_wait_vblank structure. 1231 * \return zero on success or a negative number on failure. 1232 * 1233 * This function enables the vblank interrupt on the pipe requested, then 1234 * sleeps waiting for the requested sequence number to occur, and drops 1235 * the vblank interrupt refcount afterwards. (vblank irq disable follows that 1236 * after a timeout with no further vblank waits scheduled). 1237 */ 1238 int drm_wait_vblank(struct drm_device *dev, void *data, 1239 struct drm_file *file_priv) 1240 { 1241 union drm_wait_vblank *vblwait = data; 1242 int ret; 1243 unsigned int flags, seq, crtc, high_crtc; 1244 1245 if (!dev->irq_enabled) 1246 return -EINVAL; 1247 1248 if (vblwait->request.type & _DRM_VBLANK_SIGNAL) 1249 return -EINVAL; 1250 1251 if (vblwait->request.type & 1252 ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK | 1253 _DRM_VBLANK_HIGH_CRTC_MASK)) { 1254 DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n", 1255 vblwait->request.type, 1256 (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK | 1257 _DRM_VBLANK_HIGH_CRTC_MASK)); 1258 return -EINVAL; 1259 } 1260 1261 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; 1262 high_crtc = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK); 1263 if (high_crtc) 1264 crtc = high_crtc >> _DRM_VBLANK_HIGH_CRTC_SHIFT; 1265 else 1266 crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; 1267 if (crtc >= dev->num_crtcs) 1268 return -EINVAL; 1269 1270 ret = drm_vblank_get(dev, crtc); 1271 if (ret) { 1272 DRM_DEBUG("failed to acquire vblank counter, %d\n", ret); 1273 return ret; 1274 } 1275 seq = drm_vblank_count(dev, crtc); 1276 1277 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { 1278 case _DRM_VBLANK_RELATIVE: 1279 vblwait->request.sequence += seq; 1280 vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; 1281 case _DRM_VBLANK_ABSOLUTE: 1282 break; 1283 default: 1284 ret = -EINVAL; 1285 goto done; 1286 } 1287 1288 if (flags & _DRM_VBLANK_EVENT) { 1289 /* must hold on to the vblank ref until the event fires 1290 * drm_vblank_put will be called asynchronously 1291 */ 1292 return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); 1293 } 1294 1295 if ((flags & _DRM_VBLANK_NEXTONMISS) && 1296 (seq - vblwait->request.sequence) <= (1<<23)) { 1297 vblwait->request.sequence = seq + 1; 1298 } 1299 1300 DPRINTF("waiting on vblank count %d, crtc %d\n", 1301 vblwait->request.sequence, crtc); 1302 dev->last_vblank_wait[crtc] = vblwait->request.sequence; 1303 DRM_WAIT_ON(ret, &dev->vbl_queue[crtc], &dev->vbl_lock, 3 * hz, 1304 "drmvblq", (((drm_vblank_count(dev, crtc) - 1305 vblwait->request.sequence) <= (1 << 23)) || 1306 !dev->irq_enabled)); 1307 1308 if (ret != -EINTR) { 1309 struct timeval now; 1310 1311 vblwait->reply.sequence = drm_vblank_count_and_time(dev, crtc, &now); 1312 vblwait->reply.tval_sec = now.tv_sec; 1313 vblwait->reply.tval_usec = now.tv_usec; 1314 1315 DPRINTF("returning %d to client\n", 1316 vblwait->reply.sequence); 1317 } else { 1318 DPRINTF("vblank wait interrupted by signal\n"); 1319 } 1320 1321 done: 1322 drm_vblank_put(dev, crtc); 1323 return ret; 1324 } 1325 1326 static void drm_handle_vblank_events(struct drm_device *dev, int crtc) 1327 { 1328 struct drmevlist *list; 1329 struct drm_pending_event *ev, *tmp; 1330 struct drm_pending_vblank_event *vev; 1331 struct timeval now; 1332 unsigned int seq; 1333 1334 list = &dev->vbl_events; 1335 seq = drm_vblank_count_and_time(dev, crtc, &now); 1336 1337 mtx_enter(&dev->event_lock); 1338 1339 for (ev = TAILQ_FIRST(list); ev != NULL; ev = tmp) { 1340 tmp = TAILQ_NEXT(ev, link); 1341 1342 vev = (struct drm_pending_vblank_event *)ev; 1343 1344 if (vev->pipe != crtc) 1345 continue; 1346 if ((seq - vev->event.sequence) > (1<<23)) 1347 continue; 1348 1349 DPRINTF("vblank event on %d, current %d\n", 1350 vev->event.sequence, seq); 1351 1352 TAILQ_REMOVE(list, ev, link); 1353 drm_vblank_put(dev, vev->pipe); 1354 send_vblank_event(dev, vev, seq, &now); 1355 } 1356 1357 mtx_leave(&dev->event_lock); 1358 1359 // trace_drm_vblank_event(crtc, seq); 1360 } 1361 1362 /** 1363 * drm_handle_vblank - handle a vblank event 1364 * @dev: DRM device 1365 * @crtc: where this event occurred 1366 * 1367 * Drivers should call this routine in their vblank interrupt handlers to 1368 * update the vblank counter and send any signals that may be pending. 1369 */ 1370 bool drm_handle_vblank(struct drm_device *dev, int crtc) 1371 { 1372 u32 vblcount; 1373 s64 diff_ns; 1374 struct timeval tvblank; 1375 1376 if (!dev->num_crtcs) 1377 return false; 1378 1379 /* Need timestamp lock to prevent concurrent execution with 1380 * vblank enable/disable, as this would cause inconsistent 1381 * or corrupted timestamps and vblank counts. 1382 */ 1383 mtx_enter(&dev->vblank_time_lock); 1384 1385 /* Vblank irq handling disabled. Nothing to do. */ 1386 if (!dev->vblank_enabled[crtc]) { 1387 mtx_leave(&dev->vblank_time_lock); 1388 return false; 1389 } 1390 1391 /* Fetch corresponding timestamp for this vblank interval from 1392 * driver and store it in proper slot of timestamp ringbuffer. 1393 */ 1394 1395 /* Get current timestamp and count. */ 1396 vblcount = atomic_read(&dev->_vblank_count[crtc]); 1397 drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ); 1398 1399 /* Compute time difference to timestamp of last vblank */ 1400 diff_ns = timeval_to_ns(&tvblank) - 1401 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); 1402 1403 /* Update vblank timestamp and count if at least 1404 * DRM_REDUNDANT_VBLIRQ_THRESH_NS nanoseconds 1405 * difference between last stored timestamp and current 1406 * timestamp. A smaller difference means basically 1407 * identical timestamps. Happens if this vblank has 1408 * been already processed and this is a redundant call, 1409 * e.g., due to spurious vblank interrupts. We need to 1410 * ignore those for accounting. 1411 */ 1412 if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { 1413 /* Store new timestamp in ringbuffer. */ 1414 vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; 1415 1416 /* Increment cooked vblank count. This also atomically commits 1417 * the timestamp computed above. 1418 */ 1419 smp_mb__before_atomic_inc(); 1420 atomic_inc(&dev->_vblank_count[crtc]); 1421 smp_mb__after_atomic_inc(); 1422 } else { 1423 DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", 1424 crtc, (int) diff_ns); 1425 } 1426 1427 wakeup(&dev->vbl_queue[crtc]); 1428 drm_handle_vblank_events(dev, crtc); 1429 1430 mtx_leave(&dev->vblank_time_lock); 1431 return true; 1432 } 1433 EXPORT_SYMBOL(drm_handle_vblank); 1434