aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2014-05-30 11:34:01 -0400
committerDave Airlie <airlied@redhat.com>2014-06-03 23:22:53 -0400
commit5ea22f24d77b511d68c4ecaf4e6fd5d6ab462b8f (patch)
treee6c3287bee5fec51e3deb8b905c156926c6a8985
parenta2b34e226ac9fbd20179091fad0ee1a24ad48669 (diff)
drm: add extended property types
If we continue to use bitmask for type, we will quickly run out of room to add new types. Split this up so existing part of bitmask range continues to function as before, but reserve a chunk of the remaining space for an integer type-id. Wrap this all up in some type-check helpers to keep the backwards-compat uglyness contained. Signed-off-by: Rob Clark <robdclark@gmail.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/drm_crtc.c26
-rw-r--r--include/drm/drm_crtc.h17
-rw-r--r--include/uapi/drm/drm_mode.h13
3 files changed, 47 insertions, 9 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index c4b44be7d464..73f543af4924 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3094,6 +3094,9 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
3094 } 3094 }
3095 3095
3096 list_add_tail(&property->head, &dev->mode_config.property_list); 3096 list_add_tail(&property->head, &dev->mode_config.property_list);
3097
3098 WARN_ON(!drm_property_type_valid(property));
3099
3097 return property; 3100 return property;
3098fail: 3101fail:
3099 kfree(property->values); 3102 kfree(property->values);
@@ -3251,14 +3254,16 @@ int drm_property_add_enum(struct drm_property *property, int index,
3251{ 3254{
3252 struct drm_property_enum *prop_enum; 3255 struct drm_property_enum *prop_enum;
3253 3256
3254 if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) 3257 if (!(drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
3258 drm_property_type_is(property, DRM_MODE_PROP_BITMASK)))
3255 return -EINVAL; 3259 return -EINVAL;
3256 3260
3257 /* 3261 /*
3258 * Bitmask enum properties have the additional constraint of values 3262 * Bitmask enum properties have the additional constraint of values
3259 * from 0 to 63 3263 * from 0 to 63
3260 */ 3264 */
3261 if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63)) 3265 if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK) &&
3266 (value > 63))
3262 return -EINVAL; 3267 return -EINVAL;
3263 3268
3264 if (!list_empty(&property->enum_blob_list)) { 3269 if (!list_empty(&property->enum_blob_list)) {
@@ -3439,10 +3444,11 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
3439 goto done; 3444 goto done;
3440 } 3445 }
3441 3446
3442 if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { 3447 if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
3448 drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
3443 list_for_each_entry(prop_enum, &property->enum_blob_list, head) 3449 list_for_each_entry(prop_enum, &property->enum_blob_list, head)
3444 enum_count++; 3450 enum_count++;
3445 } else if (property->flags & DRM_MODE_PROP_BLOB) { 3451 } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
3446 list_for_each_entry(prop_blob, &property->enum_blob_list, head) 3452 list_for_each_entry(prop_blob, &property->enum_blob_list, head)
3447 blob_count++; 3453 blob_count++;
3448 } 3454 }
@@ -3464,7 +3470,8 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
3464 } 3470 }
3465 out_resp->count_values = value_count; 3471 out_resp->count_values = value_count;
3466 3472
3467 if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { 3473 if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
3474 drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
3468 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { 3475 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
3469 copied = 0; 3476 copied = 0;
3470 enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; 3477 enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
@@ -3486,7 +3493,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
3486 out_resp->count_enum_blobs = enum_count; 3493 out_resp->count_enum_blobs = enum_count;
3487 } 3494 }
3488 3495
3489 if (property->flags & DRM_MODE_PROP_BLOB) { 3496 if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
3490 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) { 3497 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
3491 copied = 0; 3498 copied = 0;
3492 blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr; 3499 blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr;
@@ -3640,17 +3647,18 @@ static bool drm_property_change_is_valid(struct drm_property *property,
3640{ 3647{
3641 if (property->flags & DRM_MODE_PROP_IMMUTABLE) 3648 if (property->flags & DRM_MODE_PROP_IMMUTABLE)
3642 return false; 3649 return false;
3643 if (property->flags & DRM_MODE_PROP_RANGE) { 3650
3651 if (drm_property_type_is(property, DRM_MODE_PROP_RANGE)) {
3644 if (value < property->values[0] || value > property->values[1]) 3652 if (value < property->values[0] || value > property->values[1])
3645 return false; 3653 return false;
3646 return true; 3654 return true;
3647 } else if (property->flags & DRM_MODE_PROP_BITMASK) { 3655 } else if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
3648 int i; 3656 int i;
3649 uint64_t valid_mask = 0; 3657 uint64_t valid_mask = 0;
3650 for (i = 0; i < property->num_values; i++) 3658 for (i = 0; i < property->num_values; i++)
3651 valid_mask |= (1ULL << property->values[i]); 3659 valid_mask |= (1ULL << property->values[i]);
3652 return !(value & ~valid_mask); 3660 return !(value & ~valid_mask);
3653 } else if (property->flags & DRM_MODE_PROP_BLOB) { 3661 } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
3654 /* Only the driver knows */ 3662 /* Only the driver knows */
3655 return true; 3663 return true;
3656 } else { 3664 } else {
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 90bd1a25e2c6..92f6ec2de86a 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -930,6 +930,23 @@ extern void drm_mode_config_cleanup(struct drm_device *dev);
930 930
931extern int drm_mode_connector_update_edid_property(struct drm_connector *connector, 931extern int drm_mode_connector_update_edid_property(struct drm_connector *connector,
932 struct edid *edid); 932 struct edid *edid);
933
934static inline bool drm_property_type_is(struct drm_property *property,
935 uint32_t type)
936{
937 /* instanceof for props.. handles extended type vs original types: */
938 if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
939 return (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) == type;
940 return property->flags & type;
941}
942
943static inline bool drm_property_type_valid(struct drm_property *property)
944{
945 if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
946 return !(property->flags & DRM_MODE_PROP_LEGACY_TYPE);
947 return !!(property->flags & DRM_MODE_PROP_LEGACY_TYPE);
948}
949
933extern int drm_object_property_set_value(struct drm_mode_object *obj, 950extern int drm_object_property_set_value(struct drm_mode_object *obj,
934 struct drm_property *property, 951 struct drm_property *property,
935 uint64_t val); 952 uint64_t val);
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 719add464f95..caeaa6f7ebde 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -252,6 +252,19 @@ struct drm_mode_get_connector {
252#define DRM_MODE_PROP_BLOB (1<<4) 252#define DRM_MODE_PROP_BLOB (1<<4)
253#define DRM_MODE_PROP_BITMASK (1<<5) /* bitmask of enumerated types */ 253#define DRM_MODE_PROP_BITMASK (1<<5) /* bitmask of enumerated types */
254 254
255/* non-extended types: legacy bitmask, one bit per type: */
256#define DRM_MODE_PROP_LEGACY_TYPE ( \
257 DRM_MODE_PROP_RANGE | \
258 DRM_MODE_PROP_ENUM | \
259 DRM_MODE_PROP_BLOB | \
260 DRM_MODE_PROP_BITMASK)
261
262/* extended-types: rather than continue to consume a bit per type,
263 * grab a chunk of the bits to use as integer type id.
264 */
265#define DRM_MODE_PROP_EXTENDED_TYPE 0x0000ffc0
266#define DRM_MODE_PROP_TYPE(n) ((n) << 6)
267
255struct drm_mode_property_enum { 268struct drm_mode_property_enum {
256 __u64 value; 269 __u64 value;
257 char name[DRM_PROP_NAME_LEN]; 270 char name[DRM_PROP_NAME_LEN];