Skip to content

Commit 144a799

Browse files
committed
drm: Handle properties in the core for atomic drivers
The reason behind the original indirection through the helper functions was to allow existing drivers to overwrite how they handle properties. For example when a vendor-specific userspace had expectations that didn't match atomic. That seemed likely, since atomic is standardizing a _lot_ more of the behaviour of a kms driver. But 20 drivers later there's no such need at all. Worse, this forces all drivers to hook up the default behaviour, breaking userspace if they forget to do that. And it forces us to export a bunch of core function just for those helpers. And finally, these helpers are the last places using drm_atomic_legacy_backoff() and the implicit acquire_ctx. This patch here just implements the new behaviour and updates the docs. Follow-up patches will garbage-collect all the dead code. v2: Fixup docs even better! v3: Make it actually work ... v4: Drop the uses_atomic_modeset() checks from the previous patch again, since they're now moved up in the callchain. Cc: Maarten Lankhorst <[email protected]> Reviewed-by: Archit Taneja <[email protected]> (v3) Reviewed-by: Maarten Lankhorst <[email protected]> Signed-off-by: Daniel Vetter <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 4a97a3d commit 144a799

10 files changed

+161
-53
lines changed

drivers/gpu/drm/drm_atomic.c

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,9 +1864,60 @@ static struct drm_pending_vblank_event *create_vblank_event(
18641864
return e;
18651865
}
18661866

1867-
static int atomic_set_prop(struct drm_atomic_state *state,
1868-
struct drm_mode_object *obj, struct drm_property *prop,
1869-
uint64_t prop_value)
1867+
int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
1868+
struct drm_connector *connector,
1869+
int mode)
1870+
{
1871+
struct drm_connector *tmp_connector;
1872+
struct drm_connector_state *new_conn_state;
1873+
struct drm_crtc *crtc;
1874+
struct drm_crtc_state *crtc_state;
1875+
int i, ret, old_mode = connector->dpms;
1876+
bool active = false;
1877+
1878+
ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex,
1879+
state->acquire_ctx);
1880+
if (ret)
1881+
return ret;
1882+
1883+
if (mode != DRM_MODE_DPMS_ON)
1884+
mode = DRM_MODE_DPMS_OFF;
1885+
connector->dpms = mode;
1886+
1887+
crtc = connector->state->crtc;
1888+
if (!crtc)
1889+
goto out;
1890+
ret = drm_atomic_add_affected_connectors(state, crtc);
1891+
if (ret)
1892+
goto out;
1893+
1894+
crtc_state = drm_atomic_get_crtc_state(state, crtc);
1895+
if (IS_ERR(crtc_state)) {
1896+
ret = PTR_ERR(crtc_state);
1897+
goto out;
1898+
}
1899+
1900+
for_each_new_connector_in_state(state, tmp_connector, new_conn_state, i) {
1901+
if (new_conn_state->crtc != crtc)
1902+
continue;
1903+
if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
1904+
active = true;
1905+
break;
1906+
}
1907+
}
1908+
1909+
crtc_state->active = active;
1910+
ret = drm_atomic_commit(state);
1911+
out:
1912+
if (ret != 0)
1913+
connector->dpms = old_mode;
1914+
return ret;
1915+
}
1916+
1917+
int drm_atomic_set_property(struct drm_atomic_state *state,
1918+
struct drm_mode_object *obj,
1919+
struct drm_property *prop,
1920+
uint64_t prop_value)
18701921
{
18711922
struct drm_mode_object *ref;
18721923
int ret;
@@ -2286,7 +2337,8 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
22862337
goto out;
22872338
}
22882339

2289-
ret = atomic_set_prop(state, obj, prop, prop_value);
2340+
ret = drm_atomic_set_property(state, obj, prop,
2341+
prop_value);
22902342
if (ret) {
22912343
drm_mode_object_put(obj);
22922344
goto out;

drivers/gpu/drm/drm_connector.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -717,9 +717,9 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
717717
* drivers, it remaps to controlling the "ACTIVE" property on the CRTC the
718718
* connector is linked to. Drivers should never set this property directly,
719719
* it is handled by the DRM core by calling the &drm_connector_funcs.dpms
720-
* callback. Atomic drivers should implement this hook using
721-
* drm_atomic_helper_connector_dpms(). This is the only property standard
722-
* connector property that userspace can change.
720+
* callback. For atomic drivers the remapping to the "ACTIVE" property is
721+
* implemented in the DRM core. This is the only standard connector
722+
* property that userspace can change.
723723
* PATH:
724724
* Connector path property to identify how this sink is physically
725725
* connected. Used by DP MST. This should be set by calling
@@ -1225,7 +1225,7 @@ int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
12251225
} else if (connector->funcs->set_property)
12261226
ret = connector->funcs->set_property(connector, property, value);
12271227

1228-
if (!ret && !drm_drv_uses_atomic_modeset(property->dev))
1228+
if (!ret)
12291229
drm_object_property_set_value(&connector->base, property, value);
12301230
return ret;
12311231
}

drivers/gpu/drm/drm_crtc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
736736

737737
if (crtc->funcs->set_property)
738738
ret = crtc->funcs->set_property(crtc, property, value);
739-
if (!ret && !drm_drv_uses_atomic_modeset(property->dev))
739+
if (!ret)
740740
drm_object_property_set_value(obj, property, value);
741741

742742
return ret;

drivers/gpu/drm/drm_crtc_helper.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -863,8 +863,7 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
863863
* provided by the driver.
864864
*
865865
* This function is deprecated. New drivers must implement atomic modeset
866-
* support, for which this function is unsuitable. Instead drivers should use
867-
* drm_atomic_helper_connector_dpms().
866+
* support, where DPMS is handled in the DRM core.
868867
*
869868
* Returns:
870869
* Always returns 0.

drivers/gpu/drm/drm_crtc_internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,13 @@ struct drm_minor;
178178
int drm_atomic_debugfs_init(struct drm_minor *minor);
179179
#endif
180180

181+
int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
182+
struct drm_connector *connector,
183+
int mode);
184+
int drm_atomic_set_property(struct drm_atomic_state *state,
185+
struct drm_mode_object *obj,
186+
struct drm_property *prop,
187+
uint64_t prop_value);
181188
int drm_atomic_get_property(struct drm_mode_object *obj,
182189
struct drm_property *property, uint64_t *val);
183190
int drm_mode_atomic_ioctl(struct drm_device *dev,

drivers/gpu/drm/drm_mode_object.c

Lines changed: 83 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -392,25 +392,97 @@ struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
392392
return NULL;
393393
}
394394

395+
static int set_property_legacy(struct drm_mode_object *obj,
396+
struct drm_property *prop,
397+
uint64_t prop_value)
398+
{
399+
struct drm_device *dev = prop->dev;
400+
struct drm_mode_object *ref;
401+
int ret = -EINVAL;
402+
403+
if (!drm_property_change_valid_get(prop, prop_value, &ref))
404+
return -EINVAL;
405+
406+
drm_modeset_lock_all(dev);
407+
switch (obj->type) {
408+
case DRM_MODE_OBJECT_CONNECTOR:
409+
ret = drm_mode_connector_set_obj_prop(obj, prop,
410+
prop_value);
411+
break;
412+
case DRM_MODE_OBJECT_CRTC:
413+
ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
414+
break;
415+
case DRM_MODE_OBJECT_PLANE:
416+
ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj),
417+
prop, prop_value);
418+
break;
419+
}
420+
drm_property_change_valid_put(prop, ref);
421+
drm_modeset_unlock_all(dev);
422+
423+
return ret;
424+
}
425+
426+
static int set_property_atomic(struct drm_mode_object *obj,
427+
struct drm_property *prop,
428+
uint64_t prop_value)
429+
{
430+
struct drm_device *dev = prop->dev;
431+
struct drm_atomic_state *state;
432+
struct drm_modeset_acquire_ctx ctx;
433+
int ret;
434+
435+
drm_modeset_acquire_init(&ctx, 0);
436+
437+
state = drm_atomic_state_alloc(dev);
438+
if (!state)
439+
return -ENOMEM;
440+
state->acquire_ctx = &ctx;
441+
retry:
442+
if (prop == state->dev->mode_config.dpms_property) {
443+
if (obj->type != DRM_MODE_OBJECT_CONNECTOR) {
444+
ret = -EINVAL;
445+
goto out;
446+
}
447+
448+
ret = drm_atomic_connector_commit_dpms(state,
449+
obj_to_connector(obj),
450+
prop_value);
451+
} else {
452+
ret = drm_atomic_set_property(state, obj, prop, prop_value);
453+
if (ret)
454+
goto out;
455+
ret = drm_atomic_commit(state);
456+
}
457+
out:
458+
if (ret == -EDEADLK) {
459+
drm_atomic_state_clear(state);
460+
drm_modeset_backoff(&ctx);
461+
goto retry;
462+
}
463+
464+
drm_atomic_state_put(state);
465+
466+
drm_modeset_drop_locks(&ctx);
467+
drm_modeset_acquire_fini(&ctx);
468+
469+
return ret;
470+
}
471+
395472
int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
396473
struct drm_file *file_priv)
397474
{
398475
struct drm_mode_obj_set_property *arg = data;
399476
struct drm_mode_object *arg_obj;
400477
struct drm_property *property;
401478
int ret = -EINVAL;
402-
struct drm_mode_object *ref;
403479

404480
if (!drm_core_check_feature(dev, DRIVER_MODESET))
405481
return -EINVAL;
406482

407-
drm_modeset_lock_all(dev);
408-
409483
arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
410-
if (!arg_obj) {
411-
ret = -ENOENT;
412-
goto out;
413-
}
484+
if (!arg_obj)
485+
return -ENOENT;
414486

415487
if (!arg_obj->properties)
416488
goto out_unref;
@@ -419,28 +491,12 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
419491
if (!property)
420492
goto out_unref;
421493

422-
if (!drm_property_change_valid_get(property, arg->value, &ref))
423-
goto out_unref;
424-
425-
switch (arg_obj->type) {
426-
case DRM_MODE_OBJECT_CONNECTOR:
427-
ret = drm_mode_connector_set_obj_prop(arg_obj, property,
428-
arg->value);
429-
break;
430-
case DRM_MODE_OBJECT_CRTC:
431-
ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
432-
break;
433-
case DRM_MODE_OBJECT_PLANE:
434-
ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
435-
property, arg->value);
436-
break;
437-
}
438-
439-
drm_property_change_valid_put(property, ref);
494+
if (drm_drv_uses_atomic_modeset(property->dev))
495+
ret = set_property_atomic(arg_obj, property, arg->value);
496+
else
497+
ret = set_property_legacy(arg_obj, property, arg->value);
440498

441499
out_unref:
442500
drm_mode_object_put(arg_obj);
443-
out:
444-
drm_modeset_unlock_all(dev);
445501
return ret;
446502
}

drivers/gpu/drm/drm_plane.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
448448

449449
if (plane->funcs->set_property)
450450
ret = plane->funcs->set_property(plane, property, value);
451-
if (!ret && !drm_drv_uses_atomic_modeset(property->dev))
451+
if (!ret)
452452
drm_object_property_set_value(obj, property, value);
453453

454454
return ret;

include/drm/drm_connector.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,8 @@ struct drm_connector_funcs {
382382
* implement the 4 level DPMS support on the connector any more, but
383383
* instead only have an on/off "ACTIVE" property on the CRTC object.
384384
*
385-
* Drivers implementing atomic modeset should use
386-
* drm_atomic_helper_connector_dpms() to implement this hook.
385+
* This hook is not used by atomic drivers, remapping of the legacy DPMS
386+
* property is entirely handled in the DRM core.
387387
*
388388
* RETURNS:
389389
*
@@ -480,11 +480,9 @@ struct drm_connector_funcs {
480480
* This is the legacy entry point to update a property attached to the
481481
* connector.
482482
*
483-
* Drivers implementing atomic modeset should use
484-
* drm_atomic_helper_connector_set_property() to implement this hook.
485-
*
486483
* This callback is optional if the driver does not support any legacy
487-
* driver-private properties.
484+
* driver-private properties. For atomic drivers it is not used because
485+
* property handling is done entirely in the DRM core.
488486
*
489487
* RETURNS:
490488
*

include/drm/drm_crtc.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -473,11 +473,9 @@ struct drm_crtc_funcs {
473473
* This is the legacy entry point to update a property attached to the
474474
* CRTC.
475475
*
476-
* Drivers implementing atomic modeset should use
477-
* drm_atomic_helper_crtc_set_property() to implement this hook.
478-
*
479476
* This callback is optional if the driver does not support any legacy
480-
* driver-private properties.
477+
* driver-private properties. For atomic drivers it is not used because
478+
* property handling is done entirely in the DRM core.
481479
*
482480
* RETURNS:
483481
*

include/drm/drm_plane.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,9 @@ struct drm_plane_funcs {
233233
* This is the legacy entry point to update a property attached to the
234234
* plane.
235235
*
236-
* Drivers implementing atomic modeset should use
237-
* drm_atomic_helper_plane_set_property() to implement this hook.
238-
*
239236
* This callback is optional if the driver does not support any legacy
240-
* driver-private properties.
237+
* driver-private properties. For atomic drivers it is not used because
238+
* property handling is done entirely in the DRM core.
241239
*
242240
* RETURNS:
243241
*

0 commit comments

Comments
 (0)