drm/i915: Use I915_READ_FW in i915_get_vblank_counter()
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 9 Mar 2017 15:44:30 +0000 (17:44 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 13 Mar 2017 19:14:47 +0000 (21:14 +0200)
Optimize the multi-register read in i915_get_vblank_counter() a little
bit by grabbing the uncore lock manually and using I915_READ_FW().

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170309154434.29303-2-ville.syrjala@linux.intel.com
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
drivers/gpu/drm/i915/i915_irq.c

index b8a0afdc26a273f57b176abce3f350ff673693b2..da5137fbf6d501064976d121adcda5e27407a0aa 100644 (file)
@@ -723,6 +723,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
        struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv,
                                                                pipe);
        const struct drm_display_mode *mode = &intel_crtc->base.hwmode;
+       unsigned long irqflags;
 
        htotal = mode->crtc_htotal;
        hsync_start = mode->crtc_hsync_start;
@@ -739,17 +740,21 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
        high_frame = PIPEFRAME(pipe);
        low_frame = PIPEFRAMEPIXEL(pipe);
 
+       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
        /*
         * High & low register fields aren't synchronized, so make sure
         * we get a low value that's stable across two reads of the high
         * register.
         */
        do {
-               high1 = I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK;
-               low   = I915_READ(low_frame);
-               high2 = I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK;
+               high1 = I915_READ_FW(high_frame) & PIPE_FRAME_HIGH_MASK;
+               low   = I915_READ_FW(low_frame);
+               high2 = I915_READ_FW(high_frame) & PIPE_FRAME_HIGH_MASK;
        } while (high1 != high2);
 
+       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+
        high1 >>= PIPE_FRAME_HIGH_SHIFT;
        pixel = low & PIPE_PIXEL_MASK;
        low >>= PIPE_FRAME_LOW_SHIFT;