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