xf86-video-intel: Branch 'modesetting' - 3 commits - src/i830_display.c src/i830_driver.c src/i830_randr.c src/i830_sdvo.c src/i830_xf86Crtc.c src/i830_xf86Crtc.h

Keith Packard keithp at kemper.freedesktop.org
Wed Jan 3 10:39:20 EET 2007


 src/i830_display.c  |    3 
 src/i830_driver.c   |   25 ++-
 src/i830_randr.c    |    4 
 src/i830_sdvo.c     |    7 
 src/i830_xf86Crtc.c |  410 ++++++++++++++++++++++++++++++++++++++++++----------
 src/i830_xf86Crtc.h |   20 +-
 6 files changed, 378 insertions(+), 91 deletions(-)

New commits:
diff-tree 69f250af60220a875f4a04c6d682bffa352281e4 (from parents)
Merge: 232e2094321dbcdd6a67ef230eb50494a1c7d6df d960deab39eef91fb82b9f23118323aeb4c9c63e
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Wed Jan 3 00:39:15 2007 -0800

    Merge branch 'modesetting-origin' into modesetting

diff-tree 232e2094321dbcdd6a67ef230eb50494a1c7d6df (from 58e797b2caa6effa5455fc1f13dc4c58d0658744)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Wed Jan 3 00:38:34 2007 -0800

    Allow initial position to be set in config file. Increase 965 max size.
    
    Add relative and absolute position configuration code, using per-output
    monitor sections. Options include:
    
    	PreferredMode	selects a preferred mode for this output by name
    	Position	absolute position, x and y in a single string.
    
    	Below		relative positions; argument names other monitor.
    	RightOf
    	Above
    	LeftOf
    
    	Enable		force the monitor to be disabled by setting
    	Disable		enable to no or disable to yes.
    
    	MinClock	Set valid clock ranges
    	MaxClock
    
    Monitor sections can also include sync ranges, physical size and mode lines
    as documented in xorg.conf(5).
    
    Monitors are associated with outputs through options in the Device section:
    
    	Option "monitor-VGA" "My VGA Monitor"
    
    Output named 'VGA' will use monitor section "My VGA Monitor".

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5264767..694c96f 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -912,7 +912,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    Bool enable;
    const char *chipname;
    int num_pipe;
-   int max_width;
+   int max_width, max_height;
 #ifdef XF86DRI
    unsigned long savedMMSize;
 #endif
@@ -1183,10 +1183,16 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
    
    if (IS_I965G(pI830))
+   {
       max_width = 16384;
+      max_height = 4096;
+   }
    else
-      max_width = 8192 / pI830->cpp;
-   xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, 2048);
+   {
+      max_width = 2048;
+      max_height = 2048;
+   }
+   xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height);
 
    /* Some of the probing needs MMIO access, so map it here. */
    I830MapMMIO(pScrn);
@@ -1830,14 +1836,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 	      pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT,
 	      "VideoRam: %d KB\n", pScrn->videoRam);
 
-   if (!IS_I965G(pI830) && pScrn->displayWidth * pI830->cpp > 8192) {
+   if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		 "Cannot support DRI with frame buffer stride > 8K.\n");
+		 "Cannot support DRI with frame buffer width > 2048.\n");
       pI830->disableTiling = TRUE;
       pI830->directRenderingDisabled = TRUE;
    }
 
-   if (pScrn->virtualY > 2048) {
+   if (!IS_I965G(pI830) && pScrn->virtualY > 2048) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support > 2048 vertical lines. disabling acceleration.\n");
       pI830->noAccel = TRUE;
    }
@@ -3047,7 +3053,8 @@ i830AdjustFrame(int scrnIndex, int x, in
    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
    I830Ptr pI830 = I830PTR(pScrn);
-   xf86CrtcPtr	crtc = config->output[config->compat_output]->crtc;
+   xf86OutputPtr  output = config->output[config->compat_output];
+   xf86CrtcPtr	crtc = output->crtc;
 
    DPRINTF(PFX, "i830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
 	   x, pI830->xoffset, y, pI830->yoffset);
@@ -3059,7 +3066,7 @@ i830AdjustFrame(int scrnIndex, int x, in
 	 (*pI830->AccelInfoRec->Sync)(pScrn);
 	 pI830->AccelInfoRec->NeedToSync = FALSE;
       }
-      i830PipeSetBase(crtc, x, y);
+      i830PipeSetBase(crtc, output->initial_x + x, output->initial_y + y);
    }
 }
 
@@ -3596,7 +3603,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
        * is this.
        */
       
-      xf86ProbeOutputModes (pScrn);
+      xf86ProbeOutputModes (pScrn, 0, 0);
       xf86SetScrnInfoModes (pScrn);
       I830DGAReInit (pScrn->pScreen);
       xf86SwitchMode(pScrn->pScreen, pScrn->currentMode);
diff --git a/src/i830_randr.c b/src/i830_randr.c
index d5ccce3..83cf023 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -95,7 +95,7 @@ xf86RandR12GetInfo (ScreenPtr pScreen, R
     }
 
     /* Re-probe the outputs for new monitors or modes */
-    xf86ProbeOutputModes (scrp);
+    xf86ProbeOutputModes (scrp, 0, 0);
     xf86SetScrnInfoModes (scrp);
     I830DGAReInit (pScreen);
 
@@ -818,7 +818,7 @@ xf86RandR12GetInfo12 (ScreenPtr pScreen,
 {
     ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
 
-    xf86ProbeOutputModes (pScrn);
+    xf86ProbeOutputModes (pScrn, 0, 0);
     xf86SetScrnInfoModes (pScrn);
     I830DGAReInit (pScreen);
     return xf86RandR12SetInfo12 (pScreen);
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index b5116be..19b4b93 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1207,7 +1207,12 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int ou
     }
     strcpy (name, name_prefix);
     strcat (name, name_suffix);
-    xf86OutputRename (output, name);
+    if (!xf86OutputRename (output, name))
+    {
+	xf86OutputDestroy (output);
+	return;
+    }
+	
     
     /* Set the input timing to the screen. Assume always input 0. */
     i830_sdvo_set_target_input(output, TRUE, FALSE);
diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c
index a0f44df..ceb8f2e 100644
--- a/src/i830_xf86Crtc.c
+++ b/src/i830_xf86Crtc.c
@@ -127,6 +127,33 @@ xf86CrtcDestroy (xf86CrtcPtr crtc)
 
 extern XF86ConfigPtr xf86configptr;
 
+typedef enum {
+    OPTION_PREFERRED_MODE,
+    OPTION_POSITION,
+    OPTION_BELOW,
+    OPTION_RIGHT_OF,
+    OPTION_ABOVE,
+    OPTION_LEFT_OF,
+    OPTION_ENABLE,
+    OPTION_DISABLE,
+    OPTION_MIN_CLOCK,
+    OPTION_MAX_CLOCK,
+} OutputOpts;
+
+static OptionInfoRec xf86OutputOptions[] = {
+    {OPTION_PREFERRED_MODE, "PreferredMode",	OPTV_STRING,  {0}, FALSE },
+    {OPTION_POSITION,	    "Position",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_BELOW,	    "Below",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_RIGHT_OF,	    "RightOf",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_ABOVE,	    "Above",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_LEFT_OF,	    "LeftOf",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_ENABLE,	    "Enable",		OPTV_BOOLEAN, {0}, FALSE },
+    {OPTION_DISABLE,	    "Disable",		OPTV_BOOLEAN, {0}, FALSE },
+    {OPTION_MIN_CLOCK,	    "MinClock",		OPTV_FREQ,    {0}, FALSE },
+    {OPTION_MAX_CLOCK,	    "MaxClock",		OPTV_FREQ,    {0}, FALSE },
+    {-1,		    NULL,		OPTV_NONE,    {0}, FALSE },
+};
+
 static void
 xf86OutputSetMonitor (xf86OutputPtr output)
 {
@@ -134,6 +161,12 @@ xf86OutputSetMonitor (xf86OutputPtr outp
     static const char monitor_prefix[] = "monitor-";
     char    *monitor;
 
+    if (output->options)
+	xfree (output->options);
+
+    output->options = xnfalloc (sizeof (xf86OutputOptions));
+    memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions));
+    
     option_name = xnfalloc (strlen (monitor_prefix) +
 			    strlen (output->name) + 1);
     strcpy (option_name, monitor_prefix);
@@ -144,7 +177,24 @@ xf86OutputSetMonitor (xf86OutputPtr outp
     else
 	xf86MarkOptionUsedByName (output->scrn->options, option_name);
     xfree (option_name);
-    output->conf_monitor = xf86findMonitor (monitor, xf86configptr->conf_monitor_lst);
+    output->conf_monitor = xf86findMonitor (monitor,
+					    xf86configptr->conf_monitor_lst);
+    if (output->conf_monitor)
+	xf86ProcessOptions (output->scrn->scrnIndex,
+			    output->conf_monitor->mon_option_lst,
+			    output->options);
+}
+
+static Bool
+xf86OutputEnabled (xf86OutputPtr    output)
+{
+    /* Check to see if this output was disabled in the config file */
+    if (xf86ReturnOptValBool (output->options, OPTION_ENABLE, TRUE) == FALSE ||
+	xf86ReturnOptValBool (output->options, OPTION_DISABLE, FALSE) == TRUE)
+    {
+	return FALSE;
+    }
+    return TRUE;
 }
 
 xf86OutputPtr
@@ -167,6 +217,8 @@ xf86OutputCreate (ScrnInfoPtr		    scrn,
 #ifdef RANDR_12_INTERFACE
     output->randr_output = NULL;
 #endif
+    xf86OutputSetMonitor (output);
+    
     if (xf86_config->output)
 	outputs = xrealloc (xf86_config->output,
 			  (xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
@@ -181,24 +233,24 @@ xf86OutputCreate (ScrnInfoPtr		    scrn,
     xf86_config->output = outputs;
     xf86_config->output[xf86_config->num_output++] = output;
     
-    xf86OutputSetMonitor (output);
     return output;
 }
 
-void
+Bool
 xf86OutputRename (xf86OutputPtr output, const char *name)
 {
     int	    len = strlen(name);
     char    *newname = xalloc (len + 1);
     
     if (!newname)
-	return;	/* so sorry... */
+	return FALSE;	/* so sorry... */
     
     strcpy (newname, name);
     if (output->name != (char *) (output + 1))
 	xfree (output->name);
     output->name = newname;
     xf86OutputSetMonitor (output);
+    return TRUE;
 }
 
 void
@@ -375,7 +427,9 @@ xf86PickCrtcs (ScrnInfoPtr	pScrn,
 	     * If the two outputs desire the same mode,
 	     * see if they can be cloned
 	     */
-	    if (xf86ModesEqual (modes[o], modes[n]))
+	    if (xf86ModesEqual (modes[o], modes[n]) &&
+		config->output[o]->initial_x == config->output[n]->initial_x &&
+		config->output[o]->initial_y == config->output[n]->initial_y)
 	    {
 		for (l = 0; l < config->num_output; l++)
 		    if (output->possible_clones & (1 << l))
@@ -403,7 +457,8 @@ xf86PickCrtcs (ScrnInfoPtr	pScrn,
 
 /*
  * Compute the virtual size necessary to place all of the available
- * crtcs in a panorama configuration
+ * crtcs in the specified configuration and also large enough to
+ * resize any crtc to the largest available mode
  */
 
 static void
@@ -418,7 +473,13 @@ xf86DefaultScreenLimits (ScrnInfoPtr pSc
     for (c = 0; c < config->num_crtc; c++)
     {
 	int	    crtc_width = 0, crtc_height = 0;
+	xf86CrtcPtr crtc = config->crtc[c];
 
+	if (crtc->enabled)
+	{
+	    crtc_width = crtc->x + crtc->desiredMode.HDisplay;
+	    crtc_height = crtc->y + crtc->desiredMode.VDisplay;
+	}
 	for (o = 0; o < config->num_output; o++) 
 	{
 	    xf86OutputPtr   output = config->output[o];
@@ -436,7 +497,8 @@ xf86DefaultScreenLimits (ScrnInfoPtr pSc
 		    }
 		}
 	}
-	width += crtc_width;
+	if (crtc_width > width)
+	    width = crtc_width;
 	if (crtc_height > height)
 	    height = crtc_height;
     }
@@ -448,6 +510,186 @@ xf86DefaultScreenLimits (ScrnInfoPtr pSc
     *heightp = height;
 }
 
+#define POSITION_UNSET	-100000
+
+static Bool
+xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			o;
+    int			min_x, min_y;
+    
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+
+	output->initial_x = output->initial_y = POSITION_UNSET;
+    }
+    
+    /*
+     * Loop until all outputs are set
+     */
+    for (;;)
+    {
+	Bool	any_set = FALSE;
+	Bool	keep_going = FALSE;
+
+	for (o = 0; o < config->num_output; o++)	
+	{
+	    static const OutputOpts	relations[] = {
+		OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
+	    };
+	    xf86OutputPtr   output = config->output[o];
+	    xf86OutputPtr   relative;
+	    char	    *relative_name;
+	    char	    *position;
+	    OutputOpts	    relation;
+	    int		    r;
+
+	    if (output->initial_x != POSITION_UNSET)
+		continue;
+	    position = xf86GetOptValString (output->options,
+					    OPTION_POSITION);
+	    /*
+	     * Absolute position wins
+	     */
+	    if (position)
+	    {
+		int		    x, y;
+		if (sscanf (position, "%d %d", &x, &y) == 2)
+		{
+		    output->initial_x = x;
+		    output->initial_y = y;
+		}
+		else
+		{
+		    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+				"Output %s position not of form \"x y\"\n",
+				output->name);
+		    output->initial_x = output->initial_y = 0;
+		}
+		any_set = TRUE;
+		continue;
+	    }
+	    /*
+	     * Next comes relative positions
+	     */
+	    relation = 0;
+	    relative_name = NULL;
+	    for (r = 0; r < 4; r++)
+	    {
+		relation = relations[r];
+		relative_name = xf86GetOptValString (output->options,
+						     relation);
+		if (relative_name)
+		    break;
+	    }
+	    if (relative_name)
+	    {
+		int or;
+		relative = NULL;
+		for (or = 0; or < config->num_output; or++)
+		{
+		    xf86OutputPtr	out_rel = config->output[or];
+		    XF86ConfMonitorPtr	rel_mon = out_rel->conf_monitor;
+		    char		*name;
+
+		    if (rel_mon)
+			name = rel_mon->mon_identifier;
+		    else
+			name = out_rel->name;
+		    if (!strcmp (relative_name, name))
+		    {
+			relative = config->output[or];
+			break;
+		    }
+		}
+		if (!relative)
+		{
+		    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+				"Cannot position output %s relative to unknown output %s\n",
+				output->name, relative_name);
+		    output->initial_x = 0;
+		    output->initial_y = 0;
+		    any_set = TRUE;
+		    continue;
+		}
+		if (relative->initial_x == POSITION_UNSET)
+		{
+		    keep_going = TRUE;
+		    continue;
+		}
+		output->initial_x = relative->initial_x;
+		output->initial_y = relative->initial_y;
+		switch (relation) {
+		case OPTION_BELOW:
+		    output->initial_y += modes[or]->VDisplay;
+		    break;
+		case OPTION_RIGHT_OF:
+		    output->initial_x += modes[or]->HDisplay;
+		    break;
+		case OPTION_ABOVE:
+		    output->initial_y -= modes[o]->VDisplay;
+		    break;
+		case OPTION_LEFT_OF:
+		    output->initial_x -= modes[o]->HDisplay;
+		    break;
+		default:
+		    break;
+		}
+		any_set = TRUE;
+		continue;
+	    }
+	    
+	    /* Nothing set, just stick them at 0,0 */
+	    output->initial_x = 0;
+	    output->initial_y = 0;
+	    any_set = TRUE;
+	}
+	if (!keep_going)
+	    break;
+	if (!any_set) 
+	{
+	    for (o = 0; o < config->num_output; o++)
+	    {
+		xf86OutputPtr   output = config->output[o];
+		if (output->initial_x == POSITION_UNSET)
+		{
+		    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+				"Output position loop. Moving %s to 0,0\n",
+				output->name);
+		    output->initial_x = output->initial_y = 0;
+		    break;
+		}
+	    }
+	}
+    }
+
+    /*
+     * normalize positions
+     */
+    min_x = 1000000;
+    min_y = 1000000;
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+
+	if (output->initial_x < min_x)
+	    min_x = output->initial_x;
+	if (output->initial_y < min_y)
+	    min_y = output->initial_y;
+    }
+    
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+
+	output->initial_x -= min_x;
+	output->initial_y -= min_y;
+    }
+    return TRUE;
+}
+
 /*
  * XXX walk the monitor mode list and prune out duplicates that
  * are inserted by xf86DDCMonitorSet. In an ideal world, that
@@ -536,13 +778,13 @@ i830xf86SortModes (DisplayModePtr input)
 #define DEBUG_REPROBE 1
 
 void
-xf86ProbeOutputModes (ScrnInfoPtr pScrn)
+xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
 {
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
     int			o;
-    int			virtualX, virtualY;
 
-    xf86RandR12GetOriginalVirtualSize (pScrn, &virtualX, &virtualY);
+    if (maxX == 0 || maxY == 0)
+	xf86RandR12GetOriginalVirtualSize (pScrn, &maxX, &maxY);
 
     /* Elide duplicate modes before defaulting code uses them */
     xf86PruneDuplicateMonitorModes (pScrn->monitor);
@@ -553,11 +795,13 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn)
 	xf86OutputPtr	    output = config->output[o];
 	DisplayModePtr	    mode;
 	DisplayModePtr	    config_modes = NULL, output_modes, default_modes;
-	XF86ConfMonitorPtr  conf_monitor;
+	char		    *preferred_mode;
 	xf86MonPtr	    edid_monitor;
+	XF86ConfMonitorPtr  conf_monitor;
 	MonRec		    mon_rec;
 	int		    min_clock = 0;
 	int		    max_clock = 0;
+	double		    clock;
 	enum { sync_config, sync_edid, sync_default } sync_source = sync_default;
 	
 	while (output->probed_modes != NULL)
@@ -632,6 +876,14 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn)
 		}
 	    }
 	}
+
+	if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK,
+			       OPTUNITS_KHZ, &clock))
+	    min_clock = (int) clock;
+	if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK,
+			       OPTUNITS_KHZ, &clock))
+	    max_clock = (int) clock;
+
 	/*
 	 * These limits will end up setting a 1024x768 at 60Hz mode by default,
 	 * which seems like a fairly good mode to use when nothing else is
@@ -677,9 +929,11 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn)
 	output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
 	
 	/*
-	 * Check all modes against virtual size
+	 * Check all modes against max size
 	 */
-	i830xf86ValidateModesSize (pScrn, output->probed_modes, virtualX, virtualY, 0);
+	if (maxX && maxY)
+	    i830xf86ValidateModesSize (pScrn, output->probed_modes,
+				       maxX, maxY, 0);
 	 
 	/*
 	 * Check all modes against output
@@ -693,27 +947,28 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn)
 	output->probed_modes = i830xf86SortModes (output->probed_modes);
 	
 	/* Check for a configured preference for a particular mode */
-	if (conf_monitor)
-	{
-	    char  *preferred_mode = xf86findOptionValue (conf_monitor->mon_option_lst,
-							 "Preferred Mode");
+	preferred_mode = xf86GetOptValString (output->options,
+					      OPTION_PREFERRED_MODE);
 
-	    if (preferred_mode)
+	if (preferred_mode)
+	{
+	    for (mode = output->probed_modes; mode; mode = mode->next)
 	    {
-		for (mode = output->probed_modes; mode; mode = mode->next)
-		    if (!strcmp (preferred_mode, mode->name))
-			break;
-		if (mode && mode != output->probed_modes)
+		if (!strcmp (preferred_mode, mode->name))
 		{
-		    if (mode->prev)
-			mode->prev->next = mode->next;
-		    if (mode->next)
-			mode->next->prev = mode->prev;
-		    mode->next = output->probed_modes;
-		    output->probed_modes->prev = mode;
-		    mode->prev = NULL;
-		    output->probed_modes = mode;
+		    if (mode != output->probed_modes)
+		    {
+			if (mode->prev)
+			    mode->prev->next = mode->next;
+			if (mode->next)
+			    mode->next->prev = mode->prev;
+			mode->next = output->probed_modes;
+			output->probed_modes->prev = mode;
+			mode->prev = NULL;
+			output->probed_modes = mode;
+		    }
 		    mode->type |= M_T_PREFERRED;
+		    break;
 		}
 	    }
 	}
@@ -760,7 +1015,6 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
     xf86OutputPtr	output;
     xf86CrtcPtr		crtc;
     DisplayModePtr	last, mode;
-    int			originalVirtualX, originalVirtualY;
 
     output = config->output[config->compat_output];
     if (!output->crtc)
@@ -788,18 +1042,6 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
     /* Set pScrn->modes to the mode list for the 'compat' output */
     pScrn->modes = xf86DuplicateModes(pScrn, output->probed_modes);
 
-    xf86RandR12GetOriginalVirtualSize(pScrn, &originalVirtualX, &originalVirtualY);
-
-    /* Disable modes in the XFree86 DDX list that are larger than the current
-     * virtual size.
-     */
-    i830xf86ValidateModesSize(pScrn, pScrn->modes,
-			      originalVirtualX, originalVirtualY,
-			      pScrn->displayWidth);
-
-    /* Strip out anything that we threw out for virtualX/Y. */
-    i830xf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
-
     for (mode = pScrn->modes; mode; mode = mode->next)
 	if (xf86ModesEqual (mode, &crtc->desiredMode))
 	    break;
@@ -835,35 +1077,33 @@ xf86InitialConfiguration (ScrnInfoPtr	  
     DisplayModePtr	target_mode = NULL;
     xf86CrtcPtr		*crtcs;
     DisplayModePtr	*modes;
-    int			width, height;
-
-    xf86ProbeOutputModes (pScrn);
+    Bool		*enabled;
+    int			width;
+    int			height;
 
-    if (pScrn->display->virtualX == 0)
-    {
-	/*
-	 * Expand virtual size to cover potential mode switches
-	 */
-	xf86DefaultScreenLimits (pScrn, &width, &height);
-    
-	pScrn->display->virtualX = width;
-	pScrn->display->virtualY = height;
-    }
-    else
-    {
+    if (pScrn->display->virtualX)
 	width = pScrn->display->virtualX;
+    else
+	width = config->maxWidth;
+    if (pScrn->display->virtualY)
 	height = pScrn->display->virtualY;
-    }
-    if (width > pScrn->virtualX)
-	pScrn->virtualX = width;
-    if (height > pScrn->virtualY)
-	pScrn->virtualY = height;
-    
+    else
+	height = config->maxHeight;
+
+    xf86ProbeOutputModes (pScrn, width, height);
+
     crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
     modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
+    enabled = xnfcalloc (config->num_output, sizeof (Bool));
     
     for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr output = config->output[o];
+	
 	modes[o] = NULL;
+	enabled[o] = (xf86OutputEnabled (output) &&
+		      output->status != XF86OutputStatusDisconnected);
+    }
     
     /*
      * Let outputs with preferred modes drive screen size
@@ -872,7 +1112,7 @@ xf86InitialConfiguration (ScrnInfoPtr	  
     {
 	xf86OutputPtr output = config->output[o];
 
-	if (output->status != XF86OutputStatusDisconnected &&
+	if (enabled[o] &&
 	    xf86OutputHasPreferredMode (output, width, height))
 	{
 	    target_mode = xf86DefaultMode (output, width, height);
@@ -889,7 +1129,7 @@ xf86InitialConfiguration (ScrnInfoPtr	  
 	for (o = 0; o < config->num_output; o++)
 	{
 	    xf86OutputPtr output = config->output[o];
-	    if (output->status != XF86OutputStatusDisconnected)
+	    if (enabled[o])
 	    {
 		target_mode = xf86DefaultMode (output, width, height);
 		if (target_mode)
@@ -905,10 +1145,23 @@ xf86InitialConfiguration (ScrnInfoPtr	  
     {
 	xf86OutputPtr output = config->output[o];
 	
-	if (output->status != XF86OutputStatusDisconnected && !modes[o])
+	if (enabled[o] && !modes[o])
 	    modes[o] = xf86ClosestMode (output, target_mode, width, height);
     }
 
+    /*
+     * Set the position of each output
+     */
+    if (!xf86InitialOutputPositions (pScrn, modes))
+    {
+	xfree (crtcs);
+	xfree (modes);
+	return FALSE;
+    }
+	
+    /*
+     * Assign CRTCs to fit output configuration
+     */
     if (!xf86PickCrtcs (pScrn, crtcs, modes, 0, width, height))
     {
 	xfree (crtcs);
@@ -928,7 +1181,7 @@ xf86InitialConfiguration (ScrnInfoPtr	  
 	crtc->enabled = FALSE;
 	memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode));
     }
-	
+    
     /*
      * Set initial configuration
      */
@@ -942,13 +1195,28 @@ xf86InitialConfiguration (ScrnInfoPtr	  
 	{
 	    crtc->desiredMode = *mode;
 	    crtc->enabled = TRUE;
-	    crtc->x = 0;
-	    crtc->y = 0;
+	    crtc->x = output->initial_x;
+	    crtc->y = output->initial_y;
 	    output->crtc = crtc;
-	    /* XXX set position; for now, we clone */
 	}
     }
     
+    if (pScrn->display->virtualX == 0)
+    {
+	/*
+	 * Expand virtual size to cover potential mode switches
+	 */
+	xf86DefaultScreenLimits (pScrn, &width, &height);
+    
+	pScrn->display->virtualX = width;
+	pScrn->display->virtualY = height;
+    }
+
+    if (width > pScrn->virtualX)
+	pScrn->virtualX = width;
+    if (height > pScrn->virtualY)
+	pScrn->virtualY = height;
+    
     /* Mirror output modes to pScrn mode list */
     xf86SetScrnInfoModes (pScrn);
     
diff --git a/src/i830_xf86Crtc.h b/src/i830_xf86Crtc.h
index b30003e..2555c55 100644
--- a/src/i830_xf86Crtc.h
+++ b/src/i830_xf86Crtc.h
@@ -289,6 +289,16 @@ struct _xf86Output {
     DisplayModePtr	probed_modes;
 
     /**
+     * Options parsed from the related monitor section
+     */
+    OptionInfoPtr	options;
+    
+    /**
+     * Configured monitor section
+     */
+    XF86ConfMonitorPtr  conf_monitor;
+    
+    /**
      * Desired initial position
      */
     int			initial_x, initial_y;
@@ -313,12 +323,6 @@ struct _xf86Output {
     /** Output name */
     char		*name;
 
-    /** Configured monitor name */
-    char		*monitor_name;
-
-    /** Monitor information from config file */
-    XF86ConfMonitorPtr	conf_monitor;
-
     /** output-specific functions */
     const xf86OutputFuncsRec *funcs;
 
@@ -410,14 +414,14 @@ xf86OutputCreate (ScrnInfoPtr		scrn,
 		      const xf86OutputFuncsRec *funcs,
 		      const char	*name);
 
-void
+Bool
 xf86OutputRename (xf86OutputPtr output, const char *name);
 
 void
 xf86OutputDestroy (xf86OutputPtr	output);
 
 void
-xf86ProbeOutputModes (ScrnInfoPtr pScrn);
+xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY);
 
 void
 xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
diff-tree 58e797b2caa6effa5455fc1f13dc4c58d0658744 (from 5057769d3a7c1b3a94f49bbff47b9697f368d975)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Wed Jan 3 00:04:58 2007 -0800

    Sync dspbase/dspsurf registers by re-reading them.
    
    This seems to eliminate base/surf value confusion during EnterVT.

diff --git a/src/i830_display.c b/src/i830_display.c
index 9ec46a4..d124ba0 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -351,9 +351,12 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x,
 
     if (IS_I965G(pI830)) {
         OUTREG(dspbase, ((y * pScrn->displayWidth + x) * pI830->cpp));
+	(void) INREG(dspbase);
         OUTREG(dspsurf, Start);
+	(void) INREG(dspsurf);
     } else {
 	OUTREG(dspbase, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+	(void) INREG(dspbase);
     }
 
     crtc->x = x;



More information about the xorg-commit mailing list