[PATCH] [RFC] xf86Crtc: Trust the drivers to report the correct output modes
Chris Wilson
chris at chris-wilson.co.uk
Thu Aug 5 10:59:59 PDT 2010
In the absence of the user specifying an overriding monitor
configuration, trust the KMS drivers to have correctly probed the output
modes.
This avoids duplicating work already done by the kernel (when using KMS)
and secondly avoids disagreements (which admittedly shouldn't exist in
an ideal world) between the kernel and X over valid modes.
References:
Bug 23833 - X uses different refresh rate to that set by kernel module
https://bugs.freedesktop.org/show_bug.cgi?id=23833
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
hw/xfree86/modes/xf86Crtc.c | 264 ++++++++++++++++++++++---------------------
1 files changed, 136 insertions(+), 128 deletions(-)
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index b2daec7..d9672bb 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1554,23 +1554,14 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
}
/* Probe the list of modes for each output. */
- for (o = 0; o < config->num_output; o++)
+ for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
- DisplayModePtr mode;
DisplayModePtr config_modes = NULL, output_modes, default_modes = NULL;
+ DisplayModePtr mode;
char *preferred_mode;
- xf86MonPtr edid_monitor;
XF86ConfMonitorPtr conf_monitor;
- MonRec mon_rec;
- int min_clock = 0;
- int max_clock = 0;
- double clock;
- Bool add_default_modes = xf86ReturnOptValBool(output->options, OPTION_DEFAULT_MODES, TRUE);
- Bool debug_modes = config->debug_modes ||
- xf86Initialising;
- enum det_monrec_source sync_source = sync_default;
-
+
while (output->probed_modes != NULL)
xf86DeleteMode(&output->probed_modes, output->probed_modes);
@@ -1586,148 +1577,165 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
continue;
}
- memset (&mon_rec, '\0', sizeof (mon_rec));
-
+ output_modes = (*output->funcs->get_modes) (output);
+
conf_monitor = output->conf_monitor;
-
- if (conf_monitor)
+ if (output_modes == NULL || conf_monitor)
{
+ xf86MonPtr edid_monitor;
+ MonRec mon_rec;
+ int min_clock = 0;
+ int max_clock = 0;
+ double clock;
+ Bool add_default_modes = xf86ReturnOptValBool(output->options, OPTION_DEFAULT_MODES, TRUE);
+ Bool debug_modes = config->debug_modes ||
+ xf86Initialising;
+ enum det_monrec_source sync_source = sync_default;
int i;
-
- for (i = 0; i < conf_monitor->mon_n_hsync; i++)
+
+ memset (&mon_rec, '\0', sizeof (mon_rec));
+
+ if (conf_monitor)
{
- mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo;
- mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi;
- mon_rec.nHsync++;
- sync_source = sync_config;
+ for (i = 0; i < conf_monitor->mon_n_hsync; i++)
+ {
+ mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo;
+ mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi;
+ mon_rec.nHsync++;
+ sync_source = sync_config;
+ }
+ for (i = 0; i < conf_monitor->mon_n_vrefresh; i++)
+ {
+ mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo;
+ mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi;
+ mon_rec.nVrefresh++;
+ sync_source = sync_config;
+ }
+ config_modes = xf86GetMonitorModes (scrn, conf_monitor);
}
- for (i = 0; i < conf_monitor->mon_n_vrefresh; i++)
+
+ edid_monitor = output->MonInfo;
+ if (edid_monitor)
{
- mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo;
- mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi;
- mon_rec.nVrefresh++;
- sync_source = sync_config;
+ struct det_monrec_parameter p;
+ struct disp_features *features = &edid_monitor->features;
+
+ /* if display is not continuous-frequency, don't add default modes */
+ if (!GTF_SUPPORTED(features->msc))
+ add_default_modes = FALSE;
+
+ p.mon_rec = &mon_rec;
+ p.max_clock = &max_clock;
+ p.set_hsync = mon_rec.nHsync == 0;
+ p.set_vrefresh = mon_rec.nVrefresh == 0;
+ p.sync_source = &sync_source;
+
+ xf86ForEachDetailedBlock(edid_monitor,
+ handle_detailed_monrec,
+ &p);
}
- config_modes = xf86GetMonitorModes (scrn, conf_monitor);
- }
-
- output_modes = (*output->funcs->get_modes) (output);
-
- edid_monitor = output->MonInfo;
-
- if (edid_monitor)
- {
- struct det_monrec_parameter p;
- struct disp_features *features = &edid_monitor->features;
-
- /* if display is not continuous-frequency, don't add default modes */
- if (!GTF_SUPPORTED(features->msc))
- add_default_modes = FALSE;
-
- p.mon_rec = &mon_rec;
- p.max_clock = &max_clock;
- p.set_hsync = mon_rec.nHsync == 0;
- p.set_vrefresh = mon_rec.nVrefresh == 0;
- p.sync_source = &sync_source;
-
- xf86ForEachDetailedBlock(edid_monitor,
- handle_detailed_monrec,
- &p);
- }
- 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;
+ 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;
- /* If we still don't have a sync range, guess wildly */
- if (!mon_rec.nHsync || !mon_rec.nVrefresh)
- GuessRangeFromModes(&mon_rec, output_modes);
+ /* If we still don't have a sync range, guess wildly */
+ if (!mon_rec.nHsync || !mon_rec.nVrefresh)
+ GuessRangeFromModes(&mon_rec, output_modes);
- /*
- * 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
- * specified
- */
- if (mon_rec.nHsync == 0)
- {
- mon_rec.hsync[0].lo = 31.0;
- mon_rec.hsync[0].hi = 55.0;
- mon_rec.nHsync = 1;
- }
- if (mon_rec.nVrefresh == 0)
- {
- mon_rec.vrefresh[0].lo = 58.0;
- mon_rec.vrefresh[0].hi = 62.0;
- mon_rec.nVrefresh = 1;
- }
+ /*
+ * 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
+ * specified
+ */
+ if (mon_rec.nHsync == 0)
+ {
+ mon_rec.hsync[0].lo = 31.0;
+ mon_rec.hsync[0].hi = 55.0;
+ mon_rec.nHsync = 1;
+ }
+ if (mon_rec.nVrefresh == 0)
+ {
+ mon_rec.vrefresh[0].lo = 58.0;
+ mon_rec.vrefresh[0].hi = 62.0;
+ mon_rec.nVrefresh = 1;
+ }
- if (add_default_modes)
- default_modes = xf86GetDefaultModes ();
+ if (add_default_modes)
+ default_modes = xf86GetDefaultModes ();
- /*
- * If this is not an RB monitor, remove RB modes from the default
- * pool. RB modes from the config or the monitor itself are fine.
- */
- if (!mon_rec.reducedblanking)
- xf86ValidateModesReducedBlanking (scrn, default_modes);
+ /*
+ * If this is not an RB monitor, remove RB modes from the default
+ * pool. RB modes from the config or the monitor itself are fine.
+ */
+ if (!mon_rec.reducedblanking)
+ xf86ValidateModesReducedBlanking (scrn, default_modes);
- if (sync_source == sync_config)
- {
- /*
- * Check output and config modes against sync range from config file
+ if (sync_source == sync_config)
+ {
+ /*
+ * Check output and config modes against sync range from
+ * config file
+ */
+ xf86ValidateModesSync (scrn, output_modes, &mon_rec);
+ xf86ValidateModesSync (scrn, config_modes, &mon_rec);
+ }
+ /*
+ * Check default modes against sync range
*/
- xf86ValidateModesSync (scrn, output_modes, &mon_rec);
- xf86ValidateModesSync (scrn, config_modes, &mon_rec);
- }
- /*
- * Check default modes against sync range
- */
- xf86ValidateModesSync (scrn, default_modes, &mon_rec);
- /*
- * Check default modes against monitor max clock
- */
- if (max_clock) {
- xf86ValidateModesClocks(scrn, default_modes,
- &min_clock, &max_clock, 1);
- xf86ValidateModesClocks(scrn, output_modes,
- &min_clock, &max_clock, 1);
- }
-
- output->probed_modes = NULL;
- output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
- output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes);
- output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
-
- /*
- * Check all modes against max size, interlace, and doublescan
- */
- if (maxX && maxY)
- xf86ValidateModesSize (scrn, output->probed_modes,
+ xf86ValidateModesSync (scrn, default_modes, &mon_rec);
+ /*
+ * Check default modes against monitor max clock
+ */
+ if (max_clock) {
+ xf86ValidateModesClocks(scrn, default_modes,
+ &min_clock, &max_clock, 1);
+ xf86ValidateModesClocks(scrn, output_modes,
+ &min_clock, &max_clock, 1);
+ }
+
+ output->probed_modes = NULL;
+ output->probed_modes = xf86ModesAdd(output->probed_modes,
+ config_modes);
+ output->probed_modes = xf86ModesAdd(output->probed_modes,
+ output_modes);
+ output->probed_modes = xf86ModesAdd(output->probed_modes,
+ default_modes);
+
+ /*
+ * Check all modes against max size, interlace, and doublescan
+ */
+ if (maxX && maxY)
+ xf86ValidateModesSize (scrn, output->probed_modes,
maxX, maxY, 0);
+ {
+ int flags = (output->interlaceAllowed ? V_INTERLACE : 0) |
+ (output->doubleScanAllowed ? V_DBLSCAN : 0);
+ xf86ValidateModesFlags (scrn, output->probed_modes, flags);
+ }
+ }
+ else
{
- int flags = (output->interlaceAllowed ? V_INTERLACE : 0) |
- (output->doubleScanAllowed ? V_DBLSCAN : 0);
- xf86ValidateModesFlags (scrn, output->probed_modes, flags);
+ output->probed_modes = output_modes;
}
-
+
/*
* Check all modes against output
*/
- for (mode = output->probed_modes; mode != NULL; mode = mode->next)
+ for (mode = output->probed_modes; mode != NULL; mode = mode->next)
if (mode->status == MODE_OK)
mode->status = (*output->funcs->mode_valid)(output, mode);
-
+
xf86PruneInvalidModes(scrn, &output->probed_modes, debug_modes);
-
+
output->probed_modes = xf86SortModes (output->probed_modes);
-
+
/* Check for a configured preference for a particular mode */
preferred_mode = preferredMode(scrn, output);
-
if (preferred_mode)
{
for (mode = output->probed_modes; mode; mode = mode->next)
@@ -1750,7 +1758,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
}
}
}
-
+
output->initial_rotation = xf86OutputInitialRotation (output);
if (debug_modes) {
--
1.7.1
More information about the xorg-devel
mailing list