summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_irq.c
diff options
context:
space:
mode:
authorVille Syrjälä2013-10-28 18:53:25 +0100
committerVille Syrjälä2014-01-20 11:20:51 +0100
commitc0ae24c17ed0864b42d449733460140322f275e2 (patch)
treedaf427711e968c382b8e4ce3346db610c19e85a6 /drivers/gpu/drm/drm_irq.c
parentdrm/i915: Fix scanoutpos calculations for interlaced modes (diff)
downloadkernel-qcow2-linux-c0ae24c17ed0864b42d449733460140322f275e2.tar.gz
kernel-qcow2-linux-c0ae24c17ed0864b42d449733460140322f275e2.tar.xz
kernel-qcow2-linux-c0ae24c17ed0864b42d449733460140322f275e2.zip
drm: Fix vblank timestamping constants for interlaced modes
We're currently miscalculating the line and pixel durations for interlaced modes. crtc_htotal and crtc_vtotal are the full frame timings, and so is crtc_clock, so we can compute the line and pixel durations from those w/o any extra adjustments. But we actually want framedur_ns to be the field, not frame, duration, so we must divide it by two. This should make the scanout based vblank timestamp corrections work correctly with interlaced modes, at least for i915. It all depends whether we keep the field or frame timings in the display mode crtc_ timings. v2: Preserve halve->half typo fix that happened in the meantine Reviewed-by: mario.kleiner.de@gmail.com Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r--drivers/gpu/drm/drm_irq.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 91e8b4c55ea0..55239d285f25 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -453,12 +453,6 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
int dotclock = mode->crtc_clock;
- /* Fields of interlaced scanout modes are only half a frame duration.
- * Double the dotclock to get half the frame-/line-/pixelduration.
- */
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- dotclock *= 2;
-
/* Valid dotclock? */
if (dotclock > 0) {
int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
@@ -471,6 +465,12 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
pixeldur_ns = 1000000 / dotclock;
linedur_ns = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
framedur_ns = div_u64((u64) frame_size * 1000000, dotclock);
+
+ /*
+ * Fields of interlaced scanout modes are only half a frame duration.
+ */
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ framedur_ns /= 2;
} else
DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
crtc->base.id);