xf86-video-intel: Branch 'modesetting' - 7 commits - src/i810_reg.h src/i830_display.c src/i830_driver.c src/i830.h src/i830_lvds.c src/i830_randr.c src/i830_sdvo.c

Eric Anholt anholt at kemper.freedesktop.org
Mon Oct 30 21:07:52 EET 2006


 src/i810_reg.h     |   54 ++++++++-
 src/i830.h         |    3 
 src/i830_display.c |    7 -
 src/i830_driver.c  |  318 ++++-------------------------------------------------
 src/i830_lvds.c    |   33 +++++
 src/i830_randr.c   |   84 +++++++-------
 src/i830_sdvo.c    |   13 +-
 7 files changed, 171 insertions(+), 341 deletions(-)

New commits:
diff-tree 819a47b27cd4728feb269a08be32403304993ffa (from 71545db4614cfc4650acc4325912474e777c3b36)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Oct 30 09:50:33 2006 -0800

    Use the new fields for SDVO pixel multiply on the G965.
    
    This should fix display at resolutions/refresh rates in a different multiplier
    class than the console display (generally, high resolution modes).

diff --git a/src/i810_reg.h b/src/i810_reg.h
index a80b66e..bc6c0f8 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -799,10 +799,56 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 # define PLL_REF_INPUT_TVCLKINBC		(2 << 13)
 # define PLLB_REF_INPUT_SPREADSPECTRUMIN	(3 << 13)
 # define DISPLAY_RATE_SELECT_FPA1		(1 << 8)
+/**
+ * SDVO multiplier for 945G/GM.
+ *
+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
+ */
 # define SDVO_MULTIPLIER_MASK			0x000000ff
 # define SDVO_MULTIPLIER_SHIFT_HIRES		4
 # define SDVO_MULTIPLIER_SHIFT_VGA		0
 
+/** @defgroup DPLL_MD
+ * @{
+ */
+/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */
+#define DPLL_A_MD		0x0601c
+/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */
+#define DPLL_B_MD		0x06020
+/**
+ * UDI pixel divider, controlling how many pixels are stuffed into a packet.
+ *
+ * Value is pixels minus 1.  Must be set to 1 pixel for SDVO.
+ */
+# define DPLL_MD_UDI_DIVIDER_MASK		0x3f000000
+# define DPLL_MD_UDI_DIVIDER_SHIFT		24
+/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
+# define DPLL_MD_VGA_UDI_DIVIDER_MASK		0x003f0000
+# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT		16
+/**
+ * SDVO/UDI pixel multiplier.
+ *
+ * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
+ * clock rate is 10 times the DPLL clock.  At low resolution/refresh rate
+ * modes, the bus rate would be below the limits, so SDVO allows for stuffing
+ * dummy bytes in the datastream at an increased clock rate, with both sides of
+ * the link knowing how many bytes are fill.
+ *
+ * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
+ * rate to 130Mhz to get a bus rate of 1.30Ghz.  The DPLL clock rate would be
+ * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
+ * through an SDVO command.
+ *
+ * This register field has values of multiplication factor minus 1, with
+ * a maximum multiplier of 5 for SDVO.
+ */
+# 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. */
+# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK	0x0000003f
+# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT	0
+/** @} */
+
 #define BLC_PWM_CTL		0x61254
 #define BACKLIGHT_MODULATION_FREQ_SHIFT		(17)
 #define BACKLIGHT_MODULATION_FREQ_MASK		(0x7fff << 17)
@@ -842,7 +888,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define SDVO_PIPE_B_SELECT			(1 << 30)
 #define SDVO_STALL_SELECT			(1 << 29)
 #define SDVO_INTERRUPT_ENABLE			(1 << 26)
-/* Programmed value is multiplier - 1, up to 5x.  alv, gdg only */
+/**
+ * 915G/GM SDVO pixel multiplier.
+ *
+ * Programmed value is multiplier - 1, up to 5x.
+ *
+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
+ */
 #define SDVO_PORT_MULTIPLY_MASK			(7 << 23)
 #define SDVO_PORT_MULTIPLY_SHIFT		23
 #define SDVO_PHASE_SELECT_MASK			(15 << 19)
diff --git a/src/i830.h b/src/i830.h
index 3f4eacc..40c8cce 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -509,6 +509,7 @@ typedef struct _I830Rec {
    CARD32 saveFPA0;
    CARD32 saveFPA1;
    CARD32 saveDPLL_A;
+   CARD32 saveDPLL_A_MD;
    CARD32 saveHTOTAL_A;
    CARD32 saveHBLANK_A;
    CARD32 saveHSYNC_A;
@@ -523,6 +524,7 @@ typedef struct _I830Rec {
    CARD32 saveFPB0;
    CARD32 saveFPB1;
    CARD32 saveDPLL_B;
+   CARD32 saveDPLL_B_MD;
    CARD32 saveHTOTAL_B;
    CARD32 saveHBLANK_B;
    CARD32 saveHSYNC_B;
diff --git a/src/i830_display.c b/src/i830_display.c
index a94e21d..41f8c21 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -472,11 +472,8 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
 	}
     }
 
-    /* In SDVO, we need to keep the clock on the bus between 1Ghz and 2Ghz.
-     * The clock on the bus is 10 times the pixel clock normally.  If that
-     * would be too low, we run the DPLL at a multiple of the pixel clock, and
-     * tell the SDVO device the multiplier so it can throw away the dummy
-     * bytes.
+    /* Adjust the clock for pixel multiplication.
+     * See DPLL_MD_UDI_MULTIPLIER_MASK.
      */
     if (is_sdvo) {
 	pixel_clock *= i830_sdvo_get_pixel_multiplier(pMode);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 10c6f09..5494abb 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2506,6 +2506,8 @@ SaveHWState(ScrnInfoPtr pScrn)
    pI830->saveFPA0 = INREG(FPA0);
    pI830->saveFPA1 = INREG(FPA1);
    pI830->saveDPLL_A = INREG(DPLL_A);
+   if (IS_I965G(pI830))
+      pI830->saveDPLL_A_MD = INREG(DPLL_A_MD);
    pI830->saveHTOTAL_A = INREG(HTOTAL_A);
    pI830->saveHBLANK_A = INREG(HBLANK_A);
    pI830->saveHSYNC_A = INREG(HSYNC_A);
@@ -2528,6 +2530,8 @@ SaveHWState(ScrnInfoPtr pScrn)
       pI830->saveFPB0 = INREG(FPB0);
       pI830->saveFPB1 = INREG(FPB1);
       pI830->saveDPLL_B = INREG(DPLL_B);
+      if (IS_I965G(pI830))
+	 pI830->saveDPLL_B_MD = INREG(DPLL_B_MD);
       pI830->saveHTOTAL_B = INREG(HTOTAL_B);
       pI830->saveHBLANK_B = INREG(HBLANK_B);
       pI830->saveHSYNC_B = INREG(HSYNC_B);
@@ -2611,6 +2615,8 @@ RestoreHWState(ScrnInfoPtr pScrn)
    OUTREG(FPA0, pI830->saveFPA0);
    OUTREG(FPA1, pI830->saveFPA1);
    OUTREG(DPLL_A, pI830->saveDPLL_A);
+   if (IS_I965G(pI830))
+      OUTREG(DPLL_A_MD, pI830->saveDPLL_A_MD);
    OUTREG(HTOTAL_A, pI830->saveHTOTAL_A);
    OUTREG(HBLANK_A, pI830->saveHBLANK_A);
    OUTREG(HSYNC_A, pI830->saveHSYNC_A);
@@ -2630,6 +2636,8 @@ RestoreHWState(ScrnInfoPtr pScrn)
       OUTREG(FPB0, pI830->saveFPB0);
       OUTREG(FPB1, pI830->saveFPB1);
       OUTREG(DPLL_B, pI830->saveDPLL_B);
+      if (IS_I965G(pI830))
+	 OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD);
       OUTREG(HTOTAL_B, pI830->saveHTOTAL_B);
       OUTREG(HBLANK_B, pI830->saveHBLANK_B);
       OUTREG(HSYNC_B, pI830->saveHSYNC_B);
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 87453b9..bbc1c72 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -600,6 +600,7 @@ i830_sdvo_post_set_mode(ScrnInfoPtr pScr
     Bool out1, out2, input1, input2;
     CARD32 dpll, sdvob, sdvoc;
     int dpll_reg = (output->pipe == 0) ? DPLL_A : DPLL_B;
+    int dpll_md_reg = (output->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
     int sdvo_pixel_multiply;
     CARD8 status;
 
@@ -630,10 +631,14 @@ i830_sdvo_post_set_mode(ScrnInfoPtr pScr
     dpll = INREG(dpll_reg);
 
     sdvo_pixel_multiply = i830_sdvo_get_pixel_multiplier(mode);
-    if (IS_I945G(pI830) || IS_I945GM(pI830))
+    if (IS_I965G(pI830)) {
+	OUTREG(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
+	       ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
+    } else if (IS_I945G(pI830) || IS_I945GM(pI830)) {
 	dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
-    else
+    } else {
 	sdvob |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
+    }
 
     OUTREG(dpll_reg, dpll | DPLL_DVO_HIGH_SPEED);
 
diff-tree 71545db4614cfc4650acc4325912474e777c3b36 (from c357eca10ca1c535d305e1f3028471a912ae4102)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Oct 30 09:46:10 2006 -0800

    Return and use valid status bits for i830_sdvo_get_trained_inputs().

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index ac5ae48..87453b9 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -277,7 +277,7 @@ i830_sdvo_get_trained_inputs(I830OutputP
 
     i830_sdvo_write_cmd(output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
 
-    i830_sdvo_read_response(output, response, 2);
+    status = i830_sdvo_read_response(output, response, 2);
     if (status != SDVO_CMD_STATUS_SUCCESS)
 	return FALSE;
 
@@ -607,7 +607,7 @@ i830_sdvo_post_set_mode(ScrnInfoPtr pScr
     /* two 03s, 04 05, 10, 1d */
     /* these contain the height and mode clock / 10 by the looks of it */
 
-    i830_sdvo_get_trained_inputs(output, &input1, &input2);
+    status = i830_sdvo_get_trained_inputs(output, &input1, &input2);
 
     /* Warn if the device reported failure to sync. */
     if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
diff-tree c357eca10ca1c535d305e1f3028471a912ae4102 (from 3ab9f5a4a8cd62c8a8c2a09d3d105adbe815a83d)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Oct 30 09:44:55 2006 -0800

    Clean up whitespace in i830_randr.c.

diff --git a/src/i830_randr.c b/src/i830_randr.c
index e4075f2..f64f3da 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -58,7 +58,7 @@ typedef struct _i830RandRInfo {
     DisplayModePtr  		    modes[MAX_DISPLAY_PIPES];
 #endif
 } XF86RandRInfoRec, *XF86RandRInfoPtr;
-    
+
 #ifdef RANDR_12_INTERFACE
 static Bool I830RandRInit12 (ScreenPtr pScreen);
 static Bool I830RandRCreateScreenResources12 (ScreenPtr pScreen);
@@ -67,7 +67,8 @@ static Bool I830RandRCreateScreenResourc
 static int	    i830RandRIndex;
 static int	    i830RandRGeneration;
 
-#define XF86RANDRINFO(p)    ((XF86RandRInfoPtr) (p)->devPrivates[i830RandRIndex].ptr)
+#define XF86RANDRINFO(p) \
+	((XF86RandRInfoPtr)(p)->devPrivates[i830RandRIndex].ptr)
 
 static int
 I830RandRModeRefresh (DisplayModePtr mode)
@@ -87,10 +88,10 @@ I830RandRGetInfo (ScreenPtr pScreen, Rot
     DisplayModePtr	    mode;
     int			    refresh0 = 60;
     int			    maxX = 0, maxY = 0;
-    
+
     *rotations = randrp->supported_rotations;
 
-    if (randrp->virtualX == -1 || randrp->virtualY == -1) 
+    if (randrp->virtualX == -1 || randrp->virtualY == -1)
     {
 	randrp->virtualX = scrp->virtualX;
 	randrp->virtualY = scrp->virtualY;
@@ -133,7 +134,7 @@ I830RandRGetInfo (ScreenPtr pScreen, Rot
 	randrp->maxX = maxX;
 	randrp->maxY = maxY;
     }
-   
+
     if (scrp->currentMode->HDisplay != randrp->virtualX ||
 	scrp->currentMode->VDisplay != randrp->virtualY)
     {
@@ -144,7 +145,7 @@ I830RandRGetInfo (ScreenPtr pScreen, Rot
 	if (!pSize)
 	    return FALSE;
 	RRRegisterRate (pScreen, pSize, refresh0);
-	if (scrp->virtualX == randrp->virtualX && 
+	if (scrp->virtualX == randrp->virtualX &&
 	    scrp->virtualY == randrp->virtualY)
 	{
 	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
@@ -171,7 +172,7 @@ I830RandRSetMode (ScreenPtr	    pScreen,
     DisplayModePtr      currentMode = NULL;
     Bool 		ret = TRUE;
     PixmapPtr 		pspix = NULL;
-    
+
     if (pRoot)
 	(*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
     if (useVirtual)
@@ -227,7 +228,7 @@ I830RandRSetMode (ScreenPtr	    pScreen,
     pspix = (*pScreen->GetScreenPixmap) (pScreen);
     if (pspix->devPrivate.ptr)
        scrp->pixmapPrivate = pspix->devPrivate;
-    
+
     /*
      * Make sure the layout is correct
      */
@@ -259,7 +260,7 @@ I830RandRSetConfig (ScreenPtr		pScreen,
 
     randrp->rotation = rotation;
 
-    if (randrp->virtualX == -1 || randrp->virtualY == -1) 
+    if (randrp->virtualX == -1 || randrp->virtualY == -1)
     {
 	randrp->virtualX = scrp->virtualX;
 	randrp->virtualY = scrp->virtualY;
@@ -275,7 +276,7 @@ I830RandRSetConfig (ScreenPtr		pScreen,
 		if (maxY < mode->VDisplay)
 			maxY = mode->VDisplay;
 	}
-	if (mode->HDisplay == pSize->width && 
+	if (mode->HDisplay == pSize->width &&
 	    mode->VDisplay == pSize->height &&
 	    (rate == 0 || I830RandRModeRefresh (mode) == rate))
 	    break;
@@ -303,7 +304,8 @@ I830RandRSetConfig (ScreenPtr		pScreen,
 	randrp->maxY = maxY;
     }
 
-    if (!I830RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
+    if (!I830RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth,
+			   pSize->mmHeight)) {
         randrp->rotation = oldRotation;
 	return FALSE;
     }
@@ -361,17 +363,17 @@ I830RandRCreateScreenResources (ScreenPt
 	pI830->starting = TRUE; /* abuse this for dual head & rotation */
 	I830RandRSetConfig (pScreen, requestedRotation, 0, &p);
 	pI830->starting = FALSE;
-    } 
+    }
     return TRUE;
 }
-    
-    
+
+
 Bool
 I830RandRInit (ScreenPtr    pScreen, int rotation)
 {
     rrScrPrivPtr	rp;
     XF86RandRInfoPtr	randrp;
-    
+
 #ifdef PANORAMIX
     /* XXX disable RandR when using Xinerama */
     if (!noPanoramiXExtension)
@@ -382,11 +384,11 @@ I830RandRInit (ScreenPtr    pScreen, int
 	i830RandRIndex = AllocateScreenPrivateIndex();
 	i830RandRGeneration = serverGeneration;
     }
-    
+
     randrp = xalloc (sizeof (XF86RandRInfoRec));
     if (!randrp)
 	return FALSE;
-			
+
     if (!RRScreenInit(pScreen))
     {
 	xfree (randrp);
@@ -400,7 +402,7 @@ I830RandRInit (ScreenPtr    pScreen, int
     randrp->virtualY = -1;
     randrp->mmWidth = pScreen->mmWidth;
     randrp->mmHeight = pScreen->mmHeight;
-    
+
     randrp->rotation = RR_Rotate_0; /* initial rotated mode */
 
     randrp->supported_rotations = rotation;
@@ -446,8 +448,8 @@ I830RandRScreenSetSize (ScreenPtr	pScree
     ScrnInfoPtr		pScrn = XF86SCRNINFO(pScreen);
     WindowPtr		pRoot = WindowTable[pScreen->myNum];
     Bool 		ret = TRUE;
-    
-    if (randrp->virtualX == -1 || randrp->virtualY == -1) 
+
+    if (randrp->virtualX == -1 || randrp->virtualY == -1)
     {
 	randrp->virtualX = pScrn->virtualX;
 	randrp->virtualY = pScrn->virtualY;
@@ -461,7 +463,7 @@ I830RandRScreenSetSize (ScreenPtr	pScree
     pScreen->height = pScrn->virtualY;
     pScreen->mmWidth = mmWidth;
     pScreen->mmHeight = mmHeight;
-    
+
     xf86SetViewport (pScreen, pScreen->width, pScreen->height);
     xf86SetViewport (pScreen, 0, 0);
     if (pRoot)
@@ -490,7 +492,7 @@ I830RandRCrtcNotify (RRCrtcPtr	crtc)
     int			i, j;
     DisplayModePtr	pipeMode = &pI830->pipeCurMode[pipe];
     int			pipe_type;
-    
+
     x = pI830->pipeX[pipe];
     y = pI830->pipeY[pipe];
     rotation = RR_Rotate_0;
@@ -533,7 +535,7 @@ I830RandRCrtcNotify (RRCrtcPtr	crtc)
     }
     return RRCrtcNotify (crtc, mode, x, y, rotation, numOutputs, outputs);
 }
-    
+
 static Bool
 I830RandRCrtcSet (ScreenPtr	pScreen,
 		  RRCrtcPtr	crtc,
@@ -549,7 +551,7 @@ I830RandRCrtcSet (ScreenPtr	pScreen,
     I830Ptr		pI830 = I830PTR(pScrn);
     int			pipe = (int) (crtc->devPrivate);
     DisplayModePtr	display_mode = mode ? mode->devPrivate : NULL;
-    
+
     /* Sync the engine before adjust mode */
     if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
 	(*pI830->AccelInfoRec->Sync)(pScrn);
@@ -619,13 +621,13 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
     RRModePtr		rrmode, *rrmodes;
     CARD32		possibleOptions = 0;
     CARD32		currentOptions = 0;
-    
-    if (randrp->virtualX == -1 || randrp->virtualY == -1) 
+
+    if (randrp->virtualX == -1 || randrp->virtualY == -1)
     {
 	randrp->virtualX = pScrn->virtualX;
 	randrp->virtualY = pScrn->virtualY;
     }
-    RRScreenSetSizeRange (pScreen, 320, 240, 
+    RRScreenSetSizeRange (pScreen, 320, 240,
 			  randrp->virtualX, randrp->virtualY);
     for (i = 0; i < pI830->num_outputs; i++)
     {
@@ -697,17 +699,17 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
 	    return FALSE;
 
 	RROutputSetCrtc (randrp->outputs[i], crtc);
-    
+
 	RROutputSetPossibleOptions (randrp->outputs[i], possibleOptions);
 	RROutputSetCurrentOptions (randrp->outputs[i], currentOptions);
         nmode = 0;
 	npreferred = 0;
 	rrmodes = NULL;
-	if (pipe >= 0) 
+	if (pipe >= 0)
 	{
 	    MonPtr  mon = pI830->pipeMon[pipe];
 	    modes = mon->Modes;
-	
+
 	    for (mode = modes; mode; mode = mode->next)
 		nmode++;
 
@@ -726,20 +728,20 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
 			    modeInfo.nameLength = strlen (mode->name);
 			    modeInfo.mmWidth = mon->widthmm;
 			    modeInfo.mmHeight = mon->heightmm;
-	
+
 			    modeInfo.width = mode->HDisplay;
 			    modeInfo.dotClock = mode->Clock * 1000;
 			    modeInfo.hSyncStart = mode->HSyncStart;
 			    modeInfo.hSyncEnd = mode->HSyncEnd;
 			    modeInfo.hTotal = mode->HTotal;
 			    modeInfo.hSkew = mode->HSkew;
-	
+
 			    modeInfo.height = mode->VDisplay;
 			    modeInfo.vSyncStart = mode->VSyncStart;
 			    modeInfo.vSyncEnd = mode->VSyncEnd;
 			    modeInfo.vTotal = mode->VTotal;
 			    modeInfo.modeFlags = mode->Flags;
-	
+
 			    rrmode = RRModeGet (pScreen, &modeInfo, mode->name);
 			    rrmode->devPrivate = mode;
 			    if (rrmode)
@@ -752,21 +754,21 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
 		}
 	    }
 	}
-	
+
     	if (!RROutputSetModes (randrp->outputs[i], rrmodes, nmode, npreferred))
 	{
     	    xfree (rrmodes);
 	    return FALSE;
 	}
-	
+
 	xfree (rrmodes);
-	
+
 	connection = RR_Disconnected;
 	if (pipe >= 0)
 	    connection = RR_Connected;
 
 	RROutputSetConnection (randrp->outputs[i], connection);
-	    
+
 	RROutputSetSubpixelOrder (randrp->outputs[i], subpixel);
 
 	/*
@@ -786,7 +788,7 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
     return TRUE;
 }
 
-    
+
 /*
  * Query the hardware for the current state, then mirror
  * that to RandR
@@ -828,7 +830,7 @@ I830RandRCreateScreenResources12 (Screen
 					     name, strlen (name),
 					     (void *) i);
     }
-    
+
     mode = pScrn->currentMode;
     if (mode)
     {
@@ -852,10 +854,10 @@ I830RandRCreateScreenResources12 (Screen
 				mmWidth,
 				mmHeight);
     }
-			    
+
     for (i = 0; i < MAX_DISPLAY_PIPES; i++)
 	i830PipeSetBase(pScrn, i, 0, 0);
-	
+
     return I830RandRSetInfo12 (pScreen);
 }
 
diff-tree 3ab9f5a4a8cd62c8a8c2a09d3d105adbe815a83d (from df14838eb5d0a056f663d9f12bd8b5c25cf97330)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Oct 24 00:26:09 2006 -0700

    Move vbeInfo out of the driver struct to the one place it's used.

diff --git a/src/i830.h b/src/i830.h
index b4408c2..3f4eacc 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -447,7 +447,6 @@ typedef struct _I830Rec {
 
    /* Video BIOS support. */
    vbeInfoPtr pVbe;
-   VbeInfoBlock *vbeInfo;
    VESAPtr vesa;
 
    Bool swfSaved;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 0c0aa95..10c6f09 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -375,8 +375,6 @@ I830FreeRec(ScrnInfoPtr pScrn)
    pI830 = I830PTR(pScrn);
 
    if (I830IsPrimary(pScrn)) {
-      if (pI830->vbeInfo)
-         VBEFreeVBEInfo(pI830->vbeInfo);
       if (pI830->pVbe)
          vbeFree(pI830->pVbe);
    }
@@ -597,6 +595,7 @@ I830DetectMemory(ScrnInfoPtr pScrn)
    CARD16 gmch_ctrl;
    int memsize = 0;
    int range;
+   VbeInfoBlock *vbeInfo;
 
    bridge = pciTag(0, 0, 0);		/* This is always the host bridge */
    gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
@@ -661,6 +660,19 @@ I830DetectMemory(ScrnInfoPtr pScrn)
    } else {
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no video memory detected.\n");
    }
+
+   /* 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 (%ld 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);
+
    return memsize;
 }
 
@@ -1301,13 +1313,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	      "Integrated Graphics Chipset: Intel(R) %s\n", chipname);
 
-   if (I830IsPrimary(pScrn)) {
-      pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
-   } else {
-      I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
-      pI830->vbeInfo = pI8301->vbeInfo;
-   }
-
    /* Set the Chipset and ChipRev, allowing config file entries to override. */
    if (pI830->pEnt->device->chipset && *pI830->pEnt->device->chipset) {
       pScrn->chipset = pI830->pEnt->device->chipset;
@@ -1434,15 +1439,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    pI830->StolenMemory.Start = 0;
    pI830->StolenMemory.End = pI830->StolenMemory.Size;
 
-   /* Sanity check: compare with what the BIOS thinks. */
-   if (pI830->vbeInfo->TotalMemory != pI830->StolenMemory.Size / 1024 / 64) {
-      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		 "Detected stolen memory (%ld kB) doesn't match what the BIOS"
-		 " reports (%d kB)\n",
-		 ROUND_DOWN_TO(pI830->StolenMemory.Size / 1024, 64),
-		 pI830->vbeInfo->TotalMemory * 64);
-   }
-
    /* Find the maximum amount of agpgart memory available. */
    if (I830IsPrimary(pScrn)) {
       mem = I830CheckAvailableMemory(pScrn);
@@ -2243,10 +2239,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 
 #if 0
    if (I830IsPrimary(pScrn)) {
-      VBEFreeVBEInfo(pI830->vbeInfo);
       vbeFree(pI830->pVbe);
    }
-   pI830->vbeInfo = NULL;
    pI830->pVbe = NULL;
 #endif
 
@@ -3233,14 +3227,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
    if (!pI830->pVbe)
       return FALSE;
 
-   if (I830IsPrimary(pScrn)) {
-      if (pI830->vbeInfo)
-         VBEFreeVBEInfo(pI830->vbeInfo);
-      pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
-   } else {
-      pI830->vbeInfo = pI8301->vbeInfo;
-   }
-
    SetPipeAccess(pScrn);
 
    miClearVisualTypes();
diff-tree df14838eb5d0a056f663d9f12bd8b5c25cf97330 (from 3a6104ab89b159241845314ccf88fa62da14cf7d)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Oct 24 00:18:33 2006 -0700

    Remove dead memsize reporting.
    
    The calculation no longer made sense, as we don't use the BIOS for mode
    selection.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index be83431..0c0aa95 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1087,7 +1087,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    rgb defaultWeight = { 0, 0, 0 };
    EntityInfoPtr pEnt;
    I830EntPtr pI830Ent = NULL;					
-   int mem, memsize;
+   int mem;
    int flags24;
    int i, n;
    char *s;
@@ -2038,17 +2038,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
 	      "Maximum frambuffer space: %d kByte\n", pScrn->videoRam);
 
-   /*
-    * Limit videoram available for mode selection to what the video
-    * BIOS can see.
-    */
-   if (pScrn->videoRam > (pI830->vbeInfo->TotalMemory * 64))
-      memsize = pI830->vbeInfo->TotalMemory * 64;
-   else
-      memsize = pScrn->videoRam;
-   xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
-	      "Maximum space available for video modes: %d kByte\n", memsize);
-
    n = I830ValidateXF86ModeList(pScrn, TRUE);
    if (n <= 0) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
diff-tree 3a6104ab89b159241845314ccf88fa62da14cf7d (from 88c12f577f80fa132ec45cdf456d8060f2ece4fd)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Oct 23 19:15:30 2006 -0700

    Remove disabled I830DetectMonitorChange().
    
    This used to be called when switching back in to X.  It might make some sense
    to detect monitors at this time (it happens to occur at resume time, when
    monitors are likely to have changed), but it should probably live in either
    userland policy with RandR 1.2 or RandR 1.2 XFree86-DDX generic code.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 9f986ec..be83431 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3681,210 +3681,6 @@ I830LeaveVT(int scrnIndex, int flags)
       pI830->AccelInfoRec->NeedToSync = FALSE;
 }
 
-static Bool
-I830DetectMonitorChange(ScrnInfoPtr pScrn)
-{
-   return FALSE;
-#if 0 /* Disabled until we rewrite this natively */
-   I830Ptr pI830 = I830PTR(pScrn);
-   pointer pDDCModule = NULL;
-   DisplayModePtr p, pMon;
-   int memsize;
-   int DDCclock = 0, DDCclock2 = 0;
-   int displayWidth = pScrn->displayWidth;
-   int curHDisplay = pScrn->currentMode->HDisplay;
-   int curVDisplay = pScrn->currentMode->VDisplay;
-   xf86MonPtr monitor = NULL;
-
-   DPRINTF(PFX, "Detect Monitor Change\n");
-   
-   SetPipeAccess(pScrn);
-
-   /* Re-read EDID */
-   pDDCModule = xf86LoadSubModule(pScrn, "ddc");
-
-   pI830->pVbe->ddc = DDC_UNCHECKED;
-   monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
-   xf86UnloadSubModule(pDDCModule);
-   if ((pScrn->monitor->DDC = monitor) != NULL) {
-      xf86PrintEDID(monitor);
-      xf86SetDDCproperties(pScrn, monitor);
-   } 
-
-   DDCclock = I830UseDDC(pScrn);
-
-   /* Revalidate the modes */
-
-   /*
-    * Note: VBE modes (> 0x7f) won't work with Intel's extended BIOS
-    * functions.  
-    */
-   SetPipeAccess(pScrn);
-
-   pScrn->modePool = I830GetModePool(pScrn, pI830->pVbe, pI830->vbeInfo);
-
-   if (!pScrn->modePool) {
-      /* This is bad, which would cause the Xserver to exit, maybe
-       * we should default to a 640x480 @ 60Hz mode here ??? */
-      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		 "No Video BIOS modes for chosen depth.\n");
-      return FALSE;
-   }
-
-   VBESetModeNames(pScrn->modePool);
-
-   if (pScrn->videoRam > (pI830->vbeInfo->TotalMemory * 64))
-      memsize = pI830->vbeInfo->TotalMemory * 64;
-   else
-      memsize = pScrn->videoRam;
-
-   VBEValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, NULL,
-			NULL, 0, MAX_DISPLAY_PITCH, 1,
-			0, MAX_DISPLAY_HEIGHT,
-			pScrn->display->virtualX,
-			pScrn->display->virtualY,
-			memsize, LOOKUP_BEST_REFRESH);
-
-   if (pI830->MergedFB) {
-      VBEValidateModes(pI830->pScrn_2, pI830->pScrn_2->monitor->Modes, 
-		        pI830->pScrn_2->display->modes, NULL,
-			NULL, 0, MAX_DISPLAY_PITCH, 1,
-			0, MAX_DISPLAY_HEIGHT,
-			pScrn->display->virtualX,
-			pScrn->display->virtualY,
-			memsize, LOOKUP_BEST_REFRESH);
-   }
-
-   if (DDCclock > 0) {
-      p = pScrn->modes;
-      if (p == NULL)
-         return FALSE;
-      do {
-         int Clock = 100000000; /* incredible value */
-
-         if (p->status == MODE_OK) {
-            for (pMon = pScrn->monitor->Modes; pMon != NULL; pMon = pMon->next) {
-               if ((pMon->HDisplay != p->HDisplay) ||
-                   (pMon->VDisplay != p->VDisplay) ||
-                   (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
-                  continue;
-
-               /* Find lowest supported Clock for this resolution */
-               if (Clock > pMon->Clock)
-                  Clock = pMon->Clock;
-            } 
-
-            if (Clock != 100000000 && DDCclock < 2550 && Clock / 1000.0 > DDCclock) {
-               ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n",
-		   p->name, pScrn->monitor->id,
-		   Clock/1000.0, DDCclock);
-               p->status = MODE_BAD;
-            } 
-         }
-         p = p->next;
-      } while (p != NULL && p != pScrn->modes);
-   }
-
-   /* Only use this if we've got DDC available */
-   if (pI830->MergedFB && DDCclock2 > 0) {
-      p = pI830->pScrn_2->modes;
-      if (p == NULL)
-         return FALSE;
-      do {
-         int Clock = 100000000; /* incredible value */
-
-	 if (p->status == MODE_OK) {
-            for (pMon = pI830->pScrn_2->monitor->Modes; pMon != NULL; pMon = pMon->next) {
-               if ((pMon->HDisplay != p->HDisplay) ||
-                   (pMon->VDisplay != p->VDisplay) ||
-                   (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
-                   continue;
-
-               /* Find lowest supported Clock for this resolution */
-               if (Clock > pMon->Clock)
-                  Clock = pMon->Clock;
-            } 
-
-            if (Clock != 100000000 && DDCclock2 < 2550 && Clock / 1000.0 > DDCclock2) {
-               ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n",
-		   p->name, pI830->pScrn_2->monitor->id,
-		   Clock/1000.0, DDCclock2);
-               p->status = MODE_BAD;
-            } 
- 	 }
-         p = p->next;
-      } while (p != NULL && p != pI830->pScrn_2->modes);
-   }
-
-   xf86PruneDriverModes(pScrn);
-   I830PrintModes(pScrn);
-
-   /* Now check if the previously used mode is o.k. for the current monitor.
-    * This allows VT switching to continue happily when not disconnecting
-    * and reconnecting monitors */
-
-   pScrn->currentMode = pScrn->modes;
-
-   if (pI830->MergedFB) {
-      /* If no virtual dimension was given by the user,
-       * calculate a sane one now. Adapts pScrn->virtualX,
-       * pScrn->virtualY and pScrn->displayWidth.
-       */
-      I830RecalcDefaultVirtualSize(pScrn);
-
-      pScrn->modes = pScrn->modes->next;  /* We get the last from GenerateModeList(), skip to first */
-      pScrn->currentMode = pScrn->modes;
-      pI830->currentMode = pScrn->currentMode;
-   }
-
-   pScrn->displayWidth = displayWidth; /* restore old displayWidth */
-
-   p = pScrn->modes;
-   if (p == NULL)
-      return FALSE;
-   do {
-      if ((p->HDisplay == curHDisplay) &&
-          (p->VDisplay == curVDisplay) &&
-          (!(p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))) {
-   		pScrn->currentMode = p; /* previous mode is o.k. */
-	}
-      p = p->next;
-   } while (p != NULL && p != pScrn->modes);
-
-   I830PrintModes(pScrn);
-
-   /* Now readjust for panning if necessary */
-   {
-      pScrn->frameX0 = (pScrn->frameX0 + pScrn->frameX1 + 1 - pScrn->currentMode->HDisplay) / 2;
-
-      if (pScrn->frameX0 < 0)
-         pScrn->frameX0 = 0;
-
-      pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1;
-      if (pScrn->frameX1 >= pScrn->virtualX) {
-         pScrn->frameX0 = pScrn->virtualX - pScrn->currentMode->HDisplay;
-         pScrn->frameX1 = pScrn->virtualX - 1;
-      }
-
-      pScrn->frameY0 = (pScrn->frameY0 + pScrn->frameY1 + 1 - pScrn->currentMode->VDisplay) / 2;
-
-      if (pScrn->frameY0 < 0)
-         pScrn->frameY0 = 0;
-
-      pScrn->frameY1 = pScrn->frameY0 + pScrn->currentMode->VDisplay - 1;
-      if (pScrn->frameY1 >= pScrn->virtualY) {
-        pScrn->frameY0 = pScrn->virtualY - pScrn->currentMode->VDisplay;
-        pScrn->frameY1 = pScrn->virtualY - 1;
-      }
-   }
-
-   if (pI830->MergedFB)
-      I830AdjustFrameMerged(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
-   return TRUE;
-#endif /* 0 */
-}
-
 /*
  * This gets called when gaining control of the VT, and from ScreenInit().
  */
@@ -3925,10 +3721,6 @@ I830EnterVT(int scrnIndex, int flags)
    /* Mark that we'll need to re-set the mode for sure */
    memset(pI830->pipeCurMode, 0, sizeof(pI830->pipeCurMode));
 
-   /* Detect monitor change and switch to suitable mode */
-   if (!pI830->starting)
-      I830DetectMonitorChange(pScrn);
-
    if (!i830SetMode(pScrn, pScrn->currentMode))
       return FALSE;
    
diff-tree 88c12f577f80fa132ec45cdf456d8060f2ece4fd (from 2631014e9d5b2e64908ea413729eb5fd819b17fc)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Oct 23 18:57:57 2006 -0700

    Move LVDS initialization and blacklisting damage to the LVDS support file.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 4ee5fc2..9f986ec 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1092,7 +1092,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    int i, n;
    char *s;
    pointer pVBEModule = NULL;
-   Bool enable, has_lvds, is_apple_945gm = FALSE;
+   Bool enable;
    const char *chipname;
    unsigned int ver;
    char v[5];
@@ -1235,7 +1235,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       pI830->pVbe = pI8301->pVbe;
    }
 
-   has_lvds = TRUE;
    switch (pI830->PciInfo->chipType) {
    case PCI_CHIP_I830_M:
       chipname = "830M";
@@ -1269,11 +1268,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       break;
    case PCI_CHIP_I865_G:
       chipname = "865G";
-      has_lvds = FALSE;
       break;
    case PCI_CHIP_I915_G:
       chipname = "915G";
-      has_lvds = FALSE;
       break;
    case PCI_CHIP_E7221_G:
       chipname = "E7221 (i915)";
@@ -1283,7 +1280,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       break;
    case PCI_CHIP_I945_G:
       chipname = "945G";
-      has_lvds = FALSE;
       break;
    case PCI_CHIP_I945_GM:
       chipname = "945GM";
@@ -1540,23 +1536,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    pI830->MonType2 = PIPE_NONE;
    pI830->specifiedMonitor = FALSE;
 
-   /* Always check for LVDS info once at startup.  We hook in the BIOS data
-    * dumping here (this should be cleaner) and we get to rely on having the
-    * LVDS info later on.
-    */
-   if (!i830GetLVDSInfoFromBIOS(pScrn))
-      has_lvds = FALSE;
-
-   /* Blacklist machines with known broken BIOSes */
-   if (pI830->PciInfo->chipType == PCI_CHIP_I945_GM) {
-	if (pI830->PciInfo->subsysVendor == 0xa0a0)  /* aopen mini pc */
-	    has_lvds = FALSE;
-
-	if ((pI830->PciInfo->subsysVendor == 0x8086) &&
-	    (pI830->PciInfo->subsysCard == 0x7270)) /* mini, macbook pro... */
-	    is_apple_945gm = TRUE;
-   }
-
    if ((s = xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT)) &&
       I830IsPrimary(pScrn)) {
       char *Mon1;
@@ -1645,33 +1624,19 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       pI830->specifiedMonitor = TRUE;
    } else if (I830IsPrimary(pScrn)) {
       /* Choose a default set of outputs to use based on what we've detected. */
-
-      /*
-       * Apple hardware is out to get us.  The macbook pro has a real LVDS
-       * panel, but the mac mini does not, and they have the same device IDs.
-       * We'll distinguish by panel size, on the assumption that Apple isn't
-       * about to make any machines with an 800x600 display.
-       */
-      if (is_apple_945gm && pI830->PanelXRes == 800 && pI830->PanelYRes == 600)
-      {
-	  xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		     "Suspected Mac Mini, ignoring the LFP\n");
-	  has_lvds = FALSE;
-      }
-
-      if (has_lvds) {
-	 pI830->MonType2 |= PIPE_LFP;
-      }
-
       if (i830DetectCRT(pScrn, TRUE)) {
 	 pI830->MonType1 |= PIPE_CRT;
       }
 
       /* Check for attached SDVO outputs.  Assume that they're flat panels for
        * now.  Though really, it's just a name at the moment, since we don't
-       * treat different SDVO outputs differently.
+       * treat different SDVO outputs differently.  Also, check for LVDS and
+       * set it  to the right pipe if available.
        */
       for (i = 0; i < pI830->num_outputs; i++) {
+	 if (pI830->output[i].type == I830_OUTPUT_LVDS)
+	    pI830->MonType2 |= PIPE_LFP;
+
 	 if (pI830->output[i].type == I830_OUTPUT_SDVO) {
 	    if (!i830_sdvo_detect_displays(pScrn, &pI830->output[i]))
 	       continue;
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 399324f..5b039b8 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -181,6 +181,39 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
 
+    /* Get the LVDS fixed mode out of the BIOS.  We should support LVDS with
+     * the BIOS being unavailable or broken, but lack the configuration options
+     * for now.
+     */
+    if (!i830GetLVDSInfoFromBIOS(pScrn))
+	return;
+
+    /* Blacklist machines with BIOSes that list an LVDS panel without actually
+     * having one.
+     */
+    if (pI830->PciInfo->chipType == PCI_CHIP_I945_GM) {
+	if (pI830->PciInfo->subsysVendor == 0xa0a0)  /* aopen mini pc */
+	    return;
+
+	if ((pI830->PciInfo->subsysVendor == 0x8086) &&
+	    (pI830->PciInfo->subsysCard == 0x7270)) {
+	    /* It's a Mac Mini or Macbook Pro.
+	     *
+	     * Apple hardware is out to get us.  The macbook pro has a real
+	     * LVDS panel, but the mac mini does not, and they have the same
+	     * device IDs.  We'll distinguish by panel size, on the assumption
+	     * that Apple isn't about to make any machines with an 800x600
+	     * display.
+	     */
+
+	    if (pI830->PanelXRes == 800 && pI830->PanelYRes == 600) {
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			   "Suspected Mac Mini, ignoring the LVDS\n");
+		return;
+	    }
+	}
+   }
+
     pI830->output[pI830->num_outputs].type = I830_OUTPUT_LVDS;
     pI830->output[pI830->num_outputs].dpms = i830_lvds_dpms;
     pI830->output[pI830->num_outputs].save = i830_lvds_save;



More information about the xorg-commit mailing list