1 | /* |
2 | * Copyright (c) 2016 Intel Corporation |
3 | * |
4 | * Permission to use, copy, modify, distribute, and sell this software and its |
5 | * documentation for any purpose is hereby granted without fee, provided that |
6 | * the above copyright notice appear in all copies and that both that copyright |
7 | * notice and this permission notice appear in supporting documentation, and |
8 | * that the name of the copyright holders not be used in advertising or |
9 | * publicity pertaining to distribution of the software without specific, |
10 | * written prior permission. The copyright holders make no representations |
11 | * about the suitability of this software for any purpose. It is provided "as |
12 | * is" without express or implied warranty. |
13 | * |
14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO |
16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE |
20 | * OF THIS SOFTWARE. |
21 | */ |
22 | |
23 | #ifndef __DRM_PROPERTY_H__ |
24 | #define __DRM_PROPERTY_H__ |
25 | |
26 | #include <linux/list.h> |
27 | #include <linux/ctype.h> |
28 | #include <drm/drm_mode_object.h> |
29 | |
30 | #include <uapi/drm/drm_mode.h> |
31 | |
32 | /** |
33 | * struct drm_property_enum - symbolic values for enumerations |
34 | * @head: list of enum values, linked to &drm_property.enum_list |
35 | * @name: symbolic name for the enum |
36 | * |
37 | * For enumeration and bitmask properties this structure stores the symbolic |
38 | * decoding for each value. This is used for example for the rotation property. |
39 | */ |
40 | struct drm_property_enum { |
41 | /** |
42 | * @value: numeric property value for this enum entry |
43 | * |
44 | * If the property has the type &DRM_MODE_PROP_BITMASK, @value stores a |
45 | * bitshift, not a bitmask. In other words, the enum entry is enabled |
46 | * if the bit number @value is set in the property's value. This enum |
47 | * entry has the bitmask ``1 << value``. |
48 | */ |
49 | uint64_t value; |
50 | struct list_head head; |
51 | char name[DRM_PROP_NAME_LEN]; |
52 | }; |
53 | |
54 | /** |
55 | * struct drm_property - modeset object property |
56 | * |
57 | * This structure represent a modeset object property. It combines both the name |
58 | * of the property with the set of permissible values. This means that when a |
59 | * driver wants to use a property with the same name on different objects, but |
60 | * with different value ranges, then it must create property for each one. An |
61 | * example would be rotation of &drm_plane, when e.g. the primary plane cannot |
62 | * be rotated. But if both the name and the value range match, then the same |
63 | * property structure can be instantiated multiple times for the same object. |
64 | * Userspace must be able to cope with this and cannot assume that the same |
65 | * symbolic property will have the same modeset object ID on all modeset |
66 | * objects. |
67 | * |
68 | * Properties are created by one of the special functions, as explained in |
69 | * detail in the @flags structure member. |
70 | * |
71 | * To actually expose a property it must be attached to each object using |
72 | * drm_object_attach_property(). Currently properties can only be attached to |
73 | * &drm_connector, &drm_crtc and &drm_plane. |
74 | * |
75 | * Properties are also used as the generic metadatatransport for the atomic |
76 | * IOCTL. Everything that was set directly in structures in the legacy modeset |
77 | * IOCTLs (like the plane source or destination windows, or e.g. the links to |
78 | * the CRTC) is exposed as a property with the DRM_MODE_PROP_ATOMIC flag set. |
79 | */ |
80 | struct drm_property { |
81 | /** |
82 | * @head: per-device list of properties, for cleanup. |
83 | */ |
84 | struct list_head head; |
85 | |
86 | /** |
87 | * @base: base KMS object |
88 | */ |
89 | struct drm_mode_object base; |
90 | |
91 | /** |
92 | * @flags: |
93 | * |
94 | * Property flags and type. A property needs to be one of the following |
95 | * types: |
96 | * |
97 | * DRM_MODE_PROP_RANGE |
98 | * Range properties report their minimum and maximum admissible unsigned values. |
99 | * The KMS core verifies that values set by application fit in that |
100 | * range. The range is unsigned. Range properties are created using |
101 | * drm_property_create_range(). |
102 | * |
103 | * DRM_MODE_PROP_SIGNED_RANGE |
104 | * Range properties report their minimum and maximum admissible unsigned values. |
105 | * The KMS core verifies that values set by application fit in that |
106 | * range. The range is signed. Range properties are created using |
107 | * drm_property_create_signed_range(). |
108 | * |
109 | * DRM_MODE_PROP_ENUM |
110 | * Enumerated properties take a numerical value that ranges from 0 to |
111 | * the number of enumerated values defined by the property minus one, |
112 | * and associate a free-formed string name to each value. Applications |
113 | * can retrieve the list of defined value-name pairs and use the |
114 | * numerical value to get and set property instance values. Enum |
115 | * properties are created using drm_property_create_enum(). |
116 | * |
117 | * DRM_MODE_PROP_BITMASK |
118 | * Bitmask properties are enumeration properties that additionally |
119 | * restrict all enumerated values to the 0..63 range. Bitmask property |
120 | * instance values combine one or more of the enumerated bits defined |
121 | * by the property. Bitmask properties are created using |
122 | * drm_property_create_bitmask(). |
123 | * |
124 | * DRM_MODE_PROP_OBJECT |
125 | * Object properties are used to link modeset objects. This is used |
126 | * extensively in the atomic support to create the display pipeline, |
127 | * by linking &drm_framebuffer to &drm_plane, &drm_plane to |
128 | * &drm_crtc and &drm_connector to &drm_crtc. An object property can |
129 | * only link to a specific type of &drm_mode_object, this limit is |
130 | * enforced by the core. Object properties are created using |
131 | * drm_property_create_object(). |
132 | * |
133 | * Object properties work like blob properties, but in a more |
134 | * general fashion. They are limited to atomic drivers and must have |
135 | * the DRM_MODE_PROP_ATOMIC flag set. |
136 | * |
137 | * DRM_MODE_PROP_BLOB |
138 | * Blob properties store a binary blob without any format restriction. |
139 | * The binary blobs are created as KMS standalone objects, and blob |
140 | * property instance values store the ID of their associated blob |
141 | * object. Blob properties are created by calling |
142 | * drm_property_create() with DRM_MODE_PROP_BLOB as the type. |
143 | * |
144 | * Actual blob objects to contain blob data are created using |
145 | * drm_property_create_blob(), or through the corresponding IOCTL. |
146 | * |
147 | * Besides the built-in limit to only accept blob objects blob |
148 | * properties work exactly like object properties. The only reasons |
149 | * blob properties exist is backwards compatibility with existing |
150 | * userspace. |
151 | * |
152 | * In addition a property can have any combination of the below flags: |
153 | * |
154 | * DRM_MODE_PROP_ATOMIC |
155 | * Set for properties which encode atomic modeset state. Such |
156 | * properties are not exposed to legacy userspace. |
157 | * |
158 | * DRM_MODE_PROP_IMMUTABLE |
159 | * Set for properties whose values cannot be changed by |
160 | * userspace. The kernel is allowed to update the value of these |
161 | * properties. This is generally used to expose probe state to |
162 | * userspace, e.g. the EDID, or the connector path property on DP |
163 | * MST sinks. Kernel can update the value of an immutable property |
164 | * by calling drm_object_property_set_value(). |
165 | */ |
166 | uint32_t flags; |
167 | |
168 | /** |
169 | * @name: symbolic name of the properties |
170 | */ |
171 | char name[DRM_PROP_NAME_LEN]; |
172 | |
173 | /** |
174 | * @num_values: size of the @values array. |
175 | */ |
176 | uint32_t num_values; |
177 | |
178 | /** |
179 | * @values: |
180 | * |
181 | * Array with limits and values for the property. The |
182 | * interpretation of these limits is dependent upon the type per @flags. |
183 | */ |
184 | uint64_t *values; |
185 | |
186 | /** |
187 | * @dev: DRM device |
188 | */ |
189 | struct drm_device *dev; |
190 | |
191 | /** |
192 | * @enum_list: |
193 | * |
194 | * List of &drm_prop_enum_list structures with the symbolic names for |
195 | * enum and bitmask values. |
196 | */ |
197 | struct list_head enum_list; |
198 | }; |
199 | |
200 | /** |
201 | * struct drm_property_blob - Blob data for &drm_property |
202 | * @base: base KMS object |
203 | * @dev: DRM device |
204 | * @head_global: entry on the global blob list in |
205 | * &drm_mode_config.property_blob_list. |
206 | * @head_file: entry on the per-file blob list in &drm_file.blobs list. |
207 | * @length: size of the blob in bytes, invariant over the lifetime of the object |
208 | * @data: actual data, embedded at the end of this structure |
209 | * |
210 | * Blobs are used to store bigger values than what fits directly into the 64 |
211 | * bits available for a &drm_property. |
212 | * |
213 | * Blobs are reference counted using drm_property_blob_get() and |
214 | * drm_property_blob_put(). They are created using drm_property_create_blob(). |
215 | */ |
216 | struct drm_property_blob { |
217 | struct drm_mode_object base; |
218 | struct drm_device *dev; |
219 | struct list_head head_global; |
220 | struct list_head head_file; |
221 | size_t length; |
222 | void *data; |
223 | }; |
224 | |
225 | struct drm_prop_enum_list { |
226 | int type; |
227 | const char *name; |
228 | }; |
229 | |
230 | #define obj_to_property(x) container_of(x, struct drm_property, base) |
231 | #define obj_to_blob(x) container_of(x, struct drm_property_blob, base) |
232 | |
233 | /** |
234 | * drm_property_type_is - check the type of a property |
235 | * @property: property to check |
236 | * @type: property type to compare with |
237 | * |
238 | * This is a helper function becauase the uapi encoding of property types is |
239 | * a bit special for historical reasons. |
240 | */ |
241 | static inline bool drm_property_type_is(struct drm_property *property, |
242 | uint32_t type) |
243 | { |
244 | /* instanceof for props.. handles extended type vs original types: */ |
245 | if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) |
246 | return (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) == type; |
247 | return property->flags & type; |
248 | } |
249 | |
250 | struct drm_property *drm_property_create(struct drm_device *dev, |
251 | u32 flags, const char *name, |
252 | int num_values); |
253 | struct drm_property *drm_property_create_enum(struct drm_device *dev, |
254 | u32 flags, const char *name, |
255 | const struct drm_prop_enum_list *props, |
256 | int num_values); |
257 | struct drm_property *drm_property_create_bitmask(struct drm_device *dev, |
258 | u32 flags, const char *name, |
259 | const struct drm_prop_enum_list *props, |
260 | int num_props, |
261 | uint64_t supported_bits); |
262 | struct drm_property *drm_property_create_range(struct drm_device *dev, |
263 | u32 flags, const char *name, |
264 | uint64_t min, uint64_t max); |
265 | struct drm_property *drm_property_create_signed_range(struct drm_device *dev, |
266 | u32 flags, const char *name, |
267 | int64_t min, int64_t max); |
268 | struct drm_property *drm_property_create_object(struct drm_device *dev, |
269 | u32 flags, const char *name, |
270 | uint32_t type); |
271 | struct drm_property *drm_property_create_bool(struct drm_device *dev, |
272 | u32 flags, const char *name); |
273 | int drm_property_add_enum(struct drm_property *property, |
274 | uint64_t value, const char *name); |
275 | void drm_property_destroy(struct drm_device *dev, struct drm_property *property); |
276 | |
277 | struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, |
278 | size_t length, |
279 | const void *data); |
280 | struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev, |
281 | uint32_t id); |
282 | int drm_property_replace_blob_from_id(struct drm_device *dev, |
283 | struct drm_property_blob **blob, |
284 | uint64_t blob_id, |
285 | ssize_t expected_size, |
286 | ssize_t expected_elem_size, |
287 | bool *replaced); |
288 | int drm_property_replace_global_blob(struct drm_device *dev, |
289 | struct drm_property_blob **replace, |
290 | size_t length, |
291 | const void *data, |
292 | struct drm_mode_object *obj_holds_id, |
293 | struct drm_property *prop_holds_id); |
294 | bool drm_property_replace_blob(struct drm_property_blob **blob, |
295 | struct drm_property_blob *new_blob); |
296 | struct drm_property_blob *drm_property_blob_get(struct drm_property_blob *blob); |
297 | void drm_property_blob_put(struct drm_property_blob *blob); |
298 | |
299 | /** |
300 | * drm_property_find - find property object |
301 | * @dev: DRM device |
302 | * @file_priv: drm file to check for lease against. |
303 | * @id: property object id |
304 | * |
305 | * This function looks up the property object specified by id and returns it. |
306 | */ |
307 | static inline struct drm_property *drm_property_find(struct drm_device *dev, |
308 | struct drm_file *file_priv, |
309 | uint32_t id) |
310 | { |
311 | struct drm_mode_object *mo; |
312 | mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_PROPERTY); |
313 | return mo ? obj_to_property(mo) : NULL; |
314 | } |
315 | |
316 | #endif |
317 | |