xf86-video-intel: Branch 'modesetting' - 12 commits - src/i810_reg.h src/i830_bios.c src/i830_crt.c src/i830_cursor.c src/i830_display.c src/i830_driver.c src/i830.h src/i830_randr.c src/i830_sdvo.c

Keith Packard keithp at kemper.freedesktop.org
Thu Nov 9 06:29:58 EET 2006


 src/i810_reg.h     |   17 ++++++-
 src/i830.h         |    5 --
 src/i830_bios.c    |    9 ++--
 src/i830_crt.c     |    8 +++
 src/i830_cursor.c  |   12 ++---
 src/i830_display.c |  114 +++++++++++++++++++++++++++--------------------------
 src/i830_driver.c  |   77 +++++++++++++----------------------
 src/i830_randr.c   |    6 +-
 src/i830_sdvo.c    |    9 +++-
 9 files changed, 132 insertions(+), 125 deletions(-)

New commits:
diff-tree 81bace0c316c3ed80201a34eca533254d12cd193 (from parents)
Merge: 713c5b0899428edfea7cea0780244488115dbe1d beb89163d73376e70870e6e2a6b19863f3a058b1
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Wed Nov 8 20:23:20 2006 -0800

    Merge branch 'modesetting-keithp' into modesetting
    
    Conflicts in PipeSetMode were resolved to use the keithp changes
    that pushed more modesetting stuff into the per-pipe function.
    
    Switched availablePipes to num_pipes.
    
    Used modesetting default output configuration.

diff --cc src/i830_display.c
index c81f454,6804a4d..3603660
@@@ -375,16 -375,27 +375,32 @@@
  }
  
  /**
+  * Return whether any outputs are connected to the specified pipe
+  */
+ 
 -static Bool
++Bool
+ i830PipeInUse (ScrnInfoPtr pScrn, int pipe)
+ {
+     I830Ptr pI830 = I830PTR(pScrn);
+     int	i;
+     
+     for (i = 0; i < pI830->num_outputs; i++)
 -	if (!pI830->output[i].disabled && pI830->output[i].pipe == pipe)
++	if (pI830->output[i].enabled && pI830->output[i].pipe == pipe)
+ 	    return TRUE;
+     return FALSE;
+ }
+ 
+ /**
 - * Sets the given video mode on the given pipe.  Assumes that plane A feeds
 - * pipe A, and plane B feeds pipe B.  Should not affect the other planes/pipes.
 + * Sets the given video mode on the given pipe.
 + *
 + * Plane A is always output to pipe A, and plane B to pipe B.  The plane
 + * will not be enabled if plane_enable is FALSE, which is used for
 + * load detection, when something else will be output to the pipe other than
 + * display data.
   */
  Bool
 -i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
 +i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
 +		Bool plane_enable)
  {
      I830Ptr pI830 = I830PTR(pScrn);
      I830PipePtr pI830Pipe = &pI830->pipes[pipe];
@@@ -417,10 -432,21 +437,21 @@@
      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested pix clock: %d\n",
  	       pMode->Clock);
  
 -    pI830->pipes[pipe].planeEnabled = i830PipeInUse (pScrn, pipe);
++    pI830->pipes[pipe].enabled = i830PipeInUse (pScrn, pipe);
+     
 -    if (!pI830->pipes[pipe].planeEnabled)
++    if (!pI830->pipes[pipe].enabled)
+ 	return TRUE;
+ 
+ #ifdef XF86DRI
+     didLock = I830DRILock(pScrn);
+ #endif
+     
      for (i = 0; i < pI830->num_outputs; i++) {
 -	if (pI830->output[i].pipe != pipe || pI830->output[i].disabled)
 +	if (pI830->output[i].pipe != pipe || !pI830->output[i].enabled)
  	    continue;
  
+ 	pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);
+ 	
  	switch (pI830->output[i].type) {
  	case I830_OUTPUT_LVDS:
  	    is_lvds = TRUE;
@@@ -666,21 -704,21 +705,21 @@@
  i830DisableUnusedFunctions(ScrnInfoPtr pScrn)
  {
      I830Ptr pI830 = I830PTR(pScrn);
-     int i, pipe;
 -    int i;
++    int output, pipe;
  
      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling unused functions\n");
  
--    for (i = 0; i < pI830->num_outputs; i++) {
- 	if (!pI830->output[i].enabled)
- 	    pI830->output[i].dpms(pScrn, &pI830->output[i], DPMSModeOff);
 -	if (pI830->output[i].disabled)
 -	    pI830->output[i].dpms(pScrn, &pI830->output[i], DPMSModeOff);
++    for (output = 0; output < pI830->num_outputs; output++) {
++	if (!pI830->output[output].enabled)
++	    pI830->output[output].dpms(pScrn, &pI830->output[output], DPMSModeOff);
      }
  
      /* Now, any unused plane, pipe, and DPLL (FIXME: except for DVO, i915
       * internal TV) should have no outputs trying to pull data out of it, so
       * we're ready to turn those off.
       */
-     for (pipe = 0; pipe < pI830->availablePipes; pipe++) {
 -    for (i = 0; i < pI830->num_pipes; i++) {
 -	I830PipePtr pI830Pipe = &pI830->pipes[i];
++    for (pipe = 0; pipe < pI830->num_pipes; pipe++) {
 +	I830PipePtr pI830Pipe = &pI830->pipes[pipe];
  	int	    dspcntr_reg = pipe == 0 ? DSPACNTR : DSPBCNTR;
  	int	    pipeconf_reg = pipe == 0 ? PIPEACONF : PIPEBCONF;
  	int	    dpll_reg = pipe == 0 ? DPLL_A : DPLL_B;
@@@ -751,22 -770,9 +771,11 @@@
  
      DPRINTF(PFX, "i830SetMode\n");
  
- #ifdef XF86DRI
-     didLock = I830DRILock(pScrn);
- #endif
- 
-     for (i = 0; i < pI830->availablePipes; i++)
- 	pI830->pipes[i].enabled = i830PipeInUse (pScrn, i);
- 
-     for (i = 0; i < pI830->num_outputs; i++)
- 	pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);
- 
-     for (i = 0; i < pI830->availablePipes; i++)
+     for (i = 0; i < pI830->num_pipes; i++)
      {
- 	if (pI830->pipes[i].enabled)
- 	    ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, i,
- 								pMode),
- 				 i, TRUE);
 -	ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, i, pMode), i);
++	ok = i830PipeSetMode(pScrn, 
++			     i830PipeFindClosestMode(pScrn, i, pMode), 
++			     i, TRUE);
  	if (!ok)
  	    goto done;
      }
@@@ -822,34 -823,14 +826,34 @@@
  
      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output configuration:\n");
  
-     for (i = 0; i < pI830->availablePipes; i++) {
+     for (i = 0; i < pI830->num_pipes; i++) {
  	CARD32 dspcntr = INREG(DSPACNTR + (DSPBCNTR - DSPACNTR) * i);
 +	CARD32 pipeconf = INREG(PIPEACONF + (PIPEBCONF - PIPEACONF) * i);
 +	Bool hw_plane_enable = (dspcntr & DISPLAY_PLANE_ENABLE) != 0;
 +	Bool hw_pipe_enable = (pipeconf & PIPEACONF_ENABLE) != 0;
  
  	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 +		   "  Pipe %c is %s\n",
 +		   'A' + i, pI830->pipes[i].enabled ? "on" : "off");
 +	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
  		   "  Display plane %c is now %s and connected to pipe %c.\n",
  		   'A' + i,
 -		   pI830->pipes[i].planeEnabled ? "enabled" : "disabled",
 +		   pI830->pipes[i].enabled ? "enabled" : "disabled",
  		   dspcntr & DISPPLANE_SEL_PIPE_MASK ? 'B' : 'A');
 +	if (hw_pipe_enable != pI830->pipes[i].enabled) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 +		       "  Hardware claims pipe %c is %s while software "
 +		       "believes it is %s\n",
 +		       'A' + i, hw_pipe_enable ? "on" : "off",
 +		       pI830->pipes[i].enabled ? "on" : "off");
 +	}
 +	if (hw_plane_enable != pI830->pipes[i].enabled) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 +		       "  Hardware claims plane %c is %s while software "
 +		       "believes it is %s\n",
 +		       'A' + i, hw_plane_enable ? "on" : "off",
 +		       pI830->pipes[i].enabled ? "on" : "off");
 +	}
      }
  
      for (i = 0; i < pI830->num_outputs; i++) {
@@@ -879,91 -860,3 +883,91 @@@
  		   pI830->output[i].pipe == 0 ? 'A' : 'B');
      }
  }
 +
 +/**
 + * Get a pipe with a simple mode set on it for doing load-based monitor
 + * detection.
 + *
 + * It will be up to the load-detect code to adjust the pipe as appropriate for
 + * its requirements.  The pipe will be connected to no other outputs.
 + *
 + * Currently this code will only succeed if there is a pipe with no outputs
 + * configured for it.  In the future, it could choose to temporarily disable
 + * some outputs to free up a pipe for its use.
 + *
 + * \return monitor number, or -1 if no pipes are available.
 + */
 +int
 +i830GetLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    Bool pipe_available[MAX_DISPLAY_PIPES];
 +    int i;
 +    /* VESA 640x480x72Hz mode to set on the pipe */
 +    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 the output is not marked disabled, check if it's already assigned
 +     * to an active pipe, and is alone on that pipe.  If so, we're done.
 +     */
 +    if (output->enabled) {
 +	int pipeconf_reg = (output->pipe == 0) ? PIPEACONF : PIPEBCONF;
 +
 +	if (INREG(pipeconf_reg) & PIPEACONF_ENABLE) {
 +	    /* Actually, maybe we don't need to be all alone on the pipe.
 +	     * The worst that should happen is false positives.  Need to test,
 +	     * but actually fixing this during server startup is messy.
 +	     */
 +#if 0
 +	    for (i = 0; i < pI830->num_outputs; i++) {
 +		if (&pI830->output[i] != output &&
 +		    pI830->output[i].pipe == output->pipe)
 +		{
 +		    return -1;
 +		}
 +	    }
 +#endif
 +	    return output->pipe;
 +	}
 +    }
 +
-     for (i = 0; i < pI830->availablePipes; i++)
++    for (i = 0; i < pI830->num_pipes; i++)
 +	pipe_available[i] = i830PipeInUse(pScrn, i);
 +
-     for (i = 0; i < pI830->availablePipes; i++) {
++    for (i = 0; i < pI830->num_pipes; i++) {
 +	if (pipe_available[i])
 +	    break;
 +    }
 +
-     if (i == pI830->availablePipes) {
++    if (i == pI830->num_pipes) {
 +	return -1;
 +    }
 +    output->load_detect_temp = TRUE;
 +    output->pipe = i;
 +    output->enabled = TRUE;
 +
 +    I830xf86SetModeCrtc(&mode, INTERLACE_HALVE_V);
 +
 +    i830PipeSetMode(pScrn, &mode, i, FALSE);
 +
 +    return i;
 +}
 +
 +void
 +i830ReleaseLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output)
 +{
 +    if (output->load_detect_temp) {
 +	output->enabled = FALSE;
 +	i830DisableUnusedFunctions(pScrn);
 +	output->load_detect_temp = FALSE;
 +    }
 +}
diff --cc src/i830_driver.c
index ab0af4e,b632073..63c1fd2
@@@ -1359,23 -1341,15 +1341,22 @@@
  
        switch (pI830->output[i].type) {
        case I830_OUTPUT_LVDS:
- 	 /* LVDS must always be on pipe B. */
- 	 pI830->output[i].pipe = 1;
- 	 pI830->output[i].enabled = TRUE;
+ 	 /* LVDS must live on pipe B for two-pipe devices */
+ 	 pI830->output[i].pipe = pI830->num_pipes - 1;
  	 break;
        case I830_OUTPUT_ANALOG:
 -	 pI830->output[i].pipe = 0;
 -	 break;
        case I830_OUTPUT_DVO:
        case I830_OUTPUT_SDVO:
 -	 pI830->output[i].pipe = 1;
 +	 if (pI830->output[i].detect(pScrn, &pI830->output[i]) !=
 +	     OUTPUT_STATUS_DISCONNECTED) {
 +	    if (!i830PipeInUse(pScrn, 0)) {
 +	       pI830->output[i].pipe = 0;
 +	       pI830->output[i].enabled = TRUE;
 +	    } else if (!i830PipeInUse(pScrn, 1)) {
 +	       pI830->output[i].pipe = 1;
 +	       pI830->output[i].enabled = TRUE;
 +	    }
 +	 }
  	 break;
        default:
  	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled output type\n");
@@@ -1383,10 -1357,6 +1364,10 @@@
        }
     }
  
-    for (i = 0; i < pI830->availablePipes; i++) {
++   for (i = 0; i < pI830->num_pipes; i++) {
 +      pI830->pipes[i].enabled = i830PipeInUse(pScrn, i);
 +   }
 +
  #if 0
     pI830->CloneRefresh = 60; /* default to 60Hz */
     if (xf86GetOptValInteger(pI830->Options, OPTION_CLONE_REFRESH,
@@@ -3209,8 -3179,8 +3190,8 @@@
        pI830->AccelInfoRec->NeedToSync = FALSE;
     }
  
-    for (i = 0; i < pI830->availablePipes; i++)
+    for (i = 0; i < pI830->num_pipes; i++)
 -      if (pI830->pipes[i].planeEnabled)
 +      if (pI830->pipes[i].enabled)
  	 i830PipeSetBase(pScrn, i, x, y);
  }
  
diff-tree beb89163d73376e70870e6e2a6b19863f3a058b1 (from 997e8c9bb4235cab1fff4738387df9afcbea0a03)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sun Nov 5 19:06:45 2006 -0800

    DSPSURF must be page aligned. Place intra-screen offset in DSPBASE.
    
    DSPASURF/DSPBSURF can only take page aligned values, ignoring
    the lower order bits. So, place the offset for the output
    within the frame buffer in the DSPABASE/DSPBBASE registers instead.

diff --git a/src/i830_display.c b/src/i830_display.c
index 077e318..6804a4d 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -268,8 +268,8 @@ i830PipeSetBase(ScrnInfoPtr pScrn, int p
     }
 
     if (IS_I965G(pI830)) {
-	OUTREG(dspbase, 0);
-	OUTREG(dspsurf, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+	OUTREG(dspbase, ((y * pScrn->displayWidth + x) * pI830->cpp));
+	OUTREG(dspsurf, Start);
     } else {
 	OUTREG(dspbase, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
     }
diff-tree 997e8c9bb4235cab1fff4738387df9afcbea0a03 (from 5a355c72614ed77f2000e5ede45f3ff5990c79d9)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sun Nov 5 18:56:33 2006 -0800

    Don't allocate stuff in the first 256K of video memory (GATT?)
    
    Letting the ring buffer or other objects be allocated within the lowest
    portion of memory appears to trash some memory mapping data; I'm assuming
    this is the GATT table on the 965. Just marking this out of bounds for
    allocation fixes this problem.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 8d9712a..b632073 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -776,6 +776,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    pointer pVBEModule = NULL;
    Bool enable;
    const char *chipname;
+   int mem_skip;
 
    if (pScrn->numEntities != 1)
       return FALSE;
@@ -1092,8 +1093,15 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    /*
     * Get the pre-allocated (stolen) memory size.
     */
-   pI830->StolenMemory.Size = I830DetectMemory(pScrn);
-   pI830->StolenMemory.Start = 0;
+    
+   mem_skip = 0;
+   
+   /* On 965, it looks like the GATT table is inside the aperture? */
+   if (IS_I965G(pI830))
+      mem_skip = pI830->FbMapSize >> 10;
+    
+   pI830->StolenMemory.Size = I830DetectMemory(pScrn) - mem_skip;
+   pI830->StolenMemory.Start = mem_skip;
    pI830->StolenMemory.End = pI830->StolenMemory.Size;
 
    /* Find the maximum amount of agpgart memory available. */
@@ -1341,7 +1349,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 	 break;
       case I830_OUTPUT_DVO:
       case I830_OUTPUT_SDVO:
-	 pI830->output[i].pipe = 0;
+	 pI830->output[i].pipe = 1;
 	 break;
       default:
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled output type\n");
diff-tree 5a355c72614ed77f2000e5ede45f3ff5990c79d9 (from 68c3185046b27ab936ca6c92b924b443b3cd6fce)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sun Nov 5 18:51:28 2006 -0800

    Fix CRT output on 965 chipset.
    
    A few more register settings are needed to get CRT output working on the
    965 chipset, in particular the the SDVO/UDI clock multiplier register
    needed to get set to the default value (3). No, I really don't know what
    this does, but it does get the CRT running at a wide range of sizes.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index e126904..0ece7ee 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -800,11 +800,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 # define PLL_P1_DIVIDE_BY_TWO			(1 << 21) /* i830 */
 # define PLL_REF_INPUT_DREFCLK			(0 << 13)
 # define PLL_REF_INPUT_TVCLKINA			(1 << 13) /* i830 */
-# define PLL_REF_INPUT_TVCLKINBC		(2 << 13)
+# define PLL_REF_INPUT_TVCLKINBC		(2 << 13) /* SDVO TVCLKIN */
 # define PLLB_REF_INPUT_SPREADSPECTRUMIN	(3 << 13)
+# define PLL_LOAD_PULSE_PHASE_SHIFT		9
+/*
+ * Parallel to Serial Load Pulse phase selection.
+ * Selects the phase for the 10X DPLL clock for the PCIe
+ * digital display port. The range is 4 to 13; 10 or more
+ * is just a flip delay. The default is 6
+ */
+# define PLL_LOAD_PULSE_PHASE_MASK		(0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
 # define DISPLAY_RATE_SELECT_FPA1		(1 << 8)
 /**
- * SDVO multiplier for 945G/GM.
+ * SDVO multiplier for 945G/GM. Not used on 965.
  *
  * \sa DPLL_MD_UDI_MULTIPLIER_MASK
  */
@@ -848,7 +856,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
  */
 # define DPLL_MD_UDI_MULTIPLIER_MASK		0x00003f00
 # define DPLL_MD_UDI_MULTIPLIER_SHIFT		8
-/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. */
+/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. 
+ * This best be set to the default value (3) or the CRT won't work. No,
+ * I don't entirely understand what this does...
+ */
 # define DPLL_MD_VGA_UDI_MULTIPLIER_MASK	0x0000003f
 # define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT	0
 /** @} */
diff --git a/src/i830_crt.c b/src/i830_crt.c
index adc2d62..a7b0493 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -101,8 +101,14 @@ i830_crt_post_set_mode(ScrnInfoPtr pScrn
 		       DisplayModePtr pMode)
 {
     I830Ptr pI830 = I830PTR(pScrn);
+    int	    dpll_md_reg = (output->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
+    CARD32  adpa;
 
-    CARD32 adpa;
+    /*
+     * Not quite sure precisely what this does...
+     */
+    if (IS_I965G(pI830))
+	OUTREG(dpll_md_reg, 0x3 << DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT);
 
     adpa = ADPA_DAC_ENABLE;
 
diff --git a/src/i830_display.c b/src/i830_display.c
index 795c6f9..077e318 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -570,6 +570,8 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
 	    dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
 	    break;
 	}
+	if (IS_I965G(pI830))
+	    dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
     } else {
 	dpll |= (p1 - 2) << 16;
 	if (p2 == 4)
@@ -660,8 +662,14 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     if (((INREG(PFIT_CONTROL) >> 29) & 0x3) == pipe)
 	OUTREG(PFIT_CONTROL, 0);
 	   
+    /* 
+     * Docs say to not mess with this register. I think we will
+     * need to eventually though
+     */
+#if 0     
     OUTREG(DSPARB, (47 << 0) | (95 << 7));
-    
+#endif
+
     OUTREG(htot_reg, htot);
     OUTREG(hblank_reg, hblank);
     OUTREG(hsync_reg, hsync);
diff-tree 68c3185046b27ab936ca6c92b924b443b3cd6fce (from 15ef08046bcc3e746453301379f7c5d1bf929ee1)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sun Nov 5 13:30:32 2006 -0800

    Avoid crashing when disabling sdvo output. XXX

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index da61159..4d4817a 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -517,8 +517,8 @@ i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn
 {
     I830Ptr pI830 = I830PTR(pScrn);
     struct i830_sdvo_priv *dev_priv = output->dev_priv;
-    CARD16 width = mode->CrtcHDisplay;
-    CARD16 height = mode->CrtcVDisplay;
+    CARD16 width;
+    CARD16 height;
     CARD16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
     CARD16 h_sync_offset, v_sync_offset;
     struct i830_sdvo_dtd output_dtd;
@@ -526,6 +526,11 @@ i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn
 
     memset(&no_outputs, 0, sizeof(no_outputs));
 
+    if (!mode)
+	return;
+    width = mode->CrtcHDisplay;
+    height = mode->CrtcVDisplay;
+    
     /* do some mode translations */
     h_blank_len = mode->CrtcHBlankEnd - mode->CrtcHBlankStart;
     h_sync_len = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
diff-tree 15ef08046bcc3e746453301379f7c5d1bf929ee1 (from 7fcb555735a58e19ccc10875b211402983170a87)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sun Nov 5 13:29:56 2006 -0800

    Move remaining pipe mode setting logic to i830PipeSetMode

diff --git a/src/i830_display.c b/src/i830_display.c
index 6c5645b..795c6f9 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -375,6 +375,22 @@ i830PipeFindClosestMode(ScrnInfoPtr pScr
 }
 
 /**
+ * Return whether any outputs are connected to the specified pipe
+ */
+
+static Bool
+i830PipeInUse (ScrnInfoPtr pScrn, int pipe)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    int	i;
+    
+    for (i = 0; i < pI830->num_outputs; i++)
+	if (!pI830->output[i].disabled && pI830->output[i].pipe == pipe)
+	    return TRUE;
+    return FALSE;
+}
+
+/**
  * Sets the given video mode on the given pipe.  Assumes that plane A feeds
  * pipe A, and plane B feeds pipe B.  Should not affect the other planes/pipes.
  */
@@ -405,6 +421,10 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     int dspstride_reg = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
     int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
     int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
+    Bool ret = FALSE;
+#ifdef XF86DRI
+    Bool didLock = FALSE;
+#endif
 
     if (I830ModesEqual(&pI830Pipe->curMode, pMode))
 	return TRUE;
@@ -412,10 +432,21 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested pix clock: %d\n",
 	       pMode->Clock);
 
+    pI830->pipes[pipe].planeEnabled = i830PipeInUse (pScrn, pipe);
+    
+    if (!pI830->pipes[pipe].planeEnabled)
+	return TRUE;
+
+#ifdef XF86DRI
+    didLock = I830DRILock(pScrn);
+#endif
+    
     for (i = 0; i < pI830->num_outputs; i++) {
 	if (pI830->output[i].pipe != pipe || pI830->output[i].disabled)
 	    continue;
 
+	pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);
+	
 	switch (pI830->output[i].type) {
 	case I830_OUTPUT_LVDS:
 	    is_lvds = TRUE;
@@ -438,18 +469,18 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     if (is_lvds && (is_sdvo || is_dvo || is_tv || is_crt)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Can't enable LVDS and non-LVDS on the same pipe\n");
-	return FALSE;
+	goto done;
     }
     if (is_tv && (is_sdvo || is_dvo || is_crt || is_lvds)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Can't enable a TV and any other output on the same "
 		   "pipe\n");
-	return FALSE;
+	goto done;
     }
     if (pipe == 0 && is_lvds) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Can't support LVDS on pipe A\n");
-	return FALSE;
+	goto done;
     }
 
     htot = (pMode->CrtcHDisplay - 1) | ((pMode->CrtcHTotal - 1) << 16);
@@ -515,7 +546,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     if (!ok) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Couldn't find PLL settings for mode!\n");
-	return FALSE;
+	goto done;
     }
 
     dpll = DPLL_VCO_ENABLE | DPLL_VGA_MODE_DIS;
@@ -629,7 +660,6 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     if (((INREG(PFIT_CONTROL) >> 29) & 0x3) == pipe)
 	OUTREG(PFIT_CONTROL, 0);
 	   
-    OUTREG(PFIT_PGM_RATIOS, 0x10001000);
     OUTREG(DSPARB, (47 << 0) | (95 << 7));
     
     OUTREG(htot_reg, htot);
@@ -653,7 +683,13 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
 
     pI830Pipe->curMode = *pMode;
 
-    return TRUE;
+    ret = TRUE;
+done:
+#ifdef XF86DRI
+    if (didLock)
+	I830DRIUnlock(pScrn);
+#endif
+    return ret;
 }
 
 void
@@ -714,22 +750,6 @@ i830DisableUnusedFunctions(ScrnInfoPtr p
 }
 
 /**
- * Return whether any outputs are connected to the specified pipe
- */
-
-static Bool
-i830PipeInUse (ScrnInfoPtr pScrn, int pipe)
-{
-    I830Ptr pI830 = I830PTR(pScrn);
-    int	i;
-    
-    for (i = 0; i < pI830->num_outputs; i++)
-	if (!pI830->output[i].disabled && pI830->output[i].pipe == pipe)
-	    return TRUE;
-    return FALSE;
-}
-
-/**
  * This function configures the screens in clone mode on
  * all active outputs using a mode similar to the specified mode.
  */
@@ -738,28 +758,13 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayMo
 {
     I830Ptr pI830 = I830PTR(pScrn);
     Bool ok = TRUE;
-#ifdef XF86DRI
-    Bool didLock = FALSE;
-#endif
     int i;
 
     DPRINTF(PFX, "i830SetMode\n");
 
-#ifdef XF86DRI
-    didLock = I830DRILock(pScrn);
-#endif
-
-    for (i = 0; i < pI830->num_pipes; i++)
-	pI830->pipes[i].planeEnabled = i830PipeInUse (pScrn, i);
-
-    for (i = 0; i < pI830->num_outputs; i++)
-	pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);
-
     for (i = 0; i < pI830->num_pipes; i++)
     {
-	if (pI830->pipes[i].planeEnabled)
-	    ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, i, pMode),
-				 i);
+	ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, i, pMode), i);
 	if (!ok)
 	    goto done;
     }
@@ -797,11 +802,6 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayMo
    I830DRISetVBlankInterrupt (pScrn, TRUE);
 #endif
 done:
-#ifdef XF86DRI
-    if (didLock)
-	I830DRIUnlock(pScrn);
-#endif
-
     i830DumpRegs (pScrn);
     i830_sdvo_dump(pScrn);
     return ok;
diff-tree 7fcb555735a58e19ccc10875b211402983170a87 (from 3ab7f9693217d8fe993bdc94c376b219b0082961)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sat Nov 4 00:52:21 2006 -0800

    Rename availablePipes to num_pipes

diff --git a/src/i830.h b/src/i830.h
index 9e5c844..333b595 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -447,7 +447,7 @@ typedef struct _I830Rec {
    Bool checkDevices;
 
    /* [0] is Pipe A, [1] is Pipe B. */
-   int availablePipes;
+   int num_pipes;
    /* [0] is display plane A, [1] is display plane B. */
    I830PipeRec	  pipes[MAX_DISPLAY_PIPES];
    
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 4c6c3ca..adc2d62 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -174,12 +174,12 @@ i830_crt_detect_load(ScrnInfoPtr pScrn)
     int pipeconf_reg, bclrpat_reg, dpll_reg;
     int pipe;
 
-    for (pipe = 0; pipe < pI830->availablePipes; pipe++)
+    for (pipe = 0; pipe < pI830->num_pipes; pipe++)
 	if (!pI830->pipes[pipe].planeEnabled)
 	    break;
     
     /* No available pipes for load detection */
-    if (pipe == pI830->availablePipes)
+    if (pipe == pI830->num_pipes)
 	return FALSE;
     
     if (pipe == 0) {
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 6b0e58c..05e93fa 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -86,7 +86,7 @@ I830SetPipeCursorBase (ScrnInfoPtr pScrn
     int cursor_base = (pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE);
     I830MemRange *cursor_mem;
 
-    if (pipe >= pI830->availablePipes)
+    if (pipe >= pI830->num_pipes)
 	FatalError("Bad pipe number for cursor base setting\n");
 
     if (pI830->CursorIsARGB)
@@ -180,11 +180,11 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
    int i;
 
    DPRINTF(PFX, "I830InitHWCursor\n");
-   for (i = 0; i < pI830->availablePipes; i++) 
+   for (i = 0; i < pI830->num_pipes; i++) 
       pI830->pipes[i].cursorShown = FALSE;
    /* Initialise the HW cursor registers, leaving the cursor hidden. */
    if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
-      for (i = 0; i < pI830->availablePipes; i++)
+      for (i = 0; i < pI830->num_pipes; i++)
       {
 	 int   cursor_control = i == 0 ? CURSOR_A_CONTROL : CURSOR_B_CONTROL;
 	 temp = INREG(cursor_control);
@@ -484,7 +484,7 @@ I830SetCursorPosition(ScrnInfoPtr pScrn,
     x -= hotspotx;
     y -= hotspoty;
 
-    for (pipe = 0; pipe < pI830->availablePipes; pipe++)
+    for (pipe = 0; pipe < pI830->num_pipes; pipe++)
     {
 	I830PipePtr	pI830Pipe = &pI830->pipes[pipe];
 	DisplayModePtr	mode = &pI830Pipe->curMode;
@@ -550,7 +550,7 @@ I830ShowCursor(ScrnInfoPtr pScrn)
 	   pI830->CursorMemARGB->Physical, pI830->CursorMemARGB->Start);
 
     pI830->cursorOn = TRUE;
-    for (pipe = 0; pipe < pI830->availablePipes; pipe++)
+    for (pipe = 0; pipe < pI830->num_pipes; pipe++)
 	I830SetPipeCursor (pScrn, pipe, TRUE);
 }
 
@@ -563,7 +563,7 @@ I830HideCursor(ScrnInfoPtr pScrn)
    DPRINTF(PFX, "I830HideCursor\n");
 
    pI830->cursorOn = FALSE;
-    for (pipe = 0; pipe < pI830->availablePipes; pipe++)
+    for (pipe = 0; pipe < pI830->num_pipes; pipe++)
 	I830SetPipeCursor (pScrn, pipe, TRUE);
 }
 
diff --git a/src/i830_display.c b/src/i830_display.c
index c9b6b4d..6c5645b 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -673,7 +673,7 @@ i830DisableUnusedFunctions(ScrnInfoPtr p
      * internal TV) should have no outputs trying to pull data out of it, so
      * we're ready to turn those off.
      */
-    for (i = 0; i < pI830->availablePipes; i++) {
+    for (i = 0; i < pI830->num_pipes; i++) {
 	I830PipePtr pI830Pipe = &pI830->pipes[i];
 	int	    dspcntr_reg = pipe == 0 ? DSPACNTR : DSPBCNTR;
 	int	    pipeconf_reg = pipe == 0 ? PIPEACONF : PIPEBCONF;
@@ -749,13 +749,13 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayMo
     didLock = I830DRILock(pScrn);
 #endif
 
-    for (i = 0; i < pI830->availablePipes; i++)
+    for (i = 0; i < pI830->num_pipes; i++)
 	pI830->pipes[i].planeEnabled = i830PipeInUse (pScrn, i);
 
     for (i = 0; i < pI830->num_outputs; i++)
 	pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);
 
-    for (i = 0; i < pI830->availablePipes; i++)
+    for (i = 0; i < pI830->num_pipes; i++)
     {
 	if (pI830->pipes[i].planeEnabled)
 	    ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, i, pMode),
@@ -815,7 +815,7 @@ i830DescribeOutputConfiguration(ScrnInfo
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output configuration:\n");
 
-    for (i = 0; i < pI830->availablePipes; i++) {
+    for (i = 0; i < pI830->num_pipes; i++) {
 	CARD32 dspcntr = INREG(DSPACNTR + (DSPBCNTR - DSPACNTR) * i);
 
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 92c27af..8d9712a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -542,7 +542,7 @@ I830LoadPalette(ScrnInfoPtr pScrn, int n
    DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
    pI830 = I830PTR(pScrn);
 
-   for(p=0; p < pI830->availablePipes; p++) {
+   for(p=0; p < pI830->num_pipes; p++) {
       I830PipePtr pI830Pipe = &pI830->pipes[p];
 
       if (p == 0) {
@@ -1080,14 +1080,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    }
 
    if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G)
-      pI830->availablePipes = 1;
+      pI830->num_pipes = 1;
    else
    if (IS_MOBILE(pI830) || IS_I9XX(pI830))
-      pI830->availablePipes = 2;
+      pI830->num_pipes = 2;
    else
-      pI830->availablePipes = 1;
+      pI830->num_pipes = 1;
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n",
-	      pI830->availablePipes, pI830->availablePipes > 1 ? "s" : "");
+	      pI830->num_pipes, pI830->num_pipes > 1 ? "s" : "");
 
    /*
     * Get the pre-allocated (stolen) memory size.
@@ -1231,7 +1231,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
             } while (sub);
          }
     
-         if (pI830->availablePipes == 1 && pI830->MonType2 != PIPE_NONE) {
+         if (pI830->num_pipes == 1 && pI830->MonType2 != PIPE_NONE) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		    "Monitor 2 cannot be specified on single pipe devices\n");
             return FALSE;
@@ -1308,7 +1308,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 #endif
 
    if (xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) {
-      if (pI830->availablePipes == 1) {
+      if (pI830->num_pipes == 1) {
          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
  		 "Can't enable Clone Mode because this is a single pipe device\n");
          PreInitCleanup(pScrn);
@@ -1334,7 +1334,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       switch (pI830->output[i].type) {
       case I830_OUTPUT_LVDS:
 	 /* LVDS must live on pipe B for two-pipe devices */
-	 pI830->output[i].pipe = pI830->availablePipes - 1;
+	 pI830->output[i].pipe = pI830->num_pipes - 1;
 	 break;
       case I830_OUTPUT_ANALOG:
 	 pI830->output[i].pipe = 0;
@@ -2091,7 +2091,7 @@ SaveHWState(ScrnInfoPtr pScrn)
    temp = INREG(PIPEACONF);
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEACONF is 0x%08lx\n", 
 	      (unsigned long) temp);
-   if (pI830->availablePipes == 2) {
+   if (pI830->num_pipes == 2) {
       temp = INREG(PIPEBCONF);
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08lx\n", 
 		 (unsigned long) temp);
@@ -2123,7 +2123,7 @@ SaveHWState(ScrnInfoPtr pScrn)
       pI830->savePaletteA[i] = INREG(PALETTE_A + (i << 2));
    }
 
-   if(pI830->availablePipes == 2) {
+   if(pI830->num_pipes == 2) {
       pI830->savePIPEBCONF = INREG(PIPEBCONF);
       pI830->savePIPEBSRC = INREG(PIPEBSRC);
       pI830->saveDSPBCNTR = INREG(DSPBCNTR);
@@ -2234,7 +2234,7 @@ RestoreHWState(ScrnInfoPtr pScrn)
          OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]);
    }
 
-   if(pI830->availablePipes == 2) {
+   if(pI830->num_pipes == 2) {
       OUTREG(FPB0, pI830->saveFPB0);
       OUTREG(FPB1, pI830->saveFPB1);
       OUTREG(DPLL_B, pI830->saveDPLL_B);
@@ -3171,7 +3171,7 @@ i830AdjustFrame(int scrnIndex, int x, in
       pI830->AccelInfoRec->NeedToSync = FALSE;
    }
 
-   for (i = 0; i < pI830->availablePipes; i++)
+   for (i = 0; i < pI830->num_pipes; i++)
       if (pI830->pipes[i].planeEnabled)
 	 i830PipeSetBase(pScrn, i, x, y);
 }
@@ -3279,7 +3279,7 @@ I830EnterVT(int scrnIndex, int flags)
    SetHWOperatingState(pScrn);
 
    /* Mark that we'll need to re-set the mode for sure */
-   for (i = 0; i < pI830->availablePipes; i++)
+   for (i = 0; i < pI830->num_pipes; i++)
       memset(&pI830->pipes[i].curMode, 0, sizeof(pI830->pipes[i].curMode));
 
    if (!i830SetMode(pScrn, pScrn->currentMode))
@@ -3423,7 +3423,7 @@ I830SaveScreen(ScreenPtr pScreen, int mo
    DPRINTF(PFX, "I830SaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on));
 
    if (pScrn->vtSema) {
-      for (i = 0; i < pI830->availablePipes; i++) {
+      for (i = 0; i < pI830->num_pipes; i++) {
         if (i == 0) {
 	    ctrl = DSPACNTR;
 	    base = DSPABASE;
@@ -3474,7 +3474,7 @@ I830DisplayPowerManagementSet(ScrnInfoPt
       pI830->output[i].dpms(pScrn, &pI830->output[i], PowerManagementMode);
    }
 
-   for (i = 0; i < pI830->availablePipes; i++) {
+   for (i = 0; i < pI830->num_pipes; i++) {
       if (i == 0) {
          ctrl = DSPACNTR;
          base = DSPABASE;
diff --git a/src/i830_randr.c b/src/i830_randr.c
index afa1848..84727a6 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -752,7 +752,7 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
 	if (!RROutputSetClones (randrp->outputs[i], clones, nclone))
 	    return FALSE;
     }
-    for (i = 0; i < pI830->availablePipes; i++)
+    for (i = 0; i < pI830->num_pipes; i++)
 	I830RandRCrtcNotify (randrp->crtcs[i]);
     return TRUE;
 }
@@ -785,7 +785,7 @@ I830RandRCreateScreenResources12 (Screen
     /*
      * Create RandR resources, then probe them
      */
-    for (i = 0; i < pI830->availablePipes; i++)
+    for (i = 0; i < pI830->num_pipes; i++)
     {
 	randrp->crtcs[i] = RRCrtcCreate (pScreen, (void *) i);
 	RRCrtcGammaSetSize (randrp->crtcs[i], 256);
@@ -821,7 +821,7 @@ I830RandRCreateScreenResources12 (Screen
 				mmHeight);
     }
 
-    for (i = 0; i < pI830->availablePipes; i++)
+    for (i = 0; i < pI830->num_pipes; i++)
 	i830PipeSetBase(pScrn, i, 0, 0);
 
     return I830RandRSetInfo12 (pScreen);
diff-tree 3ab7f9693217d8fe993bdc94c376b219b0082961 (from e4bcec796e80e9fd66ab0c36394f5946915531f1)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sat Nov 4 00:46:18 2006 -0800

    Eliminate operatingDevices member and PIPE_* values.
    
    operatingDevices and MonType1/MonType2 duplicate information already stored
    in the device structures. Eliminate them and replace uses with direct
    references to the appropriate other data.

diff --git a/src/i830.h b/src/i830.h
index ea7f4c9..9e5c844 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -86,26 +86,6 @@ typedef struct _I830OutputRec I830Output
  * Paulo César Pereira de Andrade <pcpa at conectiva.com.br>.
  */
 
-#define PIPE_CRT_ID	0
-#define PIPE_TV_ID    	1
-#define PIPE_DFP_ID	2
-#define PIPE_LFP_ID	3
-#define PIPE_CRT2_ID	4
-#define PIPE_TV2_ID	5
-#define PIPE_DFP2_ID	6
-#define PIPE_LFP2_ID	7
-#define PIPE_NUM_ID	8
-
-#define PIPE_NONE	0<<0
-#define PIPE_CRT	1<<0
-#define PIPE_TV		1<<1
-#define PIPE_DFP	1<<2
-#define PIPE_LFP	1<<3
-#define PIPE_CRT2	1<<4
-#define PIPE_TV2	1<<5
-#define PIPE_DFP2	1<<6
-#define PIPE_LFP2	1<<7
-
 typedef struct _I830Rec *I830Ptr;
 
 typedef void (*I830WriteIndexedByteFunc)(I830Ptr pI830, IOADDRESS addr,
@@ -314,7 +294,9 @@ typedef struct _I830Rec {
    int CloneVDisplay;
 
    I830EntPtr entityPrivate;	
+#if 0
    int pipe, origPipe;
+#endif
    int init;
 
    unsigned int bufferOffset;		/* for I830SelectBuffer */
@@ -391,9 +373,6 @@ typedef struct _I830Rec {
    Bool CursorIsARGB;
    CursorPtr pCurs;
 
-   int MonType1;
-   int MonType2;
-
    DGAModePtr DGAModes;
    int numDGAModes;
    Bool DGAactive;
@@ -466,7 +445,6 @@ typedef struct _I830Rec {
    CARD32 saveSWF4;
 
    Bool checkDevices;
-   int operatingDevices;
 
    /* [0] is Pipe A, [1] is Pipe B. */
    int availablePipes;
@@ -660,6 +638,10 @@ extern Bool I830FixOffset(ScrnInfoPtr pS
 extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
 			char *name);
 
+/* i830_display.c */
+Bool
+i830PipeHasType (ScrnInfoPtr pScrn, int pipe, int type);
+
 /* i830_crt.c */
 void i830_crt_init(ScrnInfoPtr pScrn);
 
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 0225727..4c6c3ca 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -169,12 +169,19 @@ static Bool
 i830_crt_detect_load(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    CARD32 adpa, pipeconf;
+    CARD32 adpa, pipeconf, bclrpat;
     CARD8 st00;
     int pipeconf_reg, bclrpat_reg, dpll_reg;
     int pipe;
 
-    pipe = pI830->pipe;
+    for (pipe = 0; pipe < pI830->availablePipes; pipe++)
+	if (!pI830->pipes[pipe].planeEnabled)
+	    break;
+    
+    /* No available pipes for load detection */
+    if (pipe == pI830->availablePipes)
+	return FALSE;
+    
     if (pipe == 0) {
 	bclrpat_reg = BCLRPAT_A;
 	pipeconf_reg = PIPEACONF;
@@ -197,9 +204,10 @@ i830_crt_detect_load(ScrnInfoPtr pScrn)
 	       ((pipe == 1) ? ADPA_PIPE_B_SELECT : 0));
     }
 
-    /* Set the border color to red, green.  Maybe we should save/restore this
+    /* Set the border color to purple.  Maybe we should save/restore this
      * reg.
      */
+    bclrpat = INREG(bclrpat_reg);
     OUTREG(bclrpat_reg, 0x00500050);
 
     /* Force the border color through the active region */
@@ -210,6 +218,7 @@ i830_crt_detect_load(ScrnInfoPtr pScrn)
     st00 = pI830->readStandard(pI830, 0x3c2);
 
     /* Restore previous settings */
+    OUTREG(bclrpat_reg, bclrpat);
     OUTREG(pipeconf_reg, pipeconf);
     OUTREG(ADPA, adpa);
 
diff --git a/src/i830_display.c b/src/i830_display.c
index 8cb6660..c9b6b4d 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -61,6 +61,24 @@ i830PrintPll(char *prefix, int refclk, i
 }
 
 /**
+ * Returns whether any output on the specified pipe is an LVDS output
+ */
+Bool
+i830PipeHasType (ScrnInfoPtr pScrn, int pipe, int type)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    int	    i;
+
+    for (i = 0; i < pI830->num_outputs; i++)
+	if (!pI830->output[i].disabled && pI830->output[i].pipe == pipe)
+	{
+	    if (pI830->output[i].type == type)
+		return TRUE;
+	}
+    return FALSE;
+}
+
+/**
  * Returns whether the given set of divisors are valid for a given refclk with
  * the given outputs.
  *
@@ -68,7 +86,7 @@ i830PrintPll(char *prefix, int refclk, i
  * clk = refclk * (5 * m1 + m2) / n / (p1 * p2)
  */
 static Bool
-i830PllIsValid(ScrnInfoPtr pScrn, int outputs, int refclk, int m1, int m2,
+i830PllIsValid(ScrnInfoPtr pScrn, int pipe, int refclk, int m1, int m2,
 	       int n, int p1, int p2)
 {
     I830Ptr pI830 = I830PTR(pScrn);
@@ -87,7 +105,7 @@ i830PllIsValid(ScrnInfoPtr pScrn, int ou
 	max_n = 8;
 	min_p1 = 1;
 	max_p1 = 8;
-	if (outputs & PIPE_LCD_ACTIVE) {
+	if (i830PipeHasType (pScrn, pipe, I830_OUTPUT_LVDS)) {
 	    min_p = 7;
 	    max_p = 98;
 	} else {
@@ -153,7 +171,7 @@ i830PllIsValid(ScrnInfoPtr pScrn, int ou
  * clk = refclk * (5 * m1 + m2) / n / (p1 * p2)
  */
 static Bool
-i830FindBestPLL(ScrnInfoPtr pScrn, int outputs, int target, int refclk,
+i830FindBestPLL(ScrnInfoPtr pScrn, int pipe, int target, int refclk,
 		int *outm1, int *outm2, int *outn, int *outp1, int *outp2)
 {
     I830Ptr pI830 = I830PTR(pScrn);
@@ -170,7 +188,7 @@ i830FindBestPLL(ScrnInfoPtr pScrn, int o
 	max_n = 8;
 	min_p1 = 1;
 	max_p1 = 8;
-	if (outputs & PIPE_LCD_ACTIVE) {
+	if (i830PipeHasType (pScrn, pipe, I830_OUTPUT_LVDS)) {
 	    if (target < 200000) /* XXX: Is this the right cutoff? */
 		p2 = 14;
 	    else
@@ -203,7 +221,7 @@ i830FindBestPLL(ScrnInfoPtr pScrn, int o
 		for (p1 = min_p1; p1 <= max_p1; p1++) {
 		    int clock, this_err;
 
-		    if (!i830PllIsValid(pScrn, outputs, refclk, m1, m2, n,
+		    if (!i830PllIsValid(pScrn, pipe, refclk, m1, m2, n,
 					p1, p2)) {
 			continue;
 		    }
@@ -372,7 +390,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     Bool ok, is_sdvo = FALSE, is_dvo = FALSE;
     Bool is_crt = FALSE, is_lvds = FALSE, is_tv = FALSE;
     int refclk, pixel_clock;
-    int outputs, i;
+    int i;
     int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
     int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
     int fp_reg = (pipe == 0) ? FPA0 : FPB0;
@@ -388,11 +406,6 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
     int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
 
-    if (pipe == 0)
-	outputs = pI830->operatingDevices & 0xff;
-    else
-	outputs = (pI830->operatingDevices >> 8) & 0xff;
-
     if (I830ModesEqual(&pI830Pipe->curMode, pMode))
 	return TRUE;
 
@@ -497,7 +510,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     } else {
 	refclk = 48000;
     }
-    ok = i830FindBestPLL(pScrn, outputs, pixel_clock, refclk, &m1, &m2, &n,
+    ok = i830FindBestPLL(pScrn, pipe, pixel_clock, refclk, &m1, &m2, &n,
 			 &p1, &p2);
     if (!ok) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -701,6 +714,22 @@ i830DisableUnusedFunctions(ScrnInfoPtr p
 }
 
 /**
+ * Return whether any outputs are connected to the specified pipe
+ */
+
+static Bool
+i830PipeInUse (ScrnInfoPtr pScrn, int pipe)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    int	i;
+    
+    for (i = 0; i < pI830->num_outputs; i++)
+	if (!pI830->output[i].disabled && pI830->output[i].pipe == pipe)
+	    return TRUE;
+    return FALSE;
+}
+
+/**
  * This function configures the screens in clone mode on
  * all active outputs using a mode similar to the specified mode.
  */
@@ -720,8 +749,8 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayMo
     didLock = I830DRILock(pScrn);
 #endif
 
-    pI830->pipes[0].planeEnabled = (pI830->operatingDevices & 0xff) != 0;
-    pI830->pipes[1].planeEnabled = (pI830->operatingDevices & 0xff00) != 0;
+    for (i = 0; i < pI830->availablePipes; i++)
+	pI830->pipes[i].planeEnabled = i830PipeInUse (pScrn, i);
 
     for (i = 0; i < pI830->num_outputs; i++)
 	pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 1b75649..92c27af 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -382,88 +382,6 @@ I830ProbeDDC(ScrnInfoPtr pScrn, int inde
    ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
 }
 
-/*
- * Returns a string matching the device corresponding to the first bit set
- * in "device".  savedDevice is then set to device with that bit cleared.
- * Subsequent calls with device == -1 will use savedDevice.
- */
-
-static const char *displayDevices[] = {
-   "CRT",
-   "TV",
-   "DFP (digital flat panel)",
-   "LFP (local flat panel)",
-   "CRT2 (second CRT)",
-   "TV2 (second TV)",
-   "DFP2 (second digital flat panel)",
-   "LFP2 (second local flat panel)",
-   NULL
-};
-
-static const char *
-DeviceToString(int device)
-{
-   static int savedDevice = -1;
-   int bit = 0;
-   const char *name;
-
-   if (device == -1) {
-      device = savedDevice;
-      bit = 0;
-   }
-
-   if (device == -1)
-      return NULL;
-
-   while (displayDevices[bit]) {
-      if (device & (1 << bit)) {
-	 name = displayDevices[bit];
-	 savedDevice = device & ~(1 << bit);
-	 bit++;
-	 return name;
-      }
-      bit++;
-   }
-   return NULL;
-}
-
-static void
-PrintDisplayDeviceInfo(ScrnInfoPtr pScrn)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-   int pipe, n;
-   int displays;
-
-   DPRINTF(PFX, "PrintDisplayDeviceInfo\n");
-
-   displays = pI830->operatingDevices;
-   if (displays == -1) {
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		 "No active display devices.\n");
-      return;
-   }
-
-   /* Check for active devices connected to each display pipe. */
-   for (n = 0; n < pI830->availablePipes; n++) {
-      pipe = ((displays >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK);
-      if (pipe) {
-	 const char *name;
-
-	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		    "Currently active displays on Pipe %c:\n", PIPE_NAME(n));
-	 name = DeviceToString(pipe);
-	 do {
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t%s\n", name);
-	    name = DeviceToString(-1);
-	 } while (name);
-
-      } else {
-	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		    "No active displays on Pipe %c.\n", PIPE_NAME(n));
-      }
-   }
-}
-
 static int
 I830DetectMemory(ScrnInfoPtr pScrn)
 {
@@ -1242,9 +1160,10 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 
    I830PreInitDDC(pScrn);
 
-   pI830->MonType1 = PIPE_NONE;
-   pI830->MonType2 = PIPE_NONE;
-
+#if 0
+   /*
+    * This moves to generic RandR-based configuration code
+    */
    if ((s = xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT)) &&
       I830IsPrimary(pScrn)) {
       char *Mon1;
@@ -1329,7 +1248,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       else
 	 pI830->pipe = 1;
 
-      pI830->operatingDevices = (pI830->MonType2 << 8) | pI830->MonType1;
    } else if (I830IsPrimary(pScrn)) {
       /* Choose a default set of outputs to use based on what we've detected.
        *
@@ -1375,7 +1293,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 	 pI830->pipe = 0;
       else
 	 pI830->pipe = 1;
-      pI830->operatingDevices = (pI830->MonType2 << 8) | pI830->MonType1;
 
       if (pI830->MonType1 != 0 && pI830->MonType2 != 0) {
          xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
@@ -1384,11 +1301,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       }
    } else {
       I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
-      pI830->operatingDevices = pI8301->operatingDevices;
       pI830->pipe = !pI8301->pipe;
       pI830->MonType1 = pI8301->MonType1;
       pI830->MonType2 = pI8301->MonType2;
    }
+#endif
 
    if (xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) {
       if (pI830->availablePipes == 1) {
@@ -1408,38 +1325,23 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    }
 
 
-   /* Perform the pipe assignment of outputs.  This code shouldn't exist,
-    * but for now we're supporting the existing MonitorLayout configuration
-    * scheme.
+   /* Perform the pipe assignment of outputs. This is a kludge until
+    * we have better configuration support in the generic RandR code
     */
    for (i = 0; i < pI830->num_outputs; i++) {
       pI830->output[i].disabled = FALSE;
 
       switch (pI830->output[i].type) {
       case I830_OUTPUT_LVDS:
-	 if (pI830->MonType1 & PIPE_LFP)
-	    pI830->output[i].pipe = 0;
-	 else if (pI830->MonType2 & PIPE_LFP)
-	    pI830->output[i].pipe = 1;
-	 else
-	    pI830->output[i].disabled = TRUE;
+	 /* LVDS must live on pipe B for two-pipe devices */
+	 pI830->output[i].pipe = pI830->availablePipes - 1;
 	 break;
       case I830_OUTPUT_ANALOG:
-	 if (pI830->MonType1 & PIPE_CRT)
-	    pI830->output[i].pipe = 0;
-	 else if (pI830->MonType2 & PIPE_CRT)
-	    pI830->output[i].pipe = 1;
-	 else
-	    pI830->output[i].disabled = TRUE;
+	 pI830->output[i].pipe = 0;
 	 break;
       case I830_OUTPUT_DVO:
       case I830_OUTPUT_SDVO:
-	 if (pI830->MonType1 & PIPE_DFP)
-	    pI830->output[i].pipe = 0;
-	 else if (pI830->MonType2 & PIPE_DFP)
-	    pI830->output[i].pipe = 1;
-	 else
-	    pI830->output[i].disabled = TRUE;
+	 pI830->output[i].pipe = 0;
 	 break;
       default:
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled output type\n");
@@ -1447,8 +1349,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       }
    }
 
-   
-
+#if 0
    pI830->CloneRefresh = 60; /* default to 60Hz */
    if (xf86GetOptValInteger(pI830->Options, OPTION_CLONE_REFRESH,
 			    &(pI830->CloneRefresh))) {
@@ -1471,6 +1372,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
          return FALSE;
       }
    }
+#endif
 
    pI830->rotation = RR_Rotate_0;
    if ((s = xf86GetOptValString(pI830->Options, OPTION_ROTATE))) {
@@ -1646,8 +1548,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       }
    }
 
-   PrintDisplayDeviceInfo(pScrn);
-
+#if 0
    if (xf86IsEntityShared(pScrn->entityList[0])) {
       if (!I830IsPrimary(pScrn)) {
 	 /* This could be made to work with a little more fiddling */
@@ -1663,6 +1564,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       xf86DrvMsg(pScrn->scrnIndex, from, "Display is using Pipe %s\n",
 		pI830->pipe ? "B" : "A");
    }
+#endif
 
    /* Alloc our pointers for the primary head */
    if (I830IsPrimary(pScrn)) {
@@ -2872,17 +2774,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
    }
 #endif
 
-   if (xf86IsEntityShared(pScrn->entityList[0])) {
-      /* PreInit failed on the second head, so make sure we turn it off */
-      if (I830IsPrimary(pScrn) && !pI830->entityPrivate->pScrn_2) {
-         if (pI830->pipe == 0) {
-            pI830->operatingDevices &= 0xFF;
-         } else {
-            pI830->operatingDevices &= 0xFF00;
-         }
-      }
-   }
-
    pI830->starting = TRUE;
 
    /* Alloc our pointers for the primary head */
@@ -3269,6 +3160,7 @@ i830AdjustFrame(int scrnIndex, int x, in
 {
    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
    I830Ptr pI830 = I830PTR(pScrn);
+   int i;
 
    DPRINTF(PFX, "i830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
 	   x, pI830->xoffset, y, pI830->yoffset);
@@ -3279,9 +3171,9 @@ i830AdjustFrame(int scrnIndex, int x, in
       pI830->AccelInfoRec->NeedToSync = FALSE;
    }
 
-   i830PipeSetBase(pScrn, pI830->pipe, x, y);
-   if (pI830->Clone)
-      i830PipeSetBase(pScrn, !pI830->pipe, x, y);
+   for (i = 0; i < pI830->availablePipes; i++)
+      if (pI830->pipes[i].planeEnabled)
+	 i830PipeSetBase(pScrn, i, x, y);
 }
 
 static void
diff --git a/src/i830_randr.c b/src/i830_randr.c
index d097283..afa1848 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -492,45 +492,31 @@ I830RandRCrtcNotify (RRCrtcPtr	crtc)
     I830PipePtr		pI830Pipe = &pI830->pipes[pipe];
     int			i, j;
     DisplayModePtr	pipeMode = &pI830Pipe->curMode;
-    int			pipe_type;
 
     x = pI830Pipe->x;
     y = pI830Pipe->y;
     rotation = RR_Rotate_0;
     numOutputs = 0;
+    mode = NULL;
     for (i = 0; i < pI830->num_outputs; i++)
     {
 	output = &pI830->output[i];
-	/*
-	 * Valid crtcs
-	 */
-	switch (output->type) {
-	case I830_OUTPUT_DVO:
-	case I830_OUTPUT_SDVO:
-	    pipe_type = PIPE_DFP;
-	    break;
-	case I830_OUTPUT_ANALOG:
-	    pipe_type = PIPE_CRT;
-	    break;
-	case I830_OUTPUT_LVDS:
-	    pipe_type = PIPE_LFP;
-	    break;
-	case I830_OUTPUT_TVOUT:
-	    pipe_type = PIPE_TV;
-	    break;
-	default:
-	    pipe_type = PIPE_NONE;
-	    break;
-	}
-	if (pI830->operatingDevices & (pipe_type << (pipe << 3)))
+	if (!output->disabled && output->pipe == pipe)
 	{
 	    rrout = randrp->outputs[i];
 	    outputs[numOutputs++] = rrout;
+	    /*
+	     * We make copies of modes, so pointer equality 
+	     * isn't sufficient
+	     */
 	    for (j = 0; j < rrout->numModes; j++)
 	    {
 		DisplayModePtr	outMode = rrout->modes[j]->devPrivate;
 		if (I830ModesEqual(pipeMode, outMode))
+		{
 		    mode = rrout->modes[j];
+		    break;
+		}
 	    }
 	}
     }
@@ -571,14 +557,7 @@ I830RandRCrtcSet (ScreenPtr	pScreen,
 	}
 	else
 	{
-	    CARD32  operatingDevices = pI830->operatingDevices;
-
-	    if (pipe == 0)
-		pI830->operatingDevices &= ~0xff;
-	    else
-		pI830->operatingDevices &= ~0xff00;
 	    i830DisableUnusedFunctions (pScrn);
-	    pI830->operatingDevices = operatingDevices;
 	}
 	randrp->modes[pipe] = display_mode;
     }
@@ -614,7 +593,6 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
     int			p;
     int			clone_types;
     int			crtc_types;
-    int			pipe_type;
     int			pipe;
     int			subpixel;
     DisplayModePtr	modes, mode;
@@ -644,7 +622,6 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
 	    clone_types = ((1 << I830_OUTPUT_ANALOG) |
 			   (1 << I830_OUTPUT_DVO) |
 			   (1 << I830_OUTPUT_SDVO));
-	    pipe_type = PIPE_DFP;
 	    subpixel = SubPixelHorizontalRGB;
 	    break;
 	case I830_OUTPUT_ANALOG:
@@ -652,13 +629,11 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
 	    clone_types = ((1 << I830_OUTPUT_ANALOG) |
 			   (1 << I830_OUTPUT_DVO) |
 			   (1 << I830_OUTPUT_SDVO));
-	    pipe_type = PIPE_CRT;
 	    subpixel = SubPixelNone;
 	    break;
 	case I830_OUTPUT_LVDS:
 	    crtc_types = (1 << 1);
 	    clone_types = (1 << I830_OUTPUT_LVDS);
-	    pipe_type = PIPE_LFP;
 	    subpixel = SubPixelHorizontalRGB;
 	    possibleOptions = (RROutputOptionScaleNone|
 			       RROutputOptionScaleMaxAspect |
@@ -669,32 +644,27 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
 	    crtc_types = ((1 << 0) |
 			  (1 << 1));
 	    clone_types = (1 << I830_OUTPUT_TVOUT);
-	    pipe_type = PIPE_TV;
 	    subpixel = SubPixelNone;
 	    break;
 	default:
 	    crtc_types = 0;
 	    clone_types = 0;
-	    pipe_type = PIPE_NONE;
 	    subpixel = SubPixelUnknown;
 	    break;
 	}
-	ncrtc = 0;
-	pipe = -1;
-	crtc = NULL;
-	for (j = 0; j < pI830->availablePipes; j++)
+	if (!output->disabled)
 	{
-#if 0
-	     /* Can't flip outputs among crtcs yet */
-	    if (crtc_types & (1 << j))
-		crtcs[ncrtc++] = randrp->crtcs[j];
-#endif
-	    if (pI830->operatingDevices & (pipe_type << (j << 3)))
-	    {
-		pipe = j;
-		crtc = randrp->crtcs[j];
-		crtcs[ncrtc++] = crtc;
-	    }
+	    /* Can't flip outputs among crtcs yet */
+	    ncrtc = 1;
+	    pipe = output->pipe;
+	    crtc = randrp->crtcs[pipe];
+	    crtcs[0] = randrp->crtcs[pipe];
+	}
+	else
+	{
+	    ncrtc = 0;
+	    pipe = -1;
+	    crtc = NULL;
 	}
 	if (!RROutputSetCrtcs (randrp->outputs[i], crtcs, ncrtc))
 	    return FALSE;
diff --git a/src/i830_video.c b/src/i830_video.c
index 47f4a03..a5cd77c 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -722,7 +722,7 @@ I830SetupImageVideoOverlay(ScreenPtr pSc
    pPriv->brightness = 0;
    pPriv->contrast = 64;
    pPriv->saturation = 128;
-   pPriv->pipe = pI830->pipe; /* default to current pipe */
+   pPriv->pipe = 0;  /* XXX must choose pipe wisely */
    pPriv->linear = NULL;
    pPriv->currentBuf = 0;
    pPriv->gamma5 = 0xc0c0c0;
@@ -3592,6 +3592,8 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pSc
 
    pPriv->overlayOK = TRUE;
 
+#if 0
+   /* XXX Must choose pipe wisely */
    /* ensure pipe is updated on mode switch */
    if (!pI830->Clone) {
       if (pPriv->pipe != pI830->pipe) {
@@ -3600,6 +3602,7 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pSc
          pPriv->pipe = pI830->pipe;
       }
    }
+#endif
 
    if (!IS_I965G(pI830)) {
       if (pPriv->pipe == 0) {
@@ -3628,8 +3631,8 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pSc
    }
 
    /* Check we have an LFP connected */
-   if ((pPriv->pipe == 1 && pI830->operatingDevices & (PIPE_LFP << 8)) ||
-       (pPriv->pipe == 0 && pI830->operatingDevices & PIPE_LFP) ) {
+   if (i830PipeHasType (pScrn, pPriv->pipe, I830_OUTPUT_LVDS)) 
+   {
       size = pPriv->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
       hsize = (size >> 16) & 0x7FF;
       vsize = size & 0x7FF;
diff-tree e4bcec796e80e9fd66ab0c36394f5946915531f1 (from b7262a9a9110dac66e1a92c39dcb3ab59d95d081)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Nov 3 23:29:12 2006 -0800

    Use pI830->availablePipes instead of MAX_DISPLAY_PIPES everywhere

diff --git a/src/i830.h b/src/i830.h
index 3e0625e..ea7f4c9 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -308,8 +308,6 @@ typedef struct _I830Rec {
     */
    DisplayModePtr savedCurrentMode;
 
-   I830PipeRec	  pipes[MAX_DISPLAY_PIPES];
-   
    Bool Clone;
    int CloneRefresh;
    int CloneHDisplay;
@@ -473,7 +471,8 @@ typedef struct _I830Rec {
    /* [0] is Pipe A, [1] is Pipe B. */
    int availablePipes;
    /* [0] is display plane A, [1] is display plane B. */
-
+   I830PipeRec	  pipes[MAX_DISPLAY_PIPES];
+   
    /* Driver phase/state information */
    Bool preinit;
    Bool starting;
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 0b7e772..6b0e58c 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -180,11 +180,11 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
    int i;
 
    DPRINTF(PFX, "I830InitHWCursor\n");
-   for (i = 0; i < MAX_DISPLAY_PIPES; i++) 
+   for (i = 0; i < pI830->availablePipes; i++) 
       pI830->pipes[i].cursorShown = FALSE;
    /* Initialise the HW cursor registers, leaving the cursor hidden. */
    if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
-      for (i = 0; i < MAX_DISPLAY_PIPES; i++)
+      for (i = 0; i < pI830->availablePipes; i++)
       {
 	 int   cursor_control = i == 0 ? CURSOR_A_CONTROL : CURSOR_B_CONTROL;
 	 temp = INREG(cursor_control);
@@ -484,7 +484,7 @@ I830SetCursorPosition(ScrnInfoPtr pScrn,
     x -= hotspotx;
     y -= hotspoty;
 
-    for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
+    for (pipe = 0; pipe < pI830->availablePipes; pipe++)
     {
 	I830PipePtr	pI830Pipe = &pI830->pipes[pipe];
 	DisplayModePtr	mode = &pI830Pipe->curMode;
@@ -550,7 +550,7 @@ I830ShowCursor(ScrnInfoPtr pScrn)
 	   pI830->CursorMemARGB->Physical, pI830->CursorMemARGB->Start);
 
     pI830->cursorOn = TRUE;
-    for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
+    for (pipe = 0; pipe < pI830->availablePipes; pipe++)
 	I830SetPipeCursor (pScrn, pipe, TRUE);
 }
 
@@ -563,7 +563,7 @@ I830HideCursor(ScrnInfoPtr pScrn)
    DPRINTF(PFX, "I830HideCursor\n");
 
    pI830->cursorOn = FALSE;
-    for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
+    for (pipe = 0; pipe < pI830->availablePipes; pipe++)
 	I830SetPipeCursor (pScrn, pipe, TRUE);
 }
 
diff --git a/src/i830_display.c b/src/i830_display.c
index 1175cf1..8cb6660 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -660,7 +660,7 @@ i830DisableUnusedFunctions(ScrnInfoPtr p
      * internal TV) should have no outputs trying to pull data out of it, so
      * we're ready to turn those off.
      */
-    for (i = 0; i < MAX_DISPLAY_PIPES; i++) {
+    for (i = 0; i < pI830->availablePipes; i++) {
 	I830PipePtr pI830Pipe = &pI830->pipes[i];
 	int	    dspcntr_reg = pipe == 0 ? DSPACNTR : DSPBCNTR;
 	int	    pipeconf_reg = pipe == 0 ? PIPEACONF : PIPEBCONF;
@@ -726,7 +726,7 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayMo
     for (i = 0; i < pI830->num_outputs; i++)
 	pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);
 
-    for (i = 0; i < MAX_DISPLAY_PIPES; i++)
+    for (i = 0; i < pI830->availablePipes; i++)
     {
 	if (pI830->pipes[i].planeEnabled)
 	    ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, i, pMode),
diff --git a/src/i830_driver.c b/src/i830_driver.c
index dd96ff1..1b75649 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3387,7 +3387,7 @@ I830EnterVT(int scrnIndex, int flags)
    SetHWOperatingState(pScrn);
 
    /* Mark that we'll need to re-set the mode for sure */
-   for (i = 0; i < MAX_DISPLAY_PIPES; i++)
+   for (i = 0; i < pI830->availablePipes; i++)
       memset(&pI830->pipes[i].curMode, 0, sizeof(pI830->pipes[i].curMode));
 
    if (!i830SetMode(pScrn, pScrn->currentMode))
diff --git a/src/i830_randr.c b/src/i830_randr.c
index c4e91fd..d097283 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -682,7 +682,7 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
 	ncrtc = 0;
 	pipe = -1;
 	crtc = NULL;
-	for (j = 0; j < MAX_DISPLAY_PIPES; j++)
+	for (j = 0; j < pI830->availablePipes; j++)
 	{
 #if 0
 	     /* Can't flip outputs among crtcs yet */
@@ -782,7 +782,7 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
 	if (!RROutputSetClones (randrp->outputs[i], clones, nclone))
 	    return FALSE;
     }
-    for (i = 0; i < MAX_DISPLAY_PIPES; i++)
+    for (i = 0; i < pI830->availablePipes; i++)
 	I830RandRCrtcNotify (randrp->crtcs[i]);
     return TRUE;
 }
@@ -815,7 +815,7 @@ I830RandRCreateScreenResources12 (Screen
     /*
      * Create RandR resources, then probe them
      */
-    for (i = 0; i < MAX_DISPLAY_PIPES; i++)
+    for (i = 0; i < pI830->availablePipes; i++)
     {
 	randrp->crtcs[i] = RRCrtcCreate (pScreen, (void *) i);
 	RRCrtcGammaSetSize (randrp->crtcs[i], 256);
@@ -851,7 +851,7 @@ I830RandRCreateScreenResources12 (Screen
 				mmHeight);
     }
 
-    for (i = 0; i < MAX_DISPLAY_PIPES; i++)
+    for (i = 0; i < pI830->availablePipes; i++)
 	i830PipeSetBase(pScrn, i, 0, 0);
 
     return I830RandRSetInfo12 (pScreen);
diff-tree b7262a9a9110dac66e1a92c39dcb3ab59d95d081 (from 4625073244d4f521a07e12adcf0609e85658acbe)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Nov 3 23:24:07 2006 -0800

    Finish removing persistant vbe data

diff --git a/src/i830.h b/src/i830.h
index 10061d1..3e0625e 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -463,11 +463,6 @@ typedef struct _I830Rec {
    /* Stolen memory support */
    Bool StolenOnly;
 
-#if 0
-   /* Video BIOS support. */
-   vbeInfoPtr pVbe;
-#endif
-
    Bool swfSaved;
    CARD32 saveSWF0;
    CARD32 saveSWF4;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 1e92dac..dd96ff1 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -367,13 +367,6 @@ I830FreeRec(ScrnInfoPtr pScrn)
 
    pI830 = I830PTR(pScrn);
 
-#if 0
-   if (I830IsPrimary(pScrn)) {
-      if (pI830->pVbe)
-         vbeFree(pI830->pVbe);
-   }
-#endif
-
    xfree(pScrn->driverPrivate);
    pScrn->driverPrivate = NULL;
 }
@@ -547,20 +540,6 @@ I830DetectMemory(ScrnInfoPtr pScrn)
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no video memory detected.\n");
    }
 
-#if 0
-   /* Sanity check: compare with what the BIOS thinks. */
-   vbeInfo = VBEGetVBEInfo(pI830->pVbe);
-   if (vbeInfo != NULL && vbeInfo->TotalMemory != memsize / 1024 / 64) {
-      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		 "Detected stolen memory (%d kB) doesn't match what the BIOS"
-		 " reports (%d kB)\n",
-		 ROUND_DOWN_TO(memsize / 1024, 64),
-		 vbeInfo->TotalMemory * 64);
-   }
-   if (vbeInfo != NULL)
-      VBEFreeVBEInfo(vbeInfo);
-#endif
-
    return memsize;
 }
 
@@ -1007,19 +986,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    /* We have to use PIO to probe, because we haven't mapped yet. */
    I830SetPIOAccess(pI830);
 
-#if 0
-   /* Initialize VBE record */
-   if (I830IsPrimary(pScrn)) {
-      if ((pI830->pVbe = VBEInit(NULL, pI830->pEnt->index)) == NULL) {
-         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VBE initialization failed.\n");
-         return FALSE;
-      }
-   } else {
-      I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
-      pI830->pVbe = pI8301->pVbe;
-   }
-#endif
-
    switch (pI830->PciInfo->chipType) {
    case PCI_CHIP_I830_M:
       chipname = "830M";
diff-tree 4625073244d4f521a07e12adcf0609e85658acbe (from 719ad68515be9b996a6314de5448843de1146b88)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Nov 3 23:23:38 2006 -0800

    Oops, martian memset of randr modes pointer

diff --git a/src/i830_randr.c b/src/i830_randr.c
index 67641d6..c4e91fd 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -873,7 +873,6 @@ I830RandRInit12 (ScreenPtr pScreen)
     rp->rrCrtcSet = I830RandRCrtcSet;
     rp->rrCrtcSetGamma = I830RandRCrtcSetGamma;
     rp->rrSetConfig = NULL;
-    memset (rp->modes, '\0', sizeof (rp->modes));
     pScrn->PointerMoved = I830RandRPointerMoved;
     return TRUE;
 }
diff-tree 719ad68515be9b996a6314de5448843de1146b88 (from 9681602177124e84a817a1e1d428f1779f2a45c9)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Nov 3 19:41:41 2006 -0800

    Use VBE only temporarily to fetch BIOS rom image
    (cherry picked from 6a9386651785afc70a29e355255e8295b321f28e commit)

diff --git a/src/i830.h b/src/i830.h
index b4b17de..10061d1 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -463,8 +463,10 @@ typedef struct _I830Rec {
    /* Stolen memory support */
    Bool StolenOnly;
 
+#if 0
    /* Video BIOS support. */
    vbeInfoPtr pVbe;
+#endif
 
    Bool swfSaved;
    CARD32 saveSWF0;
diff --git a/src/i830_bios.c b/src/i830_bios.c
index 97fb7fc..0821845 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -84,15 +84,18 @@ i830GetBIOS(ScrnInfoPtr pScrn)
     struct vbt_header *vbt;
     int vbt_off;
     unsigned char *bios;
+    vbeInfoPtr	pVbe;
 
     bios = xalloc(INTEL_VBIOS_SIZE);
     if (bios == NULL)
 	return NULL;
 
-    if (pI830->pVbe != NULL) {
-	memcpy(bios, xf86int10Addr(pI830->pVbe->pInt10,
-					   pI830->pVbe->pInt10->BIOSseg << 4),
+    pVbe = VBEInit (NULL, pI830->pEnt->index);
+    if (pVbe != NULL) {
+	memcpy(bios, xf86int10Addr(pVbe->pInt10,
+				   pVbe->pInt10->BIOSseg << 4),
 	       INTEL_VBIOS_SIZE);
+	vbeFree (pVbe);
     } else {
 	xf86ReadPciBIOS(0, pI830->PciTag, 0, bios, INTEL_VBIOS_SIZE);
     }
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 3b21974..1e92dac 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -367,10 +367,12 @@ I830FreeRec(ScrnInfoPtr pScrn)
 
    pI830 = I830PTR(pScrn);
 
+#if 0
    if (I830IsPrimary(pScrn)) {
       if (pI830->pVbe)
          vbeFree(pI830->pVbe);
    }
+#endif
 
    xfree(pScrn->driverPrivate);
    pScrn->driverPrivate = NULL;
@@ -477,7 +479,9 @@ I830DetectMemory(ScrnInfoPtr pScrn)
    CARD16 gmch_ctrl;
    int memsize = 0;
    int range;
+#if 0
    VbeInfoBlock *vbeInfo;
+#endif
 
    bridge = pciTag(0, 0, 0);		/* This is always the host bridge */
    gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
@@ -543,6 +547,7 @@ I830DetectMemory(ScrnInfoPtr pScrn)
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no video memory detected.\n");
    }
 
+#if 0
    /* Sanity check: compare with what the BIOS thinks. */
    vbeInfo = VBEGetVBEInfo(pI830->pVbe);
    if (vbeInfo != NULL && vbeInfo->TotalMemory != memsize / 1024 / 64) {
@@ -554,6 +559,7 @@ I830DetectMemory(ScrnInfoPtr pScrn)
    }
    if (vbeInfo != NULL)
       VBEFreeVBEInfo(vbeInfo);
+#endif
 
    return memsize;
 }
@@ -1001,6 +1007,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    /* We have to use PIO to probe, because we haven't mapped yet. */
    I830SetPIOAccess(pI830);
 
+#if 0
    /* Initialize VBE record */
    if (I830IsPrimary(pScrn)) {
       if ((pI830->pVbe = VBEInit(NULL, pI830->pEnt->index)) == NULL) {
@@ -1011,6 +1018,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
       pI830->pVbe = pI8301->pVbe;
    }
+#endif
 
    switch (pI830->PciInfo->chipType) {
    case PCI_CHIP_I830_M:



More information about the xorg-commit mailing list