xf86-video-intel: src/i830_crt.c src/i830_display.c src/i830_dvo.c src/i830_tv.c

Keith Packard keithp at kemper.freedesktop.org
Sat Jun 30 12:46:25 PDT 2007


 src/i830_crt.c     |   36 +++++++++++++++++++++++++++---------
 src/i830_display.c |   13 +++++++++++--
 src/i830_dvo.c     |    4 ++--
 src/i830_tv.c      |    7 ++++++-
 4 files changed, 46 insertions(+), 14 deletions(-)

New commits:
diff-tree 1e2e301348b4168aeed38b3fdc6b0e43d5678a86 (from 11862c2e1f23b77b56d7bd8b384579b5e3ae377b)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Sat Jun 30 12:45:24 2007 -0700

    Fix load detection to use border region instead of blanking.
    
    Make sure there is some border area to use by changing how the pipe is
    configured, then pick a scanline in the middle of the border for load
    detection. This lets the load detect code use an active pipe instead of
    requiring an idle one.

diff --git a/src/i830_crt.c b/src/i830_crt.c
index d9f4ee6..6d70f39 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -201,15 +201,16 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	    i830_crtc = I830CrtcPrivate(crtc);
-    I830OutputPrivatePtr    intel_output = output->driver_private;
     CARD32		    save_bclrpat;
     CARD32		    save_vtotal;
     CARD32		    vtotal, vactive;
     CARD32		    vsample;
+    CARD32		    vblank, vblank_start, vblank_end;
     CARD32		    dsl;
     CARD8		    st00;
     int			    bclrpat_reg, pipeconf_reg, pipe_dsl_reg;
     int			    vtotal_reg;
+    int			    vblank_reg;
     int			    pipe = i830_crtc->pipe;
     int			    count, detect;
     Bool		    present;
@@ -218,6 +219,7 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
     {
 	bclrpat_reg = BCLRPAT_A;
 	vtotal_reg = VTOTAL_A;
+	vblank_reg = VBLANK_A;
 	pipeconf_reg = PIPEACONF;
 	pipe_dsl_reg = PIPEA_DSL;
     }
@@ -225,18 +227,26 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
     {
 	bclrpat_reg = BCLRPAT_B;
 	vtotal_reg = VTOTAL_B;
+	vblank_reg = VBLANK_B;
 	pipeconf_reg = PIPEBCONF;
 	pipe_dsl_reg = PIPEB_DSL;
     }
 
     save_bclrpat = INREG(bclrpat_reg);
     save_vtotal = INREG(vtotal_reg);
+    vblank = INREG(vblank_reg);
+    
+    vtotal = ((save_vtotal >> 16) & 0xfff) + 1;
+    vactive = (save_vtotal & 0x7ff) + 1;
 
-    vtotal = (save_vtotal >> 16) & 0xfff;
-    vactive = save_vtotal & 0x7ff;
+    vblank_start = (vblank & 0xfff) + 1;
+    vblank_end = ((vblank >> 16) & 0xfff) + 1;
     
-    /* sample the middle of the blanking interval */
-    vsample = ((vtotal - 3) + (vactive)) >> 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);
@@ -271,8 +281,6 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
      * the screen
      */
     present = detect * 4 > count * 3;
-    xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "present: %s (%d of %d) at %ld desired %ld temp %d\n",
-		present ? "TRUE" : "FALSE", detect, count, dsl, vsample, intel_output->load_detect_temp);
     return present;
 }
 
@@ -341,11 +349,16 @@ i830_crt_detect(xf86OutputPtr output)
 	Bool			connected;
 	I830OutputPrivatePtr	intel_output = output->driver_private;
 	
-	if (intel_output->load_detect_temp)
+	if (!crtc->enabled)
 	{
 	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
 	    xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
 	}
+	else if (intel_output->load_detect_temp)
+	{
+	    output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
+	    output->funcs->commit (output);
+	}
 	connected = i830_crt_detect_load (crtc, output);
 
 	i830ReleaseLoadDetectPipe (output);
@@ -384,6 +397,7 @@ i830_crt_init(ScrnInfoPtr pScrn)
 {
     xf86OutputPtr	    output;
     I830OutputPrivatePtr    i830_output;
+    I830Ptr		    pI830 = I830PTR(pScrn);
 
     output = xf86OutputCreate (pScrn, &i830_crt_output_funcs, "VGA");
     if (!output)
@@ -395,7 +409,11 @@ i830_crt_init(ScrnInfoPtr pScrn)
 	return;
     }
     i830_output->type = I830_OUTPUT_ANALOG;
-    i830_output->pipe_mask = ((1 << 0) | (1 << 1));
+    /* i830 (almador) cannot place the analog adaptor on pipe B */
+    if (IS_I830(pI830))
+	i830_output->pipe_mask = (1 << 0);
+    else
+	i830_output->pipe_mask = ((1 << 0) | (1 << 1));
     i830_output->clone_mask = ((1 << I830_OUTPUT_ANALOG) |
 			       (1 << I830_OUTPUT_DVO_TMDS));
     
diff --git a/src/i830_display.c b/src/i830_display.c
index 16ef2cc..aba86ae 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1054,6 +1054,14 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	((adjusted_mode->CrtcHSyncEnd - 1) << 16));
     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) |
@@ -1322,7 +1330,7 @@ i830GetLoadDetectPipe(xf86OutputPtr outp
 	return output->crtc;
 
     for (i = 0; i < xf86_config->num_crtc; i++)
-	if (!xf86CrtcInUse (xf86_config->crtc[i]))
+	if (output->possible_crtcs & (1 << i))
 	    break;
 
     if (i == xf86_config->num_crtc)
@@ -1344,9 +1352,10 @@ i830ReleaseLoadDetectPipe(xf86OutputPtr 
     
     if (intel_output->load_detect_temp) 
     {
-	output->crtc->enabled = FALSE;
+	xf86CrtcPtr crtc = output->crtc;
 	output->crtc = NULL;
 	intel_output->load_detect_temp = FALSE;
+	crtc->enabled = xf86CrtcInUse (crtc);
 	xf86DisableUnusedFunctions(pScrn);
     }
 }
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 2521ee3..cb461d7 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -462,13 +462,13 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 					  "TMDS");
 		break;
 	    case I830_OUTPUT_DVO_LVDS:
-		intel_output->pipe_mask = (1 << 1);
+		intel_output->pipe_mask = ((1 << 0) | (1 << 1));
 		intel_output->clone_mask = (1 << I830_OUTPUT_DVO_LVDS);
 		output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
 					  "LVDS");
 		break;
 	    case I830_OUTPUT_DVO_TVOUT:
-		intel_output->pipe_mask = (1 << 1);
+		intel_output->pipe_mask = ((1 << 0) | (1 << 1));
 		intel_output->clone_mask = (1 << I830_OUTPUT_DVO_TVOUT);
 		output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
 					  "TV");
diff --git a/src/i830_tv.c b/src/i830_tv.c
index b95986f..1c818ba 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1357,13 +1357,18 @@ i830_tv_detect(xf86OutputPtr output)
     crtc = i830GetLoadDetectPipe (output);
     if (crtc)
     {
-        if (intel_output->load_detect_temp)
+	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);
     }


More information about the xorg-commit mailing list