[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-intel: Changes to 'upstream-experimental'



 README                         |    7 
 configure.ac                   |   41 
 man/Makefile.am                |   13 
 man/intel.man                  |   51 
 src/bios_reader/bios_reader.c  |    9 
 src/ch7017/Makefile.am         |    4 
 src/ch7017/ch7017.c            |    2 
 src/ch7xxx/Makefile.am         |    3 
 src/ch7xxx/ch7xxx.c            |    2 
 src/common.h                   |    1 
 src/exa_sf.g4a                 |   28 
 src/exa_sf_mask.g4a            |   25 
 src/exa_sf_rotation.g4a        |   26 
 src/exa_wm_maskca.g4a          |   26 
 src/exa_wm_maskca_srcalpha.g4a |   26 
 src/exa_wm_masknoca.g4a        |   26 
 src/exa_wm_nomask.g4a          |   26 
 src/exa_wm_rotation.g4a        |   26 
 src/i2c_vid.h                  |  136 +
 src/i810_driver.c              |    4 
 src/i810_reg.h                 |  120 -
 src/i830.h                     |   52 
 src/i830_accel.c               |   17 
 src/i830_bios.c                |   59 
 src/i830_bios.h                |   52 
 src/i830_crt.c                 |   98 
 src/i830_debug.c               |   58 
 src/i830_display.c             |   87 
 src/i830_dri.c                 |   29 
 src/i830_driver.c              |  215 +
 src/i830_dvo.c                 |  209 +
 src/i830_exa.c                 |   38 
 src/i830_lvds.c                |  193 +
 src/i830_memory.c              |  164 +
 src/i830_reg.h                 |    2 
 src/i830_render.c              |  129 -
 src/i830_sdvo.c                |   48 
 src/i830_sdvo_regs.h           |    6 
 src/i830_tv.c                  |    2 
 src/i830_video.c               | 4619 ++++++++++++++++++++---------------------
 src/i830_video.h               |    4 
 src/i830_xaa.c                 |    4 
 src/i915_render.c              |   12 
 src/i965_render.c              |   10 
 src/i965_video.c               |   10 
 src/ivch/Makefile.am           |    3 
 src/ivch/ivch.c                |  283 ++
 src/ivch/ivch_reg.h            |  208 +
 src/packed_yuv_sf.g4a          |   28 
 src/packed_yuv_wm.g4a          |   28 
 src/sil164/Makefile.am         |    3 
 src/sil164/sil164.c            |    2 
 52 files changed, 4432 insertions(+), 2842 deletions(-)

New commits:
commit 516fb73ffee0aea7cf892e6703d37f8ecf52b812
Author: Eric Anholt <eric@anholt.net>
Date:   Tue May 29 10:22:25 2007 -0700

    Remove README statement that 830M panels are unsupported.

diff --git a/README b/README
index f209baa..bcb0205 100644
--- a/README
+++ b/README
@@ -57,11 +57,6 @@ options.
 
 
 Known Limitations
-- Bug #8534: i830 laptop panels not supported.  The driver
-  will fail to recognize them, and only function through VGA output.  Two
-  partial DVO chip drivers (ivch and ch7017) are included which contain some of
-  the code necessary for i830 laptop panel support, but some I2C debugging will
-  be necessary to get those drivers to attach.
 - No support for "zaphod mode" dualhead.  This is the mode in which two
   Device sections are placed in the config file, and doesn't support DRI or
   many other features.  Instead, only "MergedFB-style" dualhead is supported.

commit 72462568da589054828b72ace83232a71636ee73
Author: Eric Anholt <eric@anholt.net>
Date:   Tue May 29 10:21:12 2007 -0700

    Expand manpage description of outputs supported.

diff --git a/man/intel.man b/man/intel.man
index daf9030..8991619 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -168,11 +168,28 @@ Enable printing of additional debugging information about modesetting to
 the server log.
 
 .PP
-The 830M and newer driver supports RandR 1.2, exposing the VGA, LVDS
-(laptop panel), TMDS (DVI on SDVO/DVO cards), and TV (on 915GM/945GM)
-outputs.  Per-output configuration is done through the
-.B Monitor
-section of __xconfigfile__(__filemansuffix__).
+The 830M and newer driver supports the following outputs through RandR 1.2:
+.PP
+.TP
+.BI "VGA"
+Analog VGA output
+.TP
+.BI "LVDS"
+Laptop panel
+.TP
+.BI "TV"
+Integrated TV output
+.TP
+.BI "TMDS-1"
+First DVI SDVO output
+.TP
+.BI "TMDS-2"
+Second DVI SDVO output
+.PP
+SDVO and DVO TV outputs are not supported by the driver at this time.
+.PP
+See __xconfigfile__(__filemansuffix__) for information on associating Monitor
+sections with these outputs for configuration.
 
 .SH "SEE ALSO"
 __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)

commit 906b974bfeeed18d79c244ad3db4f5d30e13e4c8
Author: Eric Anholt <eric@anholt.net>
Date:   Tue May 29 09:49:08 2007 -0700

    Add a fixup to LVDS panel mode detection for 1280x768 panel from text mode.
    
    Apparently some BIOSes will program a small mode with large blanking instead of
    using the pannel fitter.

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 566c868..ecc91aa 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -496,6 +496,22 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 	    dev_priv->panel_fixed_mode = i830_crtc_mode_get(pScrn, crtc);
 	    if (dev_priv->panel_fixed_mode != NULL)
 		dev_priv->panel_fixed_mode->type |= M_T_PREFERRED;
+
+	    /* Fixup for a 1280x768 panel with the horizontal trimmed
+	     * down to 1024 for text mode.
+	     */
+	    if (!xf86ModesEqual(dev_priv->panel_fixed_mode, bios_mode) &&
+		dev_priv->panel_fixed_mode->HDisplay == 1024 &&
+		dev_priv->panel_fixed_mode->HSyncStart == 1200 &&
+		dev_priv->panel_fixed_mode->HSyncEnd == 1312 &&
+		dev_priv->panel_fixed_mode->HTotal == 1688 &&
+		dev_priv->panel_fixed_mode->VDisplay == 768)
+	    {
+		dev_priv->panel_fixed_mode->HDisplay = 1280;
+		dev_priv->panel_fixed_mode->HSyncStart = 1328;
+		dev_priv->panel_fixed_mode->HSyncEnd = 1440;
+		dev_priv->panel_fixed_mode->HTotal = 1688;
+	    }
 	}
     }
 

commit 4b2781291844b61b397e257a0fdb43e964e5f603
Author: Keith Packard <keithp@neko.keithp.com>
Date:   Sat May 26 10:09:11 2007 -0700

    Mark IVCH as connected when detected

diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c
index e0755c0..eac878e 100644
--- a/src/ivch/ivch.c
+++ b/src/ivch/ivch.c
@@ -219,7 +219,7 @@ ivch_setup (I2CDevPtr d, xf86OutputPtr output)
 static xf86OutputStatus
 ivch_detect(I2CDevPtr d)
 {
-    return XF86OutputStatusUnknown;
+    return XF86OutputStatusConnected;
 }
 
 static DisplayModePtr

commit 2a365eab0178c28782fba97bdd22365f30ce8963
Author: Keith Packard <keithp@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_names[];
 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 pScreen);
 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, int y)
 #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;

commit ff8c8cb869a3c780dbd826f7c94f06e4f3fda6af
Author: Keith Packard <keithp@dulcimer.keithp.com>
Date:   Fri May 25 20:29:59 2007 -0700

    Compute and clip to crtc before call to xf86XVClipVideoHelper.
    
    By clipping to the crtc ahead of time, xf86XVClipVideoHelper will
    correctly clip to the bounds of the crtc, eliminating the need for any
    custom crtc clipping.
    
    Also, replace the broken xf86XVFillKeyHelper with a private version that
    doesn't end up stuck with the wrong clip list when the root window changes
    size.

diff --git a/src/i830_video.c b/src/i830_video.c
index c2d3b4b..d57519b 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1636,38 +1636,35 @@ UpdateCoeff(int taps, double fCutoff, Bool isHoriz, Bool isY, coeffPtr pCoeff)
     }
 }
 
-/*
- * Return the number of pixels from 'box' covered by 'crtc'.
- * That is, the area of the intersection of 'box' and 'crtc'
- */
-static int
-I830CrtcBoxCoverage (xf86CrtcPtr crtc, BoxPtr box)
+static void
+i830_box_intersect (BoxPtr dest, BoxPtr a, BoxPtr b)
 {
-    BoxRec   dest;
-    BoxRec   pipe;
+    dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
+    dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
+    dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
+    dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
+    if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
+	dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
+}
 
+static void
+i830_crtc_box (xf86CrtcPtr crtc, BoxPtr crtc_box)
+{
     if (crtc->enabled)
     {
-	pipe.x1 = crtc->x;
-	pipe.x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
-	pipe.y1 = crtc->y;
-	pipe.y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
+	crtc_box->x1 = crtc->x;
+	crtc_box->x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
+	crtc_box->y1 = crtc->y;
+	crtc_box->y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
     }
     else
-    {
-	pipe.x1 = pipe.x2 = 0;
-	pipe.y1 = pipe.y2 = 0;
-    }
-    dest.x1 = pipe.x1 > box->x1 ? pipe.x1 : box->x1;
-    dest.x2 = pipe.x2 < box->x2 ? pipe.x2 : box->x2;
-    dest.y1 = pipe.y1 > box->y1 ? pipe.y1 : box->y1;
-    dest.y2 = pipe.y2 < box->y2 ? pipe.y2 : box->y2;
-    if (dest.x1 >= dest.x2 || dest.y1 >= dest.y2)
-    {
-	dest.x1 = dest.x2 = 0;
-	dest.y1 = dest.y2 = 0;
-    }
-    return (int) (dest.x2 - dest.x1) * (int) (dest.y2 - dest.y1);
+	crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
+}
+
+static int
+i830_box_area (BoxPtr box)
+{
+    return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
 }
 
 /*
@@ -1677,21 +1674,28 @@ I830CrtcBoxCoverage (xf86CrtcPtr crtc, BoxPtr box)
  */
 
 static xf86CrtcPtr
-I830CoveringCrtc (ScrnInfoPtr pScrn, BoxPtr pBox, xf86CrtcPtr desired)
+i830_covering_crtc (ScrnInfoPtr pScrn,
+		    BoxPtr	box,
+		    xf86CrtcPtr desired,
+		    BoxPtr	crtc_box_ret)
 {
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     xf86CrtcPtr		crtc, best_crtc;
     int			coverage, best_coverage;
     int			c;
+    BoxRec		crtc_box, cover_box;
 
     best_crtc = NULL;
     best_coverage = 0;
     for (c = 0; c < xf86_config->num_crtc; c++)
     {
 	crtc = xf86_config->crtc[c];
-	coverage = I830CrtcBoxCoverage (crtc, pBox);
+	i830_crtc_box (crtc, &crtc_box);
+	i830_box_intersect (&cover_box, &crtc_box, box);
+	coverage = i830_box_area (&cover_box);
 	if (coverage > best_coverage)
 	{
+	    *crtc_box_ret = crtc_box;
 	    if (crtc == desired)
 		return crtc;
 	    best_crtc = crtc;
@@ -1713,19 +1717,19 @@ i830_swidth (I830Ptr pI830, unsigned int offset,
 }
 
 static void
-I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
-		 int dstPitch, int x1, int y1, int x2, int y2, BoxPtr dstBox,
-		 short src_w, short src_h, short drw_w, short drw_h)
+i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
+		   int id, short width, short height,
+		   int dstPitch, int x1, int y1, int x2, int y2, BoxPtr dstBox,
+		   short src_w, short src_h, short drw_w, short drw_h)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
-    I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+    I830Ptr		pI830 = I830PTR(pScrn);
+    I830PortPrivPtr	pPriv = pI830->adaptor->pPortPrivates[0].ptr;
     I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
-    unsigned int swidth, swidthy, swidthuv;
-    unsigned int mask, shift, offsety, offsetu;
-    xf86CrtcPtr crtc;
-    int		tmp;
-    CARD32	OCMD;
-    Bool	scaleChanged = FALSE;
+    unsigned int	swidth, swidthy, swidthuv;
+    unsigned int	mask, shift, offsety, offsetu;
+    int			tmp;
+    CARD32		OCMD;
+    Bool		scaleChanged = FALSE;
 
     OVERLAY_DEBUG("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
 		  dstPitch);
@@ -1736,23 +1740,23 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
 #if VIDEO_DEBUG
     CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
 #endif
-
-    crtc = I830CoveringCrtc (pScrn, dstBox, pPriv->desired_crtc);
-    if (crtc != pPriv->current_crtc)
-    {
-        pPriv->current_crtc = crtc;
-        I830ResetVideo (pScrn);
-    }
-
+    
     /*
      * If the video isn't visible on any CRTC, turn it off
      */
     if (!crtc)
     {
+	pPriv->current_crtc = NULL;
 	i830_overlay_off (pScrn);
 	return;
     }
     
+    if (crtc != pPriv->current_crtc)
+    {
+        pPriv->current_crtc = crtc;
+        I830ResetVideo (pScrn);
+    }
+
     switch (crtc->rotation & 0xf) {
     case RR_Rotate_0:
 	dstBox->x1 -= crtc->x;
@@ -1792,44 +1796,6 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
 	break;
     }
 
-    /* Fix up the dstBox if outside the visible screen */
-    {
-	int offset_x = (dstBox->x1 < 0) ? -dstBox->x1 : 0;
-	int offset_y = (dstBox->y1 < 0) ? -dstBox->y1 : 0;
-	int offset, offset2;
-
-	/* align */
-	offset_x = (offset_x + 3) & ~3;
-	offset_y = (offset_y + 3) & ~3;
-
-	if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-	    height -= offset_x;
-	    width -= offset_y;
-	} else {
-	    height -= offset_y;
-	    width -= offset_x;
-	}
-
-	if (id == FOURCC_I420 || id == FOURCC_YV12) {
-	    offset = ((offset_x/2) + (dstPitch * offset_y)) * 2;
-	    offset2 = ((offset_x/2) + ((dstPitch/2) * offset_y));
-	} else {
-	    offset = ((offset_x*2) + (dstPitch * offset_y));
-	    offset2 = ((offset_x*2) + ((dstPitch/2) * offset_y));
-	}
-
-	/* buffer locations */
-	pPriv->YBuf0offset += offset;
-	pPriv->UBuf0offset += offset2;
-	pPriv->VBuf0offset += offset2;
-
-	if(pPriv->doubleBuffer) {
-	    pPriv->YBuf1offset += offset;
-	    pPriv->UBuf1offset += offset2;
-	    pPriv->VBuf1offset += offset2;
-	}
-    }
-
     if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
 	tmp = width;
 	width = height;
@@ -1851,32 +1817,6 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
 	drw_h = ((drw_h * pPriv->scaleRatio) >> 16) + 1;
     }
 
-    {
-	/* Keep the engine happy and clip to the real vertical size just
-	 * in case an LFP is in use and it's not at it's native resolution.
-	 */
-	int vactive = I830CrtcPipe (pPriv->current_crtc) ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
-	int hactive = pPriv->current_crtc->mode.HDisplay;
-
-	vactive += 1;
-
-	if (dstBox->y1 < 0) dstBox->y1 = 0;
-	if (dstBox->y2 < 0) dstBox->y2 = 0;
-	if (dstBox->x1 < 0) dstBox->x1 = 0;
-	if (dstBox->x2 < 0) dstBox->x2 = 0;
-	if (dstBox->y1 > vactive) dstBox->y1 = vactive;
-	if (dstBox->y2 > vactive) dstBox->y2 = vactive;
-	if (dstBox->x1 > hactive) dstBox->x1 = hactive;
-	if (dstBox->x2 > hactive) dstBox->x2 = hactive;
-
-	/* nothing do to */
-	if (dstBox->x2 - dstBox->x1 <= 2 || dstBox->y2 - dstBox->y1 < N_VERT_Y_TAPS)
-	{
-	    OVERLAY_DEBUG("NOTHING TO DO\n");
-	    return;
-	}
-    }
-
     if (IS_I9XX(pI830)) {
 	shift = 6;
 	mask = 0x3f;
@@ -2220,6 +2160,84 @@ I830FreeMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear)
     linear->offset = 0;
 }
 
+static Bool
+i830_clip_video_helper (ScrnInfoPtr pScrn,
+			xf86CrtcPtr *crtc_ret,
+			BoxPtr	    dst,
+			INT32	    *xa,
+			INT32	    *xb,
+			INT32	    *ya,
+			INT32	    *yb,
+			RegionPtr   reg,
+			INT32	    width,
+			INT32	    height)
+{
+    Bool	ret;
+    RegionRec	crtc_region_local;
+    RegionPtr	crtc_region = reg;
+    
+    /*
+     * For overlay video, compute the relevant CRTC and
+     * clip video to that
+     */
+    if (crtc_ret)
+    {
+	I830Ptr		pI830 = I830PTR(pScrn);
+	I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+	BoxRec		crtc_box;
+	xf86CrtcPtr	crtc = i830_covering_crtc (pScrn, dst,
+						   pPriv->desired_crtc,
+						   &crtc_box);
+	
+	if (crtc)
+	{
+	    REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1);
+	    crtc_region = &crtc_region_local;
+	    REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg);
+	}
+	*crtc_ret = crtc;
+    }
+    ret = xf86XVClipVideoHelper (dst, xa, xb, ya, yb, 
+				 crtc_region, width, height);
+    if (crtc_region != reg)
+	REGION_UNINIT (pScreen, &crtc_region_local);
+    return ret;
+}
+
+static void
+i830_fill_colorkey (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
+{
+   DrawablePtr root = &WindowTable[pScreen->myNum]->drawable;
+   XID	       pval[2];
+   BoxPtr      pbox = REGION_RECTS(clipboxes);
+   int	       i, nbox = REGION_NUM_RECTS(clipboxes);
+   xRectangle  *rects;
+   GCPtr       gc;
+
+   if(!xf86Screens[pScreen->myNum]->vtSema) return;
+
+   gc = GetScratchGC(root->depth, pScreen);
+   pval[0] = key;
+   pval[1] = IncludeInferiors;
+   (void) ChangeGC(gc, GCForeground|GCSubwindowMode, pval);
+   ValidateGC(root, gc);
+
+   rects = xalloc (nbox * sizeof(xRectangle));
+
+   for(i = 0; i < nbox; i++, pbox++) 
+   {
+      rects[i].x = pbox->x1;
+      rects[i].y = pbox->y1;
+      rects[i].width = pbox->x2 - pbox->x1;
+      rects[i].height = pbox->y2 - pbox->y1;
+   }
+   
+   (*gc->ops->PolyFillRect)(root, gc, nbox, rects);
+   
+   xfree (rects);
+   FreeScratchGC (gc);
+}
+
 /*
  * The source rectangle of the video is defined by (src_x, src_y, src_w, src_h).
  * The dest rectangle of the video is defined by (drw_x, drw_y, drw_w, drw_h).
@@ -2255,6 +2273,7 @@ I830PutImage(ScrnInfoPtr pScrn,
     BoxRec dstBox;
     int pitchAlignMask;
     int extraLinear;
+    xf86CrtcPtr	crtc;
 
     if (pPriv->textured)
 	overlay = NULL;
@@ -2301,8 +2320,10 @@ I830PutImage(ScrnInfoPtr pScrn,
     dstBox.y1 = drw_y;
     dstBox.y2 = drw_y + drw_h;
 
-    if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
-			       width, height))
+    if (!i830_clip_video_helper(pScrn, 
+				pPriv->textured ? NULL : &crtc,
+				&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
+				width, height))
 	return Success;
 
     destId = id;
@@ -2455,14 +2476,15 @@ I830PutImage(ScrnInfoPtr pScrn,
     }
 
     if (!pPriv->textured) {
+	i830_display_video(pScrn, crtc, destId, width, height, dstPitch,
+			   x1, y1, x2, y2, &dstBox, src_w, src_h,
+			   drw_w, drw_h);
+	
 	/* update cliplist */
 	if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
 	    REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
-	    xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes);
+	    i830_fill_colorkey (pScreen, pPriv->colorKey, clipBoxes);
 	}
-
-	I830DisplayVideo(pScrn, destId, width, height, dstPitch,
-			 x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
     } else if (IS_I965G(pI830)) {
 	I965DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
 				 dstPitch, x1, y1, x2, y2,
@@ -2754,8 +2776,8 @@ I830DisplaySurface(XF86SurfacePtr surface,
     I830Ptr pI830 = I830PTR(pScrn);
     I830PortPrivPtr pI830Priv = GET_PORT_PRIVATE(pScrn);
     INT32 x1, y1, x2, y2;
-    INT32 loops = 0;
     BoxRec dstBox;
+    xf86CrtcPtr crtc;
 
     OVERLAY_DEBUG("I830DisplaySurface\n");
 
@@ -2785,43 +2807,24 @@ I830DisplaySurface(XF86SurfacePtr surface,
     dstBox.y1 = drw_y;
     dstBox.y2 = drw_y + drw_h;
 
-    if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
-			       surface->width, surface->height))
+    if (!i830_clip_video_helper (pScrn, &crtc, &dstBox,
+				 &x1, &x2, &y1, &y2, clipBoxes,
+				 surface->width, surface->height))
 	return Success;
 
     /* fixup pointers */
     pI830Priv->YBuf0offset = surface->offsets[0];
     pI830Priv->YBuf1offset = pI830Priv->YBuf0offset;
 
-    /* Make sure this buffer isn't in use */
-    loops = 0;
-    if (*pI830->overlayOn && pI830Priv->doubleBuffer) 
-    {
-	while (loops < 1000000) {
-#if USE_USLEEP_FOR_VIDEO
-	    usleep(10);
-#endif
-	    if (((INREG(DOVSTA) & OC_BUF) >> 20) == pI830Priv->currentBuf) {
-		break;
-	    }
-	    loops++;
-	}
-	if (loops >= 1000000) {
-	    ErrorF("loops (1) maxed out for buffer %d\n", pI830Priv->currentBuf);
-#if 0
-	    pI830Priv->currentBuf = !pI830Priv->currentBuf;
-#endif
-	}
-
-	/* buffer swap */
-	pI830Priv->currentBuf = !pI830Priv->currentBuf;
-    }
+    /* Pick the idle buffer */
+    if (!pI830Priv->textured && *pI830->overlayOn && pI830Priv->doubleBuffer) 
+	pI830Priv->currentBuf = !((INREG(DOVSTA) & OC_BUF) >> 20);
 
-    I830DisplayVideo(pScrn, surface->id, surface->width, surface->height,
+    i830_display_video(pScrn, crtc, surface->id, surface->width, surface->height,
 		     surface->pitches[0], x1, y1, x2, y2, &dstBox,
 		     src_w, src_h, drw_w, drw_h);
 
-    xf86XVFillKeyHelper(pScreen, pI830Priv->colorKey, clipBoxes);
+    i830_fill_colorkey (pScreen, pI830Priv->colorKey, clipBoxes);
 
     pPriv->isOn = TRUE;
     /* we've prempted the XvImage stream so set its free timer */

commit 33f635d79fe891079558fd909d564f3cf424c482
Author: Keith Packard <keithp@dulcimer.keithp.com>
Date:   Fri May 25 17:32:06 2007 -0700

    Ensure Pipe A is active when enabling overlay the first time.
    
    The overlay on the i830 appears to be clocked by Pipe A when being enabled.
    If pipe A is not running, it will freeze the overlay and blank the screen.
    Setting a random mode on the Pipe and turning it on fixes this problem
    nicely.

diff --git a/src/i830_video.c b/src/i830_video.c
index e2d132e..c2d3b4b 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -321,6 +321,9 @@ typedef struct {
     CARD16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
 } I830OverlayRegRec, *I830OverlayRegPtr;
 
+#define I830OVERLAYREG(pI830) ((I830OverlayRegPtr)\
+			       ((pI830)->FbBase + \
+				(pI830)->overlay_regs->offset))
 #if VIDEO_DEBUG
 static void
 CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size)
@@ -342,6 +345,29 @@ CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size)
 }
 #endif
 
+static int
+I830CrtcPipe (xf86CrtcPtr crtc)
+{
+    if (crtc == NULL)
+	return 0;
+    return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe;
+}
+
+static xf86CrtcPtr
+I830CrtcForPipe (ScrnInfoPtr pScrn, int pipe)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			c;
+
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+	if (I830CrtcPipe (crtc) == pipe)
+	    return crtc;
+    }
+    return NULL;
+}
+
 /*
  * This is more or less the correct way to initalise, update, and shut down
  * the overlay.
@@ -353,40 +379,91 @@ CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size)
 static void
 i830_overlay_on(ScrnInfoPtr pScrn)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
-    I830OverlayRegPtr	overlay = (I830OverlayRegPtr) (pI830->FbBase +
-						       pI830->overlay_regs->offset);
-
+    I830Ptr		pI830 = I830PTR(pScrn);
+    I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
+    I830PortPrivPtr	pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+    xf86CrtcPtr		crtc0 = NULL;
+    
     if (*pI830->overlayOn)
 	return;
 
+    /*
+     * On I830, if pipe A is off the first time the overlay
+     * is enabled, it will fail to turn and blank the entire 
+     * screen. Light up pipe A in this case to provide a clock
+     * for the overlay hardware
+     */
+    if (!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;
+    }
+
     overlay->OCMD &= ~OVERLAY_ENABLE;
-    BEGIN_LP_RING(4);
+    BEGIN_LP_RING(6);
     OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
     OUT_RING(MI_NOOP);
     OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON);
     OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
+    /* Wait for the overlay to light up before attempting to use it */
+    OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+    OUT_RING(MI_NOOP);
     ADVANCE_LP_RING();
+    i830WaitSync(pScrn);
+    
+    /*
+     * If we turned pipe A on up above, turn it
+     * back off
+     */
+    if (crtc0)
+	crtc0->funcs->dpms (crtc0, DPMSModeOff);
+
     OVERLAY_DEBUG("overlay_on\n");
     *pI830->overlayOn = TRUE;
+
+    overlay->OCMD |= OVERLAY_ENABLE;
 }
 
 static void
-i830_overlay_continue(ScrnInfoPtr pScrn)
+i830_overlay_continue(ScrnInfoPtr pScrn, Bool update_filter)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
-    I830OverlayRegPtr	overlay = (I830OverlayRegPtr) (pI830->FbBase +
-						       pI830->overlay_regs->offset);
+    I830Ptr		pI830 = I830PTR(pScrn);
+    CARD32		flip_addr;
+    I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
 
     if (!*pI830->overlayOn)
 	return;
 
-    overlay->OCMD |= OVERLAY_ENABLE;
+    flip_addr = pI830->overlay_regs->bus_addr;
+    if (update_filter)
+	flip_addr |= OFC_UPDATE;
+    OVERLAY_DEBUG ("overlay_continue cmd 0x%08lx -> 0x%08lx sta 0x%08lx\n",
+		   overlay->OCMD, INREG(OCMD_REGISTER), INREG(DOVSTA));
     BEGIN_LP_RING(4);
     OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
     OUT_RING(MI_NOOP);
     OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
-    OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
+    OUT_RING(flip_addr);
     ADVANCE_LP_RING();
     OVERLAY_DEBUG("overlay_continue\n");
 }
@@ -395,22 +472,43 @@ static void
 i830_overlay_off(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    I830OverlayRegPtr	overlay = (I830OverlayRegPtr) (pI830->FbBase +
-						       pI830->overlay_regs->offset);
+    I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
 
     if (!*pI830->overlayOn)
 	return;
 
-    overlay->OCMD &= ~OVERLAY_ENABLE;
-    BEGIN_LP_RING(6);
-    OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
-    OUT_RING(MI_NOOP);
-    OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
-    OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
-    OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
-    OUT_RING(MI_NOOP);
-    ADVANCE_LP_RING();
-    i830WaitSync(pScrn);



Reply to: