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 <drm/drmP.h> 24 #include <drm/drm_connector.h> 25 #include <drm/drm_edid.h> 26 #include <drm/drm_encoder.h> 27 28 #include "drm_crtc_internal.h" 29 #include "drm_internal.h" 30 31 /** 32 * DOC: overview 33 * 34 * In DRM connectors are the general abstraction for display sinks, and include 35 * als fixed panels or anything else that can display pixels in some form. As 36 * opposed to all other KMS objects representing hardware (like CRTC, encoder or 37 * plane abstractions) connectors can be hotplugged and unplugged at runtime. 38 * Hence they are reference-counted using drm_connector_reference() and 39 * drm_connector_unreference(). 40 * 41 * KMS driver must create, initialize, register and attach at a &struct 42 * drm_connector for each such sink. The instance is created as other KMS 43 * objects and initialized by setting the following fields. The connector is 44 * initialized with a call to drm_connector_init() with a pointer to the 45 * &struct drm_connector_funcs and a connector type, and then exposed to 46 * userspace with a call to drm_connector_register(). 47 * 48 * Connectors must be attached to an encoder to be used. For devices that map 49 * connectors to encoders 1:1, the connector should be attached at 50 * initialization time with a call to drm_mode_connector_attach_encoder(). The 51 * driver must also set the &drm_connector.encoder field to point to the 52 * attached encoder. 53 * 54 * For connectors which are not fixed (like built-in panels) the driver needs to 55 * support hotplug notifications. The simplest way to do that is by using the 56 * probe helpers, see drm_kms_helper_poll_init() for connectors which don't have 57 * hardware support for hotplug interrupts. Connectors with hardware hotplug 58 * support can instead use e.g. drm_helper_hpd_irq_event(). 59 */ 60 61 struct drm_conn_prop_enum_list { 62 int type; 63 const char *name; 64 struct ida ida; 65 }; 66 67 /* 68 * Connector and encoder types. 69 */ 70 static struct drm_conn_prop_enum_list drm_connector_enum_list[] = { 71 { DRM_MODE_CONNECTOR_Unknown, "Unknown" }, 72 { DRM_MODE_CONNECTOR_VGA, "VGA" }, 73 { DRM_MODE_CONNECTOR_DVII, "DVI-I" }, 74 { DRM_MODE_CONNECTOR_DVID, "DVI-D" }, 75 { DRM_MODE_CONNECTOR_DVIA, "DVI-A" }, 76 { DRM_MODE_CONNECTOR_Composite, "Composite" }, 77 { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" }, 78 { DRM_MODE_CONNECTOR_LVDS, "LVDS" }, 79 { DRM_MODE_CONNECTOR_Component, "Component" }, 80 { DRM_MODE_CONNECTOR_9PinDIN, "DIN" }, 81 { DRM_MODE_CONNECTOR_DisplayPort, "DP" }, 82 { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" }, 83 { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" }, 84 { DRM_MODE_CONNECTOR_TV, "TV" }, 85 { DRM_MODE_CONNECTOR_eDP, "eDP" }, 86 { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" }, 87 { DRM_MODE_CONNECTOR_DSI, "DSI" }, 88 { DRM_MODE_CONNECTOR_DPI, "DPI" }, 89 }; 90 91 void drm_connector_ida_init(void) 92 { 93 int i; 94 95 for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++) 96 ida_init(&drm_connector_enum_list[i].ida); 97 } 98 99 void drm_connector_ida_destroy(void) 100 { 101 int i; 102 103 for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++) 104 ida_destroy(&drm_connector_enum_list[i].ida); 105 } 106 107 /** 108 * drm_connector_get_cmdline_mode - reads the user's cmdline mode 109 * @connector: connector to quwery 110 * 111 * The kernel supports per-connector configuration of its consoles through 112 * use of the video= parameter. This function parses that option and 113 * extracts the user's specified mode (or enable/disable status) for a 114 * particular connector. This is typically only used during the early fbdev 115 * setup. 116 */ 117 static void drm_connector_get_cmdline_mode(struct drm_connector *connector) 118 { 119 struct drm_cmdline_mode *mode = &connector->cmdline_mode; 120 char *option = NULL; 121 122 if (fb_get_options(connector->name, &option)) 123 return; 124 125 if (!drm_mode_parse_command_line_for_connector(option, 126 connector, 127 mode)) 128 return; 129 130 if (mode->force) { 131 const char *s; 132 133 switch (mode->force) { 134 case DRM_FORCE_OFF: 135 s = "OFF"; 136 break; 137 case DRM_FORCE_ON_DIGITAL: 138 s = "ON - dig"; 139 break; 140 default: 141 case DRM_FORCE_ON: 142 s = "ON"; 143 break; 144 } 145 146 DRM_INFO("forcing %s connector %s\n", connector->name, s); 147 connector->force = mode->force; 148 } 149 150 DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n", 151 connector->name, 152 mode->xres, mode->yres, 153 mode->refresh_specified ? mode->refresh : 60, 154 mode->rb ? " reduced blanking" : "", 155 mode->margins ? " with margins" : "", 156 mode->interlace ? " interlaced" : ""); 157 } 158 159 static void drm_connector_free(struct kref *kref) 160 { 161 struct drm_connector *connector = 162 container_of(kref, struct drm_connector, base.refcount); 163 struct drm_device *dev = connector->dev; 164 165 drm_mode_object_unregister(dev, &connector->base); 166 connector->funcs->destroy(connector); 167 } 168 169 /** 170 * drm_connector_init - Init a preallocated connector 171 * @dev: DRM device 172 * @connector: the connector to init 173 * @funcs: callbacks for this connector 174 * @connector_type: user visible type of the connector 175 * 176 * Initialises a preallocated connector. Connectors should be 177 * subclassed as part of driver connector objects. 178 * 179 * Returns: 180 * Zero on success, error code on failure. 181 */ 182 int drm_connector_init(struct drm_device *dev, 183 struct drm_connector *connector, 184 const struct drm_connector_funcs *funcs, 185 int connector_type) 186 { 187 struct drm_mode_config *config = &dev->mode_config; 188 int ret; 189 struct ida *connector_ida = 190 &drm_connector_enum_list[connector_type].ida; 191 192 ret = drm_mode_object_get_reg(dev, &connector->base, 193 DRM_MODE_OBJECT_CONNECTOR, 194 false, drm_connector_free); 195 if (ret) 196 return ret; 197 198 connector->base.properties = &connector->properties; 199 connector->dev = dev; 200 connector->funcs = funcs; 201 202 ret = ida_simple_get(&config->connector_ida, 0, 0, GFP_KERNEL); 203 if (ret < 0) 204 goto out_put; 205 connector->index = ret; 206 ret = 0; 207 208 connector->connector_type = connector_type; 209 connector->connector_type_id = 210 ida_simple_get(connector_ida, 1, 0, GFP_KERNEL); 211 if (connector->connector_type_id < 0) { 212 ret = connector->connector_type_id; 213 goto out_put_id; 214 } 215 connector->name = 216 kasprintf(GFP_KERNEL, "%s-%d", 217 drm_connector_enum_list[connector_type].name, 218 connector->connector_type_id); 219 if (!connector->name) { 220 ret = -ENOMEM; 221 goto out_put_type_id; 222 } 223 224 INIT_LIST_HEAD(&connector->probed_modes); 225 INIT_LIST_HEAD(&connector->modes); 226 mutex_init(&connector->mutex); 227 connector->edid_blob_ptr = NULL; 228 connector->status = connector_status_unknown; 229 230 drm_connector_get_cmdline_mode(connector); 231 232 /* We should add connectors at the end to avoid upsetting the connector 233 * index too much. */ 234 spin_lock_irq(&config->connector_list_lock); 235 list_add_tail(&connector->head, &config->connector_list); 236 config->num_connector++; 237 spin_unlock_irq(&config->connector_list_lock); 238 239 if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL) 240 drm_object_attach_property(&connector->base, 241 config->edid_property, 242 0); 243 244 drm_object_attach_property(&connector->base, 245 config->dpms_property, 0); 246 247 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { 248 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0); 249 } 250 251 connector->debugfs_entry = NULL; 252 out_put_type_id: 253 if (ret) 254 ida_simple_remove(connector_ida, connector->connector_type_id); 255 out_put_id: 256 if (ret) 257 ida_simple_remove(&config->connector_ida, connector->index); 258 out_put: 259 if (ret) 260 drm_mode_object_unregister(dev, &connector->base); 261 262 return ret; 263 } 264 EXPORT_SYMBOL(drm_connector_init); 265 266 /** 267 * drm_mode_connector_attach_encoder - attach a connector to an encoder 268 * @connector: connector to attach 269 * @encoder: encoder to attach @connector to 270 * 271 * This function links up a connector to an encoder. Note that the routing 272 * restrictions between encoders and crtcs are exposed to userspace through the 273 * possible_clones and possible_crtcs bitmasks. 274 * 275 * Returns: 276 * Zero on success, negative errno on failure. 277 */ 278 int drm_mode_connector_attach_encoder(struct drm_connector *connector, 279 struct drm_encoder *encoder) 280 { 281 int i; 282 283 /* 284 * In the past, drivers have attempted to model the static association 285 * of connector to encoder in simple connector/encoder devices using a 286 * direct assignment of connector->encoder = encoder. This connection 287 * is a logical one and the responsibility of the core, so drivers are 288 * expected not to mess with this. 289 * 290 * Note that the error return should've been enough here, but a large 291 * majority of drivers ignores the return value, so add in a big WARN 292 * to get people's attention. 293 */ 294 if (WARN_ON(connector->encoder)) 295 return -EINVAL; 296 297 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 298 if (connector->encoder_ids[i] == 0) { 299 connector->encoder_ids[i] = encoder->base.id; 300 return 0; 301 } 302 } 303 return -ENOMEM; 304 } 305 EXPORT_SYMBOL(drm_mode_connector_attach_encoder); 306 307 static void drm_mode_remove(struct drm_connector *connector, 308 struct drm_display_mode *mode) 309 { 310 list_del(&mode->head); 311 drm_mode_destroy(connector->dev, mode); 312 } 313 314 /** 315 * drm_connector_cleanup - cleans up an initialised connector 316 * @connector: connector to cleanup 317 * 318 * Cleans up the connector but doesn't free the object. 319 */ 320 void drm_connector_cleanup(struct drm_connector *connector) 321 { 322 struct drm_device *dev = connector->dev; 323 struct drm_display_mode *mode, *t; 324 325 /* The connector should have been removed from userspace long before 326 * it is finally destroyed. 327 */ 328 if (WARN_ON(connector->registered)) 329 drm_connector_unregister(connector); 330 331 if (connector->tile_group) { 332 drm_mode_put_tile_group(dev, connector->tile_group); 333 connector->tile_group = NULL; 334 } 335 336 list_for_each_entry_safe(mode, t, &connector->probed_modes, head) 337 drm_mode_remove(connector, mode); 338 339 list_for_each_entry_safe(mode, t, &connector->modes, head) 340 drm_mode_remove(connector, mode); 341 342 ida_simple_remove(&drm_connector_enum_list[connector->connector_type].ida, 343 connector->connector_type_id); 344 345 ida_simple_remove(&dev->mode_config.connector_ida, 346 connector->index); 347 348 kfree(connector->display_info.bus_formats); 349 drm_mode_object_unregister(dev, &connector->base); 350 kfree(connector->name); 351 connector->name = NULL; 352 spin_lock_irq(&dev->mode_config.connector_list_lock); 353 list_del(&connector->head); 354 dev->mode_config.num_connector--; 355 spin_unlock_irq(&dev->mode_config.connector_list_lock); 356 357 WARN_ON(connector->state && !connector->funcs->atomic_destroy_state); 358 if (connector->state && connector->funcs->atomic_destroy_state) 359 connector->funcs->atomic_destroy_state(connector, 360 connector->state); 361 362 mutex_destroy(&connector->mutex); 363 364 memset(connector, 0, sizeof(*connector)); 365 } 366 EXPORT_SYMBOL(drm_connector_cleanup); 367 368 /** 369 * drm_connector_register - register a connector 370 * @connector: the connector to register 371 * 372 * Register userspace interfaces for a connector 373 * 374 * Returns: 375 * Zero on success, error code on failure. 376 */ 377 int drm_connector_register(struct drm_connector *connector) 378 { 379 int ret = 0; 380 381 if (!connector->dev->registered) 382 return 0; 383 384 mutex_lock(&connector->mutex); 385 if (connector->registered) 386 goto unlock; 387 388 ret = drm_sysfs_connector_add(connector); 389 if (ret) 390 goto unlock; 391 392 ret = drm_debugfs_connector_add(connector); 393 if (ret) { 394 goto err_sysfs; 395 } 396 397 if (connector->funcs->late_register) { 398 ret = connector->funcs->late_register(connector); 399 if (ret) 400 goto err_debugfs; 401 } 402 403 drm_mode_object_register(connector->dev, &connector->base); 404 405 connector->registered = true; 406 goto unlock; 407 408 err_debugfs: 409 drm_debugfs_connector_remove(connector); 410 err_sysfs: 411 drm_sysfs_connector_remove(connector); 412 unlock: 413 mutex_unlock(&connector->mutex); 414 return ret; 415 } 416 EXPORT_SYMBOL(drm_connector_register); 417 418 /** 419 * drm_connector_unregister - unregister a connector 420 * @connector: the connector to unregister 421 * 422 * Unregister userspace interfaces for a connector 423 */ 424 void drm_connector_unregister(struct drm_connector *connector) 425 { 426 mutex_lock(&connector->mutex); 427 if (!connector->registered) { 428 mutex_unlock(&connector->mutex); 429 return; 430 } 431 432 if (connector->funcs->early_unregister) 433 connector->funcs->early_unregister(connector); 434 435 drm_sysfs_connector_remove(connector); 436 drm_debugfs_connector_remove(connector); 437 438 connector->registered = false; 439 mutex_unlock(&connector->mutex); 440 } 441 EXPORT_SYMBOL(drm_connector_unregister); 442 443 void drm_connector_unregister_all(struct drm_device *dev) 444 { 445 struct drm_connector *connector; 446 struct drm_connector_list_iter conn_iter; 447 448 drm_connector_list_iter_get(dev, &conn_iter); 449 drm_for_each_connector_iter(connector, &conn_iter) 450 drm_connector_unregister(connector); 451 drm_connector_list_iter_put(&conn_iter); 452 } 453 454 int drm_connector_register_all(struct drm_device *dev) 455 { 456 struct drm_connector *connector; 457 struct drm_connector_list_iter conn_iter; 458 int ret = 0; 459 460 drm_connector_list_iter_get(dev, &conn_iter); 461 drm_for_each_connector_iter(connector, &conn_iter) { 462 ret = drm_connector_register(connector); 463 if (ret) 464 break; 465 } 466 drm_connector_list_iter_put(&conn_iter); 467 468 if (ret) 469 drm_connector_unregister_all(dev); 470 return ret; 471 } 472 473 /** 474 * drm_get_connector_status_name - return a string for connector status 475 * @status: connector status to compute name of 476 * 477 * In contrast to the other drm_get_*_name functions this one here returns a 478 * const pointer and hence is threadsafe. 479 */ 480 const char *drm_get_connector_status_name(enum drm_connector_status status) 481 { 482 if (status == connector_status_connected) 483 return "connected"; 484 else if (status == connector_status_disconnected) 485 return "disconnected"; 486 else 487 return "unknown"; 488 } 489 EXPORT_SYMBOL(drm_get_connector_status_name); 490 491 #ifdef CONFIG_LOCKDEP 492 static struct lockdep_map connector_list_iter_dep_map = { 493 .name = "drm_connector_list_iter" 494 }; 495 #endif 496 497 /** 498 * drm_connector_list_iter_get - initialize a connector_list iterator 499 * @dev: DRM device 500 * @iter: connector_list iterator 501 * 502 * Sets @iter up to walk the &drm_mode_config.connector_list of @dev. @iter 503 * must always be cleaned up again by calling drm_connector_list_iter_put(). 504 * Iteration itself happens using drm_connector_list_iter_next() or 505 * drm_for_each_connector_iter(). 506 */ 507 void drm_connector_list_iter_get(struct drm_device *dev, 508 struct drm_connector_list_iter *iter) 509 { 510 iter->dev = dev; 511 iter->conn = NULL; 512 lock_acquire_shared_recursive(&connector_list_iter_dep_map, 0, 1, NULL, _RET_IP_); 513 } 514 EXPORT_SYMBOL(drm_connector_list_iter_get); 515 516 /** 517 * drm_connector_list_iter_next - return next connector 518 * @iter: connectr_list iterator 519 * 520 * Returns the next connector for @iter, or NULL when the list walk has 521 * completed. 522 */ 523 struct drm_connector * 524 drm_connector_list_iter_next(struct drm_connector_list_iter *iter) 525 { 526 struct drm_connector *old_conn = iter->conn; 527 struct drm_mode_config *config = &iter->dev->mode_config; 528 struct list_head *lhead; 529 unsigned long flags; 530 531 spin_lock_irqsave(&config->connector_list_lock, flags); 532 lhead = old_conn ? &old_conn->head : &config->connector_list; 533 534 do { 535 if (lhead->next == &config->connector_list) { 536 iter->conn = NULL; 537 break; 538 } 539 540 lhead = lhead->next; 541 iter->conn = list_entry(lhead, struct drm_connector, head); 542 543 /* loop until it's not a zombie connector */ 544 } while (!kref_get_unless_zero(&iter->conn->base.refcount)); 545 spin_unlock_irqrestore(&config->connector_list_lock, flags); 546 547 if (old_conn) 548 drm_connector_unreference(old_conn); 549 550 return iter->conn; 551 } 552 EXPORT_SYMBOL(drm_connector_list_iter_next); 553 554 /** 555 * drm_connector_list_iter_put - tear down a connector_list iterator 556 * @iter: connector_list iterator 557 * 558 * Tears down @iter and releases any resources (like &drm_connector references) 559 * acquired while walking the list. This must always be called, both when the 560 * iteration completes fully or when it was aborted without walking the entire 561 * list. 562 */ 563 void drm_connector_list_iter_put(struct drm_connector_list_iter *iter) 564 { 565 iter->dev = NULL; 566 if (iter->conn) 567 drm_connector_unreference(iter->conn); 568 lock_release(&connector_list_iter_dep_map, 0, _RET_IP_); 569 } 570 EXPORT_SYMBOL(drm_connector_list_iter_put); 571 572 static const struct drm_prop_enum_list drm_subpixel_enum_list[] = { 573 { SubPixelUnknown, "Unknown" }, 574 { SubPixelHorizontalRGB, "Horizontal RGB" }, 575 { SubPixelHorizontalBGR, "Horizontal BGR" }, 576 { SubPixelVerticalRGB, "Vertical RGB" }, 577 { SubPixelVerticalBGR, "Vertical BGR" }, 578 { SubPixelNone, "None" }, 579 }; 580 581 /** 582 * drm_get_subpixel_order_name - return a string for a given subpixel enum 583 * @order: enum of subpixel_order 584 * 585 * Note you could abuse this and return something out of bounds, but that 586 * would be a caller error. No unscrubbed user data should make it here. 587 */ 588 const char *drm_get_subpixel_order_name(enum subpixel_order order) 589 { 590 return drm_subpixel_enum_list[order].name; 591 } 592 EXPORT_SYMBOL(drm_get_subpixel_order_name); 593 594 static const struct drm_prop_enum_list drm_dpms_enum_list[] = { 595 { DRM_MODE_DPMS_ON, "On" }, 596 { DRM_MODE_DPMS_STANDBY, "Standby" }, 597 { DRM_MODE_DPMS_SUSPEND, "Suspend" }, 598 { DRM_MODE_DPMS_OFF, "Off" } 599 }; 600 DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) 601 602 /** 603 * drm_display_info_set_bus_formats - set the supported bus formats 604 * @info: display info to store bus formats in 605 * @formats: array containing the supported bus formats 606 * @num_formats: the number of entries in the fmts array 607 * 608 * Store the supported bus formats in display info structure. 609 * See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for 610 * a full list of available formats. 611 */ 612 int drm_display_info_set_bus_formats(struct drm_display_info *info, 613 const u32 *formats, 614 unsigned int num_formats) 615 { 616 u32 *fmts = NULL; 617 618 if (!formats && num_formats) 619 return -EINVAL; 620 621 if (formats && num_formats) { 622 fmts = kmemdup(formats, sizeof(*formats) * num_formats, 623 GFP_KERNEL); 624 if (!fmts) 625 return -ENOMEM; 626 } 627 628 kfree(info->bus_formats); 629 info->bus_formats = fmts; 630 info->num_bus_formats = num_formats; 631 632 return 0; 633 } 634 EXPORT_SYMBOL(drm_display_info_set_bus_formats); 635 636 /* Optional connector properties. */ 637 static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = { 638 { DRM_MODE_SCALE_NONE, "None" }, 639 { DRM_MODE_SCALE_FULLSCREEN, "Full" }, 640 { DRM_MODE_SCALE_CENTER, "Center" }, 641 { DRM_MODE_SCALE_ASPECT, "Full aspect" }, 642 }; 643 644 static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = { 645 { DRM_MODE_PICTURE_ASPECT_NONE, "Automatic" }, 646 { DRM_MODE_PICTURE_ASPECT_4_3, "4:3" }, 647 { DRM_MODE_PICTURE_ASPECT_16_9, "16:9" }, 648 }; 649 650 static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = { 651 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ 652 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ 653 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ 654 }; 655 DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list) 656 657 static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = { 658 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ 659 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ 660 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ 661 }; 662 DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name, 663 drm_dvi_i_subconnector_enum_list) 664 665 static const struct drm_prop_enum_list drm_tv_select_enum_list[] = { 666 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ 667 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ 668 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ 669 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ 670 { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */ 671 }; 672 DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list) 673 674 static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = { 675 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ 676 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ 677 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ 678 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ 679 { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */ 680 }; 681 DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name, 682 drm_tv_subconnector_enum_list) 683 684 /** 685 * DOC: standard connector properties 686 * 687 * DRM connectors have a few standardized properties: 688 * 689 * EDID: 690 * Blob property which contains the current EDID read from the sink. This 691 * is useful to parse sink identification information like vendor, model 692 * and serial. Drivers should update this property by calling 693 * drm_mode_connector_update_edid_property(), usually after having parsed 694 * the EDID using drm_add_edid_modes(). Userspace cannot change this 695 * property. 696 * DPMS: 697 * Legacy property for setting the power state of the connector. For atomic 698 * drivers this is only provided for backwards compatibility with existing 699 * drivers, it remaps to controlling the "ACTIVE" property on the CRTC the 700 * connector is linked to. Drivers should never set this property directly, 701 * it is handled by the DRM core by calling the &drm_connector_funcs.dpms 702 * callback. Atomic drivers should implement this hook using 703 * drm_atomic_helper_connector_dpms(). This is the only property standard 704 * connector property that userspace can change. 705 * PATH: 706 * Connector path property to identify how this sink is physically 707 * connected. Used by DP MST. This should be set by calling 708 * drm_mode_connector_set_path_property(), in the case of DP MST with the 709 * path property the MST manager created. Userspace cannot change this 710 * property. 711 * TILE: 712 * Connector tile group property to indicate how a set of DRM connector 713 * compose together into one logical screen. This is used by both high-res 714 * external screens (often only using a single cable, but exposing multiple 715 * DP MST sinks), or high-res integrated panels (like dual-link DSI) which 716 * are not gen-locked. Note that for tiled panels which are genlocked, like 717 * dual-link LVDS or dual-link DSI, the driver should try to not expose the 718 * tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers 719 * should update this value using drm_mode_connector_set_tile_property(). 720 * Userspace cannot change this property. 721 * 722 * Connectors also have one standardized atomic property: 723 * 724 * CRTC_ID: 725 * Mode object ID of the &drm_crtc this connector should be connected to. 726 */ 727 728 int drm_connector_create_standard_properties(struct drm_device *dev) 729 { 730 struct drm_property *prop; 731 732 prop = drm_property_create(dev, DRM_MODE_PROP_BLOB | 733 DRM_MODE_PROP_IMMUTABLE, 734 "EDID", 0); 735 if (!prop) 736 return -ENOMEM; 737 dev->mode_config.edid_property = prop; 738 739 prop = drm_property_create_enum(dev, 0, 740 "DPMS", drm_dpms_enum_list, 741 ARRAY_SIZE(drm_dpms_enum_list)); 742 if (!prop) 743 return -ENOMEM; 744 dev->mode_config.dpms_property = prop; 745 746 prop = drm_property_create(dev, 747 DRM_MODE_PROP_BLOB | 748 DRM_MODE_PROP_IMMUTABLE, 749 "PATH", 0); 750 if (!prop) 751 return -ENOMEM; 752 dev->mode_config.path_property = prop; 753 754 prop = drm_property_create(dev, 755 DRM_MODE_PROP_BLOB | 756 DRM_MODE_PROP_IMMUTABLE, 757 "TILE", 0); 758 if (!prop) 759 return -ENOMEM; 760 dev->mode_config.tile_property = prop; 761 762 return 0; 763 } 764 765 /** 766 * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties 767 * @dev: DRM device 768 * 769 * Called by a driver the first time a DVI-I connector is made. 770 */ 771 int drm_mode_create_dvi_i_properties(struct drm_device *dev) 772 { 773 struct drm_property *dvi_i_selector; 774 struct drm_property *dvi_i_subconnector; 775 776 if (dev->mode_config.dvi_i_select_subconnector_property) 777 return 0; 778 779 dvi_i_selector = 780 drm_property_create_enum(dev, 0, 781 "select subconnector", 782 drm_dvi_i_select_enum_list, 783 ARRAY_SIZE(drm_dvi_i_select_enum_list)); 784 dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector; 785 786 dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 787 "subconnector", 788 drm_dvi_i_subconnector_enum_list, 789 ARRAY_SIZE(drm_dvi_i_subconnector_enum_list)); 790 dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector; 791 792 return 0; 793 } 794 EXPORT_SYMBOL(drm_mode_create_dvi_i_properties); 795 796 /** 797 * drm_create_tv_properties - create TV specific connector properties 798 * @dev: DRM device 799 * @num_modes: number of different TV formats (modes) supported 800 * @modes: array of pointers to strings containing name of each format 801 * 802 * Called by a driver's TV initialization routine, this function creates 803 * the TV specific connector properties for a given device. Caller is 804 * responsible for allocating a list of format names and passing them to 805 * this routine. 806 */ 807 int drm_mode_create_tv_properties(struct drm_device *dev, 808 unsigned int num_modes, 809 const char * const modes[]) 810 { 811 struct drm_property *tv_selector; 812 struct drm_property *tv_subconnector; 813 unsigned int i; 814 815 if (dev->mode_config.tv_select_subconnector_property) 816 return 0; 817 818 /* 819 * Basic connector properties 820 */ 821 tv_selector = drm_property_create_enum(dev, 0, 822 "select subconnector", 823 drm_tv_select_enum_list, 824 ARRAY_SIZE(drm_tv_select_enum_list)); 825 if (!tv_selector) 826 goto nomem; 827 828 dev->mode_config.tv_select_subconnector_property = tv_selector; 829 830 tv_subconnector = 831 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 832 "subconnector", 833 drm_tv_subconnector_enum_list, 834 ARRAY_SIZE(drm_tv_subconnector_enum_list)); 835 if (!tv_subconnector) 836 goto nomem; 837 dev->mode_config.tv_subconnector_property = tv_subconnector; 838 839 /* 840 * Other, TV specific properties: margins & TV modes. 841 */ 842 dev->mode_config.tv_left_margin_property = 843 drm_property_create_range(dev, 0, "left margin", 0, 100); 844 if (!dev->mode_config.tv_left_margin_property) 845 goto nomem; 846 847 dev->mode_config.tv_right_margin_property = 848 drm_property_create_range(dev, 0, "right margin", 0, 100); 849 if (!dev->mode_config.tv_right_margin_property) 850 goto nomem; 851 852 dev->mode_config.tv_top_margin_property = 853 drm_property_create_range(dev, 0, "top margin", 0, 100); 854 if (!dev->mode_config.tv_top_margin_property) 855 goto nomem; 856 857 dev->mode_config.tv_bottom_margin_property = 858 drm_property_create_range(dev, 0, "bottom margin", 0, 100); 859 if (!dev->mode_config.tv_bottom_margin_property) 860 goto nomem; 861 862 dev->mode_config.tv_mode_property = 863 drm_property_create(dev, DRM_MODE_PROP_ENUM, 864 "mode", num_modes); 865 if (!dev->mode_config.tv_mode_property) 866 goto nomem; 867 868 for (i = 0; i < num_modes; i++) 869 drm_property_add_enum(dev->mode_config.tv_mode_property, i, 870 i, modes[i]); 871 872 dev->mode_config.tv_brightness_property = 873 drm_property_create_range(dev, 0, "brightness", 0, 100); 874 if (!dev->mode_config.tv_brightness_property) 875 goto nomem; 876 877 dev->mode_config.tv_contrast_property = 878 drm_property_create_range(dev, 0, "contrast", 0, 100); 879 if (!dev->mode_config.tv_contrast_property) 880 goto nomem; 881 882 dev->mode_config.tv_flicker_reduction_property = 883 drm_property_create_range(dev, 0, "flicker reduction", 0, 100); 884 if (!dev->mode_config.tv_flicker_reduction_property) 885 goto nomem; 886 887 dev->mode_config.tv_overscan_property = 888 drm_property_create_range(dev, 0, "overscan", 0, 100); 889 if (!dev->mode_config.tv_overscan_property) 890 goto nomem; 891 892 dev->mode_config.tv_saturation_property = 893 drm_property_create_range(dev, 0, "saturation", 0, 100); 894 if (!dev->mode_config.tv_saturation_property) 895 goto nomem; 896 897 dev->mode_config.tv_hue_property = 898 drm_property_create_range(dev, 0, "hue", 0, 100); 899 if (!dev->mode_config.tv_hue_property) 900 goto nomem; 901 902 return 0; 903 nomem: 904 return -ENOMEM; 905 } 906 EXPORT_SYMBOL(drm_mode_create_tv_properties); 907 908 /** 909 * drm_mode_create_scaling_mode_property - create scaling mode property 910 * @dev: DRM device 911 * 912 * Called by a driver the first time it's needed, must be attached to desired 913 * connectors. 914 */ 915 int drm_mode_create_scaling_mode_property(struct drm_device *dev) 916 { 917 struct drm_property *scaling_mode; 918 919 if (dev->mode_config.scaling_mode_property) 920 return 0; 921 922 scaling_mode = 923 drm_property_create_enum(dev, 0, "scaling mode", 924 drm_scaling_mode_enum_list, 925 ARRAY_SIZE(drm_scaling_mode_enum_list)); 926 927 dev->mode_config.scaling_mode_property = scaling_mode; 928 929 return 0; 930 } 931 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); 932 933 /** 934 * drm_mode_create_aspect_ratio_property - create aspect ratio property 935 * @dev: DRM device 936 * 937 * Called by a driver the first time it's needed, must be attached to desired 938 * connectors. 939 * 940 * Returns: 941 * Zero on success, negative errno on failure. 942 */ 943 int drm_mode_create_aspect_ratio_property(struct drm_device *dev) 944 { 945 if (dev->mode_config.aspect_ratio_property) 946 return 0; 947 948 dev->mode_config.aspect_ratio_property = 949 drm_property_create_enum(dev, 0, "aspect ratio", 950 drm_aspect_ratio_enum_list, 951 ARRAY_SIZE(drm_aspect_ratio_enum_list)); 952 953 if (dev->mode_config.aspect_ratio_property == NULL) 954 return -ENOMEM; 955 956 return 0; 957 } 958 EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property); 959 960 /** 961 * drm_mode_create_suggested_offset_properties - create suggests offset properties 962 * @dev: DRM device 963 * 964 * Create the the suggested x/y offset property for connectors. 965 */ 966 int drm_mode_create_suggested_offset_properties(struct drm_device *dev) 967 { 968 if (dev->mode_config.suggested_x_property && dev->mode_config.suggested_y_property) 969 return 0; 970 971 dev->mode_config.suggested_x_property = 972 drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested X", 0, 0xffffffff); 973 974 dev->mode_config.suggested_y_property = 975 drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested Y", 0, 0xffffffff); 976 977 if (dev->mode_config.suggested_x_property == NULL || 978 dev->mode_config.suggested_y_property == NULL) 979 return -ENOMEM; 980 return 0; 981 } 982 EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties); 983 984 /** 985 * drm_mode_connector_set_path_property - set tile property on connector 986 * @connector: connector to set property on. 987 * @path: path to use for property; must not be NULL. 988 * 989 * This creates a property to expose to userspace to specify a 990 * connector path. This is mainly used for DisplayPort MST where 991 * connectors have a topology and we want to allow userspace to give 992 * them more meaningful names. 993 * 994 * Returns: 995 * Zero on success, negative errno on failure. 996 */ 997 int drm_mode_connector_set_path_property(struct drm_connector *connector, 998 const char *path) 999 { 1000 struct drm_device *dev = connector->dev; 1001 int ret; 1002 1003 ret = drm_property_replace_global_blob(dev, 1004 &connector->path_blob_ptr, 1005 strlen(path) + 1, 1006 path, 1007 &connector->base, 1008 dev->mode_config.path_property); 1009 return ret; 1010 } 1011 EXPORT_SYMBOL(drm_mode_connector_set_path_property); 1012 1013 /** 1014 * drm_mode_connector_set_tile_property - set tile property on connector 1015 * @connector: connector to set property on. 1016 * 1017 * This looks up the tile information for a connector, and creates a 1018 * property for userspace to parse if it exists. The property is of 1019 * the form of 8 integers using ':' as a separator. 1020 * 1021 * Returns: 1022 * Zero on success, errno on failure. 1023 */ 1024 int drm_mode_connector_set_tile_property(struct drm_connector *connector) 1025 { 1026 struct drm_device *dev = connector->dev; 1027 char tile[256]; 1028 int ret; 1029 1030 if (!connector->has_tile) { 1031 ret = drm_property_replace_global_blob(dev, 1032 &connector->tile_blob_ptr, 1033 0, 1034 NULL, 1035 &connector->base, 1036 dev->mode_config.tile_property); 1037 return ret; 1038 } 1039 1040 snprintf(tile, 256, "%d:%d:%d:%d:%d:%d:%d:%d", 1041 connector->tile_group->id, connector->tile_is_single_monitor, 1042 connector->num_h_tile, connector->num_v_tile, 1043 connector->tile_h_loc, connector->tile_v_loc, 1044 connector->tile_h_size, connector->tile_v_size); 1045 1046 ret = drm_property_replace_global_blob(dev, 1047 &connector->tile_blob_ptr, 1048 strlen(tile) + 1, 1049 tile, 1050 &connector->base, 1051 dev->mode_config.tile_property); 1052 return ret; 1053 } 1054 EXPORT_SYMBOL(drm_mode_connector_set_tile_property); 1055 1056 /** 1057 * drm_mode_connector_update_edid_property - update the edid property of a connector 1058 * @connector: drm connector 1059 * @edid: new value of the edid property 1060 * 1061 * This function creates a new blob modeset object and assigns its id to the 1062 * connector's edid property. 1063 * 1064 * Returns: 1065 * Zero on success, negative errno on failure. 1066 */ 1067 int drm_mode_connector_update_edid_property(struct drm_connector *connector, 1068 const struct edid *edid) 1069 { 1070 struct drm_device *dev = connector->dev; 1071 size_t size = 0; 1072 int ret; 1073 1074 /* ignore requests to set edid when overridden */ 1075 if (connector->override_edid) 1076 return 0; 1077 1078 if (edid) 1079 size = EDID_LENGTH * (1 + edid->extensions); 1080 1081 ret = drm_property_replace_global_blob(dev, 1082 &connector->edid_blob_ptr, 1083 size, 1084 edid, 1085 &connector->base, 1086 dev->mode_config.edid_property); 1087 return ret; 1088 } 1089 EXPORT_SYMBOL(drm_mode_connector_update_edid_property); 1090 1091 int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj, 1092 struct drm_property *property, 1093 uint64_t value) 1094 { 1095 int ret = -EINVAL; 1096 struct drm_connector *connector = obj_to_connector(obj); 1097 1098 /* Do DPMS ourselves */ 1099 if (property == connector->dev->mode_config.dpms_property) { 1100 ret = (*connector->funcs->dpms)(connector, (int)value); 1101 } else if (connector->funcs->set_property) 1102 ret = connector->funcs->set_property(connector, property, value); 1103 1104 /* store the property value if successful */ 1105 if (!ret) 1106 drm_object_property_set_value(&connector->base, property, value); 1107 return ret; 1108 } 1109 1110 int drm_mode_connector_property_set_ioctl(struct drm_device *dev, 1111 void *data, struct drm_file *file_priv) 1112 { 1113 struct drm_mode_connector_set_property *conn_set_prop = data; 1114 struct drm_mode_obj_set_property obj_set_prop = { 1115 .value = conn_set_prop->value, 1116 .prop_id = conn_set_prop->prop_id, 1117 .obj_id = conn_set_prop->connector_id, 1118 .obj_type = DRM_MODE_OBJECT_CONNECTOR 1119 }; 1120 1121 /* It does all the locking and checking we need */ 1122 return drm_mode_obj_set_property_ioctl(dev, &obj_set_prop, file_priv); 1123 } 1124 1125 static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *connector) 1126 { 1127 /* For atomic drivers only state objects are synchronously updated and 1128 * protected by modeset locks, so check those first. */ 1129 if (connector->state) 1130 return connector->state->best_encoder; 1131 return connector->encoder; 1132 } 1133 1134 static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode, 1135 const struct drm_file *file_priv) 1136 { 1137 /* 1138 * If user-space hasn't configured the driver to expose the stereo 3D 1139 * modes, don't expose them. 1140 */ 1141 if (!file_priv->stereo_allowed && drm_mode_is_stereo(mode)) 1142 return false; 1143 1144 return true; 1145 } 1146 1147 int drm_mode_getconnector(struct drm_device *dev, void *data, 1148 struct drm_file *file_priv) 1149 { 1150 struct drm_mode_get_connector *out_resp = data; 1151 struct drm_connector *connector; 1152 struct drm_encoder *encoder; 1153 struct drm_display_mode *mode; 1154 int mode_count = 0; 1155 int encoders_count = 0; 1156 int ret = 0; 1157 int copied = 0; 1158 int i; 1159 struct drm_mode_modeinfo u_mode; 1160 struct drm_mode_modeinfo __user *mode_ptr; 1161 uint32_t __user *encoder_ptr; 1162 1163 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1164 return -EINVAL; 1165 1166 memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); 1167 1168 connector = drm_connector_lookup(dev, out_resp->connector_id); 1169 if (!connector) 1170 return -ENOENT; 1171 1172 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); 1173 encoder = drm_connector_get_encoder(connector); 1174 if (encoder) 1175 out_resp->encoder_id = encoder->base.id; 1176 else 1177 out_resp->encoder_id = 0; 1178 1179 ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic, 1180 (uint32_t __user *)(unsigned long)(out_resp->props_ptr), 1181 (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr), 1182 &out_resp->count_props); 1183 drm_modeset_unlock(&dev->mode_config.connection_mutex); 1184 if (ret) 1185 goto out_unref; 1186 1187 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) 1188 if (connector->encoder_ids[i] != 0) 1189 encoders_count++; 1190 1191 if ((out_resp->count_encoders >= encoders_count) && encoders_count) { 1192 copied = 0; 1193 encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr); 1194 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 1195 if (connector->encoder_ids[i] != 0) { 1196 if (put_user(connector->encoder_ids[i], 1197 encoder_ptr + copied)) { 1198 ret = -EFAULT; 1199 goto out_unref; 1200 } 1201 copied++; 1202 } 1203 } 1204 } 1205 out_resp->count_encoders = encoders_count; 1206 1207 out_resp->connector_id = connector->base.id; 1208 out_resp->connector_type = connector->connector_type; 1209 out_resp->connector_type_id = connector->connector_type_id; 1210 1211 mutex_lock(&dev->mode_config.mutex); 1212 if (out_resp->count_modes == 0) { 1213 connector->funcs->fill_modes(connector, 1214 dev->mode_config.max_width, 1215 dev->mode_config.max_height); 1216 } 1217 1218 out_resp->mm_width = connector->display_info.width_mm; 1219 out_resp->mm_height = connector->display_info.height_mm; 1220 out_resp->subpixel = connector->display_info.subpixel_order; 1221 out_resp->connection = connector->status; 1222 1223 /* delayed so we get modes regardless of pre-fill_modes state */ 1224 list_for_each_entry(mode, &connector->modes, head) 1225 if (drm_mode_expose_to_userspace(mode, file_priv)) 1226 mode_count++; 1227 1228 /* 1229 * This ioctl is called twice, once to determine how much space is 1230 * needed, and the 2nd time to fill it. 1231 */ 1232 if ((out_resp->count_modes >= mode_count) && mode_count) { 1233 copied = 0; 1234 mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr; 1235 list_for_each_entry(mode, &connector->modes, head) { 1236 if (!drm_mode_expose_to_userspace(mode, file_priv)) 1237 continue; 1238 1239 drm_mode_convert_to_umode(&u_mode, mode); 1240 if (copy_to_user(mode_ptr + copied, 1241 &u_mode, sizeof(u_mode))) { 1242 ret = -EFAULT; 1243 goto out; 1244 } 1245 copied++; 1246 } 1247 } 1248 out_resp->count_modes = mode_count; 1249 out: 1250 mutex_unlock(&dev->mode_config.mutex); 1251 out_unref: 1252 drm_connector_unreference(connector); 1253 1254 return ret; 1255 } 1256 1257 1258 /** 1259 * DOC: Tile group 1260 * 1261 * Tile groups are used to represent tiled monitors with a unique integer 1262 * identifier. Tiled monitors using DisplayID v1.3 have a unique 8-byte handle, 1263 * we store this in a tile group, so we have a common identifier for all tiles 1264 * in a monitor group. The property is called "TILE". Drivers can manage tile 1265 * groups using drm_mode_create_tile_group(), drm_mode_put_tile_group() and 1266 * drm_mode_get_tile_group(). But this is only needed for internal panels where 1267 * the tile group information is exposed through a non-standard way. 1268 */ 1269 1270 static void drm_tile_group_free(struct kref *kref) 1271 { 1272 struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount); 1273 struct drm_device *dev = tg->dev; 1274 mutex_lock(&dev->mode_config.idr_mutex); 1275 idr_remove(&dev->mode_config.tile_idr, tg->id); 1276 mutex_unlock(&dev->mode_config.idr_mutex); 1277 kfree(tg); 1278 } 1279 1280 /** 1281 * drm_mode_put_tile_group - drop a reference to a tile group. 1282 * @dev: DRM device 1283 * @tg: tile group to drop reference to. 1284 * 1285 * drop reference to tile group and free if 0. 1286 */ 1287 void drm_mode_put_tile_group(struct drm_device *dev, 1288 struct drm_tile_group *tg) 1289 { 1290 kref_put(&tg->refcount, drm_tile_group_free); 1291 } 1292 EXPORT_SYMBOL(drm_mode_put_tile_group); 1293 1294 /** 1295 * drm_mode_get_tile_group - get a reference to an existing tile group 1296 * @dev: DRM device 1297 * @topology: 8-bytes unique per monitor. 1298 * 1299 * Use the unique bytes to get a reference to an existing tile group. 1300 * 1301 * RETURNS: 1302 * tile group or NULL if not found. 1303 */ 1304 struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev, 1305 char topology[8]) 1306 { 1307 struct drm_tile_group *tg; 1308 int id; 1309 mutex_lock(&dev->mode_config.idr_mutex); 1310 idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) { 1311 if (!memcmp(tg->group_data, topology, 8)) { 1312 if (!kref_get_unless_zero(&tg->refcount)) 1313 tg = NULL; 1314 mutex_unlock(&dev->mode_config.idr_mutex); 1315 return tg; 1316 } 1317 } 1318 mutex_unlock(&dev->mode_config.idr_mutex); 1319 return NULL; 1320 } 1321 EXPORT_SYMBOL(drm_mode_get_tile_group); 1322 1323 /** 1324 * drm_mode_create_tile_group - create a tile group from a displayid description 1325 * @dev: DRM device 1326 * @topology: 8-bytes unique per monitor. 1327 * 1328 * Create a tile group for the unique monitor, and get a unique 1329 * identifier for the tile group. 1330 * 1331 * RETURNS: 1332 * new tile group or error. 1333 */ 1334 struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev, 1335 char topology[8]) 1336 { 1337 struct drm_tile_group *tg; 1338 int ret; 1339 1340 tg = kzalloc(sizeof(*tg), GFP_KERNEL); 1341 if (!tg) 1342 return ERR_PTR(-ENOMEM); 1343 1344 kref_init(&tg->refcount); 1345 memcpy(tg->group_data, topology, 8); 1346 tg->dev = dev; 1347 1348 mutex_lock(&dev->mode_config.idr_mutex); 1349 ret = idr_alloc(&dev->mode_config.tile_idr, tg, 1, 0, GFP_KERNEL); 1350 if (ret >= 0) { 1351 tg->id = ret; 1352 } else { 1353 kfree(tg); 1354 tg = ERR_PTR(ret); 1355 } 1356 1357 mutex_unlock(&dev->mode_config.idr_mutex); 1358 return tg; 1359 } 1360 EXPORT_SYMBOL(drm_mode_create_tile_group); 1361