aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorRob Clark <rob@ti.com>2012-05-17 04:23:26 -0400
committerDave Airlie <airlied@redhat.com>2012-05-22 05:54:16 -0400
commit49e2754578b9f99bde18ad318d888a462d271479 (patch)
tree9bba955211d37225a931ad45076354e2d149147d /drivers/gpu
parent345f3b9035691d2d6e97398039b99fa484653cc4 (diff)
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: Rob Clark <rob@ti.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/drm_crtc.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 6cb47d9f0ca2..e3135c7ee87a 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2748,6 +2748,34 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
2748} 2748}
2749EXPORT_SYMBOL(drm_property_create_enum); 2749EXPORT_SYMBOL(drm_property_create_enum);
2750 2750
2751struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
2752 int flags, const char *name,
2753 const struct drm_prop_enum_list *props,
2754 int num_values)
2755{
2756 struct drm_property *property;
2757 int i, ret;
2758
2759 flags |= DRM_MODE_PROP_BITMASK;
2760
2761 property = drm_property_create(dev, flags, name, num_values);
2762 if (!property)
2763 return NULL;
2764
2765 for (i = 0; i < num_values; i++) {
2766 ret = drm_property_add_enum(property, i,
2767 props[i].type,
2768 props[i].name);
2769 if (ret) {
2770 drm_property_destroy(dev, property);
2771 return NULL;
2772 }
2773 }
2774
2775 return property;
2776}
2777EXPORT_SYMBOL(drm_property_create_bitmask);
2778
2751struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, 2779struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
2752 const char *name, 2780 const char *name,
2753 uint64_t min, uint64_t max) 2781 uint64_t min, uint64_t max)
@@ -2772,7 +2800,14 @@ int drm_property_add_enum(struct drm_property *property, int index,
2772{ 2800{
2773 struct drm_property_enum *prop_enum; 2801 struct drm_property_enum *prop_enum;
2774 2802
2775 if (!(property->flags & DRM_MODE_PROP_ENUM)) 2803 if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)))
2804 return -EINVAL;
2805
2806 /*
2807 * Bitmask enum properties have the additional constraint of values
2808 * from 0 to 63
2809 */
2810 if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63))
2776 return -EINVAL; 2811 return -EINVAL;
2777 2812
2778 if (!list_empty(&property->enum_blob_list)) { 2813 if (!list_empty(&property->enum_blob_list)) {
@@ -2918,7 +2953,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
2918 } 2953 }
2919 property = obj_to_property(obj); 2954 property = obj_to_property(obj);
2920 2955
2921 if (property->flags & DRM_MODE_PROP_ENUM) { 2956 if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
2922 list_for_each_entry(prop_enum, &property->enum_blob_list, head) 2957 list_for_each_entry(prop_enum, &property->enum_blob_list, head)
2923 enum_count++; 2958 enum_count++;
2924 } else if (property->flags & DRM_MODE_PROP_BLOB) { 2959 } else if (property->flags & DRM_MODE_PROP_BLOB) {
@@ -2943,7 +2978,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
2943 } 2978 }
2944 out_resp->count_values = value_count; 2979 out_resp->count_values = value_count;
2945 2980
2946 if (property->flags & DRM_MODE_PROP_ENUM) { 2981 if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
2947 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { 2982 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
2948 copied = 0; 2983 copied = 0;
2949 enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; 2984 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 if (value < property->values[0] || value > property->values[1]) 3133 if (value < property->values[0] || value > property->values[1])
3099 return false; 3134 return false;
3100 return true; 3135 return true;
3136 } else if (property->flags & DRM_MODE_PROP_BITMASK) {
3137 int i;
3138 __u64 valid_mask = 0;
3139 for (i = 0; i < property->num_values; i++)
3140 valid_mask |= (1ULL << property->values[i]);
3141 return !(value & ~valid_mask);
3101 } else { 3142 } else {
3102 int i; 3143 int i;
3103 for (i = 0; i < property->num_values; i++) 3144 for (i = 0; i < property->num_values; i++)