All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 3/3] drm/i915: Improve the accuracy of get_scanout_pos on CTG+
Date: Wed, 25 Sep 2013 11:11:30 +0300	[thread overview]
Message-ID: <20130925081130.GJ4531@intel.com> (raw)
In-Reply-To: <524254B6.4080709@tuebingen.mpg.de>

On Wed, Sep 25, 2013 at 05:12:54AM +0200, Mario Kleiner wrote:
> 
> 
> On 23.09.13 12:02, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >
> > The DSL register increments at the start of horizontal sync, so it
> > manages to miss the entire active portion of the current line.
> >
> > Improve the get_scanoutpos accuracy a bit when the scanout position is
> > close to the start or end of vblank. We can do that by double checking
> > the DSL value against the vblank status bit from ISR.
> >
> > Cc: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >   drivers/gpu/drm/i915/i915_irq.c | 53 +++++++++++++++++++++++++++++++++++++++++
> >   1 file changed, 53 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> > index 4f74f0c..14b42d9 100644
> > --- a/drivers/gpu/drm/i915/i915_irq.c
> > +++ b/drivers/gpu/drm/i915/i915_irq.c
> > @@ -567,6 +567,47 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
> >   	return I915_READ(reg);
> >   }
> >
> > +static bool g4x_pipe_in_vblank(struct drm_device *dev, enum pipe pipe)
> > +{
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	uint32_t status;
> > +
> > +	if (IS_VALLEYVIEW(dev)) {
> > +		status = pipe == PIPE_A ?
> > +			I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT :
> > +			I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
> > +
> > +		return I915_READ(VLV_ISR) & status;
> > +	} else if (IS_G4X(dev)) {
> > +		status = pipe == PIPE_A ?
> > +			I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT :
> > +			I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
> > +
> > +		return I915_READ(ISR) & status;
> > +	} else if (INTEL_INFO(dev)->gen < 7) {
> > +		status = pipe == PIPE_A ?
> > +			DE_PIPEA_VBLANK :
> > +			DE_PIPEB_VBLANK;
> > +
> > +		return I915_READ(DEISR) & status;
> > +	} else {
> > +		switch (pipe) {
> > +		default:
> > +		case PIPE_A:
> > +			status = DE_PIPEA_VBLANK_IVB;
> > +			break;
> > +		case PIPE_B:
> > +			status = DE_PIPEB_VBLANK_IVB;
> > +			break;
> > +		case PIPE_C:
> > +			status = DE_PIPEC_VBLANK_IVB;
> > +			break;
> > +		}
> > +
> > +		return I915_READ(DEISR) & status;
> > +	}
> > +}
> > +
> >   static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
> >   			     int *vpos, int *hpos)
> >   {
> > @@ -616,6 +657,18 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
> >   		 * scanout position from Display scan line register.
> >   		 */
> >   		position = I915_READ(PIPEDSL(pipe)) & 0x1fff;
> > +
> > +		/*
> > +		 * The scanline counter increments at the leading edge
> > +		 * of hsync, ie. it completely misses the active portion
> > +		 * of the line. Fix up the counter at both edges of vblank
> > +		 * to get a more accurate picture whether we're in vblank
> > +		 * or not.
> > +		 */
> > +		in_vbl = g4x_pipe_in_vblank(dev, pipe);
> > +		if ((in_vbl && position == vbl_start - 1) ||
> > +		    (!in_vbl && position == vbl_end - 1))
> > +			position = (position + 1) % vtotal;
> >   	} else {
> >   		/* Have access to pixelcount since start of frame.
> >   		 * We can split this into vertical and horizontal
> >
> 
> This one i don't know. I think i can't follow the logic, but i don't 
> know enough about the way the intel hw counts.
> 
> Do you mean the counter increments when the scanline is over, instead of 
> when it begins?

Let me draw a picture of the scanline (not to scale):

 |XXXXXXXXXXXXX|-----|___________|---|
  horiz. active       horiz. sync
 ^                   ^
 |                   |
 first pixel         this is where the
 of the line         scanline counter increments

> With this correction by +1 at the edges of vblank, the scanlines at 
> vbl_start and vbl_end would be reported twice, for two successive 
> scanline durations, that seems a bit weird and asymmetric to the rest of 
> the scanline positions. Wouldn't it make more sense to simply always add 
> 1 for a smaller overall error, given that hblank is shorter than the 
> active scanout part of a scanline?

Since the counter increments too late, drm_handle_vblank()
may get the wrong idea ie. something like this may happen:

1. vblank irq triggered
2. drm_handle_vblank() gets called
3. i915_get_crtc_scanoutpos() returns vbl_start-1 as the scanline
4. delta_ns calculation gets confused and tries to correct for it

Now, the correction you do for delta_ns should handle this, but
I don't like having such kludges in common code, and we can handle
it in the driver as I've demonstrated. But yeah, I suppose it can
make the error slightly less stable.

For some other uses (atomic page flip stuff) of the scanline position,
I definitely want this correction since I need accurate information
whether the position has passed vblank start.

> Also it adds back one lock protected, therefore potentially slow, 
> register read into the time critical code.

I don't think a single register read should be _that_ slow even
with all the extra junk we do. And of course we can fix that problem.

-- 
Ville Syrjälä
Intel OTC

  reply	other threads:[~2013-09-25  8:11 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-23 10:02 [PATCH 0/3] drm/i915: i915_get_crtc_scanoutpos improvements ville.syrjala
2013-09-23 10:02 ` [PATCH 1/3] drm/i915: Skip register reads in i915_get_crtc_scanoutpos() ville.syrjala
2013-09-23 10:30   ` Chris Wilson
2013-09-23 11:48     ` [PATCH v2 " ville.syrjala
2013-09-24  9:11       ` Daniel Vetter
2013-09-25  4:45         ` Mario Kleiner
2013-09-25  7:52           ` Daniel Vetter
2013-09-25  2:35       ` Mario Kleiner
2013-09-25  8:14         ` Ville Syrjälä
2013-09-26 16:12           ` Mario Kleiner
2013-09-23 10:02 ` [PATCH 2/3] drm/i915: Fix scanoutpos calculations ville.syrjala
2013-09-25  2:39   ` Mario Kleiner
2013-10-11 14:31   ` Mario Kleiner
2013-10-11 16:10     ` [PATCH v2 " ville.syrjala
2013-10-11 23:19     ` [PATCH " Daniel Vetter
2013-10-11 23:22       ` Mario Kleiner
2013-10-14 15:13         ` Daniel Vetter
2013-09-23 10:02 ` [PATCH 3/3] drm/i915: Improve the accuracy of get_scanout_pos on CTG+ ville.syrjala
2013-09-25  3:12   ` Mario Kleiner
2013-09-25  8:11     ` Ville Syrjälä [this message]
2013-09-25  8:46       ` Daniel Vetter
2013-09-26 17:04       ` Mario Kleiner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130925081130.GJ4531@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=mario.kleiner@tuebingen.mpg.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.