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