diff options
| -rw-r--r-- | drivers/gpu/drm/drm_irq.c | 25 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 22 |
2 files changed, 24 insertions, 23 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index e55619f49671..c2676b5908d9 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -542,7 +542,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, | |||
| 542 | { | 542 | { |
| 543 | ktime_t stime, etime, mono_time_offset; | 543 | ktime_t stime, etime, mono_time_offset; |
| 544 | struct timeval tv_etime; | 544 | struct timeval tv_etime; |
| 545 | int vbl_status, vtotal, vdisplay; | 545 | int vbl_status; |
| 546 | int vpos, hpos, i; | 546 | int vpos, hpos, i; |
| 547 | int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; | 547 | int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; |
| 548 | bool invbl; | 548 | bool invbl; |
| @@ -558,9 +558,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, | |||
| 558 | return -EIO; | 558 | return -EIO; |
| 559 | } | 559 | } |
| 560 | 560 | ||
| 561 | vtotal = mode->crtc_vtotal; | ||
| 562 | vdisplay = mode->crtc_vdisplay; | ||
| 563 | |||
| 564 | /* Durations of frames, lines, pixels in nanoseconds. */ | 561 | /* Durations of frames, lines, pixels in nanoseconds. */ |
| 565 | framedur_ns = refcrtc->framedur_ns; | 562 | framedur_ns = refcrtc->framedur_ns; |
| 566 | linedur_ns = refcrtc->linedur_ns; | 563 | linedur_ns = refcrtc->linedur_ns; |
| @@ -569,7 +566,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, | |||
| 569 | /* If mode timing undefined, just return as no-op: | 566 | /* If mode timing undefined, just return as no-op: |
| 570 | * Happens during initial modesetting of a crtc. | 567 | * Happens during initial modesetting of a crtc. |
| 571 | */ | 568 | */ |
| 572 | if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) { | 569 | if (framedur_ns == 0) { |
| 573 | DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); | 570 | DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); |
| 574 | return -EAGAIN; | 571 | return -EAGAIN; |
| 575 | } | 572 | } |
| @@ -633,24 +630,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, | |||
| 633 | */ | 630 | */ |
| 634 | delta_ns = vpos * linedur_ns + hpos * pixeldur_ns; | 631 | delta_ns = vpos * linedur_ns + hpos * pixeldur_ns; |
| 635 | 632 | ||
| 636 | /* Is vpos outside nominal vblank area, but less than | ||
| 637 | * 1/100 of a frame height away from start of vblank? | ||
| 638 | * If so, assume this isn't a massively delayed vblank | ||
| 639 | * interrupt, but a vblank interrupt that fired a few | ||
| 640 | * microseconds before true start of vblank. Compensate | ||
| 641 | * by adding a full frame duration to the final timestamp. | ||
| 642 | * Happens, e.g., on ATI R500, R600. | ||
| 643 | * | ||
| 644 | * We only do this if DRM_CALLED_FROM_VBLIRQ. | ||
| 645 | */ | ||
| 646 | if ((flags & DRM_CALLED_FROM_VBLIRQ) && !invbl && | ||
| 647 | ((vdisplay - vpos) < vtotal / 100)) { | ||
| 648 | delta_ns = delta_ns - framedur_ns; | ||
| 649 | |||
| 650 | /* Signal this correction as "applied". */ | ||
| 651 | vbl_status |= 0x8; | ||
| 652 | } | ||
| 653 | |||
| 654 | if (!drm_timestamp_monotonic) | 633 | if (!drm_timestamp_monotonic) |
| 655 | etime = ktime_sub(etime, mono_time_offset); | 634 | etime = ktime_sub(etime, mono_time_offset); |
| 656 | 635 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 567215be4728..d680608f6f5b 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -1775,5 +1775,27 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl | |||
| 1775 | if (in_vbl) | 1775 | if (in_vbl) |
| 1776 | ret |= DRM_SCANOUTPOS_INVBL; | 1776 | ret |= DRM_SCANOUTPOS_INVBL; |
| 1777 | 1777 | ||
| 1778 | /* Is vpos outside nominal vblank area, but less than | ||
| 1779 | * 1/100 of a frame height away from start of vblank? | ||
| 1780 | * If so, assume this isn't a massively delayed vblank | ||
| 1781 | * interrupt, but a vblank interrupt that fired a few | ||
| 1782 | * microseconds before true start of vblank. Compensate | ||
| 1783 | * by adding a full frame duration to the final timestamp. | ||
| 1784 | * Happens, e.g., on ATI R500, R600. | ||
| 1785 | * | ||
| 1786 | * We only do this if DRM_CALLED_FROM_VBLIRQ. | ||
| 1787 | */ | ||
| 1788 | if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) { | ||
| 1789 | vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay; | ||
| 1790 | vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal; | ||
| 1791 | |||
| 1792 | if (vbl_start - *vpos < vtotal / 100) { | ||
| 1793 | *vpos -= vtotal; | ||
| 1794 | |||
| 1795 | /* Signal this correction as "applied". */ | ||
| 1796 | ret |= 0x8; | ||
| 1797 | } | ||
| 1798 | } | ||
| 1799 | |||
| 1778 | return ret; | 1800 | return ret; |
| 1779 | } | 1801 | } |
