summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shared-core/i915_drm.h3
-rw-r--r--shared-core/i915_drv.h5
-rw-r--r--shared-core/i915_irq.c26
3 files changed, 27 insertions, 7 deletions
diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h
index 575b182a..a57ffa73 100644
--- a/shared-core/i915_drm.h
+++ b/shared-core/i915_drm.h
@@ -114,9 +114,6 @@ typedef struct _drm_i915_sarea {
int planeB_w;
int planeB_h;
- int planeA_pipe;
- int planeB_pipe;
-
/* Triple buffering */
drm_handle_t third_handle;
int third_offset;
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index c5f51897..899817ec 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -490,6 +490,11 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define DISPLAY_PLANE_A (0<<20)
#define DISPLAY_PLANE_B (1<<20)
+/* Display regs */
+#define DSPACNTR 0x70180
+#define DSPBCNTR 0x71180
+#define DISPPLANE_SEL_PIPE_MASK (1<<24)
+
/* Define the region of interest for the binner:
*/
#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4)
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index 72c61876..804e3fb1 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -38,6 +38,26 @@
#define MAX_NOPID ((u32)~0)
/**
+ * i915_get_pipe - return the the pipe associated with a given plane
+ * @dev: DRM device
+ * @plane: plane to look for
+ *
+ * We need to get the pipe associated with a given plane to correctly perform
+ * vblank driven swapping, and they may not always be equal. So look up the
+ * pipe associated with @plane here.
+ */
+static int
+i915_get_pipe(struct drm_device *dev, int plane)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ u32 dspcntr;
+
+ dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
+
+ return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
+}
+
+/**
* Emit a synchronous flip.
*
* This function must be called with the drawable spinlock held.
@@ -124,8 +144,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
drm_i915_vbl_swap_t *vbl_swap =
list_entry(list, drm_i915_vbl_swap_t, head);
- int pipe = vbl_swap->plane ? sarea_priv->planeB_pipe :
- sarea_priv->planeA_pipe;
+ int pipe = i915_get_pipe(dev, vbl_swap->plane);
if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
continue;
@@ -565,7 +584,6 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
unsigned int pipe, seqtype, curseq, plane;
unsigned long irqflags;
struct list_head *list;
- drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
if (!dev_priv) {
DRM_ERROR("%s called with no initialization\n", __func__);
@@ -585,7 +603,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
}
plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
- pipe = plane ? sarea_priv->planeB_pipe : sarea_priv->planeA_pipe;
+ pipe = i915_get_pipe(dev, plane);
seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);