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