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 2 (21.10.2013).\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 /** 411 * drm_calc_timestamping_constants - Calculate vblank timestamp constants 412 * 413 * @crtc drm_crtc whose timestamp constants should be updated. 414 * @mode display mode containing the scanout timings 415 * 416 * Calculate and store various constants which are later 417 * needed by vblank and swap-completion timestamping, e.g, 418 * by drm_calc_vbltimestamp_from_scanoutpos(). They are 419 * derived from crtc's true scanout timing, so they take 420 * things like panel scaling or other adjustments into account. 421 */ 422 void drm_calc_timestamping_constants(struct drm_crtc *crtc, 423 const struct drm_display_mode *mode) 424 { 425 int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0; 426 int dotclock = mode->crtc_clock; 427 428 /* Valid dotclock? */ 429 if (dotclock > 0) { 430 int frame_size = mode->crtc_htotal * mode->crtc_vtotal; 431 432 /* 433 * Convert scanline length in pixels and video 434 * dot clock to line duration, frame duration 435 * and pixel duration in nanoseconds: 436 */ 437 pixeldur_ns = 1000000 / dotclock; 438 linedur_ns = div_u64((u64) mode->crtc_htotal * 1000000, dotclock); 439 framedur_ns = div_u64((u64) frame_size * 1000000, dotclock); 440 441 /* 442 * Fields of interlaced scanout modes are only half a frame duration. 443 */ 444 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 445 framedur_ns /= 2; 446 } else 447 DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n", 448 crtc->base.id); 449 450 crtc->pixeldur_ns = pixeldur_ns; 451 crtc->linedur_ns = linedur_ns; 452 crtc->framedur_ns = framedur_ns; 453 454 DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n", 455 crtc->base.id, mode->crtc_htotal, 456 mode->crtc_vtotal, mode->crtc_vdisplay); 457 DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n", 458 crtc->base.id, dotclock, framedur_ns, 459 linedur_ns, pixeldur_ns); 460 } 461 EXPORT_SYMBOL(drm_calc_timestamping_constants); 462 463 /** 464 * drm_calc_vbltimestamp_from_scanoutpos - helper routine for kms 465 * drivers. Implements calculation of exact vblank timestamps from 466 * given drm_display_mode timings and current video scanout position 467 * of a crtc. This can be called from within get_vblank_timestamp() 468 * implementation of a kms driver to implement the actual timestamping. 469 * 470 * Should return timestamps conforming to the OML_sync_control OpenML 471 * extension specification. The timestamp corresponds to the end of 472 * the vblank interval, aka start of scanout of topmost-leftmost display 473 * pixel in the following video frame. 474 * 475 * Requires support for optional dev->driver->get_scanout_position() 476 * in kms driver, plus a bit of setup code to provide a drm_display_mode 477 * that corresponds to the true scanout timing. 478 * 479 * The current implementation only handles standard video modes. It 480 * returns as no operation if a doublescan or interlaced video mode is 481 * active. Higher level code is expected to handle this. 482 * 483 * @dev: DRM device. 484 * @crtc: Which crtc's vblank timestamp to retrieve. 485 * @max_error: Desired maximum allowable error in timestamps (nanosecs). 486 * On return contains true maximum error of timestamp. 487 * @vblank_time: Pointer to struct timeval which should receive the timestamp. 488 * @flags: Flags to pass to driver: 489 * 0 = Default. 490 * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. 491 * @refcrtc: drm_crtc* of crtc which defines scanout timing. 492 * 493 * Returns negative value on error, failure or if not supported in current 494 * video mode: 495 * 496 * -EINVAL - Invalid crtc. 497 * -EAGAIN - Temporary unavailable, e.g., called before initial modeset. 498 * -ENOTSUPP - Function not supported in current display mode. 499 * -EIO - Failed, e.g., due to failed scanout position query. 500 * 501 * Returns or'ed positive status flags on success: 502 * 503 * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. 504 * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. 505 * 506 */ 507 int 508 drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, 509 int *max_error, struct timeval *vblank_time, unsigned flags, 510 struct drm_crtc *refcrtc) 511 { 512 struct timeval stime, raw_time; 513 struct drm_display_mode *mode; 514 int vbl_status, vtotal, vdisplay; 515 int vpos, hpos, i; 516 int64_t framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; 517 bool invbl; 518 519 if (crtc < 0 || crtc >= dev->num_crtcs) { 520 DRM_ERROR("Invalid crtc %d\n", crtc); 521 return -EINVAL; 522 } 523 524 /* Scanout position query not supported? Should not happen. */ 525 if (!dev->driver->get_scanout_position) { 526 DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); 527 return -EIO; 528 } 529 530 mode = &refcrtc->hwmode; 531 vtotal = mode->crtc_vtotal; 532 vdisplay = mode->crtc_vdisplay; 533 534 /* Durations of frames, lines, pixels in nanoseconds. */ 535 framedur_ns = refcrtc->framedur_ns; 536 linedur_ns = refcrtc->linedur_ns; 537 pixeldur_ns = refcrtc->pixeldur_ns; 538 539 /* If mode timing undefined, just return as no-op: 540 * Happens during initial modesetting of a crtc. 541 */ 542 if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) { 543 DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); 544 return -EAGAIN; 545 } 546 547 /* Get current scanout position with system timestamp. 548 * Repeat query up to DRM_TIMESTAMP_MAXRETRIES times 549 * if single query takes longer than max_error nanoseconds. 550 * 551 * This guarantees a tight bound on maximum error if 552 * code gets preempted or delayed for some reason. 553 */ 554 for (i = 0; i < DRM_TIMESTAMP_MAXRETRIES; i++) { 555 /* Disable preemption to make it very likely to 556 * succeed in the first iteration. 557 */ 558 crit_enter(); 559 560 /* Get system timestamp before query. */ 561 getmicrouptime(&stime); 562 563 /* Get vertical and horizontal scanout pos. vpos, hpos. */ 564 vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, &hpos); 565 566 /* Get system timestamp after query. */ 567 getmicrouptime(&raw_time); 568 569 crit_exit(); 570 571 /* Return as no-op if scanout query unsupported or failed. */ 572 if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { 573 DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n", 574 crtc, vbl_status); 575 return -EIO; 576 } 577 578 duration_ns = timeval_to_ns(&raw_time) - timeval_to_ns(&stime); 579 580 /* Accept result with < max_error nsecs timing uncertainty. */ 581 if (duration_ns <= (int64_t) *max_error) 582 break; 583 } 584 585 /* Noisy system timing? */ 586 if (i == DRM_TIMESTAMP_MAXRETRIES) { 587 DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n", 588 crtc, (int) duration_ns/1000, *max_error/1000, i); 589 } 590 591 /* Return upper bound of timestamp precision error. */ 592 *max_error = (int) duration_ns; 593 594 /* Check if in vblank area: 595 * vpos is >=0 in video scanout area, but negative 596 * within vblank area, counting down the number of lines until 597 * start of scanout. 598 */ 599 invbl = vbl_status & DRM_SCANOUTPOS_INVBL; 600 601 /* Convert scanout position into elapsed time at raw_time query 602 * since start of scanout at first display scanline. delta_ns 603 * can be negative if start of scanout hasn't happened yet. 604 */ 605 delta_ns = (int64_t)vpos * linedur_ns + (int64_t)hpos * pixeldur_ns; 606 607 /* Is vpos outside nominal vblank area, but less than 608 * 1/100 of a frame height away from start of vblank? 609 * If so, assume this isn't a massively delayed vblank 610 * interrupt, but a vblank interrupt that fired a few 611 * microseconds before true start of vblank. Compensate 612 * by adding a full frame duration to the final timestamp. 613 * Happens, e.g., on ATI R500, R600. 614 * 615 * We only do this if DRM_CALLED_FROM_VBLIRQ. 616 */ 617 if ((flags & DRM_CALLED_FROM_VBLIRQ) && !invbl && 618 ((vdisplay - vpos) < vtotal / 100)) { 619 delta_ns = delta_ns - framedur_ns; 620 621 /* Signal this correction as "applied". */ 622 vbl_status |= 0x8; 623 } 624 625 /* Subtract time delta from raw timestamp to get final 626 * vblank_time timestamp for end of vblank. 627 */ 628 *vblank_time = ns_to_timeval(timeval_to_ns(&raw_time) - delta_ns); 629 630 DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %jd.%jd -> %jd.%jd [e %d us, %d rep]\n", 631 crtc, (int)vbl_status, hpos, vpos, (uintmax_t)raw_time.tv_sec, 632 (uintmax_t)raw_time.tv_usec, (uintmax_t)vblank_time->tv_sec, 633 (uintmax_t)vblank_time->tv_usec, (int)duration_ns/1000, i); 634 635 vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD; 636 if (invbl) 637 vbl_status |= DRM_VBLANKTIME_INVBL; 638 639 return vbl_status; 640 } 641 642 static struct timeval get_drm_timestamp(void) 643 { 644 struct timeval now; 645 646 getmicrouptime(&now); 647 648 return now; 649 } 650 651 /** 652 * drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent 653 * vblank interval. 654 * 655 * @dev: DRM device 656 * @crtc: which crtc's vblank timestamp to retrieve 657 * @tvblank: Pointer to target struct timeval which should receive the timestamp 658 * @flags: Flags to pass to driver: 659 * 0 = Default. 660 * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. 661 * 662 * Fetches the system timestamp corresponding to the time of the most recent 663 * vblank interval on specified crtc. May call into kms-driver to 664 * compute the timestamp with a high-precision GPU specific method. 665 * 666 * Returns zero if timestamp originates from uncorrected do_gettimeofday() 667 * call, i.e., it isn't very precisely locked to the true vblank. 668 * 669 * Returns non-zero if timestamp is considered to be very precise. 670 */ 671 u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, 672 struct timeval *tvblank, unsigned flags) 673 { 674 int ret = 0; 675 676 /* Define requested maximum error on timestamps (nanoseconds). */ 677 int max_error = (int) drm_timestamp_precision * 1000; 678 679 /* Query driver if possible and precision timestamping enabled. */ 680 if (dev->driver->get_vblank_timestamp && (max_error > 0)) { 681 ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error, 682 tvblank, flags); 683 if (ret > 0) 684 return (u32) ret; 685 } 686 687 /* GPU high precision timestamp query unsupported or failed. 688 * Return gettimeofday timestamp as best estimate. 689 */ 690 microtime(tvblank); 691 692 return 0; 693 } 694 695 /** 696 * drm_vblank_count - retrieve "cooked" vblank counter value 697 * @dev: DRM device 698 * @crtc: which counter to retrieve 699 * 700 * Fetches the "cooked" vblank count value that represents the number of 701 * vblank events since the system was booted, including lost events due to 702 * modesetting activity. 703 */ 704 u32 drm_vblank_count(struct drm_device *dev, int crtc) 705 { 706 return atomic_read(&dev->_vblank_count[crtc]); 707 } 708 709 /** 710 * drm_vblank_count_and_time - retrieve "cooked" vblank counter value 711 * and the system timestamp corresponding to that vblank counter value. 712 * 713 * @dev: DRM device 714 * @crtc: which counter to retrieve 715 * @vblanktime: Pointer to struct timeval to receive the vblank timestamp. 716 * 717 * Fetches the "cooked" vblank count value that represents the number of 718 * vblank events since the system was booted, including lost events due to 719 * modesetting activity. Returns corresponding system timestamp of the time 720 * of the vblank interval that corresponds to the current value vblank counter 721 * value. 722 */ 723 u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, 724 struct timeval *vblanktime) 725 { 726 u32 cur_vblank; 727 728 /* Read timestamp from slot of _vblank_time ringbuffer 729 * that corresponds to current vblank count. Retry if 730 * count has incremented during readout. This works like 731 * a seqlock. 732 */ 733 do { 734 cur_vblank = atomic_read(&dev->_vblank_count[crtc]); 735 *vblanktime = vblanktimestamp(dev, crtc, cur_vblank); 736 cpu_lfence(); 737 } while (cur_vblank != atomic_read(&dev->_vblank_count[crtc])); 738 739 return cur_vblank; 740 } 741 742 static void send_vblank_event(struct drm_device *dev, 743 struct drm_pending_vblank_event *e, 744 unsigned long seq, struct timeval *now) 745 { 746 KKASSERT(mutex_is_locked(&dev->event_lock)); 747 e->event.sequence = seq; 748 e->event.tv_sec = now->tv_sec; 749 e->event.tv_usec = now->tv_usec; 750 751 list_add_tail(&e->base.link, 752 &e->base.file_priv->event_list); 753 drm_event_wakeup(&e->base); 754 #if 0 755 trace_drm_vblank_event_delivered(e->base.pid, e->pipe, 756 e->event.sequence); 757 #endif 758 } 759 760 /** 761 * drm_send_vblank_event - helper to send vblank event after pageflip 762 * @dev: DRM device 763 * @crtc: CRTC in question 764 * @e: the event to send 765 * 766 * Updates sequence # and timestamp on event, and sends it to userspace. 767 * Caller must hold event lock. 768 */ 769 void drm_send_vblank_event(struct drm_device *dev, int crtc, 770 struct drm_pending_vblank_event *e) 771 { 772 struct timeval now; 773 unsigned int seq; 774 if (crtc >= 0) { 775 seq = drm_vblank_count_and_time(dev, crtc, &now); 776 } else { 777 seq = 0; 778 779 now = get_drm_timestamp(); 780 } 781 e->pipe = crtc; 782 send_vblank_event(dev, e, seq, &now); 783 } 784 EXPORT_SYMBOL(drm_send_vblank_event); 785 786 /** 787 * drm_update_vblank_count - update the master vblank counter 788 * @dev: DRM device 789 * @crtc: counter to update 790 * 791 * Call back into the driver to update the appropriate vblank counter 792 * (specified by @crtc). Deal with wraparound, if it occurred, and 793 * update the last read value so we can deal with wraparound on the next 794 * call if necessary. 795 * 796 * Only necessary when going from off->on, to account for frames we 797 * didn't get an interrupt for. 798 * 799 * Note: caller must hold dev->vbl_lock since this reads & writes 800 * device vblank fields. 801 */ 802 static void drm_update_vblank_count(struct drm_device *dev, int crtc) 803 { 804 u32 cur_vblank, diff, tslot, rc; 805 struct timeval t_vblank; 806 807 /* 808 * Interrupts were disabled prior to this call, so deal with counter 809 * wrap if needed. 810 * NOTE! It's possible we lost a full dev->max_vblank_count events 811 * here if the register is small or we had vblank interrupts off for 812 * a long time. 813 * 814 * We repeat the hardware vblank counter & timestamp query until 815 * we get consistent results. This to prevent races between gpu 816 * updating its hardware counter while we are retrieving the 817 * corresponding vblank timestamp. 818 */ 819 do { 820 cur_vblank = dev->driver->get_vblank_counter(dev, crtc); 821 rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0); 822 } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc)); 823 824 /* Deal with counter wrap */ 825 diff = cur_vblank - dev->last_vblank[crtc]; 826 if (cur_vblank < dev->last_vblank[crtc]) { 827 diff += dev->max_vblank_count; 828 829 DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", 830 crtc, dev->last_vblank[crtc], cur_vblank, diff); 831 } 832 833 DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", 834 crtc, diff); 835 836 /* Reinitialize corresponding vblank timestamp if high-precision query 837 * available. Skip this step if query unsupported or failed. Will 838 * reinitialize delayed at next vblank interrupt in that case. 839 */ 840 if (rc) { 841 tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; 842 vblanktimestamp(dev, crtc, tslot) = t_vblank; 843 } 844 845 atomic_add(diff, &dev->_vblank_count[crtc]); 846 } 847 848 /** 849 * drm_vblank_get - get a reference count on vblank events 850 * @dev: DRM device 851 * @crtc: which CRTC to own 852 * 853 * Acquire a reference count on vblank events to avoid having them disabled 854 * while in use. 855 * 856 * RETURNS 857 * Zero on success, nonzero on failure. 858 */ 859 int drm_vblank_get(struct drm_device *dev, int crtc) 860 { 861 int ret = 0; 862 863 lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); 864 /* Going from 0->1 means we have to enable interrupts again */ 865 if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { 866 lockmgr(&dev->vblank_time_lock, LK_EXCLUSIVE); 867 if (!dev->vblank_enabled[crtc]) { 868 /* Enable vblank irqs under vblank_time_lock protection. 869 * All vblank count & timestamp updates are held off 870 * until we are done reinitializing master counter and 871 * timestamps. Filtercode in drm_handle_vblank() will 872 * prevent double-accounting of same vblank interval. 873 */ 874 ret = -dev->driver->enable_vblank(dev, crtc); 875 DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", 876 crtc, ret); 877 if (ret) 878 atomic_dec(&dev->vblank_refcount[crtc]); 879 else { 880 dev->vblank_enabled[crtc] = 1; 881 drm_update_vblank_count(dev, crtc); 882 } 883 } 884 lockmgr(&dev->vblank_time_lock, LK_RELEASE); 885 } else { 886 if (!dev->vblank_enabled[crtc]) { 887 atomic_dec(&dev->vblank_refcount[crtc]); 888 ret = EINVAL; 889 } 890 } 891 lockmgr(&dev->vbl_lock, LK_RELEASE); 892 893 return ret; 894 } 895 896 /** 897 * drm_vblank_put - give up ownership of vblank events 898 * @dev: DRM device 899 * @crtc: which counter to give up 900 * 901 * Release ownership of a given vblank counter, turning off interrupts 902 * if possible. Disable interrupts after drm_vblank_offdelay milliseconds. 903 */ 904 void drm_vblank_put(struct drm_device *dev, int crtc) 905 { 906 BUG_ON(atomic_read(&dev->vblank_refcount[crtc]) == 0); 907 908 /* Last user schedules interrupt disable */ 909 lockmgr(&dev->vblank_time_lock, LK_EXCLUSIVE); 910 if (atomic_dec_and_test(&dev->vblank_refcount[crtc]) && 911 (drm_vblank_offdelay > 0)) { 912 mod_timer(&dev->vblank_disable_timer, 913 jiffies + ((drm_vblank_offdelay * DRM_HZ)/1000)); 914 } 915 lockmgr(&dev->vblank_time_lock, LK_RELEASE); 916 } 917 EXPORT_SYMBOL(drm_vblank_put); 918 919 void drm_vblank_off(struct drm_device *dev, int crtc) 920 { 921 struct drm_pending_vblank_event *e, *t; 922 struct timeval now; 923 unsigned int seq; 924 925 lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); 926 vblank_disable_and_save(dev, crtc); 927 lockmgr(&dev->event_lock, LK_EXCLUSIVE); 928 wakeup(&dev->_vblank_count[crtc]); 929 930 /* Send any queued vblank events, lest the natives grow disquiet */ 931 seq = drm_vblank_count_and_time(dev, crtc, &now); 932 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { 933 if (e->pipe != crtc) 934 continue; 935 DRM_DEBUG("Sending premature vblank event on disable: \ 936 wanted %d, current %d\n", 937 e->event.sequence, seq); 938 list_del(&e->base.link); 939 drm_vblank_put(dev, e->pipe); 940 send_vblank_event(dev, e, seq, &now); 941 } 942 943 lockmgr(&dev->event_lock, LK_RELEASE); 944 lockmgr(&dev->vbl_lock, LK_RELEASE); 945 } 946 947 /** 948 * drm_vblank_pre_modeset - account for vblanks across mode sets 949 * @dev: DRM device 950 * @crtc: CRTC in question 951 * @post: post or pre mode set? 952 * 953 * Account for vblank events across mode setting events, which will likely 954 * reset the hardware frame counter. 955 */ 956 void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) 957 { 958 /* vblank is not initialized (IRQ not installed ?) */ 959 if (!dev->num_crtcs) 960 return; 961 /* 962 * To avoid all the problems that might happen if interrupts 963 * were enabled/disabled around or between these calls, we just 964 * have the kernel take a reference on the CRTC (just once though 965 * to avoid corrupting the count if multiple, mismatch calls occur), 966 * so that interrupts remain enabled in the interim. 967 */ 968 if (!dev->vblank_inmodeset[crtc]) { 969 dev->vblank_inmodeset[crtc] = 0x1; 970 if (drm_vblank_get(dev, crtc) == 0) 971 dev->vblank_inmodeset[crtc] |= 0x2; 972 } 973 } 974 975 void drm_vblank_post_modeset(struct drm_device *dev, int crtc) 976 { 977 978 if (dev->vblank_inmodeset[crtc]) { 979 lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); 980 dev->vblank_disable_allowed = 1; 981 lockmgr(&dev->vbl_lock, LK_RELEASE); 982 983 if (dev->vblank_inmodeset[crtc] & 0x2) 984 drm_vblank_put(dev, crtc); 985 986 dev->vblank_inmodeset[crtc] = 0; 987 } 988 } 989 990 /** 991 * drm_modeset_ctl - handle vblank event counter changes across mode switch 992 * @DRM_IOCTL_ARGS: standard ioctl arguments 993 * 994 * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET 995 * ioctls around modesetting so that any lost vblank events are accounted for. 996 * 997 * Generally the counter will reset across mode sets. If interrupts are 998 * enabled around this call, we don't have to do anything since the counter 999 * will have already been incremented. 1000 */ 1001 int drm_modeset_ctl(struct drm_device *dev, void *data, 1002 struct drm_file *file_priv) 1003 { 1004 struct drm_modeset_ctl *modeset = data; 1005 int ret = 0; 1006 unsigned int crtc; 1007 1008 /* If drm_vblank_init() hasn't been called yet, just no-op */ 1009 if (!dev->num_crtcs) 1010 goto out; 1011 1012 crtc = modeset->crtc; 1013 if (crtc >= dev->num_crtcs) { 1014 ret = -EINVAL; 1015 goto out; 1016 } 1017 1018 switch (modeset->cmd) { 1019 case _DRM_PRE_MODESET: 1020 drm_vblank_pre_modeset(dev, crtc); 1021 break; 1022 case _DRM_POST_MODESET: 1023 drm_vblank_post_modeset(dev, crtc); 1024 break; 1025 default: 1026 ret = -EINVAL; 1027 break; 1028 } 1029 1030 out: 1031 return ret; 1032 } 1033 1034 static void 1035 drm_vblank_event_destroy(struct drm_pending_event *e) 1036 { 1037 1038 drm_free(e, M_DRM); 1039 } 1040 1041 static int drm_queue_vblank_event(struct drm_device *dev, int pipe, 1042 union drm_wait_vblank *vblwait, 1043 struct drm_file *file_priv) 1044 { 1045 struct drm_pending_vblank_event *e; 1046 struct timeval now; 1047 unsigned int seq; 1048 int ret; 1049 1050 e = kmalloc(sizeof *e, M_DRM, M_WAITOK | M_ZERO); 1051 1052 e->pipe = pipe; 1053 e->base.pid = curproc->p_pid; 1054 e->event.base.type = DRM_EVENT_VBLANK; 1055 e->event.base.length = sizeof e->event; 1056 e->event.user_data = vblwait->request.signal; 1057 e->base.event = &e->event.base; 1058 e->base.file_priv = file_priv; 1059 e->base.destroy = drm_vblank_event_destroy; 1060 1061 lockmgr(&dev->event_lock, LK_EXCLUSIVE); 1062 1063 if (file_priv->event_space < sizeof e->event) { 1064 ret = EBUSY; 1065 goto err_unlock; 1066 } 1067 1068 file_priv->event_space -= sizeof e->event; 1069 seq = drm_vblank_count_and_time(dev, pipe, &now); 1070 1071 if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) && 1072 (seq - vblwait->request.sequence) <= (1 << 23)) { 1073 vblwait->request.sequence = seq + 1; 1074 vblwait->reply.sequence = vblwait->request.sequence; 1075 } 1076 1077 DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n", 1078 vblwait->request.sequence, seq, pipe); 1079 1080 e->event.sequence = vblwait->request.sequence; 1081 if ((seq - vblwait->request.sequence) <= (1 << 23)) { 1082 drm_vblank_put(dev, pipe); 1083 send_vblank_event(dev, e, seq, &now); 1084 vblwait->reply.sequence = seq; 1085 } else { 1086 /* drm_handle_vblank_events will call drm_vblank_put */ 1087 list_add_tail(&e->base.link, &dev->vblank_event_list); 1088 vblwait->reply.sequence = vblwait->request.sequence; 1089 } 1090 1091 lockmgr(&dev->event_lock, LK_RELEASE); 1092 1093 return 0; 1094 1095 err_unlock: 1096 lockmgr(&dev->event_lock, LK_RELEASE); 1097 drm_free(e, M_DRM); 1098 drm_vblank_put(dev, pipe); 1099 return ret; 1100 } 1101 1102 /** 1103 * Wait for VBLANK. 1104 * 1105 * \param inode device inode. 1106 * \param file_priv DRM file private. 1107 * \param cmd command. 1108 * \param data user argument, pointing to a drm_wait_vblank structure. 1109 * \return zero on success or a negative number on failure. 1110 * 1111 * This function enables the vblank interrupt on the pipe requested, then 1112 * sleeps waiting for the requested sequence number to occur, and drops 1113 * the vblank interrupt refcount afterwards. (vblank irq disable follows that 1114 * after a timeout with no further vblank waits scheduled). 1115 */ 1116 int drm_wait_vblank(struct drm_device *dev, void *data, 1117 struct drm_file *file_priv) 1118 { 1119 union drm_wait_vblank *vblwait = data; 1120 int ret = 0; 1121 unsigned int flags, seq, crtc, high_crtc; 1122 1123 if (/*(!drm_dev_to_irq(dev)) || */(!dev->irq_enabled)) 1124 return (EINVAL); 1125 1126 if (vblwait->request.type & _DRM_VBLANK_SIGNAL) 1127 return (EINVAL); 1128 1129 if (vblwait->request.type & 1130 ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK | 1131 _DRM_VBLANK_HIGH_CRTC_MASK)) { 1132 DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n", 1133 vblwait->request.type, 1134 (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK | 1135 _DRM_VBLANK_HIGH_CRTC_MASK)); 1136 return (EINVAL); 1137 } 1138 1139 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; 1140 high_crtc = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK); 1141 if (high_crtc) 1142 crtc = high_crtc >> _DRM_VBLANK_HIGH_CRTC_SHIFT; 1143 else 1144 crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; 1145 if (crtc >= dev->num_crtcs) 1146 return (EINVAL); 1147 1148 ret = drm_vblank_get(dev, crtc); 1149 if (ret) { 1150 DRM_DEBUG("failed to acquire vblank counter, %d\n", ret); 1151 return (ret); 1152 } 1153 seq = drm_vblank_count(dev, crtc); 1154 1155 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { 1156 case _DRM_VBLANK_RELATIVE: 1157 vblwait->request.sequence += seq; 1158 vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; 1159 case _DRM_VBLANK_ABSOLUTE: 1160 break; 1161 default: 1162 ret = (EINVAL); 1163 goto done; 1164 } 1165 1166 if (flags & _DRM_VBLANK_EVENT) { 1167 /* must hold on to the vblank ref until the event fires 1168 * drm_vblank_put will be called asynchronously 1169 */ 1170 return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); 1171 } 1172 1173 if ((flags & _DRM_VBLANK_NEXTONMISS) && 1174 (seq - vblwait->request.sequence) <= (1<<23)) { 1175 vblwait->request.sequence = seq + 1; 1176 } 1177 1178 dev->last_vblank_wait[crtc] = vblwait->request.sequence; 1179 lockmgr(&dev->vblank_time_lock, LK_EXCLUSIVE); 1180 while (((drm_vblank_count(dev, crtc) - vblwait->request.sequence) > 1181 (1 << 23)) && dev->irq_enabled) { 1182 /* 1183 * The wakeups from the drm_irq_uninstall() and 1184 * drm_vblank_off() may be lost there since vbl_lock 1185 * is not held. Then, the timeout will wake us; the 3 1186 * seconds delay should not be a problem for 1187 * application when crtc is disabled or irq 1188 * uninstalled anyway. 1189 */ 1190 ret = lksleep(&dev->_vblank_count[crtc], &dev->vblank_time_lock, 1191 PCATCH, "drmvbl", 3 * hz); 1192 if (ret != 0) 1193 break; 1194 } 1195 lockmgr(&dev->vblank_time_lock, LK_RELEASE); 1196 if (ret != EINTR) { 1197 struct timeval now; 1198 long reply_seq; 1199 1200 reply_seq = drm_vblank_count_and_time(dev, crtc, &now); 1201 vblwait->reply.sequence = reply_seq; 1202 vblwait->reply.tval_sec = now.tv_sec; 1203 vblwait->reply.tval_usec = now.tv_usec; 1204 } 1205 1206 done: 1207 drm_vblank_put(dev, crtc); 1208 return ret; 1209 } 1210 1211 void drm_handle_vblank_events(struct drm_device *dev, int crtc) 1212 { 1213 struct drm_pending_vblank_event *e, *t; 1214 struct timeval now; 1215 unsigned int seq; 1216 1217 seq = drm_vblank_count_and_time(dev, crtc, &now); 1218 1219 lockmgr(&dev->event_lock, LK_EXCLUSIVE); 1220 1221 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { 1222 if (e->pipe != crtc) 1223 continue; 1224 if ((seq - e->event.sequence) > (1<<23)) 1225 continue; 1226 1227 DRM_DEBUG("vblank event on %d, current %d\n", 1228 e->event.sequence, seq); 1229 1230 list_del(&e->base.link); 1231 drm_vblank_put(dev, e->pipe); 1232 send_vblank_event(dev, e, seq, &now); 1233 } 1234 1235 lockmgr(&dev->event_lock, LK_RELEASE); 1236 } 1237 1238 /** 1239 * drm_handle_vblank - handle a vblank event 1240 * @dev: DRM device 1241 * @crtc: where this event occurred 1242 * 1243 * Drivers should call this routine in their vblank interrupt handlers to 1244 * update the vblank counter and send any signals that may be pending. 1245 */ 1246 bool drm_handle_vblank(struct drm_device *dev, int crtc) 1247 { 1248 u32 vblcount; 1249 int64_t diff_ns; 1250 struct timeval tvblank; 1251 1252 if (!dev->num_crtcs) 1253 return false; 1254 1255 /* Need timestamp lock to prevent concurrent execution with 1256 * vblank enable/disable, as this would cause inconsistent 1257 * or corrupted timestamps and vblank counts. 1258 */ 1259 lockmgr(&dev->vblank_time_lock, LK_EXCLUSIVE); 1260 1261 /* Vblank irq handling disabled. Nothing to do. */ 1262 if (!dev->vblank_enabled[crtc]) { 1263 lockmgr(&dev->vblank_time_lock, LK_RELEASE); 1264 return false; 1265 } 1266 1267 /* Fetch corresponding timestamp for this vblank interval from 1268 * driver and store it in proper slot of timestamp ringbuffer. 1269 */ 1270 1271 /* Get current timestamp and count. */ 1272 vblcount = atomic_read(&dev->_vblank_count[crtc]); 1273 drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ); 1274 1275 /* Compute time difference to timestamp of last vblank */ 1276 diff_ns = timeval_to_ns(&tvblank) - 1277 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); 1278 1279 /* Update vblank timestamp and count if at least 1280 * DRM_REDUNDANT_VBLIRQ_THRESH_NS nanoseconds 1281 * difference between last stored timestamp and current 1282 * timestamp. A smaller difference means basically 1283 * identical timestamps. Happens if this vblank has 1284 * been already processed and this is a redundant call, 1285 * e.g., due to spurious vblank interrupts. We need to 1286 * ignore those for accounting. 1287 */ 1288 if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { 1289 /* Store new timestamp in ringbuffer. */ 1290 vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; 1291 1292 /* Increment cooked vblank count. This also atomically commits 1293 * the timestamp computed above. 1294 */ 1295 atomic_inc(&dev->_vblank_count[crtc]); 1296 } else { 1297 DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", 1298 crtc, (int) diff_ns); 1299 } 1300 1301 wakeup(&dev->_vblank_count[crtc]); 1302 drm_handle_vblank_events(dev, crtc); 1303 1304 lockmgr(&dev->vblank_time_lock, LK_RELEASE); 1305 return true; 1306 } 1307