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