Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'drm-vbl-timestamp' of git://gitorious.org/vsyrjala/linux into drm-next

Here's the vblank timestamp pull request you wanted.

I addressed the few bugs that Mario pointed out and added
the r-bs.

As it has been a while since I made the changes, I gave it a
quick spin on a few different i915 machines. Fortunately
everything still seems to be fine.

* 'drm-vbl-timestamp' of git://gitorious.org/vsyrjala/linux:
drm/i915: Add a kludge for DSL incrementing too late and ISR not working
drm/radeon: Move the early vblank IRQ fixup to radeon_get_crtc_scanoutpos()
drm: Pass 'flags' from the caller to .get_scanout_position()
drm: Fix vblank timestamping constants for interlaced modes
drm/i915: Fix scanoutpos calculations for interlaced modes
drm: Change {pixel,line,frame}dur_ns from s64 to int
drm: Use crtc_clock in drm_calc_timestamping_constants()
drm/radeon: Populate crtc_clock in radeon_atom_get_tv_timings()
drm: Simplify the math in drm_calc_timestamping_constants()
drm: Improve drm_calc_timestamping_constants() documentation
drm/i915: Call drm_calc_timestamping_constants() earlier
drm/i915: Kill hwmode save/restore
drm: Pass the display mode to drm_calc_vbltimestamp_from_scanoutpos()
drm: Pass the display mode to drm_calc_timestamping_constants()

+144 -138
+1 -1
drivers/gpu/drm/drm_crtc_helper.c
··· 536 536 * are later needed by vblank and swap-completion 537 537 * timestamping. They are derived from true hwmode. 538 538 */ 539 - drm_calc_timestamping_constants(crtc); 539 + drm_calc_timestamping_constants(crtc, &crtc->hwmode); 540 540 541 541 /* FIXME: add subpixel order */ 542 542 done:
+42 -67
drivers/gpu/drm/drm_irq.c
··· 436 436 } 437 437 438 438 /** 439 - * drm_calc_timestamping_constants - Calculate and 440 - * store various constants which are later needed by 441 - * vblank and swap-completion timestamping, e.g, by 442 - * drm_calc_vbltimestamp_from_scanoutpos(). 443 - * They are derived from crtc's true scanout timing, 444 - * so they take things like panel scaling or other 445 - * adjustments into account. 439 + * drm_calc_timestamping_constants - Calculate vblank timestamp constants 446 440 * 447 441 * @crtc drm_crtc whose timestamp constants should be updated. 442 + * @mode display mode containing the scanout timings 448 443 * 444 + * Calculate and store various constants which are later 445 + * needed by vblank and swap-completion timestamping, e.g, 446 + * by drm_calc_vbltimestamp_from_scanoutpos(). They are 447 + * derived from crtc's true scanout timing, so they take 448 + * things like panel scaling or other adjustments into account. 449 449 */ 450 - void drm_calc_timestamping_constants(struct drm_crtc *crtc) 450 + void drm_calc_timestamping_constants(struct drm_crtc *crtc, 451 + const struct drm_display_mode *mode) 451 452 { 452 - s64 linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0; 453 - u64 dotclock; 454 - 455 - /* Dot clock in Hz: */ 456 - dotclock = (u64) crtc->hwmode.clock * 1000; 457 - 458 - /* Fields of interlaced scanout modes are only half a frame duration. 459 - * Double the dotclock to get half the frame-/line-/pixelduration. 460 - */ 461 - if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE) 462 - dotclock *= 2; 453 + int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0; 454 + int dotclock = mode->crtc_clock; 463 455 464 456 /* Valid dotclock? */ 465 457 if (dotclock > 0) { 466 - int frame_size; 467 - /* Convert scanline length in pixels and video dot clock to 468 - * line duration, frame duration and pixel duration in 469 - * nanoseconds: 458 + int frame_size = mode->crtc_htotal * mode->crtc_vtotal; 459 + 460 + /* 461 + * Convert scanline length in pixels and video 462 + * dot clock to line duration, frame duration 463 + * and pixel duration in nanoseconds: 470 464 */ 471 - pixeldur_ns = (s64) div64_u64(1000000000, dotclock); 472 - linedur_ns = (s64) div64_u64(((u64) crtc->hwmode.crtc_htotal * 473 - 1000000000), dotclock); 474 - frame_size = crtc->hwmode.crtc_htotal * 475 - crtc->hwmode.crtc_vtotal; 476 - framedur_ns = (s64) div64_u64((u64) frame_size * 1000000000, 477 - dotclock); 465 + pixeldur_ns = 1000000 / dotclock; 466 + linedur_ns = div_u64((u64) mode->crtc_htotal * 1000000, dotclock); 467 + framedur_ns = div_u64((u64) frame_size * 1000000, dotclock); 468 + 469 + /* 470 + * Fields of interlaced scanout modes are only half a frame duration. 471 + */ 472 + if (mode->flags & DRM_MODE_FLAG_INTERLACE) 473 + framedur_ns /= 2; 478 474 } else 479 475 DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n", 480 476 crtc->base.id); ··· 480 484 crtc->framedur_ns = framedur_ns; 481 485 482 486 DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n", 483 - crtc->base.id, crtc->hwmode.crtc_htotal, 484 - crtc->hwmode.crtc_vtotal, crtc->hwmode.crtc_vdisplay); 487 + crtc->base.id, mode->crtc_htotal, 488 + mode->crtc_vtotal, mode->crtc_vdisplay); 485 489 DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n", 486 - crtc->base.id, (int) dotclock/1000, (int) framedur_ns, 487 - (int) linedur_ns, (int) pixeldur_ns); 490 + crtc->base.id, dotclock, framedur_ns, 491 + linedur_ns, pixeldur_ns); 488 492 } 489 493 EXPORT_SYMBOL(drm_calc_timestamping_constants); 490 494 ··· 517 521 * 0 = Default. 518 522 * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. 519 523 * @refcrtc: drm_crtc* of crtc which defines scanout timing. 524 + * @mode: mode which defines the scanout timings 520 525 * 521 526 * Returns negative value on error, failure or if not supported in current 522 527 * video mode: ··· 537 540 int *max_error, 538 541 struct timeval *vblank_time, 539 542 unsigned flags, 540 - struct drm_crtc *refcrtc) 543 + const struct drm_crtc *refcrtc, 544 + const struct drm_display_mode *mode) 541 545 { 542 546 ktime_t stime, etime, mono_time_offset; 543 547 struct timeval tv_etime; 544 - struct drm_display_mode *mode; 545 - int vbl_status, vtotal, vdisplay; 548 + int vbl_status; 546 549 int vpos, hpos, i; 547 - s64 framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; 550 + int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; 548 551 bool invbl; 549 552 550 553 if (crtc < 0 || crtc >= dev->num_crtcs) { ··· 558 561 return -EIO; 559 562 } 560 563 561 - mode = &refcrtc->hwmode; 562 - vtotal = mode->crtc_vtotal; 563 - vdisplay = mode->crtc_vdisplay; 564 - 565 564 /* Durations of frames, lines, pixels in nanoseconds. */ 566 565 framedur_ns = refcrtc->framedur_ns; 567 566 linedur_ns = refcrtc->linedur_ns; ··· 566 573 /* If mode timing undefined, just return as no-op: 567 574 * Happens during initial modesetting of a crtc. 568 575 */ 569 - if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) { 576 + if (framedur_ns == 0) { 570 577 DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); 571 578 return -EAGAIN; 572 579 } ··· 583 590 * Get vertical and horizontal scanout position vpos, hpos, 584 591 * and bounding timestamps stime, etime, pre/post query. 585 592 */ 586 - vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, 593 + vbl_status = dev->driver->get_scanout_position(dev, crtc, flags, &vpos, 587 594 &hpos, &stime, &etime); 588 595 589 596 /* ··· 604 611 duration_ns = ktime_to_ns(etime) - ktime_to_ns(stime); 605 612 606 613 /* Accept result with < max_error nsecs timing uncertainty. */ 607 - if (duration_ns <= (s64) *max_error) 614 + if (duration_ns <= *max_error) 608 615 break; 609 616 } 610 617 611 618 /* Noisy system timing? */ 612 619 if (i == DRM_TIMESTAMP_MAXRETRIES) { 613 620 DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n", 614 - crtc, (int) duration_ns/1000, *max_error/1000, i); 621 + crtc, duration_ns/1000, *max_error/1000, i); 615 622 } 616 623 617 624 /* Return upper bound of timestamp precision error. */ 618 - *max_error = (int) duration_ns; 625 + *max_error = duration_ns; 619 626 620 627 /* Check if in vblank area: 621 628 * vpos is >=0 in video scanout area, but negative ··· 628 635 * since start of scanout at first display scanline. delta_ns 629 636 * can be negative if start of scanout hasn't happened yet. 630 637 */ 631 - delta_ns = (s64) vpos * linedur_ns + (s64) hpos * pixeldur_ns; 632 - 633 - /* Is vpos outside nominal vblank area, but less than 634 - * 1/100 of a frame height away from start of vblank? 635 - * If so, assume this isn't a massively delayed vblank 636 - * interrupt, but a vblank interrupt that fired a few 637 - * microseconds before true start of vblank. Compensate 638 - * by adding a full frame duration to the final timestamp. 639 - * Happens, e.g., on ATI R500, R600. 640 - * 641 - * We only do this if DRM_CALLED_FROM_VBLIRQ. 642 - */ 643 - if ((flags & DRM_CALLED_FROM_VBLIRQ) && !invbl && 644 - ((vdisplay - vpos) < vtotal / 100)) { 645 - delta_ns = delta_ns - framedur_ns; 646 - 647 - /* Signal this correction as "applied". */ 648 - vbl_status |= 0x8; 649 - } 638 + delta_ns = vpos * linedur_ns + hpos * pixeldur_ns; 650 639 651 640 if (!drm_timestamp_monotonic) 652 641 etime = ktime_sub(etime, mono_time_offset); ··· 648 673 crtc, (int)vbl_status, hpos, vpos, 649 674 (long)tv_etime.tv_sec, (long)tv_etime.tv_usec, 650 675 (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, 651 - (int)duration_ns/1000, i); 676 + duration_ns/1000, i); 652 677 653 678 vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD; 654 679 if (invbl)
+49 -42
drivers/gpu/drm/i915/i915_irq.c
··· 621 621 #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__)) 622 622 #define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__)) 623 623 624 - static bool intel_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe) 624 + static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe) 625 625 { 626 626 struct drm_i915_private *dev_priv = dev->dev_private; 627 627 uint32_t status; 628 - int reg; 629 628 630 - if (IS_VALLEYVIEW(dev)) { 631 - status = pipe == PIPE_A ? 632 - I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT : 633 - I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; 634 - 635 - reg = VLV_ISR; 636 - } else if (IS_GEN2(dev)) { 637 - status = pipe == PIPE_A ? 638 - I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT : 639 - I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; 640 - 641 - reg = ISR; 642 - } else if (INTEL_INFO(dev)->gen < 5) { 643 - status = pipe == PIPE_A ? 644 - I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT : 645 - I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; 646 - 647 - reg = ISR; 648 - } else if (INTEL_INFO(dev)->gen < 7) { 629 + if (INTEL_INFO(dev)->gen < 7) { 649 630 status = pipe == PIPE_A ? 650 631 DE_PIPEA_VBLANK : 651 632 DE_PIPEB_VBLANK; 652 - 653 - reg = DEISR; 654 633 } else { 655 634 switch (pipe) { 656 635 default: ··· 643 664 status = DE_PIPEC_VBLANK_IVB; 644 665 break; 645 666 } 646 - 647 - reg = DEISR; 648 667 } 649 668 650 - if (IS_GEN2(dev)) 651 - return __raw_i915_read16(dev_priv, reg) & status; 652 - else 653 - return __raw_i915_read32(dev_priv, reg) & status; 669 + return __raw_i915_read32(dev_priv, DEISR) & status; 654 670 } 655 671 656 672 static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, 657 - int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) 673 + unsigned int flags, int *vpos, int *hpos, 674 + ktime_t *stime, ktime_t *etime) 658 675 { 659 676 struct drm_i915_private *dev_priv = dev->dev_private; 660 677 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; ··· 672 697 vtotal = mode->crtc_vtotal; 673 698 vbl_start = mode->crtc_vblank_start; 674 699 vbl_end = mode->crtc_vblank_end; 700 + 701 + if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 702 + vbl_start = DIV_ROUND_UP(vbl_start, 2); 703 + vbl_end /= 2; 704 + vtotal /= 2; 705 + } 675 706 676 707 ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; 677 708 ··· 703 722 else 704 723 position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; 705 724 706 - /* 707 - * The scanline counter increments at the leading edge 708 - * of hsync, ie. it completely misses the active portion 709 - * of the line. Fix up the counter at both edges of vblank 710 - * to get a more accurate picture whether we're in vblank 711 - * or not. 712 - */ 713 - in_vbl = intel_pipe_in_vblank_locked(dev, pipe); 714 - if ((in_vbl && position == vbl_start - 1) || 715 - (!in_vbl && position == vbl_end - 1)) 716 - position = (position + 1) % vtotal; 725 + if (HAS_PCH_SPLIT(dev)) { 726 + /* 727 + * The scanline counter increments at the leading edge 728 + * of hsync, ie. it completely misses the active portion 729 + * of the line. Fix up the counter at both edges of vblank 730 + * to get a more accurate picture whether we're in vblank 731 + * or not. 732 + */ 733 + in_vbl = ilk_pipe_in_vblank_locked(dev, pipe); 734 + if ((in_vbl && position == vbl_start - 1) || 735 + (!in_vbl && position == vbl_end - 1)) 736 + position = (position + 1) % vtotal; 737 + } else { 738 + /* 739 + * ISR vblank status bits don't work the way we'd want 740 + * them to work on non-PCH platforms (for 741 + * ilk_pipe_in_vblank_locked()), and there doesn't 742 + * appear any other way to determine if we're currently 743 + * in vblank. 744 + * 745 + * Instead let's assume that we're already in vblank if 746 + * we got called from the vblank interrupt and the 747 + * scanline counter value indicates that we're on the 748 + * line just prior to vblank start. This should result 749 + * in the correct answer, unless the vblank interrupt 750 + * delivery really got delayed for almost exactly one 751 + * full frame/field. 752 + */ 753 + if (flags & DRM_CALLED_FROM_VBLIRQ && 754 + position == vbl_start - 1) { 755 + position = (position + 1) % vtotal; 756 + 757 + /* Signal this correction as "applied". */ 758 + ret |= 0x8; 759 + } 760 + } 717 761 } else { 718 762 /* Have access to pixelcount since start of frame. 719 763 * We can split this into vertical and horizontal ··· 815 809 /* Helper routine in DRM core does all the work: */ 816 810 return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, 817 811 vblank_time, flags, 818 - crtc); 812 + crtc, 813 + &to_intel_crtc(crtc)->config.adjusted_mode); 819 814 } 820 815 821 816 static bool intel_hpd_irq_event(struct drm_device *dev,
+11 -18
drivers/gpu/drm/i915/intel_display.c
··· 9597 9597 { 9598 9598 struct drm_device *dev = crtc->dev; 9599 9599 drm_i915_private_t *dev_priv = dev->dev_private; 9600 - struct drm_display_mode *saved_mode, *saved_hwmode; 9600 + struct drm_display_mode *saved_mode; 9601 9601 struct intel_crtc_config *pipe_config = NULL; 9602 9602 struct intel_crtc *intel_crtc; 9603 9603 unsigned disable_pipes, prepare_pipes, modeset_pipes; 9604 9604 int ret = 0; 9605 9605 9606 - saved_mode = kcalloc(2, sizeof(*saved_mode), GFP_KERNEL); 9606 + saved_mode = kmalloc(sizeof(*saved_mode), GFP_KERNEL); 9607 9607 if (!saved_mode) 9608 9608 return -ENOMEM; 9609 - saved_hwmode = saved_mode + 1; 9610 9609 9611 9610 intel_modeset_affected_pipes(crtc, &modeset_pipes, 9612 9611 &prepare_pipes, &disable_pipes); 9613 9612 9614 - *saved_hwmode = crtc->hwmode; 9615 9613 *saved_mode = crtc->mode; 9616 9614 9617 9615 /* Hack: Because we don't (yet) support global modeset on multiple ··· 9660 9662 /* mode_set/enable/disable functions rely on a correct pipe 9661 9663 * config. */ 9662 9664 to_intel_crtc(crtc)->config = *pipe_config; 9665 + 9666 + /* 9667 + * Calculate and store various constants which 9668 + * are later needed by vblank and swap-completion 9669 + * timestamping. They are derived from true hwmode. 9670 + */ 9671 + drm_calc_timestamping_constants(crtc, 9672 + &pipe_config->adjusted_mode); 9663 9673 } 9664 9674 9665 9675 /* Only after disabling all output pipelines that will be changed can we ··· 9691 9685 for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) 9692 9686 dev_priv->display.crtc_enable(&intel_crtc->base); 9693 9687 9694 - if (modeset_pipes) { 9695 - /* Store real post-adjustment hardware mode. */ 9696 - crtc->hwmode = pipe_config->adjusted_mode; 9697 - 9698 - /* Calculate and store various constants which 9699 - * are later needed by vblank and swap-completion 9700 - * timestamping. They are derived from true hwmode. 9701 - */ 9702 - drm_calc_timestamping_constants(crtc); 9703 - } 9704 - 9705 9688 /* FIXME: add subpixel order */ 9706 9689 done: 9707 - if (ret && crtc->enabled) { 9708 - crtc->hwmode = *saved_hwmode; 9690 + if (ret && crtc->enabled) 9709 9691 crtc->mode = *saved_mode; 9710 - } 9711 9692 9712 9693 out: 9713 9694 kfree(pipe_config);
+4 -2
drivers/gpu/drm/radeon/radeon_atombios.c
··· 1799 1799 if (misc & ATOM_DOUBLE_CLOCK_MODE) 1800 1800 mode->flags |= DRM_MODE_FLAG_DBLSCAN; 1801 1801 1802 - mode->clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; 1802 + mode->crtc_clock = mode->clock = 1803 + le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; 1803 1804 1804 1805 if (index == 1) { 1805 1806 /* PAL timings appear to have wrong values for totals */ ··· 1843 1842 if (misc & ATOM_DOUBLE_CLOCK_MODE) 1844 1843 mode->flags |= DRM_MODE_FLAG_DBLSCAN; 1845 1844 1846 - mode->clock = le16_to_cpu(dtd_timings->usPixClk) * 10; 1845 + mode->crtc_clock = mode->clock = 1846 + le16_to_cpu(dtd_timings->usPixClk) * 10; 1847 1847 break; 1848 1848 } 1849 1849 return true;
+26 -3
drivers/gpu/drm/radeon/radeon_display.c
··· 306 306 * to complete in this vblank? 307 307 */ 308 308 if (update_pending && 309 - (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, 309 + (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, 0, 310 310 &vpos, &hpos, NULL, NULL)) && 311 311 ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) || 312 312 (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) { ··· 1610 1610 * 1611 1611 * \param dev Device to query. 1612 1612 * \param crtc Crtc to query. 1613 + * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). 1613 1614 * \param *vpos Location where vertical scanout position should be stored. 1614 1615 * \param *hpos Location where horizontal scanout position should go. 1615 1616 * \param *stime Target location for timestamp taken immediately before ··· 1632 1631 * unknown small number of scanlines wrt. real scanout position. 1633 1632 * 1634 1633 */ 1635 - int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos, 1636 - ktime_t *stime, ktime_t *etime) 1634 + int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags, 1635 + int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) 1637 1636 { 1638 1637 u32 stat_crtc = 0, vbl = 0, position = 0; 1639 1638 int vbl_start, vbl_end, vtotal, ret = 0; ··· 1774 1773 /* In vblank? */ 1775 1774 if (in_vbl) 1776 1775 ret |= DRM_SCANOUTPOS_INVBL; 1776 + 1777 + /* Is vpos outside nominal vblank area, but less than 1778 + * 1/100 of a frame height away from start of vblank? 1779 + * If so, assume this isn't a massively delayed vblank 1780 + * interrupt, but a vblank interrupt that fired a few 1781 + * microseconds before true start of vblank. Compensate 1782 + * by adding a full frame duration to the final timestamp. 1783 + * Happens, e.g., on ATI R500, R600. 1784 + * 1785 + * We only do this if DRM_CALLED_FROM_VBLIRQ. 1786 + */ 1787 + if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) { 1788 + vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay; 1789 + vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal; 1790 + 1791 + if (vbl_start - *vpos < vtotal / 100) { 1792 + *vpos -= vtotal; 1793 + 1794 + /* Signal this correction as "applied". */ 1795 + ret |= 0x8; 1796 + } 1797 + } 1777 1798 1778 1799 return ret; 1779 1800 }
+1
drivers/gpu/drm/radeon/radeon_drv.c
··· 109 109 void radeon_gem_object_close(struct drm_gem_object *obj, 110 110 struct drm_file *file_priv); 111 111 extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, 112 + unsigned int flags, 112 113 int *vpos, int *hpos, ktime_t *stime, 113 114 ktime_t *etime); 114 115 extern const struct drm_ioctl_desc radeon_ioctls_kms[];
+1 -1
drivers/gpu/drm/radeon/radeon_kms.c
··· 719 719 /* Helper routine in DRM core does all the work: */ 720 720 return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, 721 721 vblank_time, flags, 722 - drmcrtc); 722 + drmcrtc, &drmcrtc->hwmode); 723 723 } 724 724 725 725 #define KMS_INVALID_IOCTL(name) \
+1
drivers/gpu/drm/radeon/radeon_mode.h
··· 801 801 int x, int y); 802 802 803 803 extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, 804 + unsigned int flags, 804 805 int *vpos, int *hpos, ktime_t *stime, 805 806 ktime_t *etime); 806 807
+1 -1
drivers/gpu/drm/radeon/radeon_pm.c
··· 1486 1486 */ 1487 1487 for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { 1488 1488 if (rdev->pm.active_crtcs & (1 << crtc)) { 1489 - vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, &vpos, &hpos, NULL, NULL); 1489 + vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, 0, &vpos, &hpos, NULL, NULL); 1490 1490 if ((vbl_status & DRM_SCANOUTPOS_VALID) && 1491 1491 !(vbl_status & DRM_SCANOUTPOS_INVBL)) 1492 1492 in_vbl = false;
+6 -2
include/drm/drmP.h
··· 845 845 * 846 846 * \param dev DRM device. 847 847 * \param crtc Id of the crtc to query. 848 + * \param flags Flags from the caller (DRM_CALLED_FROM_VBLIRQ or 0). 848 849 * \param *vpos Target location for current vertical scanout position. 849 850 * \param *hpos Target location for current horizontal scanout position. 850 851 * \param *stime Target location for timestamp taken immediately before ··· 868 867 * 869 868 */ 870 869 int (*get_scanout_position) (struct drm_device *dev, int crtc, 870 + unsigned int flags, 871 871 int *vpos, int *hpos, ktime_t *stime, 872 872 ktime_t *etime); 873 873 ··· 1403 1401 int crtc, int *max_error, 1404 1402 struct timeval *vblank_time, 1405 1403 unsigned flags, 1406 - struct drm_crtc *refcrtc); 1407 - extern void drm_calc_timestamping_constants(struct drm_crtc *crtc); 1404 + const struct drm_crtc *refcrtc, 1405 + const struct drm_display_mode *mode); 1406 + extern void drm_calc_timestamping_constants(struct drm_crtc *crtc, 1407 + const struct drm_display_mode *mode); 1408 1408 1409 1409 extern bool 1410 1410 drm_mode_parse_command_line_for_connector(const char *mode_option,
+1 -1
include/drm/drm_crtc.h
··· 449 449 uint16_t *gamma_store; 450 450 451 451 /* Constants needed for precise vblank and swap timestamping. */ 452 - s64 framedur_ns, linedur_ns, pixeldur_ns; 452 + int framedur_ns, linedur_ns, pixeldur_ns; 453 453 454 454 /* if you are using the helper */ 455 455 void *helper_private;