Commit 49e27545 authored by Rob Clark's avatar Rob Clark Committed by Dave Airlie

drm: add bitmask property type

A bitmask property is similar to an enum.  The enum value is a bit
position (0-63), and valid property values consist of a mask of
zero or more of (1 << enum_val[n]).

[airlied: 1LL -> 1ULL]
Signed-off-by: default avatarRob Clark <rob@ti.com>
Reviewed-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 345f3b90
...@@ -2748,6 +2748,34 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, ...@@ -2748,6 +2748,34 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
} }
EXPORT_SYMBOL(drm_property_create_enum); EXPORT_SYMBOL(drm_property_create_enum);
struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
int flags, const char *name,
const struct drm_prop_enum_list *props,
int num_values)
{
struct drm_property *property;
int i, ret;
flags |= DRM_MODE_PROP_BITMASK;
property = drm_property_create(dev, flags, name, num_values);
if (!property)
return NULL;
for (i = 0; i < num_values; i++) {
ret = drm_property_add_enum(property, i,
props[i].type,
props[i].name);
if (ret) {
drm_property_destroy(dev, property);
return NULL;
}
}
return property;
}
EXPORT_SYMBOL(drm_property_create_bitmask);
struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
const char *name, const char *name,
uint64_t min, uint64_t max) uint64_t min, uint64_t max)
...@@ -2772,7 +2800,14 @@ int drm_property_add_enum(struct drm_property *property, int index, ...@@ -2772,7 +2800,14 @@ int drm_property_add_enum(struct drm_property *property, int index,
{ {
struct drm_property_enum *prop_enum; struct drm_property_enum *prop_enum;
if (!(property->flags & DRM_MODE_PROP_ENUM)) if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)))
return -EINVAL;
/*
* Bitmask enum properties have the additional constraint of values
* from 0 to 63
*/
if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63))
return -EINVAL; return -EINVAL;
if (!list_empty(&property->enum_blob_list)) { if (!list_empty(&property->enum_blob_list)) {
...@@ -2918,7 +2953,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, ...@@ -2918,7 +2953,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
} }
property = obj_to_property(obj); property = obj_to_property(obj);
if (property->flags & DRM_MODE_PROP_ENUM) { if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
list_for_each_entry(prop_enum, &property->enum_blob_list, head) list_for_each_entry(prop_enum, &property->enum_blob_list, head)
enum_count++; enum_count++;
} else if (property->flags & DRM_MODE_PROP_BLOB) { } else if (property->flags & DRM_MODE_PROP_BLOB) {
...@@ -2943,7 +2978,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, ...@@ -2943,7 +2978,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
} }
out_resp->count_values = value_count; out_resp->count_values = value_count;
if (property->flags & DRM_MODE_PROP_ENUM) { if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
copied = 0; copied = 0;
enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
...@@ -3098,6 +3133,12 @@ static bool drm_property_change_is_valid(struct drm_property *property, ...@@ -3098,6 +3133,12 @@ static bool drm_property_change_is_valid(struct drm_property *property,
if (value < property->values[0] || value > property->values[1]) if (value < property->values[0] || value > property->values[1])
return false; return false;
return true; return true;
} else if (property->flags & DRM_MODE_PROP_BITMASK) {
int i;
__u64 valid_mask = 0;
for (i = 0; i < property->num_values; i++)
valid_mask |= (1ULL << property->values[i]);
return !(value & ~valid_mask);
} else { } else {
int i; int i;
for (i = 0; i < property->num_values; i++) for (i = 0; i < property->num_values; i++)
......
...@@ -933,6 +933,10 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int ...@@ -933,6 +933,10 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int
const char *name, const char *name,
const struct drm_prop_enum_list *props, const struct drm_prop_enum_list *props,
int num_values); int num_values);
struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
int flags, const char *name,
const struct drm_prop_enum_list *props,
int num_values);
struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
const char *name, const char *name,
uint64_t min, uint64_t max); uint64_t min, uint64_t max);
......
...@@ -230,6 +230,7 @@ struct drm_mode_get_connector { ...@@ -230,6 +230,7 @@ struct drm_mode_get_connector {
#define DRM_MODE_PROP_IMMUTABLE (1<<2) #define DRM_MODE_PROP_IMMUTABLE (1<<2)
#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */ #define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */
#define DRM_MODE_PROP_BLOB (1<<4) #define DRM_MODE_PROP_BLOB (1<<4)
#define DRM_MODE_PROP_BITMASK (1<<5) /* bitmask of enumerated types */
struct drm_mode_property_enum { struct drm_mode_property_enum {
__u64 value; __u64 value;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment