xf86-video-intel: Branch 'fbc' - 7 commits - man/intel.man src/i830_crt.c src/i830_display.c src/i830_display.h src/i830_driver.c src/i830.h src/i830_memory.c src/i830_tv.c src/i915_render.c

Keith Packard keithp at kemper.freedesktop.org
Fri Jul 13 13:42:05 PDT 2007


 man/intel.man      |    4 -
 src/i830.h         |    6 +-
 src/i830_crt.c     |  140 ++++++++++++++++++++++++++++-------------------------
 src/i830_display.c |  108 +++++++++++++++++++++++++++++++++-------
 src/i830_display.h |    4 -
 src/i830_driver.c  |   40 ++++++++++-----
 src/i830_memory.c  |   57 +++++++++++----------
 src/i830_tv.c      |   19 +------
 src/i915_render.c  |    7 --
 9 files changed, 235 insertions(+), 150 deletions(-)

New commits:
diff-tree ff2be3995d33f9e4b7f63b380f166b6168c9b9c6 (from 00f4587025a3879626623135b0a153fcdb906719)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Jul 13 12:47:18 2007 -0700

    Remove hard-coded CRT blanking frobbing for load detection.
    
    CRT blanking needn't be adjusted to perform load detection on 9xx chips, and
    the 8xx load detection path now adjusts blanking just during load detection.
    Adjusting the blanking interval turned out to cause many monitors to fail to
    sync.

diff --git a/src/i830_crt.c b/src/i830_crt.c
index 9e6180e..d7762a0 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -97,8 +97,6 @@ static Bool
 i830_crt_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		    DisplayModePtr adjusted_mode)
 {
-    /* disable blanking so we can detect monitors */
-    adjusted_mode->CrtcVBlankStart = adjusted_mode->CrtcVTotal - 3;
     return TRUE;
 }
 
@@ -360,8 +358,8 @@ i830_crt_detect(xf86OutputPtr output)
 	    return XF86OutputStatusDisconnected;
     }
 
-//    if (i830_crt_detect_ddc(output))
-//	return XF86OutputStatusConnected;
+    if (i830_crt_detect_ddc(output))
+	return XF86OutputStatusConnected;
 
     /* Use the load-detect method if we have no other way of telling. */
     crtc = i830GetLoadDetectPipe (output, NULL, &dpms_mode);
diff --git a/src/i830_display.c b/src/i830_display.c
index 16af496..26873fe 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1509,6 +1509,8 @@ i830GetLoadDetectPipe(xf86OutputPtr outp
 	output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
 	output->funcs->commit (output);
     }
+    /* let the output get through one full cycle before testing */
+    i830WaitForVblank (pScrn);
 
     return crtc;
 }
diff-tree 00f4587025a3879626623135b0a153fcdb906719 (from 6f18300aed1340348c6d395f326061b5315be643)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Jul 13 10:58:06 2007 -0700

    Ensure pipe/output active before doing load detection.
    
    If the pipe or output have been set to DPMSOff, then load detection will not
    work correctly. Also, share the load detection configuration code between
    crt and tv outputs.

diff --git a/src/i830.h b/src/i830.h
index 409057c..b85ee26 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -220,6 +220,8 @@ typedef struct _I830CrtcPrivateRec {
 
     Bool    		    enabled;
     
+    int			    dpms_mode;
+    
     /* Lookup table values to be set when the CRTC is enabled */
     CARD8 lut_r[256], lut_g[256], lut_b[256];
 
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 1900dfb..9e6180e 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -349,8 +349,9 @@ i830_crt_detect(xf86OutputPtr output)
 {
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
-    xf86CrtcPtr	    crtc;
-
+    xf86CrtcPtr		    crtc;
+    int			    dpms_mode;
+    
     if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_I965G(pI830) ||
 	    IS_G33CLASS(pI830)) {
 	if (i830_crt_detect_hotplug(output))
@@ -359,49 +360,18 @@ i830_crt_detect(xf86OutputPtr output)
 	    return XF86OutputStatusDisconnected;
     }
 
-    if (i830_crt_detect_ddc(output))
-	return XF86OutputStatusConnected;
+//    if (i830_crt_detect_ddc(output))
+//	return XF86OutputStatusConnected;
 
     /* Use the load-detect method if we have no other way of telling. */
-    crtc = i830GetLoadDetectPipe (output);
+    crtc = i830GetLoadDetectPipe (output, NULL, &dpms_mode);
     
     if (crtc)
     {
-	/* 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
-	};
 	Bool			connected;
-	I830OutputPrivatePtr	intel_output = output->driver_private;
-	
-	if (!crtc->enabled)
-	{
-	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
-	    /*
-	     * Give us some border at the bottom for load detection on i8xx
-	     */
-	    mode.CrtcVBlankStart = mode.CrtcVSyncStart;
-	    if (mode.CrtcVBlankEnd - mode.CrtcVBlankStart < 3)
-		mode.CrtcVBlankStart = mode.CrtcVBlankEnd - 3;
-	    xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
-	}
-	else if (intel_output->load_detect_temp)
-	{
-	    /* Add this output to the crtc */
-	    output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
-	    output->funcs->commit (output);
-	}
-	connected = i830_crt_detect_load (crtc, output);
 
-	i830ReleaseLoadDetectPipe (output);
+	connected = i830_crt_detect_load (crtc, output);
+	i830ReleaseLoadDetectPipe (output, dpms_mode);
 	if (connected)
 	    return XF86OutputStatusConnected;
 	else
diff --git a/src/i830_display.c b/src/i830_display.c
index ff25b29..16af496 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -605,6 +605,8 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
 	break;
     }
 
+    intel_crtc->dpms_mode = mode;
+
 #ifdef XF86DRI
     if (pI830->directRenderingEnabled) {
 	drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen);
@@ -1424,58 +1426,116 @@ i830DescribeOutputConfiguration(ScrnInfo
  * \return crtc, or NULL if no pipes are available.
  */
     
+/* VESA 640x480x72Hz mode to set on the pipe */
+static DisplayModeRec   load_detect_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,
+
+    640, 640, 664, 704, 832, 832, 0,
+    480, 489, 489, 491, 520, 520,
+    FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
+};
+
 xf86CrtcPtr
-i830GetLoadDetectPipe(xf86OutputPtr output)
+i830GetLoadDetectPipe(xf86OutputPtr output, DisplayModePtr mode, int *dpms_mode)
 {
     ScrnInfoPtr		    pScrn = output->scrn;
     xf86CrtcConfigPtr	    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
+    I830CrtcPrivatePtr	    intel_crtc;
     xf86CrtcPtr		    supported_crtc =NULL;
-    xf86CrtcPtr		    detect_crtc = NULL;
+    xf86CrtcPtr		    crtc = NULL;
     int			    i;
 
     if (output->crtc) 
-	return output->crtc;
+    {
+	crtc = output->crtc;
+	/*
+	 * Make sure the crtc and output are running
+	 */
+	intel_crtc = crtc->driver_private;
+	*dpms_mode = intel_crtc->dpms_mode;
+	if (intel_crtc->dpms_mode != DPMSModeOn)
+	{
+	    crtc->funcs->dpms (crtc, DPMSModeOn);
+	    output->funcs->dpms (output, DPMSModeOn);
+	}
+	return crtc;
+    }
 
     for (i = 0; i < xf86_config->num_crtc; i++)
     {
-	xf86CrtcPtr crtc;
+	xf86CrtcPtr possible_crtc;
 	if (!(output->possible_crtcs & (1 << i)))
 	    continue;
-	crtc = xf86_config->crtc[i];
-	if (!crtc->enabled)
+	possible_crtc = xf86_config->crtc[i];
+	if (!possible_crtc->enabled)
 	{
-	    detect_crtc = crtc;
+	    crtc = possible_crtc;
 	    break;
 	}
 	if (!supported_crtc)
-	    supported_crtc = crtc;
+	    supported_crtc = possible_crtc;
+    }
+    if (!crtc)
+    {
+	crtc = supported_crtc;
+	if (!crtc)
+	    return NULL;
     }
-    if (!detect_crtc)
-	detect_crtc = supported_crtc;
-    if (!detect_crtc)
-	return NULL;
 
-    output->crtc = detect_crtc;
+    output->crtc = crtc;
     intel_output->load_detect_temp = TRUE;
+    
+    intel_crtc = crtc->driver_private;
+    *dpms_mode = intel_crtc->dpms_mode;
 
-    return detect_crtc;
+    if (!crtc->enabled)
+    {
+	if (!mode)
+	    mode = &load_detect_mode;
+	xf86CrtcSetMode (crtc, mode, RR_Rotate_0, 0, 0);
+    }
+    else
+    {
+	if (intel_crtc->dpms_mode != DPMSModeOn)
+	    crtc->funcs->dpms (crtc, DPMSModeOn);
+
+	/* Add this output to the crtc */
+	output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
+	output->funcs->commit (output);
+    }
+
+    return crtc;
 }
 
 void
-i830ReleaseLoadDetectPipe(xf86OutputPtr output)
+i830ReleaseLoadDetectPipe(xf86OutputPtr output, int dpms_mode)
 {
     ScrnInfoPtr		    pScrn = output->scrn;
     I830OutputPrivatePtr    intel_output = output->driver_private;
+    xf86CrtcPtr		    crtc = output->crtc;
     
     if (intel_output->load_detect_temp) 
     {
-	xf86CrtcPtr crtc = output->crtc;
 	output->crtc = NULL;
 	intel_output->load_detect_temp = FALSE;
 	crtc->enabled = xf86CrtcInUse (crtc);
 	xf86DisableUnusedFunctions(pScrn);
     }
+    /*
+     * Switch crtc and output back off if necessary
+     */
+    if (crtc->enabled && dpms_mode != DPMSModeOn)
+    {
+	if (output->crtc == crtc)
+	    output->funcs->dpms (output, dpms_mode);
+	crtc->funcs->dpms (crtc, dpms_mode);
+    }
 }
 
 /* Returns the clock of the currently programmed mode of the given pipe. */
@@ -1623,6 +1683,7 @@ i830_crtc_init(ScrnInfoPtr pScrn, int pi
 
     intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1);
     intel_crtc->pipe = pipe;
+    intel_crtc->dpms_mode = DPMSModeOff;
 
     /* Initialize the LUTs for when we turn on the CRTC. */
     for (i = 0; i < 256; i++) {
diff --git a/src/i830_display.h b/src/i830_display.h
index 07dfe93..1eeb7f1 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -32,8 +32,8 @@ void i830PipeSetBase(xf86CrtcPtr crtc, i
 void i830WaitForVblank(ScrnInfoPtr pScrn);
 void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn);
 
-xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output);
-void i830ReleaseLoadDetectPipe(xf86OutputPtr output);
+xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output, DisplayModePtr mode, int *dpms_mode);
+void i830ReleaseLoadDetectPipe(xf86OutputPtr output, int dpms_mode);
 void i830_crtc_init(ScrnInfoPtr pScrn, int pipe);
 void i830_crtc_load_lut(xf86CrtcPtr crtc);
 DisplayModePtr i830_crtc_mode_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc);
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 1c818ba..8337d86 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1353,24 +1353,15 @@ i830_tv_detect(xf86OutputPtr output)
     DisplayModeRec	    mode;
     I830OutputPrivatePtr    intel_output = output->driver_private;
     struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+    int			    dpms_mode;
 
-    crtc = i830GetLoadDetectPipe (output);
+    mode = reported_modes[0];
+    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+    crtc = i830GetLoadDetectPipe (output, &mode, &dpms_mode);
     if (crtc)
     {
-	if (!crtc->enabled)
-        {
-            /* we only need the pixel clock set correctly here */
-            mode = reported_modes[0];
-            xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
-	    crtc->funcs->mode_set(crtc, &mode, &mode, 0, 0);
-        }
-	else if (intel_output->load_detect_temp)
-	{
-	    output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
-	    output->funcs->commit (output);
-	}
         i830_tv_detect_type (crtc, output);
-        i830ReleaseLoadDetectPipe (output);
+        i830ReleaseLoadDetectPipe (output, dpms_mode);
     }
 
     switch (dev_priv->type) {
diff-tree 6f18300aed1340348c6d395f326061b5315be643 (from 04130ac6b705aa49161fb6dae83ad0bdd76e89d9)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Mon Jul 9 21:29:55 2007 -0700

    Eliminate bogus (and harmful) blanking adjustment for load detect.
    
    Instead of always adding blanking to mode lines, use the FORCE_BORDER option
    on i9xx hardware where it works, and dynamically add a bit of border if
    necessary on i8xx hardware to make load detection work. This may cause
    flashing when a usable crtc is not otherwise idle when load detection is
    requested.

diff --git a/src/i830_crt.c b/src/i830_crt.c
index 6d70f39..1900dfb 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -209,10 +209,8 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
     CARD32		    dsl;
     CARD8		    st00;
     int			    bclrpat_reg, pipeconf_reg, pipe_dsl_reg;
-    int			    vtotal_reg;
-    int			    vblank_reg;
+    int			    vtotal_reg, vblank_reg, vsync_reg;
     int			    pipe = i830_crtc->pipe;
-    int			    count, detect;
     Bool		    present;
 
     if (pipe == 0) 
@@ -220,6 +218,7 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
 	bclrpat_reg = BCLRPAT_A;
 	vtotal_reg = VTOTAL_A;
 	vblank_reg = VBLANK_A;
+	vsync_reg = VSYNC_A;
 	pipeconf_reg = PIPEACONF;
 	pipe_dsl_reg = PIPEA_DSL;
     }
@@ -228,6 +227,7 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
 	bclrpat_reg = BCLRPAT_B;
 	vtotal_reg = VTOTAL_B;
 	vblank_reg = VBLANK_B;
+	vsync_reg = VSYNC_B;
 	pipeconf_reg = PIPEBCONF;
 	pipe_dsl_reg = PIPEB_DSL;
     }
@@ -242,45 +242,78 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
     vblank_start = (vblank & 0xfff) + 1;
     vblank_end = ((vblank >> 16) & 0xfff) + 1;
     
-    /* sample in the vertical border, selecting the larger one */
-    if (vblank_start - vactive >= vtotal - vblank_end)
-	vsample = (vblank_start + vactive) >> 1;
-    else
-	vsample = (vtotal + vblank_end) >> 1;
-
     /* Set the border color to purple. */
     OUTREG(bclrpat_reg, 0x500050);
     
-    /*
-     * Wait for the border to be displayed
-     */
-    while (INREG(pipe_dsl_reg) >= vactive)
-	;
-    while ((dsl = INREG(pipe_dsl_reg)) <= vsample)
-	;
-    /*
-     * Watch ST00 for an entire scanline
-     */
-    detect = 0;
-    count = 0;
-    do {
-	count++;
-	/* Read the ST00 VGA status register */
-	st00 = pI830->readStandard(pI830, 0x3c2);
-	if (st00 & (1 << 4))
-	    detect++;
-    } while ((INREG(pipe_dsl_reg) == dsl));
+    if (IS_I9XX (pI830))
+    {
+	CARD32	pipeconf = INREG(pipeconf_reg);
+	OUTREG(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
+	
+	st00 = pI830->readStandard (pI830, 0x3c2);
+	present = (st00 & (1 << 4)) != 0;
+	OUTREG(pipeconf_reg, pipeconf);
+    }
+    else
+    {
+	Bool	restore_vblank = FALSE;
+	int	count, detect;
+
+	/*
+	 * If there isn't any border, add some.
+	 * Yes, this will flicker
+	 */
+	if (vblank_start <= vactive && vblank_end >= vtotal)
+	{
+	    CARD32  vsync = INREG(vsync_reg);
+	    CARD32  vsync_start = (vsync & 0xffff) + 1;
+
+	    vblank_start = vsync_start;
+	    OUTREG(vblank_reg, (vblank_start - 1) | ((vblank_end - 1) << 16));
+	    restore_vblank = TRUE;
+	}
+	
+	/* sample in the vertical border, selecting the larger one */
+	if (vblank_start - vactive >= vtotal - vblank_end)
+	    vsample = (vblank_start + vactive) >> 1;
+	else
+	    vsample = (vtotal + vblank_end) >> 1;
+
+	/*
+	 * Wait for the border to be displayed
+	 */
+	while (INREG(pipe_dsl_reg) >= vactive)
+	    ;
+	while ((dsl = INREG(pipe_dsl_reg)) <= vsample)
+	    ;
+	/*
+	 * Watch ST00 for an entire scanline
+	 */
+	detect = 0;
+	count = 0;
+	do {
+	    count++;
+	    /* Read the ST00 VGA status register */
+	    st00 = pI830->readStandard(pI830, 0x3c2);
+	    if (st00 & (1 << 4))
+		detect++;
+	} while ((INREG(pipe_dsl_reg) == dsl));
+	
+	/* restore vblank if necessary */
+	if (restore_vblank)
+	    OUTREG(vblank_reg, vblank);
+	/*
+	 * If more than 3/4 of the scanline detected a monitor,
+	 * then it is assumed to be present. This works even on i830,
+	 * where there isn't any way to force the border color across
+	 * the screen
+	 */
+	present = detect * 4 > count * 3;
+    }
 
     /* Restore previous settings */
     OUTREG(bclrpat_reg, save_bclrpat);
 
-    /*
-     * If more than 3/4 of the scanline detected a monitor,
-     * then it is assumed to be present. This works even on i830,
-     * where there isn't any way to force the border color across
-     * the screen
-     */
-    present = detect * 4 > count * 3;
     return present;
 }
 
@@ -352,10 +385,17 @@ i830_crt_detect(xf86OutputPtr output)
 	if (!crtc->enabled)
 	{
 	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+	    /*
+	     * Give us some border at the bottom for load detection on i8xx
+	     */
+	    mode.CrtcVBlankStart = mode.CrtcVSyncStart;
+	    if (mode.CrtcVBlankEnd - mode.CrtcVBlankStart < 3)
+		mode.CrtcVBlankStart = mode.CrtcVBlankEnd - 3;
 	    xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
 	}
 	else if (intel_output->load_detect_temp)
 	{
+	    /* Add this output to the crtc */
 	    output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
 	    output->funcs->commit (output);
 	}
diff --git a/src/i830_display.c b/src/i830_display.c
index f3b5c50..ff25b29 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1169,13 +1169,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
     OUTREG(vtot_reg, (adjusted_mode->CrtcVDisplay - 1) |
 	((adjusted_mode->CrtcVTotal - 1) << 16));
     
-    /*
-     * Give us some border at the bottom for load detection
-     */
-    adjusted_mode->CrtcVBlankStart = adjusted_mode->CrtcVSyncStart;
-    if (adjusted_mode->CrtcVBlankEnd - adjusted_mode->CrtcVBlankStart < 3)
-	adjusted_mode->CrtcVBlankStart = adjusted_mode->CrtcVBlankEnd - 3;
-    
     OUTREG(vblank_reg, (adjusted_mode->CrtcVBlankStart - 1) |
 	((adjusted_mode->CrtcVBlankEnd - 1) << 16));
     OUTREG(vsync_reg, (adjusted_mode->CrtcVSyncStart - 1) |
@@ -1437,25 +1430,36 @@ i830GetLoadDetectPipe(xf86OutputPtr outp
     ScrnInfoPtr		    pScrn = output->scrn;
     xf86CrtcConfigPtr	    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
-    xf86CrtcPtr	    crtc;
+    xf86CrtcPtr		    supported_crtc =NULL;
+    xf86CrtcPtr		    detect_crtc = NULL;
     int			    i;
 
     if (output->crtc) 
 	return output->crtc;
 
     for (i = 0; i < xf86_config->num_crtc; i++)
-	if (output->possible_crtcs & (1 << i))
+    {
+	xf86CrtcPtr crtc;
+	if (!(output->possible_crtcs & (1 << i)))
+	    continue;
+	crtc = xf86_config->crtc[i];
+	if (!crtc->enabled)
+	{
+	    detect_crtc = crtc;
 	    break;
-
-    if (i == xf86_config->num_crtc)
+	}
+	if (!supported_crtc)
+	    supported_crtc = crtc;
+    }
+    if (!detect_crtc)
+	detect_crtc = supported_crtc;
+    if (!detect_crtc)
 	return NULL;
 
-    crtc = xf86_config->crtc[i];
-
-    output->crtc = crtc;
+    output->crtc = detect_crtc;
     intel_output->load_detect_temp = TRUE;
 
-    return crtc;
+    return detect_crtc;
 }
 
 void
diff-tree 04130ac6b705aa49161fb6dae83ad0bdd76e89d9 (from 88f8b688e2316ae4a1f7485f0010ce90de54783a)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Jul 11 11:42:56 2007 +0800

    Fix i915 rendering for tiled buffer
    
    Make it to check fence register for dest buffer.

diff --git a/src/i915_render.c b/src/i915_render.c
index 2148883..9d5bc0a 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -373,12 +373,9 @@ i915_prepare_composite(int op, PicturePt
 	CARD32 ss2;
 
 	BEGIN_LP_RING(16);
-	/* color buffer
-	 * XXX: Need to add USE_FENCE if we ever tile the X Server's pixmaps or
-	 * visible screen.
-	 */
 	OUT_RING(_3DSTATE_BUF_INFO_CMD);
-	OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch));
+	OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_USE_FENCE|
+		BUF_3D_PITCH(dst_pitch));
 	OUT_RING(BUF_3D_ADDR(dst_offset));
 
 	OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
diff-tree 88f8b688e2316ae4a1f7485f0010ce90de54783a (from bf831117b4659cc4f2774098dee938505f780a9b)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jul 9 12:56:13 2007 -0700

    Fix some physical address handling for >4GB addresses.
    
    The upper bits would have been inappropriately dropped on G33-class hardware,
    and on G965-class hardware in a 32-bit environment.  The only use of physical
    addresses on these should be for FBC, though, and FBC requires addresses
    below 4GB.  This is unresolved.

diff --git a/src/i830.h b/src/i830.h
index 8b6c5e6..409057c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -134,7 +134,7 @@ struct _i830_memory {
      * Physical (or more properly, bus) address of the allocation.
      * Only set if requested during allocation.
      */
-    unsigned long bus_addr;
+    uint64_t bus_addr;
     /** AGP memory handle */
     int key;
     /**
@@ -235,7 +235,7 @@ typedef struct _I830CrtcPrivateRec {
     /* Physical or virtual addresses of the cursor for setting in the cursor
      * registers.
      */
-    unsigned long cursor_addr;
+    uint64_t cursor_addr;
     unsigned long cursor_argb_addr;
     Bool	cursor_is_argb;
 } I830CrtcPrivateRec, *I830CrtcPrivatePtr;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index a589738..b38a5df 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -319,9 +319,9 @@ i830_allocator_init(ScrnInfoPtr pScrn, u
  * physical address.
  *
  * \return physical address if successful.
- * \return (unsigned long)-1 if unsuccessful.
+ * \return (uint64_t)-1 if unsuccessful.
  */
-static unsigned long
+static uint64_t
 i830_get_gtt_physical(ScrnInfoPtr pScrn, unsigned long offset)
 {
     I830Ptr pI830 = I830PTR(pScrn);
@@ -334,8 +334,11 @@ i830_get_gtt_physical(ScrnInfoPtr pScrn,
     gttentry = INGTT(offset / 1024);
 
     /* Mask out these reserved bits on this hardware. */
-    if (!IS_I965G(pI830))
+    if (!IS_I9XX(pI830) || IS_I915G(pI830) || IS_I915GM(pI830) ||
+	IS_I945G(pI830) || IS_I945GM(pI830))
+    {
 	gttentry &= ~PTE_ADDRESS_MASK_HIGH;
+    }
 
     /* If it's not a mapping type we know, then bail. */
     if ((gttentry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED &&
@@ -346,19 +349,10 @@ i830_get_gtt_physical(ScrnInfoPtr pScrn,
 		   (unsigned int)(gttentry & PTE_MAPPING_TYPE_MASK));
 	return -1;
     }
-    /* If we can't represent the address with an unsigned long, bail. */
-    if (sizeof(unsigned long) == 4 &&
-	(gttentry & PTE_ADDRESS_MASK_HIGH) != 0)
-    {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		   "High memory PTE (0x%08x) on 32-bit system\n",
-		   (unsigned int)gttentry);
-	return -1;
-    }
     assert((gttentry & PTE_VALID) != 0);
 
     return (gttentry & PTE_ADDRESS_MASK) |
-	(gttentry & PTE_ADDRESS_MASK_HIGH << (32 - 4));
+	((uint64_t)(gttentry & PTE_ADDRESS_MASK_HIGH) << (32 - 4));
 }
 
 /**
@@ -366,14 +360,15 @@ i830_get_gtt_physical(ScrnInfoPtr pScrn,
  * physical address.
  *
  * \return physical address if successful.
- * \return (unsigned long)-1 if unsuccessful.
+ * \return (uint64_t)-1 if unsuccessful.
  */
-static unsigned long
+static uint64_t
 i830_get_stolen_physical(ScrnInfoPtr pScrn, unsigned long offset,
 			 unsigned long size)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    unsigned long physical, scan;
+    uint64_t physical;
+    unsigned long scan;
 
     /* Check that the requested region is within stolen memory. */
     if (offset + size >= pI830->stolen_size)
@@ -387,11 +382,12 @@ i830_get_stolen_physical(ScrnInfoPtr pSc
      * contiguously.
      */
     for (scan = offset + 4096; scan < offset + size; scan += 4096) {
-	unsigned long scan_physical = i830_get_gtt_physical(pScrn, scan);
+	uint64_t scan_physical = i830_get_gtt_physical(pScrn, scan);
 
 	if ((scan - offset) != (scan_physical - physical)) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "Non-contiguous GTT entries: (%ld,%ld) vs (%ld,%ld)\n",
+		       "Non-contiguous GTT entries: (%ld,0x16%llx) vs "
+		       "(%ld,0x%16llx)\n",
 		       scan, scan_physical, offset, physical);
 	    return -1;
 	}
@@ -444,7 +440,7 @@ i830_allocate_aperture(ScrnInfoPtr pScrn
 	    mem->bus_addr = i830_get_stolen_physical(pScrn, mem->offset,
 						     mem->size);
 
-	    if (mem->bus_addr == ((unsigned long)-1)) {
+	    if (mem->bus_addr == ((uint64_t)-1)) {
 		/* Move the start of the allocation to just past the end of
 		 * stolen memory.
 		 */
@@ -498,11 +494,15 @@ i830_allocate_agp_memory(ScrnInfoPtr pSc
 
     size = mem->size - (mem->agp_offset - mem->offset);
 
-    if (flags & NEED_PHYSICAL_ADDR)
+    if (flags & NEED_PHYSICAL_ADDR) {
+	unsigned long agp_bus_addr;
+
 	mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2,
-					  &mem->bus_addr);
-    else
+					  &agp_bus_addr);
+	mem->bus_addr = agp_bus_addr;
+    } else {
 	mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
+    }
     if (mem->key == -1 || ((flags & NEED_PHYSICAL_ADDR) && mem->bus_addr == 0))
     {
 	return FALSE;
@@ -688,7 +688,8 @@ i830_describe_allocations(ScrnInfoPtr pS
 			   mem->size / 1024);
 	} else {
 	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
-			   "%s0x%08lx-0x%08lx: %s (%ld kB, 0x%08lx physical)\n",
+			   "%s0x%08lx-0x%08lx: %s "
+			   "(%ld kB, 0x%16llx physical)\n",
 			   prefix,
 			   mem->offset, mem->end - 1, mem->name,
 			   mem->size / 1024, mem->bus_addr);
@@ -956,9 +957,13 @@ i830_allocate_cursor_buffers(ScrnInfoPtr
 	unsigned long cursor_offset_base = pI830->cursor_mem->offset;
 	unsigned long cursor_addr_base, offset = 0;
 
-	if (pI830->CursorNeedsPhysical)
-	    cursor_addr_base = pI830->cursor_mem->bus_addr;
-	else
+	if (pI830->CursorNeedsPhysical) {
+	    /* On any hardware that requires physical addresses for cursors,
+	     * the PTEs don't support memory above 4GB, so we can safely
+	     * ignore the top 32 bits of cursor_mem->bus_addr.
+	     */
+	    cursor_addr_base = (unsigned long)pI830->cursor_mem->bus_addr;
+	} else
 	    cursor_addr_base = pI830->cursor_mem->offset;
 
 	/* Set up the offsets for our cursors in each CRTC. */
diff-tree bf831117b4659cc4f2774098dee938505f780a9b (from b426866fe1be2ad3861559beff69186379a6afad)
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Sat Jul 7 10:15:32 2007 -0700

    FBC fixes:
      - allow FBC and Tiling to be forced off if configured to do so
      - only touch FBC registers if pI830->fb_compression is true

diff --git a/src/i830_display.c b/src/i830_display.c
index 853f4e4..f3b5c50 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -747,7 +747,7 @@ i830_disable_fb_compression(xf86CrtcPtr 
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
     uint32_t fbc_ctl;
-    char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';;
+    char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
 
     /* Disable compression */
     fbc_ctl = INREG(FBC_CONTROL);
@@ -764,7 +764,8 @@ static void
 i830_crtc_prepare (xf86CrtcPtr crtc)
 {
     /* Temporarily turn off FB compression during modeset */
-    i830_disable_fb_compression(crtc);
+    if (i830_use_fb_compression(crtc))
+        i830_disable_fb_compression(crtc);
     crtc->funcs->dpms (crtc, DPMSModeOff);
 }
 
diff --git a/src/i830_driver.c b/src/i830_driver.c
index dcbed22..51a17f0 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1753,10 +1753,12 @@ SaveHWState(ScrnInfoPtr pScrn)
    vgaRegPtr vgaReg = &hwp->SavedReg;
    int i;
 
-   pI830->saveFBC_CFB_BASE = INREG(FBC_CFB_BASE);
-   pI830->saveFBC_LL_BASE = INREG(FBC_LL_BASE);
-   pI830->saveFBC_CONTROL2 = INREG(FBC_CONTROL2);
-   pI830->saveFBC_CONTROL = INREG(FBC_CONTROL);
+   if (pI830->fb_compression) {
+       pI830->saveFBC_CFB_BASE = INREG(FBC_CFB_BASE);
+       pI830->saveFBC_LL_BASE = INREG(FBC_LL_BASE);
+       pI830->saveFBC_CONTROL2 = INREG(FBC_CONTROL2);
+       pI830->saveFBC_CONTROL = INREG(FBC_CONTROL);
+   }
 
    /* Save video mode information for native mode-setting. */
    pI830->saveDSPACNTR = INREG(DSPACNTR);
@@ -1982,10 +1984,12 @@ RestoreHWState(ScrnInfoPtr pScrn)
    OUTREG(SWF31, pI830->saveSWF[15]);
    OUTREG(SWF32, pI830->saveSWF[16]);
 
-   OUTREG(FBC_CFB_BASE, pI830->saveFBC_CFB_BASE);
-   OUTREG(FBC_LL_BASE, pI830->saveFBC_LL_BASE);
-   OUTREG(FBC_CONTROL2, pI830->saveFBC_CONTROL2);
-   OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL);
+   if (pI830->fb_compression) {
+       OUTREG(FBC_CFB_BASE, pI830->saveFBC_CFB_BASE);
+       OUTREG(FBC_LL_BASE, pI830->saveFBC_LL_BASE);
+       OUTREG(FBC_CONTROL2, pI830->saveFBC_CONTROL2);
+       OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL);
+   }
 
    vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
    vgaHWLock(hwp);
@@ -2320,14 +2324,19 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       pI830->CacheLines = -1;
    }
 
-   /* Enable tiling by default where supported or if the user forced it on */
+   /* Enable tiling by default where supported */
    if (i830_tiling_supported(pI830))
        pI830->tiling = TRUE;
    else
        pI830->tiling = FALSE;
 
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_TILING, FALSE))
-       pI830->tiling = TRUE;
+   /* Allow user override if they set a value */
+   if (xf86IsOptionSet(pI830->Options, OPTION_TILING)) {
+       if (xf86ReturnOptValBool(pI830->Options, OPTION_TILING, FALSE))
+	   pI830->tiling = TRUE;
+       else
+	   pI830->tiling = FALSE;
+   }
 
    /* Enable FB compression if possible */
    if (i830_fb_compression_supported(pI830))
@@ -2335,8 +2344,13 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
    else
        pI830->fb_compression = FALSE;
 
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE))
-       pI830->fb_compression = TRUE;
+   /* Again, allow user override if set */
+   if (xf86IsOptionSet(pI830->Options, OPTION_FBC)) {
+       if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE))
+	   pI830->fb_compression = TRUE;
+       else
+	   pI830->fb_compression = FALSE;
+   }
 
    if (pI830->fb_compression) {
        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression enabled, "
diff-tree b426866fe1be2ad3861559beff69186379a6afad (from 377c58373daa6bef5d37ead2b6f9a769a905b6fa)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 20:48:40 2007 -0700

    Fix manpage to reflect default behavior.

diff --git a/man/intel.man b/man/intel.man
index 8bd3f28..33dc319 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -80,12 +80,12 @@ This option controls whether the framebu
 If possible, the front buffer will be allocated in a tiled format and compressed
 periodically to save memory bandwidth and power.
 This option is only available on mobile chipsets.
-Default: disabled.
+Default: enabled on supported configurations.
 .TP
 .BI "Option \*qTiling\*q \*q" boolean \*q
 This option controls whether memory buffers are allocated in tiled mode.  In
 many cases (especially for complex rendering), tiling can improve performance.
-Default: enabled.
+Default: enabled on supported configurations.
 .TP
 .BI "Option \*qDRI\*q \*q" boolean \*q
 Disable or enable DRI support.


More information about the xorg-commit mailing list