xf86-video-intel: src/i830_display.c src/i830.h src/i830_video.c

Keith Packard keithp at kemper.freedesktop.org
Sun May 27 12:35:53 PDT 2007


 src/i830.h         |   11 +++++++
 src/i830_display.c |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/i830_video.c   |   31 ++++----------------
 3 files changed, 98 insertions(+), 24 deletions(-)

New commits:
diff-tree 2a365eab0178c28782fba97bdd22365f30ce8963 (from ff8c8cb869a3c780dbd826f7c94f06e4f3fda6af)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Sun May 27 12:35:55 2007 -0700

    On i830, Pipe B cannot be lit the first time unless Pipe A is running.
    
    I don't understand it, but just like the video overlay, if Pipe A is not
    running, Pipe B will not turn the first time it is activated. This
    patch restructures the code used for the video overlay to share it
    with the crtc commit function.

diff --git a/src/i830.h b/src/i830.h
index 35f8192..76cc6e8 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -216,6 +216,8 @@ extern const char *i830_output_type_name
 typedef struct _I830CrtcPrivateRec {
     int			    pipe;
 
+    Bool    		    enabled;
+    
     /* Lookup table values to be set when the CRTC is enabled */
     CARD8 lut_r[256], lut_g[256], lut_b[256];
 
@@ -579,6 +581,15 @@ extern void I830InitVideo(ScreenPtr pScr
 extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on);
 #endif
 
+int
+i830_crtc_pipe (xf86CrtcPtr crtc);
+
+Bool
+i830_pipe_a_require_activate (ScrnInfoPtr scrn);
+
+void
+i830_pipe_a_require_deactivate (ScrnInfoPtr scrn);
+
 #ifdef XF86DRI
 extern Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags);
 extern void I830SetupMemoryTiling(ScrnInfoPtr pScrn);
diff --git a/src/i830_display.c b/src/i830_display.c
index 023a1aa..adc7479 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -429,6 +429,76 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x,
 #endif
 }
 
+/*
+ * Both crtc activation and video overlay enablement on pipe B
+ * will fail on i830 if pipe A is not running. This function
+ * makes sure pipe A is active for these cases
+ */
+
+int
+i830_crtc_pipe (xf86CrtcPtr crtc)
+{
+    if (crtc == NULL)
+	return 0;
+    return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe;
+}
+
+static xf86CrtcPtr
+i830_crtc_for_pipe (ScrnInfoPtr scrn, int pipe)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			c;
+
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+	if (i830_crtc_pipe (crtc) == pipe)
+	    return crtc;
+    }
+    return NULL;
+}
+
+Bool
+i830_pipe_a_require_activate (ScrnInfoPtr scrn)
+{
+    xf86CrtcPtr	crtc = i830_crtc_for_pipe (scrn, 0);
+    /* VESA 640x480x72Hz mode to set on the pipe */
+    static DisplayModeRec   mode = {
+	NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
+	31500,
+	640, 664, 704, 832, 0,
+	480, 489, 491, 520, 0,
+	V_NHSYNC | V_NVSYNC,
+	0, 0,
+	0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0,
+	FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
+    };
+
+    if (!crtc)
+	return FALSE;
+    if (crtc->enabled)
+	return FALSE;
+    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+    crtc->funcs->mode_set (crtc, &mode, &mode, 0, 0);
+    crtc->funcs->dpms (crtc, DPMSModeOn);
+    return TRUE;
+}
+
+void
+i830_pipe_a_require_deactivate (ScrnInfoPtr scrn)
+{
+    xf86CrtcPtr	crtc = i830_crtc_for_pipe (scrn, 0);
+
+    if (!crtc)
+	return;
+    if (crtc->enabled)
+	return;
+    crtc->funcs->dpms (crtc, DPMSModeOff);
+    return;
+}
+
+
 /**
  * Sets the power management mode of the pipe and plane.
  *
@@ -593,9 +663,19 @@ i830_crtc_prepare (xf86CrtcPtr crtc)
 static void
 i830_crtc_commit (xf86CrtcPtr crtc)
 {
+    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    Bool		deactivate = FALSE;
+
+    if (!intel_crtc->enabled && intel_crtc->pipe != 0)
+	deactivate = i830_pipe_a_require_activate (crtc->scrn);
+    
+    intel_crtc->enabled = TRUE;
+    
     crtc->funcs->dpms (crtc, DPMSModeOn);
     if (crtc->scrn->pScreen != NULL)
 	xf86_reload_cursors (crtc->scrn->pScreen);
+    if (deactivate)
+	i830_pipe_a_require_deactivate (crtc->scrn);
 }
 
 void
diff --git a/src/i830_video.c b/src/i830_video.c
index d57519b..4517975 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -382,6 +382,7 @@ i830_overlay_on(ScrnInfoPtr pScrn)
     I830Ptr		pI830 = I830PTR(pScrn);
     I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
     I830PortPrivPtr	pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+    Bool		deactivate = FALSE;
     xf86CrtcPtr		crtc0 = NULL;
     
     if (*pI830->overlayOn)
@@ -393,30 +394,12 @@ i830_overlay_on(ScrnInfoPtr pScrn)
      * screen. Light up pipe A in this case to provide a clock
      * for the overlay hardware
      */
-    if (!pPriv->started_video)
+    if (pPriv->current_crtc && 
+	i830_crtc_pipe (pPriv->current_crtc) != 0 &&
+	!pPriv->started_video)
     {
 	pPriv->started_video = TRUE;
-	crtc0 = I830CrtcForPipe (pScrn, 0);
-	if (!crtc0->enabled)
-	{
-	    /* VESA 640x480x72Hz mode to set on the pipe */
-	    static DisplayModeRec   mode = {
-		NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
-		31500,
-		640, 664, 704, 832, 0,
-		480, 489, 491, 520, 0,
-		V_NHSYNC | V_NVSYNC,
-		0, 0,
-		0, 0, 0, 0, 0, 0, 0,
-		0, 0, 0, 0, 0, 0,
-		FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
-	    };
-	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
-	    crtc0->funcs->mode_set (crtc0, &mode, &mode, 0, 0);
-	    crtc0->funcs->dpms (crtc0, DPMSModeOn);
-	}
-	else
-	    crtc0 = NULL;
+	deactivate = i830_pipe_a_require_activate (pScrn);
     }
 
     overlay->OCMD &= ~OVERLAY_ENABLE;
@@ -435,8 +418,8 @@ i830_overlay_on(ScrnInfoPtr pScrn)
      * If we turned pipe A on up above, turn it
      * back off
      */
-    if (crtc0)
-	crtc0->funcs->dpms (crtc0, DPMSModeOff);
+    if (deactivate)
+	i830_pipe_a_require_deactivate (pScrn);
 
     OVERLAY_DEBUG("overlay_on\n");
     *pI830->overlayOn = TRUE;


More information about the xorg-commit mailing list