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