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