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 <[email protected]>
---
 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 1024x...@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 1024x...@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

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to