aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_display.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-01-21 18:13:13 -0500
committerDave Airlie <airlied@redhat.com>2014-01-21 18:13:13 -0500
commitf5395ba35f2ae52eb5839f8046e4aeef6df7f357 (patch)
tree12f147678c6a3eb110d25b36e630de0faefdc0da /drivers/gpu/drm/radeon/radeon_display.c
parent2b76a676f797b4bfbe6e856f5f608bed4e6e92b4 (diff)
parent095163bad59bfeed294a81e0d873fa8943e4fa01 (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.c29
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 */
1634int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos, 1635int 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}