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 /* helper for getconnector and getproperties ioctls */ 389 int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic, 390 bool plane_color_pipeline, 391 uint32_t __user *prop_ptr, 392 uint64_t __user *prop_values, 393 uint32_t *arg_count_props) 394 { 395 int i, ret, count; 396 397 for (i = 0, count = 0; i < obj->properties->count; i++) { 398 struct drm_property *prop = obj->properties->properties[i]; 399 uint64_t val; 400 401 if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic) 402 continue; 403 404 if (plane_color_pipeline && obj->type == DRM_MODE_OBJECT_PLANE) { 405 struct drm_plane *plane = obj_to_plane(obj); 406 407 if (prop == plane->color_encoding_property || 408 prop == plane->color_range_property) 409 continue; 410 } 411 412 if (!plane_color_pipeline && obj->type == DRM_MODE_OBJECT_PLANE) { 413 struct drm_plane *plane = obj_to_plane(obj); 414 415 if (prop == plane->color_pipeline_property) 416 continue; 417 } 418 419 if (*arg_count_props > count) { 420 ret = __drm_object_property_get_value(obj, prop, &val); 421 if (ret) 422 return ret; 423 424 if (put_user(prop->base.id, prop_ptr + count)) 425 return -EFAULT; 426 427 if (put_user(val, prop_values + count)) 428 return -EFAULT; 429 } 430 431 count++; 432 } 433 *arg_count_props = count; 434 435 return 0; 436 } 437 438 /** 439 * drm_mode_obj_get_properties_ioctl - get the current value of a object's property 440 * @dev: DRM device 441 * @data: ioctl data 442 * @file_priv: DRM file info 443 * 444 * This function retrieves the current value for an object's property. Compared 445 * to the connector specific ioctl this one is extended to also work on crtc and 446 * plane objects. 447 * 448 * Called by the user via ioctl. 449 * 450 * Returns: 451 * Zero on success, negative errno on failure. 452 */ 453 int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, 454 struct drm_file *file_priv) 455 { 456 struct drm_mode_obj_get_properties *arg = data; 457 struct drm_mode_object *obj; 458 struct drm_modeset_acquire_ctx ctx; 459 int ret = 0; 460 461 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 462 return -EOPNOTSUPP; 463 464 DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); 465 466 obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type); 467 if (!obj) { 468 ret = -ENOENT; 469 goto out; 470 } 471 if (!obj->properties) { 472 ret = -EINVAL; 473 goto out_unref; 474 } 475 476 ret = drm_mode_object_get_properties(obj, file_priv->atomic, 477 file_priv->plane_color_pipeline, 478 (uint32_t __user *)(unsigned long)(arg->props_ptr), 479 (uint64_t __user *)(unsigned long)(arg->prop_values_ptr), 480 &arg->count_props); 481 482 out_unref: 483 drm_mode_object_put(obj); 484 out: 485 DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); 486 return ret; 487 } 488 489 struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj, 490 uint32_t prop_id) 491 { 492 int i; 493 494 for (i = 0; i < obj->properties->count; i++) 495 if (obj->properties->properties[i]->base.id == prop_id) 496 return obj->properties->properties[i]; 497 498 return NULL; 499 } 500 EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_mode_obj_find_prop_id); 501 502 static int set_property_legacy(struct drm_mode_object *obj, 503 struct drm_property *prop, 504 uint64_t prop_value) 505 { 506 struct drm_device *dev = prop->dev; 507 struct drm_mode_object *ref; 508 struct drm_modeset_acquire_ctx ctx; 509 int ret = -EINVAL; 510 511 if (!drm_property_change_valid_get(prop, prop_value, &ref)) 512 return -EINVAL; 513 514 DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); 515 switch (obj->type) { 516 case DRM_MODE_OBJECT_CONNECTOR: 517 ret = drm_connector_set_obj_prop(obj, prop, prop_value); 518 break; 519 case DRM_MODE_OBJECT_CRTC: 520 ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value); 521 break; 522 case DRM_MODE_OBJECT_PLANE: 523 ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj), 524 prop, prop_value); 525 break; 526 } 527 drm_property_change_valid_put(prop, ref); 528 DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); 529 530 return ret; 531 } 532 533 static int set_property_atomic(struct drm_mode_object *obj, 534 struct drm_file *file_priv, 535 struct drm_property *prop, 536 uint64_t prop_value) 537 { 538 struct drm_device *dev = prop->dev; 539 struct drm_atomic_state *state; 540 struct drm_modeset_acquire_ctx ctx; 541 int ret; 542 543 state = drm_atomic_state_alloc(dev); 544 if (!state) 545 return -ENOMEM; 546 547 drm_modeset_acquire_init(&ctx, 0); 548 state->acquire_ctx = &ctx; 549 550 retry: 551 if (prop == state->dev->mode_config.dpms_property) { 552 if (obj->type != DRM_MODE_OBJECT_CONNECTOR) { 553 ret = -EINVAL; 554 goto out; 555 } 556 557 ret = drm_atomic_connector_commit_dpms(state, 558 obj_to_connector(obj), 559 prop_value); 560 } else { 561 ret = drm_atomic_set_property(state, file_priv, obj, prop, prop_value, false); 562 if (ret) 563 goto out; 564 ret = drm_atomic_commit(state); 565 } 566 out: 567 if (ret == -EDEADLK) { 568 drm_atomic_state_clear(state); 569 drm_modeset_backoff(&ctx); 570 goto retry; 571 } 572 573 drm_atomic_state_put(state); 574 575 drm_modeset_drop_locks(&ctx); 576 drm_modeset_acquire_fini(&ctx); 577 578 return ret; 579 } 580 581 int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, 582 struct drm_file *file_priv) 583 { 584 struct drm_mode_obj_set_property *arg = data; 585 struct drm_mode_object *arg_obj; 586 struct drm_property *property; 587 int ret = -EINVAL; 588 589 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 590 return -EOPNOTSUPP; 591 592 arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type); 593 if (!arg_obj) 594 return -ENOENT; 595 596 if (!arg_obj->properties) 597 goto out_unref; 598 599 property = drm_mode_obj_find_prop_id(arg_obj, arg->prop_id); 600 if (!property) 601 goto out_unref; 602 603 if (drm_drv_uses_atomic_modeset(property->dev)) 604 ret = set_property_atomic(arg_obj, file_priv, property, arg->value); 605 else 606 ret = set_property_legacy(arg_obj, property, arg->value); 607 608 out_unref: 609 drm_mode_object_put(arg_obj); 610 return ret; 611 } 612