diff options
Diffstat (limited to 'drivers/gpu/drm/drm_modes.c')
-rw-r--r-- | drivers/gpu/drm/drm_modes.c | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 4a3f68a33844..c397b523c945 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -833,7 +833,7 @@ EXPORT_SYMBOL(drm_mode_get_hv_timing); */ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) { - if ((p == NULL) || ((p->type & DRM_MODE_TYPE_CRTC_C) == DRM_MODE_TYPE_BUILTIN)) + if (!p) return; p->crtc_clock = p->clock; @@ -1023,19 +1023,18 @@ 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 +static enum drm_mode_status drm_mode_validate_basic(const struct drm_display_mode *mode) { + if (mode->type & ~DRM_MODE_TYPE_ALL) + return MODE_BAD; + + if (mode->flags & ~DRM_MODE_FLAG_ALL) + return MODE_BAD; + + if ((mode->flags & DRM_MODE_FLAG_3D_MASK) > DRM_MODE_FLAG_3D_MAX) + return MODE_BAD; + if (mode->clock == 0) return MODE_CLOCK_LOW; @@ -1053,7 +1052,35 @@ drm_mode_validate_basic(const struct drm_display_mode *mode) return MODE_OK; } -EXPORT_SYMBOL(drm_mode_validate_basic); + +/** + * drm_mode_validate_driver - make sure the mode is somewhat sane + * @dev: drm device + * @mode: mode to check + * + * First do basic validation on the mode, and then allow the driver + * to check for device/driver specific limitations via the optional + * &drm_mode_config_helper_funcs.mode_valid hook. + * + * Returns: + * The mode status + */ +enum drm_mode_status +drm_mode_validate_driver(struct drm_device *dev, + const struct drm_display_mode *mode) +{ + enum drm_mode_status status; + + status = drm_mode_validate_basic(mode); + if (status != MODE_OK) + return status; + + if (dev->mode_config.funcs->mode_valid) + return dev->mode_config.funcs->mode_valid(dev, mode); + else + return MODE_OK; +} +EXPORT_SYMBOL(drm_mode_validate_driver); /** * drm_mode_validate_size - make sure modes adhere to size constraints @@ -1555,6 +1582,7 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out, /** * drm_crtc_convert_umode - convert a modeinfo into a drm_display_mode + * @dev: drm device * @out: drm_display_mode to return to the user * @in: drm_mode_modeinfo to use * @@ -1564,7 +1592,8 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out, * Returns: * Zero on success, negative errno on failure. */ -int drm_mode_convert_umode(struct drm_display_mode *out, +int drm_mode_convert_umode(struct drm_device *dev, + struct drm_display_mode *out, const struct drm_mode_modeinfo *in) { int ret = -EINVAL; @@ -1574,9 +1603,6 @@ int drm_mode_convert_umode(struct drm_display_mode *out, goto out; } - if ((in->flags & DRM_MODE_FLAG_3D_MASK) > DRM_MODE_FLAG_3D_MAX) - goto out; - out->clock = in->clock; out->hdisplay = in->hdisplay; out->hsync_start = in->hsync_start; @@ -1594,7 +1620,7 @@ int drm_mode_convert_umode(struct drm_display_mode *out, strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); out->name[DRM_DISPLAY_MODE_LEN-1] = 0; - out->status = drm_mode_validate_basic(out); + out->status = drm_mode_validate_driver(dev, out); if (out->status != MODE_OK) goto out; |