#define I915REG_INT_ENABLE_R 0x020a0
#define I915REG_INSTPM 0x020c0
+#define PIPEADSL 0x70000
+#define PIPEBDSL 0x71000
+
#define I915REG_PIPEASTAT 0x70024
#define I915REG_PIPEBSTAT 0x71024
/*
#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)
/**
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;
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 "
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;
}