Merge branches 'clk-of-refcount', 'clk-mmio-fixed-clock', 'clk-remove-clps', 'clk...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / drm_mode_object.c
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 #include <linux/export.h>
24 #include <drm/drmP.h>
25 #include <drm/drm_mode_object.h>
26 #include <drm/drm_atomic.h>
27
28 #include "drm_crtc_internal.h"
29
30 /*
31  * Internal function to assign a slot in the object idr and optionally
32  * register the object into the idr.
33  */
34 int __drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj,
35                           uint32_t obj_type, bool register_obj,
36                           void (*obj_free_cb)(struct kref *kref))
37 {
38         int ret;
39
40         mutex_lock(&dev->mode_config.idr_mutex);
41         ret = idr_alloc(&dev->mode_config.crtc_idr, register_obj ? obj : NULL,
42                         1, 0, GFP_KERNEL);
43         if (ret >= 0) {
44                 /*
45                  * Set up the object linking under the protection of the idr
46                  * lock so that other users can't see inconsistent state.
47                  */
48                 obj->id = ret;
49                 obj->type = obj_type;
50                 if (obj_free_cb) {
51                         obj->free_cb = obj_free_cb;
52                         kref_init(&obj->refcount);
53                 }
54         }
55         mutex_unlock(&dev->mode_config.idr_mutex);
56
57         return ret < 0 ? ret : 0;
58 }
59
60 /**
61  * drm_mode_object_add - allocate a new modeset identifier
62  * @dev: DRM device
63  * @obj: object pointer, used to generate unique ID
64  * @obj_type: object type
65  *
66  * Create a unique identifier based on @ptr in @dev's identifier space.  Used
67  * for tracking modes, CRTCs and connectors.
68  *
69  * Returns:
70  * Zero on success, error code on failure.
71  */
72 int drm_mode_object_add(struct drm_device *dev,
73                         struct drm_mode_object *obj, uint32_t obj_type)
74 {
75         return __drm_mode_object_add(dev, obj, obj_type, true, NULL);
76 }
77
78 void drm_mode_object_register(struct drm_device *dev,
79                               struct drm_mode_object *obj)
80 {
81         mutex_lock(&dev->mode_config.idr_mutex);
82         idr_replace(&dev->mode_config.crtc_idr, obj, obj->id);
83         mutex_unlock(&dev->mode_config.idr_mutex);
84 }
85
86 /**
87  * drm_mode_object_unregister - free a modeset identifer
88  * @dev: DRM device
89  * @object: object to free
90  *
91  * Free @id from @dev's unique identifier pool.
92  * This function can be called multiple times, and guards against
93  * multiple removals.
94  * These modeset identifiers are _not_ reference counted. Hence don't use this
95  * for reference counted modeset objects like framebuffers.
96  */
97 void drm_mode_object_unregister(struct drm_device *dev,
98                                 struct drm_mode_object *object)
99 {
100         mutex_lock(&dev->mode_config.idr_mutex);
101         if (object->id) {
102                 idr_remove(&dev->mode_config.crtc_idr, object->id);
103                 object->id = 0;
104         }
105         mutex_unlock(&dev->mode_config.idr_mutex);
106 }
107
108 /**
109  * drm_lease_required - check types which must be leased to be used
110  * @type: type of object
111  *
112  * Returns whether the provided type of drm_mode_object must
113  * be owned or leased to be used by a process.
114  */
115 bool drm_mode_object_lease_required(uint32_t type)
116 {
117         switch(type) {
118         case DRM_MODE_OBJECT_CRTC:
119         case DRM_MODE_OBJECT_CONNECTOR:
120         case DRM_MODE_OBJECT_PLANE:
121                 return true;
122         default:
123                 return false;
124         }
125 }
126
127 struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
128                                                struct drm_file *file_priv,
129                                                uint32_t id, uint32_t type)
130 {
131         struct drm_mode_object *obj = NULL;
132
133         mutex_lock(&dev->mode_config.idr_mutex);
134         obj = idr_find(&dev->mode_config.crtc_idr, id);
135         if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type)
136                 obj = NULL;
137         if (obj && obj->id != id)
138                 obj = NULL;
139
140         if (obj && drm_mode_object_lease_required(obj->type) &&
141             !_drm_lease_held(file_priv, obj->id))
142                 obj = NULL;
143
144         if (obj && obj->free_cb) {
145                 if (!kref_get_unless_zero(&obj->refcount))
146                         obj = NULL;
147         }
148         mutex_unlock(&dev->mode_config.idr_mutex);
149
150         return obj;
151 }
152
153 /**
154  * drm_mode_object_find - look up a drm object with static lifetime
155  * @dev: drm device
156  * @file_priv: drm file
157  * @id: id of the mode object
158  * @type: type of the mode object
159  *
160  * This function is used to look up a modeset object. It will acquire a
161  * reference for reference counted objects. This reference must be dropped again
162  * by callind drm_mode_object_put().
163  */
164 struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
165                 struct drm_file *file_priv,
166                 uint32_t id, uint32_t type)
167 {
168         struct drm_mode_object *obj = NULL;
169
170         obj = __drm_mode_object_find(dev, file_priv, id, type);
171         return obj;
172 }
173 EXPORT_SYMBOL(drm_mode_object_find);
174
175 /**
176  * drm_mode_object_put - release a mode object reference
177  * @obj: DRM mode object
178  *
179  * This function decrements the object's refcount if it is a refcounted modeset
180  * object. It is a no-op on any other object. This is used to drop references
181  * acquired with drm_mode_object_get().
182  */
183 void drm_mode_object_put(struct drm_mode_object *obj)
184 {
185         if (obj->free_cb) {
186                 DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, kref_read(&obj->refcount));
187                 kref_put(&obj->refcount, obj->free_cb);
188         }
189 }
190 EXPORT_SYMBOL(drm_mode_object_put);
191
192 /**
193  * drm_mode_object_get - acquire a mode object reference
194  * @obj: DRM mode object
195  *
196  * This function increments the object's refcount if it is a refcounted modeset
197  * object. It is a no-op on any other object. References should be dropped again
198  * by calling drm_mode_object_put().
199  */
200 void drm_mode_object_get(struct drm_mode_object *obj)
201 {
202         if (obj->free_cb) {
203                 DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, kref_read(&obj->refcount));
204                 kref_get(&obj->refcount);
205         }
206 }
207 EXPORT_SYMBOL(drm_mode_object_get);
208
209 /**
210  * drm_object_attach_property - attach a property to a modeset object
211  * @obj: drm modeset object
212  * @property: property to attach
213  * @init_val: initial value of the property
214  *
215  * This attaches the given property to the modeset object with the given initial
216  * value. Currently this function cannot fail since the properties are stored in
217  * a statically sized array.
218  */
219 void drm_object_attach_property(struct drm_mode_object *obj,
220                                 struct drm_property *property,
221                                 uint64_t init_val)
222 {
223         int count = obj->properties->count;
224
225         if (count == DRM_OBJECT_MAX_PROPERTY) {
226                 WARN(1, "Failed to attach object property (type: 0x%x). Please "
227                         "increase DRM_OBJECT_MAX_PROPERTY by 1 for each time "
228                         "you see this message on the same object type.\n",
229                         obj->type);
230                 return;
231         }
232
233         obj->properties->properties[count] = property;
234         obj->properties->values[count] = init_val;
235         obj->properties->count++;
236 }
237 EXPORT_SYMBOL(drm_object_attach_property);
238
239 /**
240  * drm_object_property_set_value - set the value of a property
241  * @obj: drm mode object to set property value for
242  * @property: property to set
243  * @val: value the property should be set to
244  *
245  * This function sets a given property on a given object. This function only
246  * changes the software state of the property, it does not call into the
247  * driver's ->set_property callback.
248  *
249  * Note that atomic drivers should not have any need to call this, the core will
250  * ensure consistency of values reported back to userspace through the
251  * appropriate ->atomic_get_property callback. Only legacy drivers should call
252  * this function to update the tracked value (after clamping and other
253  * restrictions have been applied).
254  *
255  * Returns:
256  * Zero on success, error code on failure.
257  */
258 int drm_object_property_set_value(struct drm_mode_object *obj,
259                                   struct drm_property *property, uint64_t val)
260 {
261         int i;
262
263         WARN_ON(drm_drv_uses_atomic_modeset(property->dev) &&
264                 !(property->flags & DRM_MODE_PROP_IMMUTABLE));
265
266         for (i = 0; i < obj->properties->count; i++) {
267                 if (obj->properties->properties[i] == property) {
268                         obj->properties->values[i] = val;
269                         return 0;
270                 }
271         }
272
273         return -EINVAL;
274 }
275 EXPORT_SYMBOL(drm_object_property_set_value);
276
277 static int __drm_object_property_get_value(struct drm_mode_object *obj,
278                                            struct drm_property *property,
279                                            uint64_t *val)
280 {
281         int i;
282
283         /* read-only properties bypass atomic mechanism and still store
284          * their value in obj->properties->values[].. mostly to avoid
285          * having to deal w/ EDID and similar props in atomic paths:
286          */
287         if (drm_drv_uses_atomic_modeset(property->dev) &&
288                         !(property->flags & DRM_MODE_PROP_IMMUTABLE))
289                 return drm_atomic_get_property(obj, property, val);
290
291         for (i = 0; i < obj->properties->count; i++) {
292                 if (obj->properties->properties[i] == property) {
293                         *val = obj->properties->values[i];
294                         return 0;
295                 }
296
297         }
298
299         return -EINVAL;
300 }
301
302 /**
303  * drm_object_property_get_value - retrieve the value of a property
304  * @obj: drm mode object to get property value from
305  * @property: property to retrieve
306  * @val: storage for the property value
307  *
308  * This function retrieves the softare state of the given property for the given
309  * property. Since there is no driver callback to retrieve the current property
310  * value this might be out of sync with the hardware, depending upon the driver
311  * and property.
312  *
313  * Atomic drivers should never call this function directly, the core will read
314  * out property values through the various ->atomic_get_property callbacks.
315  *
316  * Returns:
317  * Zero on success, error code on failure.
318  */
319 int drm_object_property_get_value(struct drm_mode_object *obj,
320                                   struct drm_property *property, uint64_t *val)
321 {
322         WARN_ON(drm_drv_uses_atomic_modeset(property->dev));
323
324         return __drm_object_property_get_value(obj, property, val);
325 }
326 EXPORT_SYMBOL(drm_object_property_get_value);
327
328 /* helper for getconnector and getproperties ioctls */
329 int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic,
330                                    uint32_t __user *prop_ptr,
331                                    uint64_t __user *prop_values,
332                                    uint32_t *arg_count_props)
333 {
334         int i, ret, count;
335
336         for (i = 0, count = 0; i < obj->properties->count; i++) {
337                 struct drm_property *prop = obj->properties->properties[i];
338                 uint64_t val;
339
340                 if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic)
341                         continue;
342
343                 if (*arg_count_props > count) {
344                         ret = __drm_object_property_get_value(obj, prop, &val);
345                         if (ret)
346                                 return ret;
347
348                         if (put_user(prop->base.id, prop_ptr + count))
349                                 return -EFAULT;
350
351                         if (put_user(val, prop_values + count))
352                                 return -EFAULT;
353                 }
354
355                 count++;
356         }
357         *arg_count_props = count;
358
359         return 0;
360 }
361
362 /**
363  * drm_mode_obj_get_properties_ioctl - get the current value of a object's property
364  * @dev: DRM device
365  * @data: ioctl data
366  * @file_priv: DRM file info
367  *
368  * This function retrieves the current value for an object's property. Compared
369  * to the connector specific ioctl this one is extended to also work on crtc and
370  * plane objects.
371  *
372  * Called by the user via ioctl.
373  *
374  * Returns:
375  * Zero on success, negative errno on failure.
376  */
377 int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
378                                       struct drm_file *file_priv)
379 {
380         struct drm_mode_obj_get_properties *arg = data;
381         struct drm_mode_object *obj;
382         int ret = 0;
383
384         if (!drm_core_check_feature(dev, DRIVER_MODESET))
385                 return -EOPNOTSUPP;
386
387         drm_modeset_lock_all(dev);
388
389         obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
390         if (!obj) {
391                 ret = -ENOENT;
392                 goto out;
393         }
394         if (!obj->properties) {
395                 ret = -EINVAL;
396                 goto out_unref;
397         }
398
399         ret = drm_mode_object_get_properties(obj, file_priv->atomic,
400                         (uint32_t __user *)(unsigned long)(arg->props_ptr),
401                         (uint64_t __user *)(unsigned long)(arg->prop_values_ptr),
402                         &arg->count_props);
403
404 out_unref:
405         drm_mode_object_put(obj);
406 out:
407         drm_modeset_unlock_all(dev);
408         return ret;
409 }
410
411 struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
412                                                uint32_t prop_id)
413 {
414         int i;
415
416         for (i = 0; i < obj->properties->count; i++)
417                 if (obj->properties->properties[i]->base.id == prop_id)
418                         return obj->properties->properties[i];
419
420         return NULL;
421 }
422
423 static int set_property_legacy(struct drm_mode_object *obj,
424                                struct drm_property *prop,
425                                uint64_t prop_value)
426 {
427         struct drm_device *dev = prop->dev;
428         struct drm_mode_object *ref;
429         int ret = -EINVAL;
430
431         if (!drm_property_change_valid_get(prop, prop_value, &ref))
432                 return -EINVAL;
433
434         drm_modeset_lock_all(dev);
435         switch (obj->type) {
436         case DRM_MODE_OBJECT_CONNECTOR:
437                 ret = drm_connector_set_obj_prop(obj, prop, prop_value);
438                 break;
439         case DRM_MODE_OBJECT_CRTC:
440                 ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
441                 break;
442         case DRM_MODE_OBJECT_PLANE:
443                 ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj),
444                                                   prop, prop_value);
445                 break;
446         }
447         drm_property_change_valid_put(prop, ref);
448         drm_modeset_unlock_all(dev);
449
450         return ret;
451 }
452
453 static int set_property_atomic(struct drm_mode_object *obj,
454                                struct drm_property *prop,
455                                uint64_t prop_value)
456 {
457         struct drm_device *dev = prop->dev;
458         struct drm_atomic_state *state;
459         struct drm_modeset_acquire_ctx ctx;
460         int ret;
461
462         state = drm_atomic_state_alloc(dev);
463         if (!state)
464                 return -ENOMEM;
465
466         drm_modeset_acquire_init(&ctx, 0);
467         state->acquire_ctx = &ctx;
468 retry:
469         if (prop == state->dev->mode_config.dpms_property) {
470                 if (obj->type != DRM_MODE_OBJECT_CONNECTOR) {
471                         ret = -EINVAL;
472                         goto out;
473                 }
474
475                 ret = drm_atomic_connector_commit_dpms(state,
476                                                        obj_to_connector(obj),
477                                                        prop_value);
478         } else {
479                 ret = drm_atomic_set_property(state, obj, prop, prop_value);
480                 if (ret)
481                         goto out;
482                 ret = drm_atomic_commit(state);
483         }
484 out:
485         if (ret == -EDEADLK) {
486                 drm_atomic_state_clear(state);
487                 drm_modeset_backoff(&ctx);
488                 goto retry;
489         }
490
491         drm_atomic_state_put(state);
492
493         drm_modeset_drop_locks(&ctx);
494         drm_modeset_acquire_fini(&ctx);
495
496         return ret;
497 }
498
499 int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
500                                     struct drm_file *file_priv)
501 {
502         struct drm_mode_obj_set_property *arg = data;
503         struct drm_mode_object *arg_obj;
504         struct drm_property *property;
505         int ret = -EINVAL;
506
507         if (!drm_core_check_feature(dev, DRIVER_MODESET))
508                 return -EOPNOTSUPP;
509
510         arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
511         if (!arg_obj)
512                 return -ENOENT;
513
514         if (!arg_obj->properties)
515                 goto out_unref;
516
517         property = drm_mode_obj_find_prop_id(arg_obj, arg->prop_id);
518         if (!property)
519                 goto out_unref;
520
521         if (drm_drv_uses_atomic_modeset(property->dev))
522                 ret = set_property_atomic(arg_obj, property, arg->value);
523         else
524                 ret = set_property_legacy(arg_obj, property, arg->value);
525
526 out_unref:
527         drm_mode_object_put(arg_obj);
528         return ret;
529 }