drm: Reorganize probed mode validation
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 17 Dec 2014 11:56:22 +0000 (13:56 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 17 Dec 2014 17:29:28 +0000 (18:29 +0100)
Make drm_mode_validate_size() and drm_mode_validate_flag() deal with a
single mode instead of having each iterate through the mode list.

The hope is that in the future we might be able to share various mode
validation functions between modeset and get_modes.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/drm_modes.c
drivers/gpu/drm/drm_probe_helper.c
include/drm/drm_modes.h

index 6d8b941c8200414f1bf3b193cbdc395c27e8622d..19188667f9287d4702da95b50525acfd2a423e10 100644 (file)
@@ -907,8 +907,7 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
 
 /**
  * drm_mode_validate_size - make sure modes adhere to size constraints
- * @dev: DRM device
- * @mode_list: list of modes to check
+ * @mode: mode to check
  * @maxX: maximum width
  * @maxY: maximum height
  *
@@ -916,20 +915,21 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
  * limitations of the DRM device/connector. If a mode is too big its status
  * member is updated with the appropriate validation failure code. The list
  * itself is not changed.
+ *
+ * Returns:
+ * The mode status
  */
-void drm_mode_validate_size(struct drm_device *dev,
-                           struct list_head *mode_list,
-                           int maxX, int maxY)
+enum drm_mode_status
+drm_mode_validate_size(const struct drm_display_mode *mode,
+                      int maxX, int maxY)
 {
-       struct drm_display_mode *mode;
+       if (maxX > 0 && mode->hdisplay > maxX)
+               return MODE_VIRTUAL_X;
 
-       list_for_each_entry(mode, mode_list, head) {
-               if (maxX > 0 && mode->hdisplay > maxX)
-                       mode->status = MODE_VIRTUAL_X;
+       if (maxY > 0 && mode->vdisplay > maxY)
+               return MODE_VIRTUAL_Y;
 
-               if (maxY > 0 && mode->vdisplay > maxY)
-                       mode->status = MODE_VIRTUAL_Y;
-       }
+       return MODE_OK;
 }
 EXPORT_SYMBOL(drm_mode_validate_size);
 
index 7483a47de8e41630a37e7db22c5e9585dff11013..2161d8ed7c6583ab44079de3fc70b58c06b3269f 100644 (file)
 static bool drm_kms_helper_poll = true;
 module_param_named(poll, drm_kms_helper_poll, bool, 0600);
 
-static void drm_mode_validate_flag(struct drm_connector *connector,
-                                  int flags)
+static enum drm_mode_status
+drm_mode_validate_flag(const struct drm_display_mode *mode,
+                      int flags)
 {
-       struct drm_display_mode *mode;
+       if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
+           !(flags & DRM_MODE_FLAG_INTERLACE))
+               return MODE_NO_INTERLACE;
 
-       if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
-                     DRM_MODE_FLAG_3D_MASK))
-               return;
+       if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
+           !(flags & DRM_MODE_FLAG_DBLSCAN))
+               return MODE_NO_DBLESCAN;
 
-       list_for_each_entry(mode, &connector->modes, head) {
-               if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
-                               !(flags & DRM_MODE_FLAG_INTERLACE))
-                       mode->status = MODE_NO_INTERLACE;
-               if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
-                               !(flags & DRM_MODE_FLAG_DBLSCAN))
-                       mode->status = MODE_NO_DBLESCAN;
-               if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
-                               !(flags & DRM_MODE_FLAG_3D_MASK))
-                       mode->status = MODE_NO_STEREO;
-       }
+       if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
+           !(flags & DRM_MODE_FLAG_3D_MASK))
+               return MODE_NO_STEREO;
 
-       return;
+       return MODE_OK;
 }
 
 static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
@@ -164,18 +159,19 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
 
        drm_mode_connector_list_update(connector, merge_type_bits);
 
-       if (maxX && maxY)
-               drm_mode_validate_size(dev, &connector->modes, maxX, maxY);
-
        if (connector->interlace_allowed)
                mode_flags |= DRM_MODE_FLAG_INTERLACE;
        if (connector->doublescan_allowed)
                mode_flags |= DRM_MODE_FLAG_DBLSCAN;
        if (connector->stereo_allowed)
                mode_flags |= DRM_MODE_FLAG_3D_MASK;
-       drm_mode_validate_flag(connector, mode_flags);
 
        list_for_each_entry(mode, &connector->modes, head) {
+               mode->status = drm_mode_validate_size(mode, maxX, maxY);
+
+               if (mode->status == MODE_OK)
+                       mode->status = drm_mode_validate_flag(mode, mode_flags);
+
                if (mode->status == MODE_OK && connector_funcs->mode_valid)
                        mode->status = connector_funcs->mode_valid(connector,
                                                                   mode);
index 91d0582f924e3e90539f0373b4daaaa2b20ae9cb..6c531140d4584b25f0fc2ebea7120f18fdfd23cf 100644 (file)
@@ -217,9 +217,8 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
                                        const struct drm_display_mode *mode2);
 
 /* for use by the crtc helper probe functions */
-void drm_mode_validate_size(struct drm_device *dev,
-                           struct list_head *mode_list,
-                           int maxX, int maxY);
+enum drm_mode_status drm_mode_validate_size(const struct drm_display_mode *mode,
+                                           int maxX, int maxY);
 void drm_mode_prune_invalid(struct drm_device *dev,
                            struct list_head *mode_list, bool verbose);
 void drm_mode_sort(struct list_head *mode_list);