|
@@ -392,6 +392,83 @@ struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+static int set_property_legacy(struct drm_mode_object *obj,
|
|
|
+ struct drm_property *prop,
|
|
|
+ uint64_t prop_value)
|
|
|
+{
|
|
|
+ struct drm_device *dev = prop->dev;
|
|
|
+ struct drm_mode_object *ref;
|
|
|
+ int ret = -EINVAL;
|
|
|
+
|
|
|
+ if (!drm_property_change_valid_get(prop, prop_value, &ref))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ drm_modeset_lock_all(dev);
|
|
|
+ switch (obj->type) {
|
|
|
+ case DRM_MODE_OBJECT_CONNECTOR:
|
|
|
+ ret = drm_mode_connector_set_obj_prop(obj, prop,
|
|
|
+ prop_value);
|
|
|
+ break;
|
|
|
+ case DRM_MODE_OBJECT_CRTC:
|
|
|
+ ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
|
|
|
+ break;
|
|
|
+ case DRM_MODE_OBJECT_PLANE:
|
|
|
+ ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj),
|
|
|
+ prop, prop_value);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ drm_property_change_valid_put(prop, ref);
|
|
|
+ drm_modeset_unlock_all(dev);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static int set_property_atomic(struct drm_mode_object *obj,
|
|
|
+ struct drm_property *prop,
|
|
|
+ uint64_t prop_value)
|
|
|
+{
|
|
|
+ struct drm_device *dev = prop->dev;
|
|
|
+ struct drm_atomic_state *state;
|
|
|
+ struct drm_modeset_acquire_ctx ctx;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ drm_modeset_acquire_init(&ctx, 0);
|
|
|
+
|
|
|
+ state = drm_atomic_state_alloc(dev);
|
|
|
+ if (!state)
|
|
|
+ return -ENOMEM;
|
|
|
+ state->acquire_ctx = &ctx;
|
|
|
+retry:
|
|
|
+ if (prop == state->dev->mode_config.dpms_property) {
|
|
|
+ if (obj->type != DRM_MODE_OBJECT_CONNECTOR) {
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = drm_atomic_connector_commit_dpms(state,
|
|
|
+ obj_to_connector(obj),
|
|
|
+ prop_value);
|
|
|
+ } else {
|
|
|
+ ret = drm_atomic_set_property(state, obj, prop, prop_value);
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
+ ret = drm_atomic_commit(state);
|
|
|
+ }
|
|
|
+out:
|
|
|
+ if (ret == -EDEADLK) {
|
|
|
+ drm_atomic_state_clear(state);
|
|
|
+ drm_modeset_backoff(&ctx);
|
|
|
+ goto retry;
|
|
|
+ }
|
|
|
+
|
|
|
+ drm_atomic_state_put(state);
|
|
|
+
|
|
|
+ drm_modeset_drop_locks(&ctx);
|
|
|
+ drm_modeset_acquire_fini(&ctx);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
|
|
|
struct drm_file *file_priv)
|
|
|
{
|
|
@@ -399,18 +476,13 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
|
|
|
struct drm_mode_object *arg_obj;
|
|
|
struct drm_property *property;
|
|
|
int ret = -EINVAL;
|
|
|
- struct drm_mode_object *ref;
|
|
|
|
|
|
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- drm_modeset_lock_all(dev);
|
|
|
-
|
|
|
arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
|
|
|
- if (!arg_obj) {
|
|
|
- ret = -ENOENT;
|
|
|
- goto out;
|
|
|
- }
|
|
|
+ if (!arg_obj)
|
|
|
+ return -ENOENT;
|
|
|
|
|
|
if (!arg_obj->properties)
|
|
|
goto out_unref;
|
|
@@ -419,28 +491,12 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
|
|
|
if (!property)
|
|
|
goto out_unref;
|
|
|
|
|
|
- if (!drm_property_change_valid_get(property, arg->value, &ref))
|
|
|
- goto out_unref;
|
|
|
-
|
|
|
- switch (arg_obj->type) {
|
|
|
- case DRM_MODE_OBJECT_CONNECTOR:
|
|
|
- ret = drm_mode_connector_set_obj_prop(arg_obj, property,
|
|
|
- arg->value);
|
|
|
- break;
|
|
|
- case DRM_MODE_OBJECT_CRTC:
|
|
|
- ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
|
|
|
- break;
|
|
|
- case DRM_MODE_OBJECT_PLANE:
|
|
|
- ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
|
|
|
- property, arg->value);
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- drm_property_change_valid_put(property, ref);
|
|
|
+ if (drm_drv_uses_atomic_modeset(property->dev))
|
|
|
+ ret = set_property_atomic(arg_obj, property, arg->value);
|
|
|
+ else
|
|
|
+ ret = set_property_legacy(arg_obj, property, arg->value);
|
|
|
|
|
|
out_unref:
|
|
|
drm_mode_object_put(arg_obj);
|
|
|
-out:
|
|
|
- drm_modeset_unlock_all(dev);
|
|
|
return ret;
|
|
|
}
|