diff options
-rw-r--r-- | shared-core/i915_drv.h | 6 | ||||
-rw-r--r-- | shared-core/i915_irq.c | 15 |
2 files changed, 19 insertions, 2 deletions
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index b8d027d7..2c1f2c2e 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -471,6 +471,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define I915REG_INT_ENABLE_R 0x020a0 #define I915REG_INSTPM 0x020c0 +#define PIPEADSL 0x70000 +#define PIPEBDSL 0x71000 + #define I915REG_PIPEASTAT 0x70024 #define I915REG_PIPEBSTAT 0x71024 /* @@ -790,6 +793,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define BCLRPAT_B 0x61020 #define VSYNCSHIFT_B 0x61028 +#define HACTIVE_MASK 0x00000fff +#define VBLANK_START_MASK 0x00001fff + #define PP_STATUS 0x61200 # define PP_ON (1 << 31) /** diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index bef73b62..7ad21a97 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -69,8 +69,6 @@ i915_get_pipe(struct drm_device *dev, int plane) static int i915_get_plane(struct drm_device *dev, int pipe) { - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - if (i915_get_pipe(dev, 0) == pipe) return 0; return 1; @@ -349,12 +347,16 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long high_frame; unsigned long low_frame; + unsigned long pipedsl, vblank, htotal; u32 high1, high2, low, count; int pipe; pipe = i915_get_pipe(dev, plane); high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH; low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; + pipedsl = pipe ? PIPEBDSL : PIPEADSL; + vblank = pipe ? VBLANK_B : VBLANK_A; + htotal = pipe ? HTOTAL_B : HTOTAL_A; if (!i915_pipe_enabled(dev, pipe)) { printk(KERN_ERR "trying to get vblank count for disabled " @@ -378,6 +380,15 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane) count = (high1 << 8) | low; + /* + * If we're in the middle of the vblank period, the + * above regs won't have been updated yet, so return + * an incremented count to stay accurate + */ + if ((I915_READ(pipedsl) >= (I915_READ(vblank) & VBLANK_START_MASK)) || + (I915_READ(pipedsl) < (I915_READ(htotal) & HACTIVE_MASK))) + count++; + return count; } |