summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@nietzche.virtuousgeek.org>2008-01-24 08:57:04 -0800
committerJesse Barnes <jbarnes@nietzche.virtuousgeek.org>2008-01-24 08:57:04 -0800
commitc7ee6cc269c26d8e7ed98a16a272eca63daab201 (patch)
tree92a842d5d7989cf376e77339ab94831adbc8e811
parentb5a34f5da50e22ecb80853f0f422beb90857dc2d (diff)
Remove broken 'in vblank' accounting
We need to return an accurate vblank count to the callers of ->get_vblank_counter, and in the Intel case the actual frame count register isn't udpated until the next active line is displayed, so we need to return one more than the frame count register if we're currently in a vblank period. However, none of the various ways of doing this is working yet, so disable the logic for now. This may result in a few missed events, but should fix the hangs some people have seen due to the current code tripping the wraparound logic in drm_update_vblank_count.
-rw-r--r--shared-core/i915_drv.h4
-rw-r--r--shared-core/i915_irq.c31
2 files changed, 28 insertions, 7 deletions
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index 7a0c0ea1..c92758fa 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -794,7 +794,11 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define VSYNCSHIFT_B 0x61028
#define HACTIVE_MASK 0x00000fff
+#define VTOTAL_MASK 0x00001fff
+#define VTOTAL_SHIFT 16
#define VACTIVE_MASK 0x00000fff
+#define VBLANK_END_MASK 0x00001fff
+#define VBLANK_END_SHIFT 16
#define VBLANK_START_MASK 0x00001fff
#define PP_STATUS 0x61200
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index 56bcac9c..d463f6e6 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -341,22 +341,39 @@ static void i915_vblank_tasklet(struct drm_device *dev)
drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
}
}
+#if 0
+static int i915_in_vblank(struct drm_device *dev, int pipe)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ unsigned long pipedsl, vblank, vtotal;
+ unsigned long vbl_start, vbl_end, cur_line;
+
+ pipedsl = pipe ? PIPEBDSL : PIPEADSL;
+ vblank = pipe ? VBLANK_B : VBLANK_A;
+ vtotal = pipe ? VTOTAL_B : VTOTAL_A;
+
+ vbl_start = I915_READ(vblank) & VBLANK_START_MASK;
+ vbl_end = (I915_READ(vblank) >> VBLANK_END_SHIFT) & VBLANK_END_MASK;
+
+ cur_line = I915_READ(pipedsl);
+
+ if (cur_line >= vbl_start)
+ return 1;
+ return 0;
+}
+#endif
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, vtotal;
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;
- vtotal = pipe ? VTOTAL_B : VTOTAL_A;
if (!i915_pipe_enabled(dev, pipe)) {
printk(KERN_ERR "trying to get vblank count for disabled "
@@ -385,10 +402,10 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
* 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(vtotal) & VACTIVE_MASK)))
+#if 0
+ if (i915_in_vblank(dev, pipe))
count++;
-
+#endif
return count;
}