summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2014-12-17 13:56:23 +0200
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-12-17 18:29:35 +0100
commitabc0b1447d4974963548777a5ba4a4457c82c426 (patch)
tree37d56dd85aefc2ec4f297268b11242e3ddbf89fa /drivers/gpu
parent05acaec334fcc1132d1e48c5042e044651e0b75b (diff)
drm: Perform basic sanity checks on probed modes
Make sure the timings of probed modes at least pass some very basic sanity checks. The checks include: - clock,hdisplay,vdisplay are non zero - sync pulse fits within the blanking period - htotal,vtotal are big enough I have not checked all the drivers to see if the modes the generate might violate these constraints. I'm hoping not, because that would mean either abandoning the idea of doing this from the core code, or fixing the drivers. I'm not entirely sure about limiting the sync pulse to the blanking period. Intel hardware doesn't support such things, but some other hardware might. However at least HDMI doesn't allow having sync pulse edges within the active period, so I'm thinking the check is probably OK to have in the common code. 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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/drm_modes.c32
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c5
2 files changed, 36 insertions, 1 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 19188667f92..11cc4deca55 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -906,6 +906,38 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
/**
+ * drm_mode_validate_basic - make sure the mode is somewhat sane
+ * @mode: mode to check
+ *
+ * Check that the mode timings are at least somewhat reasonable.
+ * Any hardware specific limits are left up for each driver to check.
+ *
+ * Returns:
+ * The mode status
+ */
+enum drm_mode_status
+drm_mode_validate_basic(const struct drm_display_mode *mode)
+{
+ if (mode->clock == 0)
+ return MODE_CLOCK_LOW;
+
+ if (mode->hdisplay == 0 ||
+ mode->hsync_start < mode->hdisplay ||
+ mode->hsync_end < mode->hsync_start ||
+ mode->htotal < mode->hsync_end)
+ return MODE_H_ILLEGAL;
+
+ if (mode->vdisplay == 0 ||
+ mode->vsync_start < mode->vdisplay ||
+ mode->vsync_end < mode->vsync_start ||
+ mode->vtotal < mode->vsync_end)
+ return MODE_V_ILLEGAL;
+
+ return MODE_OK;
+}
+EXPORT_SYMBOL(drm_mode_validate_basic);
+
+/**
* drm_mode_validate_size - make sure modes adhere to size constraints
* @mode: mode to check
* @maxX: maximum width
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 2161d8ed7c6..2fbdcca7ca9 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -167,7 +167,10 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
mode_flags |= DRM_MODE_FLAG_3D_MASK;
list_for_each_entry(mode, &connector->modes, head) {
- mode->status = drm_mode_validate_size(mode, maxX, maxY);
+ mode->status = drm_mode_validate_basic(mode);
+
+ if (mode->status == MODE_OK)
+ mode->status = drm_mode_validate_size(mode, maxX, maxY);
if (mode->status == MODE_OK)
mode->status = drm_mode_validate_flag(mode, mode_flags);