summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_display.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2015-09-14 22:43:44 +0300
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-09-24 20:14:21 +0200
commit3bb403bf421b5b00366a9041a7edc0a1f6494f5e (patch)
treed280555ef17c89c2a1e952d03749d230547598c3 /drivers/gpu/drm/radeon/radeon_display.c
parenteba1f35dfe145247c7eb690c7c32740fde8ec699 (diff)
downloadlinux-3bb403bf421b5b00366a9041a7edc0a1f6494f5e.tar.bz2
drm: Stop using linedur_ns and pixeldur_ns for vblank timestamps
linedur_ns, and especially pixeldur_ns are becoming rather inaccurate to be used for the vblank timestamp correction. With 4k@60 the pixel duration is already below 2ns, so the amount of error due to the truncation to nanoseconds is introducing quite a bit of error. We can avoid such problems if we instead calculate the timestamp delta_ns directly from the dislay timings, avoiding the use of these intermediate truncated values. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> [danvet: Squash in fixup from Thierry Reding for amdgpu.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_display.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index d2e9e9efc159..0503af748d99 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -323,7 +323,8 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
*/
if (update_pending &&
(DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, 0,
- &vpos, &hpos, NULL, NULL)) &&
+ &vpos, &hpos, NULL, NULL,
+ &rdev->mode_info.crtcs[crtc_id]->base.hwmode)) &&
((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) ||
(vpos < 0 && !ASIC_IS_AVIVO(rdev)))) {
/* crtc didn't flip in this target vblank interval,
@@ -1799,7 +1800,8 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
*
*/
int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags,
- int *vpos, int *hpos, ktime_t *stime, ktime_t *etime)
+ int *vpos, int *hpos, ktime_t *stime, ktime_t *etime,
+ const struct drm_display_mode *mode)
{
u32 stat_crtc = 0, vbl = 0, position = 0;
int vbl_start, vbl_end, vtotal, ret = 0;
@@ -1914,7 +1916,7 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl
}
else {
/* No: Fake something reasonable which gives at least ok results. */
- vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay;
+ vbl_start = mode->crtc_vdisplay;
vbl_end = 0;
}
@@ -1930,7 +1932,7 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl
/* Inside "upper part" of vblank area? Apply corrective offset if so: */
if (in_vbl && (*vpos >= vbl_start)) {
- vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal;
+ vtotal = mode->crtc_vtotal;
*vpos = *vpos - vtotal;
}
@@ -1952,8 +1954,8 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl
* We only do this if DRM_CALLED_FROM_VBLIRQ.
*/
if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) {
- vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay;
- vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal;
+ vbl_start = mode->crtc_vdisplay;
+ vtotal = mode->crtc_vtotal;
if (vbl_start - *vpos < vtotal / 100) {
*vpos -= vtotal;