diff options
author | Rob Clark <rob@ti.com> | 2012-05-17 04:23:26 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-05-22 05:54:16 -0400 |
commit | 49e2754578b9f99bde18ad318d888a462d271479 (patch) | |
tree | 9bba955211d37225a931ad45076354e2d149147d /drivers/gpu | |
parent | 345f3b9035691d2d6e97398039b99fa484653cc4 (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.c | 47 |
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 | } |
2749 | EXPORT_SYMBOL(drm_property_create_enum); | 2749 | EXPORT_SYMBOL(drm_property_create_enum); |
2750 | 2750 | ||
2751 | struct 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 | } | ||
2777 | EXPORT_SYMBOL(drm_property_create_bitmask); | ||
2778 | |||
2751 | struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, | 2779 | struct 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++) |