diff options
author | Dave Airlie <airlied@redhat.com> | 2014-01-21 18:13:13 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-01-21 18:13:13 -0500 |
commit | f5395ba35f2ae52eb5839f8046e4aeef6df7f357 (patch) | |
tree | 12f147678c6a3eb110d25b36e630de0faefdc0da /drivers/gpu/drm/radeon/radeon_display.c | |
parent | 2b76a676f797b4bfbe6e856f5f608bed4e6e92b4 (diff) | |
parent | 095163bad59bfeed294a81e0d873fa8943e4fa01 (diff) |
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()
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_display.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 7ea647b84733..d680608f6f5b 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -306,7 +306,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) | |||
306 | * to complete in this vblank? | 306 | * to complete in this vblank? |
307 | */ | 307 | */ |
308 | if (update_pending && | 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 | &vpos, &hpos, NULL, NULL)) && | 310 | &vpos, &hpos, NULL, NULL)) && |
311 | ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) || | 311 | ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) || |
312 | (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) { | 312 | (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) { |
@@ -1610,6 +1610,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
1610 | * | 1610 | * |
1611 | * \param dev Device to query. | 1611 | * \param dev Device to query. |
1612 | * \param crtc Crtc to query. | 1612 | * \param crtc Crtc to query. |
1613 | * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). | ||
1613 | * \param *vpos Location where vertical scanout position should be stored. | 1614 | * \param *vpos Location where vertical scanout position should be stored. |
1614 | * \param *hpos Location where horizontal scanout position should go. | 1615 | * \param *hpos Location where horizontal scanout position should go. |
1615 | * \param *stime Target location for timestamp taken immediately before | 1616 | * \param *stime Target location for timestamp taken immediately before |
@@ -1631,8 +1632,8 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
1631 | * unknown small number of scanlines wrt. real scanout position. | 1632 | * unknown small number of scanlines wrt. real scanout position. |
1632 | * | 1633 | * |
1633 | */ | 1634 | */ |
1634 | int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos, | 1635 | int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags, |
1635 | ktime_t *stime, ktime_t *etime) | 1636 | int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) |
1636 | { | 1637 | { |
1637 | u32 stat_crtc = 0, vbl = 0, position = 0; | 1638 | u32 stat_crtc = 0, vbl = 0, position = 0; |
1638 | int vbl_start, vbl_end, vtotal, ret = 0; | 1639 | int vbl_start, vbl_end, vtotal, ret = 0; |
@@ -1774,5 +1775,27 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int | |||
1774 | if (in_vbl) | 1775 | if (in_vbl) |
1775 | ret |= DRM_SCANOUTPOS_INVBL; | 1776 | ret |= DRM_SCANOUTPOS_INVBL; |
1776 | 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 | |||
1777 | return ret; | 1800 | return ret; |
1778 | } | 1801 | } |