aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_modes.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2017-11-14 20:32:57 +0200
committerVille Syrjälä <ville.syrjala@linux.intel.com>2018-01-29 21:51:51 +0200
commit75a655e0a26cf0bfbaaa8df0ff5a9d1807bb1f4e (patch)
treedd77ee71b0813434e34d971aeaa1a64251a24545 /drivers/gpu/drm/drm_modes.c
parentdrm/uapi: Deprecate nonsense kms mode types (diff)
downloadlinux-dev-75a655e0a26cf0bfbaaa8df0ff5a9d1807bb1f4e.tar.xz
linux-dev-75a655e0a26cf0bfbaaa8df0ff5a9d1807bb1f4e.zip
drm/modes: Provide global mode_valid hook
Allow drivers to provide a device wide .mode_valid() hook in addition to the already existing crtc/encoder/bridge/connector hooks. This can be used to validate device/driver wide constraings without having to add those to the other hooks. And since we call this hook also for user modes later on in the modeset we don't have to worry about anything the hook has already rejected. I also have some further ideas for this hook. Eg. we could replace the drm_mode_set_crtcinfo(HALVE_V) call in drm_mode_convert_umode()/etc. with a driver specific variant via this hook. At least on i915 we would like to pass CRTC_STEREO_DOUBLE to that function instead, and then we could safely use the crtc_ timings in all our .mode_valid() hooks, which would allow us to reuse those hooks for validating the adjusted_mode during a modeset. v2: Fix the language fails in the kernel docs (Daniel) Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20171114183258.16976-10-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/drm_modes.c')
-rw-r--r--drivers/gpu/drm/drm_modes.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index b35324a50fdf..c397b523c945 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1023,17 +1023,7 @@ 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)
@@ -1062,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
@@ -1564,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
*
@@ -1573,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;
@@ -1600,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;