[Intel-gfx] [PATCH 2/2] drm/i915/tv: Use the scanline counter for timestamps on i965gm TV output
Imre Deak
imre.deak at intel.com
Fri Jan 25 20:17:04 UTC 2019
On Fri, Jan 25, 2019 at 08:19:31PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
>
> Just like the frame counter, the pixel counter also reads zero
> all the time when the TV encoder is used. Fortunately the
> scanline counter still works sufficiently well so let's use that
> to correct the vblank timestamps. Otherwise the timestamps may
> en up out of whack, and since we use them to guesstimate the
> vblank counter value that may end up incorrect as well.
>
> Cc: Imre Deak <imre.deak at intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
Reviewed-by: Imre Deak <imre.deak at intel.com>
> ---
> drivers/gpu/drm/i915/i915_irq.c | 7 +++++--
> drivers/gpu/drm/i915/intel_drv.h | 4 +++-
> drivers/gpu/drm/i915/intel_tv.c | 10 ++++++++++
> 3 files changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index fe097725c27a..caade521c174 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -1014,6 +1014,9 @@ static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
> int position;
> int vbl_start, vbl_end, hsync_start, htotal, vtotal;
> unsigned long irqflags;
> + bool use_scanline_counter = INTEL_GEN(dev_priv) >= 5 ||
> + IS_G4X(dev_priv) || IS_GEN(dev_priv, 2) ||
> + mode->private_flags & I915_MODE_FLAG_USE_SCANLINE_COUNTER;
>
> if (WARN_ON(!mode->crtc_clock)) {
> DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled "
> @@ -1046,7 +1049,7 @@ static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
> if (stime)
> *stime = ktime_get();
>
> - if (IS_GEN(dev_priv, 2) || IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5) {
> + if (use_scanline_counter) {
> /* No obvious pixelcount register. Only query vertical
> * scanout position from Display scan line register.
> */
> @@ -1106,7 +1109,7 @@ static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
> else
> position += vtotal - vbl_end;
>
> - if (IS_GEN(dev_priv, 2) || IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5) {
> + if (use_scanline_counter) {
> *vpos = position;
> *hpos = 0;
> } else {
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 85b913ea6e80..90ba5436370e 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -630,9 +630,11 @@ struct intel_crtc_scaler_state {
> };
>
> /* drm_mode->private_flags */
> -#define I915_MODE_FLAG_INHERITED 1
> +#define I915_MODE_FLAG_INHERITED (1<<0)
> /* Flag to get scanline using frame time stamps */
> #define I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP (1<<1)
> +/* Flag to use the scanline counter instead of the pixel counter */
> +#define I915_MODE_FLAG_USE_SCANLINE_COUNTER (1<<2)
>
> struct intel_pipe_wm {
> struct intel_wm_level wm[5];
> diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
> index 78be08e2971b..751b88dde18e 100644
> --- a/drivers/gpu/drm/i915/intel_tv.c
> +++ b/drivers/gpu/drm/i915/intel_tv.c
> @@ -1150,6 +1150,11 @@ intel_tv_get_config(struct intel_encoder *encoder,
> ypos, mode.vdisplay - ysize - ypos);
>
> adjusted_mode->crtc_clock = mode.clock;
> +
> + /* pixel counter doesn't work on i965gm TV output */
> + if (IS_I965GM(dev_priv))
> + adjusted_mode->private_flags |=
> + I915_MODE_FLAG_USE_SCANLINE_COUNTER;
> }
>
> static int
> @@ -1295,6 +1300,11 @@ intel_tv_compute_config(struct intel_encoder *encoder,
> drm_mode_set_crtcinfo(adjusted_mode, 0);
> adjusted_mode->name[0] = '\0';
>
> + /* pixel counter doesn't work on i965gm TV output */
> + if (IS_I965GM(dev_priv))
> + adjusted_mode->private_flags |=
> + I915_MODE_FLAG_USE_SCANLINE_COUNTER;
> +
> return 0;
> }
>
> --
> 2.19.2
>
More information about the Intel-gfx
mailing list