From: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: intel-gfx@lists.freedesktop.org,
Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
Subject: Re: [PATCH v2 1/3] drm/i915: Skip register reads in i915_get_crtc_scanoutpos()
Date: Thu, 26 Sep 2013 18:12:06 +0200 [thread overview]
Message-ID: <52445CD6.1080601@gmail.com> (raw)
In-Reply-To: <20130925081405.GK4531@intel.com>
On 25.09.13 10:14, Ville Syrjälä wrote:
> On Wed, Sep 25, 2013 at 04:35:56AM +0200, Mario Kleiner wrote:
>> On 23.09.13 13:48, ville.syrjala@linux.intel.com wrote:
>>> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>>>
>>> We have all the information we need in the mode structure, so going and
>>> reading it from the hardware is pointless, and slower.
>>>
>>> We never populated ->get_vblank_timestamp() in the UMS case, and as that
>>> is the only way we'd ever call ->get_scanout_position(), we can
>>> completely ignore UMS in i915_get_crtc_scanoutpos().
>>>
>>> Also reorganize intel_irq_init() a bit to clarify the KMS vs. UMS
>>> situation.
>>>
>>> v2: Drop UMS code
>>>
>>> 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 | 43 ++++++++++++++++-------------------------
>>> 1 file changed, 17 insertions(+), 26 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
>>> index b356dc1..058f099 100644
>>> --- a/drivers/gpu/drm/i915/i915_irq.c
>>> +++ b/drivers/gpu/drm/i915/i915_irq.c
>>> @@ -570,24 +570,29 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
>>> static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
>>> int *vpos, int *hpos)
>>> {
>>> - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
>>> - u32 vbl = 0, position = 0;
>>> + struct drm_i915_private *dev_priv = dev->dev_private;
>>> + struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
>>> + struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>> + const struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode;
>>> + u32 position;
>>> int vbl_start, vbl_end, htotal, vtotal;
>>> bool in_vbl = true;
>>> int ret = 0;
>>> - enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
>>> - pipe);
>>>
>>> - if (!i915_pipe_enabled(dev, pipe)) {
>>> + if (!intel_crtc->active) {
>>> DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled "
>>> "pipe %c\n", pipe_name(pipe));
>>> return 0;
>>> }
>>>
>>> - /* Get vtotal. */
>>> - vtotal = 1 + ((I915_READ(VTOTAL(cpu_transcoder)) >> 16) & 0x1fff);
>>> + htotal = mode->crtc_htotal;
>>> + vtotal = mode->crtc_vtotal;
>>> + vbl_start = mode->crtc_vblank_start;
>>> + vbl_end = mode->crtc_vblank_end;
>>>
>>> - if (INTEL_INFO(dev)->gen >= 4) {
>>> + ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
>>> +
>>> + if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
>>> /* No obvious pixelcount register. Only query vertical
>>> * scanout position from Display scan line register.
>>> */
>>> @@ -605,29 +610,16 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
>>> */
>>> position = (I915_READ(PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT;
>>>
>>> - htotal = 1 + ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff);
>>> *vpos = position / htotal;
>>> *hpos = position - (*vpos * htotal);
>>> }
>>>
>>> - /* Query vblank area. */
>>> - vbl = I915_READ(VBLANK(cpu_transcoder));
>>> -
>>> - /* Test position against vblank region. */
>>> - vbl_start = vbl & 0x1fff;
>>> - vbl_end = (vbl >> 16) & 0x1fff;
>>> -
>>> - if ((*vpos < vbl_start) || (*vpos > vbl_end))
>>> - in_vbl = false;
>>> + in_vbl = *vpos >= vbl_start && *vpos < vbl_end;
>>
>> I think this should be a <= instead of < in *vpos < vbl_end, if it is
>> meant to be equal to the line it replaces (not > is <=), unless the
>> original comparison was off-by-one?
>
> Yeah, I think the original was wrong, in more ways than one. It forgot
> to add +1 to vbl_start/end, and then it did the comparison wrong as
> well.
>
Ah ok, that's possible. Then you have my blessing :).
On the Intel side i only had and have sporadic access to an old Intel
GMA-950 (Gen-3?) when writing that function, so i could only really test
one half of the code-path in that function. Also that card only has a
VGA output, which limits my actual measurements to use of a photo-diode
attached to a CRT monitor. That means i can only verify the accuracy of
timestamping down to about 0.2 msecs variability and 0.5 msecs bias due
to the limitations/noise of the measurement setup (depending how close i
get the photo-diode to the corner of the monitor, how dark it is, etc.).
So i know that the jitter in the timestamps is very low, less than 1
usec standard deviation iirc, and that the absolute error wrt. reality
is lower than 0.2 msecs, but i wouldn't be able to detect absolute
errors of a few scanlines.
-mario
>>
>> > + in_vbl = *vpos >= vbl_start && *vpos <= vbl_end;
>>
>> Other than that, it looks good.
>>
>> Reviewed-by: mario.kleiner.de@gmail.com
>>
>>>
>>> /* Inside "upper part" of vblank area? Apply corrective offset: */
>>> if (in_vbl && (*vpos >= vbl_start))
>>> *vpos = *vpos - vtotal;
>>>
>>> - /* Readouts valid? */
>>> - if (vbl > 0)
>>> - ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
>>> -
>>> /* In vblank? */
>>> if (in_vbl)
>>> ret |= DRM_SCANOUTPOS_INVBL;
>>> @@ -3148,11 +3140,10 @@ void intel_irq_init(struct drm_device *dev)
>>> dev->driver->get_vblank_counter = gm45_get_vblank_counter;
>>> }
>>>
>>> - if (drm_core_check_feature(dev, DRIVER_MODESET))
>>> + if (drm_core_check_feature(dev, DRIVER_MODESET)) {
>>> dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
>>> - else
>>> - dev->driver->get_vblank_timestamp = NULL;
>>> - dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
>>> + dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
>>> + }
>>>
>>> if (IS_VALLEYVIEW(dev)) {
>>> dev->driver->irq_handler = valleyview_irq_handler;
>>>
>
next prev parent reply other threads:[~2013-09-26 16:12 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 [this message]
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ä
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=52445CD6.1080601@gmail.com \
--to=mario.kleiner.de@gmail.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.