[PATCH RFC 1/2] drm: add bitmask property type
Rob Clark
rob.clark at linaro.org
Thu Mar 29 18:02:45 PDT 2012
From: Rob Clark <rob at ti.com>
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]).
TODO: word commit msg better
TODO: maybe "flags" would be a better name for the property type?
---
See https://github.com/robclark/kernel-omap4/commit/970b7bb95993fc43b4977976bf8005dc2e1a4ad3#L6R411
for an example usage. In this case combinations of "x-invert", "y-invert"
and "xy-flip" can express all possible combinations of rotations of
multiples of 90 degrees plus mirroring. Which is sufficient for an
xrandr v1.2 rotation support. For arbitrary transforms in xrandr v1.3
a different property with a transform matrix (if supported by the
driver) should be used.
Note: I've not finished updating libdrm and ddx driver to use this
yet, so other than compile and boot test, you can consider this as
untested. But I figure that it is at least worthwhile to send as
an RFC at this point to get feedback.
drivers/gpu/drm/drm_crtc.c | 46 +++++++++++++++++++++++++++++++++++++++++--
include/drm/drm_crtc.h | 3 ++
include/drm/drm_mode.h | 1 +
3 files changed, 47 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 95c7ab2..2b462f6 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2713,6 +2713,33 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
}
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,
const char *name,
uint64_t min, uint64_t max)
@@ -2737,7 +2764,14 @@ int drm_property_add_enum(struct drm_property *property, int index,
{
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;
if (!list_empty(&property->enum_blob_list)) {
@@ -2881,7 +2915,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
}
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)
enum_count++;
} else if (property->flags & DRM_MODE_PROP_BLOB) {
@@ -2906,7 +2940,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
}
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) {
copied = 0;
enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
@@ -3063,6 +3097,12 @@ static bool drm_property_change_is_valid(struct drm_property *property,
if (value > property->values[1])
return false;
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 |= (1 << property->values[i]);
+ return !(value & ~valid_mask);
} else {
int i;
for (i = 0; i < property->num_values; i++)
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 32e9c51..28e9a78 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -940,6 +940,9 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int
const char *name,
const struct drm_prop_enum_list *props,
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,
const char *name,
uint64_t min, uint64_t max);
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index de5de2a..3190dfe 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -228,6 +228,7 @@ struct drm_mode_get_connector {
#define DRM_MODE_PROP_IMMUTABLE (1<<2)
#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */
#define DRM_MODE_PROP_BLOB (1<<4)
+#define DRM_MODE_PROP_BITMASK (1<<5) /* bitmask of enumerated types */
struct drm_mode_property_enum {
__u64 value;
--
1.7.9.1
More information about the dri-devel
mailing list