Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0ae24c1 authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

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: default avatar <mario.kleiner.de@gmail.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
parent d31faf65
Loading
Loading
Loading
Loading
+6 −6
Original line number Original line Diff line number Diff line
@@ -453,12 +453,6 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
	int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
	int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
	int dotclock = mode->crtc_clock;
	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? */
	/* Valid dotclock? */
	if (dotclock > 0) {
	if (dotclock > 0) {
		int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
		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;
		pixeldur_ns = 1000000 / dotclock;
		linedur_ns  = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
		linedur_ns  = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
		framedur_ns = div_u64((u64) frame_size * 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
	} else
		DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
		DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
			  crtc->base.id);
			  crtc->base.id);