aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2014-12-18 16:01:50 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-01-05 07:54:38 -0500
commit88a48e297b3a3bac6022c03babfb038f1a886cea (patch)
tree8b914276b0e77e447aa3de5f4d7cefc1597911b1 /drivers/gpu/drm/drm_crtc.c
parent95cbf110756c21397946ded181cc5ea4ab568c11 (diff)
drm: add atomic properties
Once a driver is using atomic helpers for modeset, the next step is to switch over to atomic properties. To do this, make sure that any modeset objects have their ->atomic_{get,set}_property() vfuncs suitably populated if they have custom properties (you did already remember to plug in atomic-helper func for the legacy ->set_property() vfuncs, right?), and then set DRIVER_ATOMIC bit in driver_features flag. A new cap is introduced, DRM_CLIENT_CAP_ATOMIC, for the purposes of shielding legacy userspace from atomic properties. Mostly for the benefit of legacy DDX drivers that do silly things like getting/setting each property at startup (since some of the new atomic properties will be able to trigger modeset). Signed-off-by: Rob Clark <robdclark@gmail.com> [danvet: Squash in fixup patch to check for DRM_MODE_PROP_ATOMIC instaed of the CAP define when filtering properties. Reported by Tvrtko Uruslin, acked by Rob.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r--drivers/gpu/drm/drm_crtc.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index f5f34d0d7c20..3bac877228fa 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -38,6 +38,7 @@
38#include <drm/drm_edid.h> 38#include <drm/drm_edid.h>
39#include <drm/drm_fourcc.h> 39#include <drm/drm_fourcc.h>
40#include <drm/drm_modeset_lock.h> 40#include <drm/drm_modeset_lock.h>
41#include <drm/drm_atomic.h>
41 42
42#include "drm_crtc_internal.h" 43#include "drm_crtc_internal.h"
43#include "drm_internal.h" 44#include "drm_internal.h"
@@ -1992,19 +1993,25 @@ static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *conne
1992} 1993}
1993 1994
1994/* helper for getconnector and getproperties ioctls */ 1995/* helper for getconnector and getproperties ioctls */
1995static int get_properties(struct drm_mode_object *obj, 1996static int get_properties(struct drm_mode_object *obj, bool atomic,
1996 uint32_t __user *prop_ptr, uint64_t __user *prop_values, 1997 uint32_t __user *prop_ptr, uint64_t __user *prop_values,
1997 uint32_t *arg_count_props) 1998 uint32_t *arg_count_props)
1998{ 1999{
1999 int props_count = obj->properties->count; 2000 int props_count;
2000 int i, ret, copied = 0; 2001 int i, ret, copied;
2002
2003 props_count = obj->properties->count;
2004 if (!atomic)
2005 props_count -= obj->properties->atomic_count;
2001 2006
2002 if ((*arg_count_props >= props_count) && props_count) { 2007 if ((*arg_count_props >= props_count) && props_count) {
2003 copied = 0; 2008 for (i = 0, copied = 0; copied < props_count; i++) {
2004 for (i = 0; i < props_count; i++) {
2005 struct drm_property *prop = obj->properties->properties[i]; 2009 struct drm_property *prop = obj->properties->properties[i];
2006 uint64_t val; 2010 uint64_t val;
2007 2011
2012 if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic)
2013 continue;
2014
2008 ret = drm_object_property_get_value(obj, prop, &val); 2015 ret = drm_object_property_get_value(obj, prop, &val);
2009 if (ret) 2016 if (ret)
2010 return ret; 2017 return ret;
@@ -2118,7 +2125,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2118 } 2125 }
2119 out_resp->count_modes = mode_count; 2126 out_resp->count_modes = mode_count;
2120 2127
2121 ret = get_properties(&connector->base, 2128 ret = get_properties(&connector->base, file_priv->atomic,
2122 (uint32_t __user *)(unsigned long)(out_resp->props_ptr), 2129 (uint32_t __user *)(unsigned long)(out_resp->props_ptr),
2123 (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr), 2130 (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
2124 &out_resp->count_props); 2131 &out_resp->count_props);
@@ -3832,6 +3839,8 @@ void drm_object_attach_property(struct drm_mode_object *obj,
3832 obj->properties->properties[count] = property; 3839 obj->properties->properties[count] = property;
3833 obj->properties->values[count] = init_val; 3840 obj->properties->values[count] = init_val;
3834 obj->properties->count++; 3841 obj->properties->count++;
3842 if (property->flags & DRM_MODE_PROP_ATOMIC)
3843 obj->properties->atomic_count++;
3835} 3844}
3836EXPORT_SYMBOL(drm_object_attach_property); 3845EXPORT_SYMBOL(drm_object_attach_property);
3837 3846
@@ -3883,6 +3892,14 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
3883{ 3892{
3884 int i; 3893 int i;
3885 3894
3895 /* read-only properties bypass atomic mechanism and still store
3896 * their value in obj->properties->values[].. mostly to avoid
3897 * having to deal w/ EDID and similar props in atomic paths:
3898 */
3899 if (drm_core_check_feature(property->dev, DRIVER_ATOMIC) &&
3900 !(property->flags & DRM_MODE_PROP_IMMUTABLE))
3901 return drm_atomic_get_property(obj, property, val);
3902
3886 for (i = 0; i < obj->properties->count; i++) { 3903 for (i = 0; i < obj->properties->count; i++) {
3887 if (obj->properties->properties[i] == property) { 3904 if (obj->properties->properties[i] == property) {
3888 *val = obj->properties->values[i]; 3905 *val = obj->properties->values[i];
@@ -4413,7 +4430,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
4413 goto out; 4430 goto out;
4414 } 4431 }
4415 4432
4416 ret = get_properties(obj, 4433 ret = get_properties(obj, file_priv->atomic,
4417 (uint32_t __user *)(unsigned long)(arg->props_ptr), 4434 (uint32_t __user *)(unsigned long)(arg->props_ptr),
4418 (uint64_t __user *)(unsigned long)(arg->prop_values_ptr), 4435 (uint64_t __user *)(unsigned long)(arg->prop_values_ptr),
4419 &arg->count_props); 4436 &arg->count_props);