|
@@ -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,
|
|
struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv,
|
|
pipe);
|
|
pipe);
|
|
const struct drm_display_mode *mode = &intel_crtc->base.hwmode;
|
|
const struct drm_display_mode *mode = &intel_crtc->base.hwmode;
|
|
|
|
+ unsigned long irqflags;
|
|
|
|
|
|
htotal = mode->crtc_htotal;
|
|
htotal = mode->crtc_htotal;
|
|
hsync_start = mode->crtc_hsync_start;
|
|
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);
|
|
high_frame = PIPEFRAME(pipe);
|
|
low_frame = PIPEFRAMEPIXEL(pipe);
|
|
low_frame = PIPEFRAMEPIXEL(pipe);
|
|
|
|
|
|
|
|
+ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* High & low register fields aren't synchronized, so make sure
|
|
* High & low register fields aren't synchronized, so make sure
|
|
* we get a low value that's stable across two reads of the high
|
|
* we get a low value that's stable across two reads of the high
|
|
* register.
|
|
* register.
|
|
*/
|
|
*/
|
|
do {
|
|
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);
|
|
} while (high1 != high2);
|
|
|
|
|
|
|
|
+ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
|
|
|
|
+
|
|
high1 >>= PIPE_FRAME_HIGH_SHIFT;
|
|
high1 >>= PIPE_FRAME_HIGH_SHIFT;
|
|
pixel = low & PIPE_PIXEL_MASK;
|
|
pixel = low & PIPE_PIXEL_MASK;
|
|
low >>= PIPE_FRAME_LOW_SHIFT;
|
|
low >>= PIPE_FRAME_LOW_SHIFT;
|